Merge "platform: msm-shared: Ability to flash only one volume for UBIFS partitions"
diff --git a/AndroidBoot.mk b/AndroidBoot.mk
index b27a1a0..1b336e3 100644
--- a/AndroidBoot.mk
+++ b/AndroidBoot.mk
@@ -20,13 +20,17 @@
ifeq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),true)
VERIFIED_BOOT := VERIFIED_BOOT=1
else
- VERIFIED_BOOT := VERIFEID_BOOT=0
+ VERIFIED_BOOT := VERIFIED_BOOT=0
endif
ifneq ($(TARGET_BUILD_VARIANT),user)
DEVICE_STATUS := DEFAULT_UNLOCK=true
endif
+ifeq ($(TARGET_BUILD_VARIANT),user)
+ BUILD_VARIANT := USER_BUILD_VARIANT=true
+endif
+
ifeq ($(TARGET_BOARD_PLATFORM),msm8660)
BOOTLOADER_PLATFORM := msm8660_surf
endif
@@ -41,7 +45,7 @@
# ELF binary for ABOOT
TARGET_ABOOT_ELF := $(PRODUCT_OUT)/aboot.elf
$(TARGET_ABOOT_ELF): ABOOT_CLEAN | $(ABOOT_OUT)
- $(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=../../../$(ABOOT_OUT) $(BOOTLOADER_PLATFORM) $(EMMC_BOOT) $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(DEVICE_STATUS)
+ $(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=../../../$(ABOOT_OUT) $(BOOTLOADER_PLATFORM) $(EMMC_BOOT) $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(DEVICE_STATUS) $(BUILD_VARIANT)
# NAND variant output
TARGET_NAND_BOOTLOADER := $(PRODUCT_OUT)/appsboot.mbn
@@ -70,7 +74,7 @@
# Top level for eMMC variant targets
$(TARGET_EMMC_BOOTLOADER): emmc_appsbootldr_clean | $(EMMC_BOOTLOADER_OUT) $(INSTALLED_KEYSTOREIMAGE_TARGET)
- $(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=../../../$(EMMC_BOOTLOADER_OUT) $(BOOTLOADER_PLATFORM) EMMC_BOOT=1 $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(DEVICE_STATUS)
+ $(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=../../../$(EMMC_BOOTLOADER_OUT) $(BOOTLOADER_PLATFORM) EMMC_BOOT=1 $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(DEVICE_STATUS) $(BUILD_VARIANT)
# Keep build NAND & eMMC as default for targets still using TARGET_BOOTLOADER
TARGET_BOOTLOADER := $(PRODUCT_OUT)/EMMCBOOT.MBN
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index ccf95c8..5451150 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -57,6 +57,10 @@
#include <boot_device.h>
#include <boot_verifier.h>
#include <image_verify.h>
+#include <decompress.h>
+#if USE_RPMB_FOR_DEVINFO
+#include <rpmb.h>
+#endif
#if DEVICE_TREE
#include <libfdt.h>
@@ -68,6 +72,7 @@
#include "bootimg.h"
#include "fastboot.h"
#include "sparse_format.h"
+#include "meta_format.h"
#include "mmc.h"
#include "devinfo.h"
#include "board.h"
@@ -138,6 +143,7 @@
static const char *battchg_pause = " androidboot.mode=charger";
static const char *auth_kernel = " androidboot.authorized_kernel=true";
static const char *secondary_gpt_enable = " gpt";
+static const char *mdtp_activated_flag = " mdtp";
static const char *baseband_apq = " androidboot.baseband=apq";
static const char *baseband_msm = " androidboot.baseband=msm";
@@ -157,11 +163,12 @@
static bool boot_into_ffbm;
static char target_boot_params[64];
static bool boot_reason_alarm;
+static bool devinfo_present = true;
/* Assuming unauthorized kernel image by default */
static int auth_kernel_img = 0;
-static device_info device = {DEVICE_MAGIC, 0, 0, 0, 0, {0}};
+static device_info device = {DEVICE_MAGIC, 0, 0, 0, 0, {0}, {0},{0}};
struct atag_ptbl_entry
{
@@ -242,6 +249,10 @@
bool gpt_exists = partition_gpt_exists();
int have_target_boot_params = 0;
char *boot_dev_buf = NULL;
+ bool is_mdtp_activated = 0;
+#ifdef MDTP_SUPPORT
+ mdtp_activated(&is_mdtp_activated);
+#endif /* MDTP_SUPPORT */
if (cmdline && cmdline[0]) {
cmdline_len = strlen(cmdline);
@@ -263,6 +274,9 @@
if (boot_into_recovery && gpt_exists)
cmdline_len += strlen(secondary_gpt_enable);
+ if(is_mdtp_activated)
+ cmdline_len += strlen(mdtp_activated_flag);
+
if (boot_into_ffbm) {
cmdline_len += strlen(androidboot_mode);
cmdline_len += strlen(ffbm_mode_string);
@@ -391,6 +405,12 @@
while ((*dst++ = *src++));
}
+ if (is_mdtp_activated) {
+ src = mdtp_activated_flag;
+ if (have_cmdline) --dst;
+ while ((*dst++ = *src++));
+ }
+
if (boot_into_ffbm) {
src = androidboot_mode;
if (have_cmdline) --dst;
@@ -625,7 +645,7 @@
#if VERIFIED_BOOT
/* Write protect the device info */
- if (mmc_write_protect("devinfo", 1))
+ if (target_build_variant_user() && devinfo_present && mmc_write_protect("devinfo", 1))
{
dprintf(INFO, "Failed to write protect dev info\n");
ASSERT(0);
@@ -739,18 +759,6 @@
set_tamper_flag(device.is_tampered);
#endif
- if(device.is_tampered)
- {
- write_device_info_mmc(&device);
- #ifdef TZ_TAMPER_FUSE
- set_tamper_fuse_cmd();
- #endif
- #ifdef ASSERT_ON_TAMPER
- dprintf(CRITICAL, "Device is tampered. Asserting..\n");
- ASSERT(0);
- #endif
- }
-
#if VERIFIED_BOOT
if(boot_verify_get_state() == RED)
{
@@ -768,6 +776,19 @@
}
}
#endif
+
+ if(device.is_tampered)
+ {
+ write_device_info_mmc(&device);
+ #ifdef TZ_TAMPER_FUSE
+ set_tamper_fuse_cmd();
+ #endif
+ #ifdef ASSERT_ON_TAMPER
+ dprintf(CRITICAL, "Device is tampered. Asserting..\n");
+ ASSERT(0);
+ #endif
+ }
+
}
static bool check_format_bit()
@@ -854,6 +875,14 @@
unsigned imagesize_actual;
unsigned second_actual = 0;
+ unsigned int out_len = 0;
+ unsigned int out_avai_len = 0;
+ unsigned char *out_addr = NULL;
+ uint32_t dtb_offset = 0;
+ unsigned char *kernel_start_addr = NULL;
+ unsigned int kernel_size = 0;
+ int rc;
+
#if DEVICE_TREE
struct dt_table *table;
struct dt_entry dt_entry;
@@ -861,8 +890,7 @@
uint32_t dt_actual;
uint32_t dt_hdr_size;
#endif
- BUF_DMA_ALIGN(kbuf, BOOT_IMG_MAX_PAGE_SIZE);
- struct kernel64_hdr *kptr = (void*) kbuf;
+ struct kernel64_hdr *kptr = NULL;
if (check_format_bit())
boot_into_recovery = 1;
@@ -923,45 +951,50 @@
page_mask = page_size - 1;
}
- /* Read the next page to get kernel Image header
- * which lives in the second page for arm64 targets.
- */
-
- if (mmc_read(ptn + page_size, (uint32_t *) kbuf, page_size)) {
- dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
- return -1;
- }
-
- /*
- * Update the kernel/ramdisk/tags address if the boot image header
- * has default values, these default values come from mkbootimg when
- * the boot image is flashed using fastboot flash:raw
- */
- update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
-
- /* Get virtual addresses since the hdr saves physical addresses. */
- hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
- hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
- hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
-
kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
- /* Check if the addresses in the header are valid. */
- if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
- check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
+ image_addr = (unsigned char *)target_get_scratch_address();
+
+#if DEVICE_TREE
+ dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
+ imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
+#else
+ imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
+#endif
+
+#if VERIFIED_BOOT
+ boot_verifier_init();
+#endif
+
+ if (check_aboot_addr_range_overlap((uint32_t) image_addr, imagesize_actual))
{
- dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");
+ dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
return -1;
}
-#ifndef DEVICE_TREE
- if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
+ /*
+ * Update loading flow of bootimage to support compressed/uncompressed
+ * bootimage on both 64bit and 32bit platform.
+ * 1. Load bootimage from emmc partition onto DDR.
+ * 2. Check if bootimage is gzip format. If yes, decompress compressed kernel
+ * 3. Check kernel header and update kernel load addr for 64bit and 32bit
+ * platform accordingly.
+ * 4. Sanity Check on kernel_addr and ramdisk_addr and copy data.
+ */
+
+ dprintf(INFO, "Loading boot image (%d): start\n", imagesize_actual);
+ bs_set_timestamp(BS_KERNEL_LOAD_START);
+
+ /* Read image without signature */
+ if (mmc_read(ptn + offset, (void *)image_addr, imagesize_actual))
{
- dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
+ dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
return -1;
}
-#endif
+
+ dprintf(INFO, "Loading boot image (%d): done\n", imagesize_actual);
+ bs_set_timestamp(BS_KERNEL_LOAD_DONE);
/* Authenticate Kernel */
dprintf(INFO, "use_signed_kernel=%d, is_unlocked=%d, is_tampered=%d.\n",
@@ -969,51 +1002,9 @@
device.is_unlocked,
device.is_tampered);
-#if VERIFIED_BOOT
- boot_verifier_init();
-#endif
-
if(target_use_signed_kernel() && (!device.is_unlocked))
{
- offset = 0;
-
- image_addr = (unsigned char *)target_get_scratch_address();
-
-#if DEVICE_TREE
- dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
- imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
-
- if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_actual))
- {
- dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
- return -1;
- }
-#else
- imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
-
-#endif
-
- dprintf(INFO, "Loading boot image (%d): start\n", imagesize_actual);
- bs_set_timestamp(BS_KERNEL_LOAD_START);
-
- if (check_aboot_addr_range_overlap((uint32_t)image_addr, imagesize_actual))
- {
- dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
- return -1;
- }
-
- /* Read image without signature */
- if (mmc_read(ptn + offset, (void *)image_addr, imagesize_actual))
- {
- dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
- return -1;
- }
-
- dprintf(INFO, "Loading boot image (%d): done\n", imagesize_actual);
- bs_set_timestamp(BS_KERNEL_LOAD_DONE);
-
offset = imagesize_actual;
-
if (check_aboot_addr_range_overlap((uint32_t)image_addr + offset, page_size))
{
dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
@@ -1028,147 +1019,120 @@
}
verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
-
- /* Move kernel, ramdisk and device tree to correct address */
- memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
- memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
-
- #if DEVICE_TREE
- if(hdr->dt_size) {
- dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
- table = (struct dt_table*) dt_table_offset;
-
- if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
- dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
- return -1;
- }
-
- /* Find index of device tree within device tree table */
- if(dev_tree_get_entry_info(table, &dt_entry) != 0){
- dprintf(CRITICAL, "ERROR: Device Tree Blob cannot be found\n");
- return -1;
- }
-
- /* Validate and Read device device tree in the "tags_add */
- if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
- {
- dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
- return -1;
- }
-
- memmove((void *)hdr->tags_addr, (char *)dt_table_offset + dt_entry.offset, dt_entry.size);
- } else {
- /*
- * If appended dev tree is found, update the atags with
- * memory address to the DTB appended location on RAM.
- * Else update with the atags address in the kernel header
- */
- void *dtb;
- dtb = dev_tree_appended((void*) hdr->kernel_addr,
- hdr->kernel_size,
- (void *)hdr->tags_addr);
- if (!dtb) {
- dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
- return -1;
- }
- }
- #endif
- }
- else
- {
+ } else {
second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
+ #ifdef TZ_SAVE_KERNEL_HASH
+ aboot_save_boot_hash_mmc((uint32_t) image_addr, imagesize_actual);
+ #endif /* TZ_SAVE_KERNEL_HASH */
+ }
- image_addr = (unsigned char *)target_get_scratch_address();
-#if DEVICE_TREE
- dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
- imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
+ /*
+ * Check if the kernel image is a gzip package. If yes, need to decompress it.
+ * If not, continue booting.
+ */
+ if (is_gzip_package((unsigned char *)(image_addr + page_size), hdr->kernel_size))
+ {
+ out_addr = (unsigned char *)(image_addr + imagesize_actual + page_size);
+ out_avai_len = target_get_max_flash_size() - imagesize_actual - page_size;
+ dprintf(INFO, "decompress image start\n");
+ rc = decompress((unsigned char *)(image_addr + page_size),
+ hdr->kernel_size, out_addr, out_avai_len,
+ &dtb_offset, &out_len);
+ if (rc)
+ {
+ dprintf(INFO, "decompress image failed!!!\n");
+ ASSERT(0);
+ }
- if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_actual))
+ dprintf(INFO, "decompressed image finished.\n");
+ kptr = (struct kernel64_hdr *)out_addr;
+ kernel_start_addr = out_addr;
+ kernel_size = out_len;
+ } else {
+ kptr = (struct kernel64_hdr *)(image_addr + page_size);
+ kernel_start_addr = (unsigned char *)(image_addr + page_size);
+ kernel_size = hdr->kernel_size;
+ }
+
+ /*
+ * Update the kernel/ramdisk/tags address if the boot image header
+ * has default values, these default values come from mkbootimg when
+ * the boot image is flashed using fastboot flash:raw
+ */
+ update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
+
+ /* Get virtual addresses since the hdr saves physical addresses. */
+ hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
+ hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
+ hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
+
+ kernel_size = ROUND_TO_PAGE(kernel_size, page_mask);
+ /* Check if the addresses in the header are valid. */
+ if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
+ check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
+ {
+ dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");
+ return -1;
+ }
+
+#ifndef DEVICE_TREE
+ if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
+ {
+ dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
+ return -1;
+ }
+#endif
+
+ /* Move kernel, ramdisk and device tree to correct address */
+ memmove((void*) hdr->kernel_addr, kernel_start_addr, kernel_size);
+ memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
+
+ #if DEVICE_TREE
+ if(hdr->dt_size) {
+ dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
+ table = (struct dt_table*) dt_table_offset;
+
+ if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
+ dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
+ return -1;
+ }
+
+ /* Find index of device tree within device tree table */
+ if(dev_tree_get_entry_info(table, &dt_entry) != 0){
+ dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
+ return -1;
+ }
+
+ /* Validate and Read device device tree in the tags_addr */
+ if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
{
dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
return -1;
}
-#else
- imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
-#endif
- if (check_aboot_addr_range_overlap((uint32_t) image_addr, imagesize_actual))
+ memmove((void *)hdr->tags_addr, (char *)dt_table_offset + dt_entry.offset, dt_entry.size);
+ } else {
+ /* Validate the tags_addr */
+ if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual))
{
- dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
+ dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
return -1;
}
-
- dprintf(INFO, "Loading boot image (%d): start\n",
- imagesize_actual);
- bs_set_timestamp(BS_KERNEL_LOAD_START);
-
- offset = 0;
-
- /* Load the entire boot image */
- if (mmc_read(ptn + offset, (void *)image_addr, imagesize_actual)) {
- dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
- return -1;
+ /*
+ * If appended dev tree is found, update the atags with
+ * memory address to the DTB appended location on RAM.
+ * Else update with the atags address in the kernel header
+ */
+ void *dtb;
+ dtb = dev_tree_appended((void*)(image_addr + page_size),
+ hdr->kernel_size, dtb_offset,
+ (void *)hdr->tags_addr);
+ if (!dtb) {
+ dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
+ return -1;
}
-
- dprintf(INFO, "Loading boot image (%d): done\n",
- imagesize_actual);
- bs_set_timestamp(BS_KERNEL_LOAD_DONE);
-
- #ifdef TZ_SAVE_KERNEL_HASH
- aboot_save_boot_hash_mmc((uint32_t) image_addr, imagesize_actual);
- #endif /* TZ_SAVE_KERNEL_HASH */
-
- /* Move kernel, ramdisk and device tree to correct address */
- memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
- memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
-
- #if DEVICE_TREE
- if(hdr->dt_size) {
- dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
- table = (struct dt_table*) dt_table_offset;
-
- if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
- dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
- return -1;
- }
-
- /* Find index of device tree within device tree table */
- if(dev_tree_get_entry_info(table, &dt_entry) != 0){
- dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
- return -1;
- }
-
- /* Validate and Read device device tree in the tags_addr */
- if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
- {
- dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
- return -1;
- }
-
- memmove((void *)hdr->tags_addr, (char *)dt_table_offset + dt_entry.offset, dt_entry.size);
- } else {
- /* Validate the tags_addr */
- if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual))
- {
- dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
- return -1;
- }
- /*
- * If appended dev tree is found, update the atags with
- * memory address to the DTB appended location on RAM.
- * Else update with the atags address in the kernel header
- */
- void *dtb;
- dtb = dev_tree_appended((void*) hdr->kernel_addr,
- kernel_actual,
- (void *)hdr->tags_addr);
- if (!dtb) {
- dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
- return -1;
- }
- }
- #endif
}
+ #endif
if (boot_into_recovery && !device.is_unlocked && !device.is_tampered)
target_load_ssd_keystore();
@@ -1324,8 +1288,8 @@
verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
/* Move kernel and ramdisk to correct address */
- memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
- memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
+ memmove((void*) hdr->kernel_addr, (char*) (image_addr + page_size), hdr->kernel_size);
+ memmove((void*) hdr->ramdisk_addr, (char*) (image_addr + page_size + kernel_actual), hdr->ramdisk_size);
#if DEVICE_TREE
/* Validate and Read device device tree in the "tags_add */
if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
@@ -1444,20 +1408,17 @@
BUF_DMA_ALIGN(info_buf, BOOT_IMG_MAX_PAGE_SIZE);
void write_device_info_mmc(device_info *dev)
{
- struct device_info *info = (void*) info_buf;
unsigned long long ptn = 0;
-#if !VERIFIED_BOOT
unsigned long long size;
-#endif
int index = INVALID_PTN;
uint32_t blocksize;
uint8_t lun = 0;
+ uint32_t ret = 0;
-#if VERIFIED_BOOT
- index = partition_get_index("devinfo");
-#else
- index = partition_get_index("aboot");
-#endif
+ if (devinfo_present)
+ index = partition_get_index("devinfo");
+ else
+ index = partition_get_index("aboot");
ptn = partition_get_offset(index);
if(ptn == 0)
@@ -1468,40 +1429,34 @@
lun = partition_get_lun(index);
mmc_set_lun(lun);
-#if !VERIFIED_BOOT
size = partition_get_size(index);
-#endif
-
- memcpy(info, dev, sizeof(device_info));
blocksize = mmc_get_device_blocksize();
-#if VERIFIED_BOOT
- if(mmc_write(ptn, blocksize, (void *)info_buf))
-#else
- if(mmc_write((ptn + size - blocksize), blocksize, (void *)info_buf))
-#endif
+ if (devinfo_present)
+ ret = mmc_write(ptn, blocksize, (void *)info_buf);
+ else
+ ret = mmc_write((ptn + size - blocksize), blocksize, (void *)info_buf);
+ if (ret)
{
dprintf(CRITICAL, "ERROR: Cannot write device info\n");
return;
}
}
-void read_device_info_mmc(device_info *dev)
+void read_device_info_mmc(struct device_info *info)
{
- struct device_info *info = (void*) info_buf;
unsigned long long ptn = 0;
-#if !VERIFIED_BOOT
unsigned long long size;
-#endif
int index = INVALID_PTN;
uint32_t blocksize;
+ uint32_t ret = 0;
-#if VERIFIED_BOOT
- index = partition_get_index("devinfo");
-#else
- index = partition_get_index("aboot");
-#endif
+ if ((index = partition_get_index("devinfo")) < 0)
+ {
+ devinfo_present = false;
+ index = partition_get_index("aboot");
+ }
ptn = partition_get_offset(index);
if(ptn == 0)
@@ -1511,37 +1466,20 @@
mmc_set_lun(partition_get_lun(index));
-#if !VERIFIED_BOOT
size = partition_get_size(index);
-#endif
blocksize = mmc_get_device_blocksize();
-#if VERIFIED_BOOT
- if(mmc_read(ptn, (void *)info_buf, blocksize))
-#else
- if(mmc_read((ptn + size - blocksize), (void *)info_buf, blocksize))
-#endif
+ if (devinfo_present)
+ ret = mmc_read(ptn, (void *)info_buf, blocksize);
+ else
+ ret = mmc_read((ptn + size - blocksize), (void *)info_buf, blocksize);
+ if (ret)
{
dprintf(CRITICAL, "ERROR: Cannot read device info\n");
return;
}
- if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
- {
- memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
-#if DEFAULT_UNLOCK
- info->is_unlocked = 1;
-#else
- info->is_unlocked = 0;
-#endif
- info->is_verified = 0;
- info->is_tampered = 0;
- info->charger_screen_enabled = 0;
-
- write_device_info_mmc(info);
- }
- memcpy(dev, info, sizeof(device_info));
}
void write_device_info_flash(device_info *dev)
@@ -1613,7 +1551,15 @@
{
if(target_is_emmc_boot())
{
- write_device_info_mmc(dev);
+ struct device_info *info = (void*) info_buf;
+ memcpy(info, dev, sizeof(struct device_info));
+
+#if USE_RPMB_FOR_DEVINFO
+ if (is_secure_boot_enable())
+ write_device_info_rpmb((void*) info, mmc_get_device_blocksize());
+#else
+ write_device_info_mmc(info);
+#endif
}
else
{
@@ -1625,7 +1571,32 @@
{
if(target_is_emmc_boot())
{
- read_device_info_mmc(dev);
+ struct device_info *info = (void*) info_buf;
+
+#if USE_RPMB_FOR_DEVINFO
+ if (is_secure_boot_enable())
+ read_device_info_rpmb((void*) info, mmc_get_device_blocksize());
+#else
+ read_device_info_mmc(info);
+#endif
+
+ if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
+ {
+ memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
+ if (is_secure_boot_enable())
+ info->is_unlocked = 0;
+ else
+ info->is_unlocked = 1;
+ info->is_verified = 0;
+ info->is_tampered = 0;
+#if USER_BUILD_VARIANT
+ info->charger_screen_enabled = 1;
+#else
+ info->charger_screen_enabled = 0;
+#endif
+ write_device_info(info);
+ }
+ memcpy(dev, info, sizeof(device_info));
}
else
{
@@ -1659,7 +1630,6 @@
struct boot_img_hdr *hdr = (struct boot_img_hdr *) (boot_image_start);
if(hdr->dt_size != 0) {
-
/* add kernel offset */
dt_image_offset += page_size;
n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
@@ -1714,16 +1684,23 @@
uint32_t image_actual;
uint32_t dt_actual = 0;
uint32_t sig_actual = SIGNATURE_SIZE;
- struct boot_img_hdr *hdr;
- struct kernel64_hdr *kptr;
+ struct boot_img_hdr *hdr = NULL;
+ struct kernel64_hdr *kptr = NULL;
char *ptr = ((char*) data);
int ret = 0;
uint8_t dtb_copied = 0;
+ unsigned int out_len = 0;
+ unsigned int out_avai_len = 0;
+ unsigned char *out_addr = NULL;
+ uint32_t dtb_offset = 0;
+ unsigned char *kernel_start_addr = NULL;
+ unsigned int kernel_size = 0;
+
#ifdef MDTP_SUPPORT
/* Go through Firmware Lock verification before continue with boot process */
mdtp_fwlock_verify_lock();
- fbcon_clear();
+ display_image_on_screen();
#endif /* MDTP_SUPPORT */
#if VERIFIED_BOOT
@@ -1778,11 +1755,39 @@
verify_signed_bootimg((uint32_t)data, (image_actual - sig_actual));
/*
+ * Check if the kernel image is a gzip package. If yes, need to decompress it.
+ * If not, continue booting.
+ */
+ if (is_gzip_package((unsigned char *)(data + page_size), hdr->kernel_size))
+ {
+ out_addr = (unsigned char *)target_get_scratch_address();
+ out_addr = (unsigned char *)(out_addr + image_actual + page_size);
+ out_avai_len = target_get_max_flash_size() - image_actual - page_size;
+ dprintf(INFO, "decompress image start\n");
+ ret = decompress((unsigned char *)(ptr + page_size),
+ hdr->kernel_size, out_addr, out_avai_len,
+ &dtb_offset, &out_len);
+ if (ret)
+ {
+ dprintf(INFO, "decompress image failed!!!\n");
+ ASSERT(0);
+ }
+
+ dprintf(INFO, "decompressed image finished.\n");
+ kptr = (struct kernel64_hdr *)out_addr;
+ kernel_start_addr = out_addr;
+ kernel_size = out_len;
+ } else {
+ kptr = (struct kernel64_hdr*)((char *)data + page_size);
+ kernel_start_addr = (unsigned char *)((char *)data + page_size);
+ kernel_size = hdr->kernel_size;
+ }
+
+ /*
* Update the kernel/ramdisk/tags address if the boot image header
* has default values, these default values come from mkbootimg when
* the boot image is flashed using fastboot flash:raw
*/
- kptr = (struct kernel64_hdr*)((char*) data + page_size);
update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
/* Get virtual addresses since the hdr saves physical addresses. */
@@ -1790,8 +1795,9 @@
hdr->ramdisk_addr = VA(hdr->ramdisk_addr);
hdr->tags_addr = VA(hdr->tags_addr);
+ kernel_size = ROUND_TO_PAGE(kernel_size, page_mask);
/* Check if the addresses in the header are valid. */
- if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
+ if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
{
dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");
@@ -1813,9 +1819,15 @@
/* Load ramdisk & kernel */
memmove((void*) hdr->ramdisk_addr, ptr + page_size + kernel_actual, hdr->ramdisk_size);
- memmove((void*) hdr->kernel_addr, ptr + page_size, hdr->kernel_size);
+ memmove((void*) hdr->kernel_addr, (char*) (kernel_start_addr), kernel_size);
#if DEVICE_TREE
+ if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual))
+ {
+ dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
+ return;
+ }
+
/*
* If dtb is not found look for appended DTB in the kernel.
* If appended dev tree is found, update the atags with
@@ -1824,7 +1836,8 @@
*/
if (!dtb_copied) {
void *dtb;
- dtb = dev_tree_appended((void *)hdr->kernel_addr, hdr->kernel_size,
+ dtb = dev_tree_appended((void*)(ptr + page_size),
+ hdr->kernel_size, dtb_offset,
(void *)hdr->tags_addr);
if (!dtb) {
fastboot_fail("dtb not found");
@@ -1833,14 +1846,6 @@
}
#endif
-#ifndef DEVICE_TREE
- if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
- {
- dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
- return;
- }
-#endif
-
fastboot_okay("");
fastboot_stop();
@@ -1904,24 +1909,25 @@
lun = partition_get_lun(index);
mmc_set_lun(lun);
-#if MMC_SDHCI_SUPPORT
- if (mmc_erase_card(ptn, size)) {
- fastboot_fail("failed to erase partition\n");
- return;
- }
-#else
- BUF_DMA_ALIGN(out, DEFAULT_ERASE_SIZE);
- size = partition_get_size(index);
- if (size > DEFAULT_ERASE_SIZE)
- size = DEFAULT_ERASE_SIZE;
+ if (platform_boot_dev_isemmc())
+ {
+ if (mmc_erase_card(ptn, size)) {
+ fastboot_fail("failed to erase partition\n");
+ return;
+ }
+ } else {
+ BUF_DMA_ALIGN(out, DEFAULT_ERASE_SIZE);
+ size = partition_get_size(index);
+ if (size > DEFAULT_ERASE_SIZE)
+ size = DEFAULT_ERASE_SIZE;
- /* Simple inefficient version of erase. Just writing
- 0 in first several blocks */
- if (mmc_write(ptn , size, (unsigned int *)out)) {
- fastboot_fail("failed to erase partition");
- return;
+ /* Simple inefficient version of erase. Just writing
+ 0 in first several blocks */
+ if (mmc_write(ptn , size, (unsigned int *)out)) {
+ fastboot_fail("failed to erase partition");
+ return;
+ }
}
-#endif
fastboot_okay("");
}
@@ -2015,6 +2021,47 @@
return;
}
+void cmd_flash_meta_img(const char *arg, void *data, unsigned sz)
+{
+ int i, images;
+ meta_header_t *meta_header;
+ img_header_entry_t *img_header_entry;
+
+ meta_header = (meta_header_t*) data;
+ img_header_entry = (img_header_entry_t*) (data+sizeof(meta_header_t));
+
+ images = meta_header->img_hdr_sz / sizeof(img_header_entry_t);
+
+ for (i=0; i<images; i++) {
+
+ if((img_header_entry[i].ptn_name == NULL) ||
+ (img_header_entry[i].start_offset == 0) ||
+ (img_header_entry[i].size == 0))
+ break;
+
+ cmd_flash_mmc_img(img_header_entry[i].ptn_name,
+ (void *) data + img_header_entry[i].start_offset,
+ img_header_entry[i].size);
+ }
+
+ if (!strncmp(arg, "bootloader", strlen("bootloader")))
+ {
+ strlcpy(device.bootloader_version, TARGET(BOARD), MAX_VERSION_LEN);
+ strlcat(device.bootloader_version, "-", MAX_VERSION_LEN);
+ strlcat(device.bootloader_version, meta_header->img_version, MAX_VERSION_LEN);
+ }
+ else
+ {
+ strlcpy(device.radio_version, TARGET(BOARD), MAX_VERSION_LEN);
+ strlcat(device.radio_version, "-", MAX_VERSION_LEN);
+ strlcat(device.radio_version, meta_header->img_version, MAX_VERSION_LEN);
+ }
+
+ write_device_info(&device);
+ fastboot_okay("");
+ return;
+}
+
void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
{
unsigned int chunk;
@@ -2192,6 +2239,7 @@
void cmd_flash_mmc(const char *arg, void *data, unsigned sz)
{
sparse_header_t *sparse_header;
+ meta_header_t *meta_header;
#ifdef SSD_ENABLE
/* 8 Byte Magic + 2048 Byte xml + Encrypted Data */
@@ -2278,10 +2326,13 @@
#endif
sparse_header = (sparse_header_t *) data;
- if (sparse_header->magic != SPARSE_HEADER_MAGIC)
- cmd_flash_mmc_img(arg, data, sz);
- else
+ meta_header = (meta_header_t *) data;
+ if (sparse_header->magic == SPARSE_HEADER_MAGIC)
cmd_flash_mmc_sparse_img(arg, data, sz);
+ else if (meta_header->magic == META_HEADER_MAGIC)
+ cmd_flash_meta_img(arg, data, sz);
+ else
+ cmd_flash_mmc_img(arg, data, sz);
return;
}
@@ -2377,7 +2428,7 @@
#ifdef MDTP_SUPPORT
/* Go through Firmware Lock verification before continue with boot process */
mdtp_fwlock_verify_lock();
- fbcon_clear();
+ display_image_on_screen();
#endif /* MDTP_SUPPORT */
if (target_is_emmc_boot())
@@ -2560,6 +2611,7 @@
struct fbimage *logo = NULL;
uint32_t blocksize;
uint32_t readsize;
+ uint32_t logosize;
uint32_t ptn_size;
index = partition_get_index("splash");
@@ -2576,12 +2628,12 @@
ptn_size = partition_get_size(index);
blocksize = mmc_get_device_blocksize();
- readsize = ROUNDUP(sizeof(logo->header), blocksize);
+ logosize = ROUNDUP(sizeof(logo->header), blocksize);
- logo = (struct fbimage *)memalign(CACHE_LINE, ROUNDUP(readsize, CACHE_LINE));
+ logo = (struct fbimage *)memalign(CACHE_LINE, ROUNDUP(logosize, CACHE_LINE));
ASSERT(logo);
- if (mmc_read(ptn, (uint32_t *) logo, readsize)) {
+ if (mmc_read(ptn, (uint32_t *) logo, logosize)) {
dprintf(CRITICAL, "ERROR: Cannot read splash image header\n");
goto err;
}
@@ -2606,7 +2658,7 @@
goto err;
}
- if (mmc_read(ptn + sizeof(logo->header),(uint32_t *)base, readsize)) {
+ if (mmc_read(ptn + logosize,(uint32_t *)base, readsize)) {
fbcon_clear();
dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
goto err;
@@ -2752,6 +2804,8 @@
device.display_panel);
fastboot_publish("display-panel",
(const char *) panel_display_mode);
+ fastboot_publish("version-bootloader", (const char *) device.bootloader_version);
+ fastboot_publish("version-baseband", (const char *) device.radio_version);
}
void aboot_init(const struct app_descriptor *app)
@@ -2778,11 +2832,16 @@
/* Display splash screen if enabled */
#if DISPLAY_SPLASH_SCREEN
- dprintf(SPEW, "Display Init: Start\n");
- target_display_init(device.display_panel);
- dprintf(SPEW, "Display Init: Done\n");
+#if NO_ALARM_DISPLAY
+ if (!check_alarm_boot()) {
#endif
-
+ dprintf(SPEW, "Display Init: Start\n");
+ target_display_init(device.display_panel);
+ dprintf(SPEW, "Display Init: Done\n");
+#if NO_ALARM_DISPLAY
+ }
+#endif
+#endif
target_serialno((unsigned char *) sn_buf);
dprintf(SPEW,"serial number: %s\n",sn_buf);
@@ -2860,7 +2919,7 @@
#ifdef MDTP_SUPPORT
/* Go through Firmware Lock verification before continue with boot process */
mdtp_fwlock_verify_lock();
- fbcon_clear();
+ display_image_on_screen();
#endif /* MDTP_SUPPORT */
boot_linux_from_mmc();
diff --git a/app/aboot/devinfo.h b/app/aboot/devinfo.h
index bd78771..7eee69b 100644
--- a/app/aboot/devinfo.h
+++ b/app/aboot/devinfo.h
@@ -1,5 +1,5 @@
/*
- * * Copyright (c) 2011,2014, The Linux Foundation. All rights reserved.
+ * * Copyright (c) 2011,2014-2015, 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
@@ -35,6 +35,7 @@
#define DEVICE_MAGIC "ANDROID-BOOT!"
#define DEVICE_MAGIC_SIZE 13
#define MAX_PANEL_ID_LEN 64
+#define MAX_VERSION_LEN 64
struct device_info
{
@@ -44,6 +45,8 @@
bool is_verified;
bool charger_screen_enabled;
char display_panel[MAX_PANEL_ID_LEN];
+ char bootloader_version[MAX_VERSION_LEN];
+ char radio_version[MAX_VERSION_LEN];
};
#endif
diff --git a/app/aboot/fastboot.c b/app/aboot/fastboot.c
index 9dac985..6f1841f 100644
--- a/app/aboot/fastboot.c
+++ b/app/aboot/fastboot.c
@@ -2,7 +2,7 @@
* Copyright (c) 2009, Google Inc.
* All rights reserved.
*
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 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
@@ -428,10 +428,32 @@
fastboot_ack("OKAY", info);
}
+static void getvar_all()
+{
+ struct fastboot_var *var;
+ char getvar_all[64];
+
+ for (var = varlist; var; var = var->next)
+ {
+ strlcpy((char *) getvar_all, var->name, sizeof(getvar_all));
+ strlcat((char *) getvar_all, ":", sizeof(getvar_all));
+ strlcat((char *) getvar_all, var->value, sizeof(getvar_all));
+ fastboot_info(getvar_all);
+ memset((void *) getvar_all, '\0', sizeof(getvar_all));
+ }
+ fastboot_okay("");
+}
+
static void cmd_getvar(const char *arg, void *data, unsigned sz)
{
struct fastboot_var *var;
+ if (!strncmp("all", arg, strlen(arg)))
+ {
+ getvar_all();
+ return;
+ }
+
for (var = varlist; var; var = var->next) {
if (!strcmp(var->name, arg)) {
fastboot_okay(var->value);
@@ -456,6 +478,10 @@
snprintf((char *)response, MAX_RSP_SIZE, "DATA%08x", len);
if (usb_if.usb_write(response, strlen((const char *)response)) < 0)
return;
+ /*
+ * Discard the cache contents before starting the download
+ */
+ arch_invalidate_cache_range((addr_t) download_base, sz);
r = usb_if.usb_read(download_base, len);
if ((r < 0) || ((unsigned) r != len)) {
diff --git a/app/aboot/mdtp.c b/app/aboot/mdtp.c
index 60b97b0..160f6c8 100644
--- a/app/aboot/mdtp.c
+++ b/app/aboot/mdtp.c
@@ -47,6 +47,7 @@
static int mdtp_tzbsp_dec_verify_DIP(DIP_t *enc_dip, DIP_t *dec_dip, uint32_t *verified);
static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip);
+static int is_mdtp_activated = -1;
/********************************************************************************/
/* Read the DIP from EMMC */
@@ -76,7 +77,7 @@
return -1;
}
- dprintf(INFO, "mdtp: read_DIP: SUCCESS, read %d bytes\n", actual_partition_size);
+ dprintf(SPEW, "mdtp: read_DIP: SUCCESS, read %d bytes\n", actual_partition_size);
return 0;
}
@@ -85,7 +86,6 @@
static int write_DIP(DIP_t *dip)
{
unsigned long long ptn = 0;
- uint32_t partition_size;
uint32_t block_size = mmc_get_device_blocksize();
int index = INVALID_PTN;
@@ -94,30 +94,25 @@
index = partition_get_index("dip");
ptn = partition_get_offset(index);
+
if(ptn == 0)
{
return -1;
}
- partition_size = partition_get_size(index);
-
- if(partition_size < size)
- {
- dprintf(CRITICAL, "mdtp: write_DIP: ERROR, DIP partition too small\n");
- return -1;
- }
-
- if(mmc_write(ptn, ROUNDUP(size, block_size), (void *)dip))
+ if(mmc_write(ptn, ROUNDUP(sizeof(DIP_t), block_size), (void *)dip))
{
dprintf(CRITICAL, "mdtp: write_DIP: ERROR, cannot read DIP info\n");
return -1;
}
+ dprintf(SPEW, "mdtp: write_DIP: SUCCESS, write %d bytes\n", ROUNDUP(sizeof(DIP_t), block_size));
+
return 0;
}
-/* Provision the DIP by storing the default DIP into the EMMC */
-static void provision_DIP()
+/* Deactivate MDTP by storing the default DIP into the EMMC */
+static void write_deactivated_DIP()
{
DIP_t *enc_dip;
DIP_t *dec_dip;
@@ -126,14 +121,14 @@
enc_dip = malloc(sizeof(DIP_t));
if (enc_dip == NULL)
{
- dprintf(CRITICAL, "mdtp: provision_DIP: ERROR, cannot allocate DIP\n");
+ dprintf(CRITICAL, "mdtp: write_deactivated_DIP: ERROR, cannot allocate DIP\n");
return;
}
dec_dip = malloc(sizeof(DIP_t));
if (dec_dip == NULL)
{
- dprintf(CRITICAL, "mdtp: provision_DIP: ERROR, cannot allocate DIP\n");
+ dprintf(CRITICAL, "mdtp: write_deactivated_DIP: ERROR, cannot allocate DIP\n");
free(enc_dip);
return;
}
@@ -145,21 +140,14 @@
ret = mdtp_tzbsp_enc_hash_DIP(dec_dip, enc_dip);
if(ret < 0)
{
- dprintf(CRITICAL, "mdtp: provision_DIP: ERROR, cannot cipher DIP\n");
+ dprintf(CRITICAL, "mdtp: write_deactivated_DIP: ERROR, cannot cipher DIP\n");
goto out;
}
ret = write_DIP(enc_dip);
if(ret < 0)
{
- dprintf(CRITICAL, "mdtp: provision_DIP: ERROR, cannot write DIP\n");
- goto out;
- }
-
- ret = mdtp_tzbsp_set_provisioned_fuse();
- if(ret < 0)
- {
- dprintf(CRITICAL, "mdtp: provision_DIP: ERROR, cannot set DIP_PROVISIONED fuse\n\n");
+ dprintf(CRITICAL, "mdtp: write_deactivated_DIP: ERROR, cannot write DIP\n");
goto out;
}
@@ -178,7 +166,7 @@
uint32_t block_size = mmc_get_device_blocksize();
uint32_t actual_partition_size = ROUNDUP(size, block_size);
- dprintf(INFO, "mdtp: verify_partition_single_hash: %s, %u\n", name, size);
+ dprintf(SPEW, "mdtp: verify_partition_single_hash: %s, %u\n", name, size);
ASSERT(name != NULL);
ASSERT(hash_table != NULL);
@@ -208,7 +196,7 @@
return -1;
}
- dprintf(INFO, "verify_partition_single_hash: %s: VERIFIED!\n", name);
+ dprintf(SPEW, "verify_partition_single_hash: %s: VERIFIED!\n", name);
return 0;
}
@@ -228,7 +216,7 @@
uint32_t bytes_to_read;
uint32_t block_num = 0;
- dprintf(INFO, "mdtp: verify_partition_block_hash: %s, %u\n", name, size);
+ dprintf(SPEW, "mdtp: verify_partition_block_hash: %s, %u\n", name, size);
ASSERT(name != NULL);
ASSERT(hash_table != NULL);
@@ -287,7 +275,7 @@
force_verify_block += 1;
}
- dprintf(INFO, "verify_partition_block_hash: %s: VERIFIED!\n", name);
+ dprintf(SPEW, "verify_partition_block_hash: %s: VERIFIED!\n", name);
return 0;
}
@@ -321,6 +309,75 @@
return 0;
}
+/* Display the recovery UI to allow the user to enter the PIN and continue boot */
+static int display_recovery_ui(DIP_t *dip)
+{
+ uint32_t pin_length = 0;
+ char entered_pin[MDTP_MAX_PIN_LEN+1] = {0};
+ uint32_t i;
+ uint32_t equal_count = 0, different_count = 0;
+
+ if (dip->mdtp_cfg.enable_local_pin_authentication)
+ {
+ dprintf(SPEW, "mdtp: display_recovery_ui: Local deactivation enabled\n");
+
+ pin_length = strlen(dip->mdtp_cfg.mdtp_pin.mdtp_pin);
+
+ if (pin_length > MDTP_MAX_PIN_LEN || pin_length < MDTP_MIN_PIN_LEN)
+ {
+ dprintf(CRITICAL, "mdtp: display_recovery_ui: Error, invalid PIN length\n");
+ display_error_msg();
+ return -1;
+ }
+
+ // Set entered_pin to initial '0' string + null terminator
+ for (i=0; i<pin_length; i++)
+ {
+ entered_pin[i] = '0';
+ }
+
+ // Allow the user to enter the PIN as many times as he wishes
+ // (with INVALID_PIN_DELAY_MSECONDS after each failed attempt)
+ while (1)
+ {
+ get_pin_from_user(entered_pin, pin_length);
+
+ // Go over the entire PIN in any case, to prevent side-channel attacks
+ for (i=0; i<pin_length; i++)
+ {
+ if (dip->mdtp_cfg.mdtp_pin.mdtp_pin[i] == entered_pin[i])
+ equal_count++;
+ else
+ different_count++;
+ }
+
+ if (equal_count == pin_length)
+ {
+ // Valid PIN - deactivate and continue boot
+ dprintf(SPEW, "mdtp: display_recovery_ui: valid PIN, continue boot\n");
+ write_deactivated_DIP();
+ return 0;
+ }
+ else
+ {
+ // Invalid PIN - display an appropriate message (which also includes a wait
+ // for INVALID_PIN_DELAY_MSECONDS), and allow the user to try again
+ dprintf(CRITICAL, "mdtp: display_recovery_ui: ERROR, invalid PIN\n");
+ display_invalid_pin_msg();
+
+ equal_count = 0;
+ different_count = 0;
+ }
+ }
+ }
+ else
+ {
+ dprintf(CRITICAL, "mdtp: display_recovery_ui: Local deactivation disabled, unable to display recovery UI\n");
+ display_error_msg();
+ return -1;
+ }
+}
+
/* Verify all protected partitinons according to the DIP */
static int verify_all_partitions(DIP_t *dip, verify_result_t *verify_result)
{
@@ -340,8 +397,6 @@
}
else if (dip->status == DIP_STATUS_ACTIVATED)
{
- show_checking_msg();
-
for(i=0; i<MAX_PARTITIONS; i++)
{
if(dip->partition_cfg[i].lock_enabled && dip->partition_cfg[i].size)
@@ -361,14 +416,13 @@
if (verify_failure)
{
dprintf(CRITICAL, "mdtp: verify_all_partitions: Failed partition verification\n");
- show_invalid_msg();
- return -1;
+ return 0;
}
+ is_mdtp_activated = 1;
}
*verify_result = VERIFY_OK;
- show_OK_msg();
return 0;
}
@@ -385,14 +439,14 @@
enc_dip = malloc(ROUNDUP(sizeof(DIP_t), block_size));
if (enc_dip == NULL)
{
- dprintf(CRITICAL, "mdtp: provision_DIP: ERROR, cannot allocate DIP\n");
+ dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot allocate DIP\n");
return;
}
dec_dip = malloc(ROUNDUP(sizeof(DIP_t), block_size));
if (dec_dip == NULL)
{
- dprintf(CRITICAL, "mdtp: provision_DIP: ERROR, cannot allocate DIP\n");
+ dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot allocate DIP\n");
free(enc_dip);
return;
}
@@ -410,7 +464,7 @@
if(ret < 0)
{
dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot verify DIP\n");
- show_invalid_msg();
+ display_error_msg();
goto out;
}
@@ -418,7 +472,7 @@
if(!verified)
{
dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted DIP\n");
- show_invalid_msg();
+ display_error_msg();
goto out;
}
@@ -432,14 +486,15 @@
if (verify_result == VERIFY_OK)
{
- dprintf(INFO, "mdtp: validate_DIP_and_firmware: Verify OK\n");
+ dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify OK\n");
}
else if (verify_result == VERIFY_FAILED)
{
dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted firmware\n");
+ display_recovery_ui(dec_dip);
} else /* VERIFY_SKIPPED */
{
- dprintf(INFO, "mdtp: validate_DIP_and_firmware: Verify skipped\n");
+ dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify skipped\n");
}
out:
@@ -459,6 +514,9 @@
int ret;
bool enabled;
+ /* sets the default value of this global to be MDTP not activated */
+ is_mdtp_activated = 0;
+
ret = mdtp_fuse_get_enabled(&enabled);
if(ret)
{
@@ -474,6 +532,18 @@
return 0;
}
+/********************************************************************************/
+
+/** Indicates whether the MDTP is currently in ACTIVATED state **/
+int mdtp_activated(bool * activated){
+ if(is_mdtp_activated < 0){
+ /* mdtp_fwlock_verify_lock was not called before, the value is not valid */
+ return is_mdtp_activated;
+ }
+
+ *activated = is_mdtp_activated;
+ return 0;
+}
/********************************************************************************/
diff --git a/app/aboot/mdtp.h b/app/aboot/mdtp.h
index 9975899..865c791 100644
--- a/app/aboot/mdtp.h
+++ b/app/aboot/mdtp.h
@@ -34,9 +34,13 @@
#define MAX_PARTITIONS 3
#define MAX_PARTITION_NAME_LEN 100
#define HASH_LEN 32
+#define MDTP_MIN_PIN_LEN 5
#define MDTP_MAX_PIN_LEN 8
#define DIP_PADDING 11
+#define INITIAL_DELAY_MSECONDS 5000
+#define INVALID_PIN_DELAY_MSECONDS 5000
+
#define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))
#define MDTP_FWLOCK_BLOCK_SIZE (1024*1024*16)
#define MDTP_FWLOCK_MAX_FILES (100)
@@ -104,19 +108,71 @@
VERIFY_FAILED,
} verify_result_t;
-/* Start Firmware Lock verification process */
+
+/**
+ * mdtp_fwlock_verify_lock
+ *
+ * Start Firmware Lock verification process.
+ *
+ * @return - negative value for an error, 0 for success.
+ */
int mdtp_fwlock_verify_lock();
-/* Return whether the MDTP is currently enabled or disabled in HW */
+/**
+ * mdtp_fuse_get_enabled
+ *
+ * Return whether the MDTP is currently enabled or
+ * disabled in HW.
+ *
+ * @param[out] enabled: set to true if MDTP enabled,
+ * false otherwise.
+ *
+ * @return - negative value for an error, 0 for success.
+ */
int mdtp_fuse_get_enabled(bool *enabled);
-/* Display the "Firmware Valid" screen */
-void show_OK_msg();
+/**
+ * get_pin_from_user
+ *
+ * Display the recovery PIN screen and set received buffer
+ * with the PIN the user has entered.
+ *
+ * @param[out] entered_pin: buffer holding the received PIN.
+ * @param[in] pin_length: PIN length (and also entered_pin buffer length).
+ *
+ * @return - None.
+ */
+void get_pin_from_user(char *entered_pin, uint32_t pin_length);
-/* Display the "Firmware Invalid" screen */
-void show_invalid_msg();
+/**
+ * display_invalid_pin_msg
+ *
+ * User has entered invalid PIN, display error message and
+ * allow the user to try again.
+ *
+ * @return - None.
+ */
+void display_invalid_pin_msg();
-/* Display the "Verifying Firmware" screen */
-void show_checking_msg();
+/**
+ * display_error_msg
+ *
+ * Display error message and stop boot process.
+ *
+ * @return - None.
+ */
+void display_error_msg();
+
+/**
+ * mdtp_activated
+ *
+ * Indicates whether the MDTP is currently in ACTIVATED state.
+ * You must call this function only after calling to mdtp_fwlock_verify_lock();
+ *
+ * @param[out] activated: MDTP is in ACTIVATED state (TRUE/FALSE).
+ *
+ * @return - negative value for an error, 0 for success.
+ */
+int mdtp_activated(bool * activated);
#endif
diff --git a/app/aboot/mdtp_fuse.c b/app/aboot/mdtp_fuse.c
index c4abd19..1487057 100644
--- a/app/aboot/mdtp_fuse.c
+++ b/app/aboot/mdtp_fuse.c
@@ -41,6 +41,8 @@
#define MAX_METADATA_SIZE (0x1000)
#define QFPROM_ADDR_SPACE_RAW (0)
+char metadata_block[MAX_METADATA_SIZE] = {0};
+
/********************************************************************************/
typedef union
@@ -116,7 +118,6 @@
{
unsigned long long ptn = 0;
uint32_t actual_size;
- char metadata_block[MAX_METADATA_SIZE];
int index = INVALID_PTN;
uint32_t block_size = mmc_get_device_blocksize();
@@ -128,21 +129,21 @@
return -1;
}
- if (sizeof(metadata_t) > MAX_METADATA_SIZE)
+ actual_size = ROUNDUP(sizeof(metadata_t), block_size);
+
+ if (actual_size > MAX_METADATA_SIZE)
{
- dprintf(CRITICAL, "mdtp: read_metadata: ERROR, meta data size %d too big\n", sizeof(metadata_t));
+ dprintf(CRITICAL, "mdtp: read_metadata: ERROR, meta data size %d too big\n", actual_size);
return -1;
}
- actual_size = ROUNDUP(MAX_METADATA_SIZE, block_size);
-
if(mmc_read(ptn, (void *)metadata_block, actual_size))
{
dprintf(CRITICAL, "mdtp: read_metadata: ERROR, cannot read mdtp info\n");
return -1;
}
- memcpy(metadata, metadata_block, sizeof(metadata_t));
+ memscpy((uint8_t*)metadata, sizeof(metadata_t), (uint8_t*)(&(metadata_block[0])), MAX_METADATA_SIZE);
dprintf(INFO, "mdtp: read_metadata: SUCCESS, read %d bytes\n", actual_size);
diff --git a/app/aboot/mdtp_ui.c b/app/aboot/mdtp_ui.c
index 30d70d6..48d899e 100644
--- a/app/aboot/mdtp_ui.c
+++ b/app/aboot/mdtp_ui.c
@@ -32,31 +32,88 @@
#include <mmc.h>
#include <partition_parser.h>
#include <stdlib.h>
+#include <string.h>
#include "mdtp.h"
-#define MDTP_IMAGE_WIDTH 500
-#define MDTP_IMAGE_HEIGHT 800
-#define MDTP_UX_DELAY 1000
-#define MDTP_OK_OFFSET 0x0
-#define MDTP_CHECKING_OFFSET 0x200000
-#define MDTP_INVALID_OFFSET 0x400000
-#define MDTP_RECOVERED_OFFSET 0x600000
+// Image dimensions
+#define MDTP_ERROR_MSG_WIDTH (1412)
+#define MDTP_ERROR_MSG_HEIGHT (212)
+#define MDTP_MAIN_TEXT_WIDTH (1364)
+#define MDTP_MAIN_TEXT_HEIGHT (288)
+#define MDTP_PIN_DIGIT_WIDTH (180)
+#define MDTP_PIN_DIGIT_HEIGHT (180)
+#define MDTP_OK_BUTTON_WIDTH (644)
+#define MDTP_OK_BUTTON_HEIGHT (158)
+#define MDTP_DIGITS_INSTRUCTIONS_WIDTH (1384)
+#define MDTP_DIGITS_INSTRUCTIONS_HEIGHT (166)
+#define MDTP_PIN_INSTRUCTIONS_WIDTH (920)
+#define MDTP_PIN_INSTRUCTIONS_HEIGHT (204)
-extern uint32_t target_volume_down(void);
-extern void fbcon_putImage(struct fbimage *fbimg, bool flag);
+// Image offsets
+#define MDTP_ERROR_MSG_OFFSET (0x1000)
+#define MDTP_INITIAL_DELAY_OFFSET (0xDD000)
+#define MDTP_ENTER_PIN_OFFSET (0x1FD000)
+#define MDTP_INVALID_PIN_OFFSET (0x31D000)
+#define MDTP_PIN_DIGIT_0_OFFSET (0x43D000)
+#define MDTP_PIN_DIGITS_OFFSET (0x18000)
+#define MDTP_PIN_SELECTED_DIGIT_0_OFFSET (MDTP_PIN_DIGIT_0_OFFSET + 10*MDTP_PIN_DIGITS_OFFSET) // (0x52D000)
+#define MDTP_OK_BUTTON_OFFSET (0x61D000)
+#define MDTP_SELECTED_OK_BUTTON_OFFSET (0x668000)
+#define MDTP_DIGITS_INSTRUCTIONS_OFFSET (0x6B3000)
+#define MDTP_PIN_INSTRUCTIONS_OFFSET (0x75C000)
+
+// Image releative locations
+#define ERROR_MESSAGE_RELATIVE_Y_LOCATION (0.18)
+#define MAIN_TEXT_RELATIVE_Y_LOCATION (0.33)
+#define PIN_RELATIVE_Y_LOCATION (0.47)
+#define PIN_TEXT_RELATIVE_Y_LOCATION (0.57)
+#define OK_BUTTON_RELATIVE_Y_LOCATION (0.75)
+#define OK_TEXT_RELATIVE_Y_LOCATION (0.82)
+
+#define DIGIT_SPACE (12)
+
+#define MDTP_PRESSING_DELAY_MSEC (400)
+#define MDTP_MAX_IMAGE_SIZE (1183000) //size in bytes, includes some extra bytes since we round up to block size in read
+#define RGB888_BLACK (0x000000)
+#define BITS_PER_BYTE (8)
+
+
+#define CENTER_IMAGE_ON_X_AXIS(image_width,screen_width) ((screen_width-image_width)/2)
+
extern void mdelay(unsigned msecs);
+extern uint32_t target_volume_up();
+extern uint32_t target_volume_down();
-static struct fbimage mdtp_header;/* = {0};*/
+struct mdtp_fbimage {
+ uint32_t width;
+ uint32_t height;
+ uint8_t image[MDTP_MAX_IMAGE_SIZE];
+};
-/********************************************************************************/
+/*----------------------------------------------------------------------------
+ * Global Variables
+ * -------------------------------------------------------------------------*/
-/* Load the "Firmware Valid" image from EMMC */
-static struct fbimage* mdtp_images_mmc_OK()
+static uint32_t g_pin_frames_x_location[MDTP_MAX_PIN_LEN] = {0};
+static uint32_t g_pin_frames_y_location = 0;
+
+static bool g_initial_screen_displayed = false;
+
+static struct mdtp_fbimage g_mdtp_header;
+static struct fbcon_config *fb_config = NULL;
+
+/*----------------------------------------------------------------------------
+ * Local Functions
+ * -------------------------------------------------------------------------*/
+
+/**
+ * Load images from EMMC
+ */
+static struct mdtp_fbimage* mdtp_read_mmc_image(uint32_t offset, uint32_t width, uint32_t height)
{
int index = INVALID_PTN;
unsigned long long ptn = 0;
- struct fbcon_config *fb_display = NULL;
- struct fbimage *logo = &mdtp_header;
+ struct mdtp_fbimage *logo = &g_mdtp_header;
uint32_t block_size = mmc_get_device_blocksize();
index = partition_get_index("mdtp");
@@ -71,231 +128,475 @@
return NULL;
}
- fb_display = fbcon_display();
- if (fb_display)
+ if (fb_config)
{
- uint8_t *base = (uint8_t *) fb_display->base;
- base += LOGO_IMG_OFFSET;
+ uint8_t *base = logo->image;
- if (mmc_read(ptn, (void*)base, ROUNDUP(MDTP_IMAGE_WIDTH*MDTP_IMAGE_HEIGHT*3, block_size))) {
+ if (mmc_read(ptn+offset, (void*)base, ROUNDUP(width*height*3, block_size))) {
fbcon_clear();
dprintf(CRITICAL, "ERROR: mdtp image read failed\n");
return NULL;
}
- logo->image = base;
+ logo->width = width;
+ logo->height = height;
}
return logo;
}
-/* Load the "Firmware Invalid" image from EMMC */
-static struct fbimage* mdtp_images_mmc_INVALID()
+/**
+ * flush fbcon display
+ *
+ * The function is duplicated from fbcon.c
+ */
+static void fbcon_flush(void)
{
- int index = INVALID_PTN;
- unsigned long long ptn = 0;
- struct fbcon_config *fb_display = NULL;
- struct fbimage *logo = &mdtp_header;
- uint32_t block_size = mmc_get_device_blocksize();
+ if (fb_config->update_start)
+ fb_config->update_start();
+ if (fb_config->update_done)
+ while (!fb_config->update_done());
+}
- index = partition_get_index("mdtp");
- if (index == 0) {
- dprintf(CRITICAL, "ERROR: mdtp Partition table not found\n");
- return NULL;
- }
+/**
+ * Clear complete section on the screen.
+ * The section is of section_height, and is located from the y
+ * coordinate and down.
+ */
+static void fbcon_clear_section(uint32_t y, uint32_t section_height)
+{
+ unsigned image_base;
+ unsigned bytes_per_bpp;
- ptn = partition_get_offset(index);
- if (ptn == 0) {
- dprintf(CRITICAL, "ERROR: mdtp Partition invalid\n");
- return NULL;
- }
-
- fb_display = fbcon_display();
- if (fb_display)
+ if (fb_config)
{
- uint8_t *base = (uint8_t *) fb_display->base;
- base += LOGO_IMG_OFFSET;
+ image_base = (y *(fb_config->width));
+ bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
- if (mmc_read(ptn+MDTP_INVALID_OFFSET, (void*)base, ROUNDUP(MDTP_IMAGE_WIDTH*MDTP_IMAGE_HEIGHT*3, block_size))) {
- fbcon_clear();
- dprintf(CRITICAL, "ERROR: mdtp image read failed\n");
- return NULL;
- }
- logo->image = base;
+ unsigned count = fb_config->width*section_height;
+ memset(fb_config->base + image_base*bytes_per_bpp, RGB888_BLACK, count*bytes_per_bpp);
+
+ fbcon_flush();
}
-
- return logo;
-}
-
-/* Load the "Verifying Firmware" image from EMMC */
-static struct fbimage* mdtp_images_mmc_CHECKING()
-{
- int index = INVALID_PTN;
- unsigned long long ptn = 0;
- struct fbcon_config *fb_display = NULL;
- struct fbimage *logo = &mdtp_header;
- uint32_t block_size = mmc_get_device_blocksize();
-
- index = partition_get_index("mdtp");
- if (index == 0) {
- dprintf(CRITICAL, "ERROR: mdtp Partition table not found\n");
- return NULL;
- }
-
- ptn = partition_get_offset(index);
- if (ptn == 0) {
- dprintf(CRITICAL, "ERROR: mdtp Partition invalid\n");
- return NULL;
- }
-
- fb_display = fbcon_display();
- if (fb_display)
+ else
{
- uint8_t *base = (uint8_t *) fb_display->base;
- base += LOGO_IMG_OFFSET;
-
- if (mmc_read(ptn+MDTP_CHECKING_OFFSET, (void*)base, ROUNDUP(MDTP_IMAGE_WIDTH*MDTP_IMAGE_HEIGHT*3, block_size))) {
- fbcon_clear();
- dprintf(CRITICAL, "ERROR: mdtp image read failed\n");
- return NULL;
- }
- logo->image = base;
+ dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
+ display_error_msg();
}
-
- return logo;
}
-/* Load the "Verifying Firmware" image from EMMC */
-static struct fbimage* mdtp_images_mmc_RECOVERED()
+/**
+ * Put image at a specific (x,y) location on the screen.
+ * Duplicated from fbcon.c, with modifications to allow (x,y) location (instead of a centered image),
+ * and display bmp images properly (order of copying the lines to the screen was reversed)
+ */
+static void fbcon_putImage_in_location(struct mdtp_fbimage *fbimg, uint32_t x, uint32_t y)
{
- int index = INVALID_PTN;
- unsigned long long ptn = 0;
- struct fbcon_config *fb_display = NULL;
- struct fbimage *logo = &mdtp_header;
- uint32_t block_size = mmc_get_device_blocksize();
+ unsigned i = 0;
+ unsigned bytes_per_bpp;
+ unsigned image_base;
+ unsigned width, pitch, height;
+ unsigned char *logo_base = NULL;
- index = partition_get_index("mdtp");
- if (index == 0) {
- dprintf(CRITICAL, "ERROR: mdtp Partition table not found\n");
- return NULL;
+ if (!fb_config) {
+ dprintf(CRITICAL,"ERROR: NULL configuration, image cannot be displayed\n");
+ return;
}
- ptn = partition_get_offset(index);
- if (ptn == 0) {
- dprintf(CRITICAL, "ERROR: mdtp Partition invalid\n");
- return NULL;
+ if(fbimg) {
+ width = pitch = fbimg->width;
+ height = fbimg->height;
+ logo_base = (unsigned char *)fbimg->image;
+ }
+ else {
+ dprintf(CRITICAL,"ERROR: invalid image struct\n");
+ return;
}
- fb_display = fbcon_display();
- if (fb_display)
+ bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
+
+#if DISPLAY_TYPE_MIPI
+ if (bytes_per_bpp == 3)
{
- uint8_t *base = (uint8_t *) fb_display->base;
- base += LOGO_IMG_OFFSET;
+ if (fbimg->width == fb_config->width && fbimg->height == fb_config->height)
+ return;
- if (mmc_read(ptn+MDTP_RECOVERED_OFFSET, (void*)base, ROUNDUP(MDTP_IMAGE_WIDTH*MDTP_IMAGE_HEIGHT*3, block_size))) {
- fbcon_clear();
- dprintf(CRITICAL, "ERROR: mdtp image read failed\n");
- return NULL;
+ if (fbimg->width > fb_config->width || fbimg->height > fb_config->height)
+ {
+ dprintf(CRITICAL,"ERROR: invalid image size, larger than the screen\n");
+ return;
}
- logo->image = base;
+
+ image_base = ( (y *(fb_config->width)) + x);
+ for (i = 0; i < height; i++) {
+ memcpy (fb_config->base + ((image_base + (i * (fb_config->width))) * bytes_per_bpp),
+ logo_base + ((height - 1 - i) * pitch * bytes_per_bpp), width * bytes_per_bpp);
+ }
}
- return logo;
+ fbcon_flush();
+
+#if DISPLAY_MIPI_PANEL_NOVATEK_BLUE
+ if(is_cmd_mode_enabled())
+ mipi_dsi_cmd_mode_trigger();
+#endif
+
+#else
+ if (bytes_per_bpp == 2)
+ {
+ for (i = 0; i < fbimg->width; i++)
+ {
+ memcpy (fb_config->base + ((image_base + (i * (fb_config->width))) * bytes_per_bpp),
+ fbimg->image + (i * fbimg->height * bytes_per_bpp),
+ fbimg->height * bytes_per_bpp);
+ }
+ }
+ fbcon_flush();
+#endif
}
-/* Show the "Firmware Valid" image */
-static void display_image_on_screen_OK()
+/**
+ * Display main error message
+ */
+static int display_error_message()
{
- struct fbimage *fbimg;
+ struct mdtp_fbimage *fbimg;
- fbcon_clear();
- fbimg = mdtp_images_mmc_OK();
- fbimg->header.width = MDTP_IMAGE_WIDTH;
- fbimg->header.height = MDTP_IMAGE_HEIGHT;
+ fb_config = fbcon_display();
- dprintf(CRITICAL, "display_image_on_screen_OK\n");
- fbcon_putImage(fbimg, true);
+ if (fb_config)
+ {
+ uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_ERROR_MSG_WIDTH,fb_config->width);
+ uint32_t y = ((fb_config->height)*ERROR_MESSAGE_RELATIVE_Y_LOCATION);
+
+ fbimg = mdtp_read_mmc_image(MDTP_ERROR_MSG_OFFSET, MDTP_ERROR_MSG_WIDTH, MDTP_ERROR_MSG_HEIGHT);
+ if (NULL == fbimg)
+ {
+ dprintf(CRITICAL,"ERROR: failed to read error image from mmc\n");
+ return -1;
+ }
+
+ fbcon_putImage_in_location(fbimg, x, y);
+
+ return 0;
+ }
+ else
+ {
+ dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
+ return -1;
+ }
}
-/* Show the "Firmware Invalid" image */
-static void display_image_on_screen_INVALID()
+/**
+ * Read from mmc the image in the given offset, of the given width and height.
+ * Then, display the image on the screen in the given (x,y) location.
+ */
+static void display_image(uint32_t offset, uint32_t width, uint32_t height, uint32_t x, uint32_t y)
{
- struct fbimage *fbimg;
+ struct mdtp_fbimage *fbimg;
- fbcon_clear();
- fbimg = mdtp_images_mmc_INVALID();
- fbimg->header.width = MDTP_IMAGE_WIDTH;
- fbimg->header.height = MDTP_IMAGE_HEIGHT;
+ if (fb_config)
+ {
+ fbimg = mdtp_read_mmc_image(offset, width, height);
+ if (NULL == fbimg)
+ {
+ dprintf(CRITICAL,"ERROR: failed to read image from mmc\n");
+ display_error_msg();
+ }
- dprintf(CRITICAL, "display_image_on_screen_INVALID\n");
- fbcon_putImage(fbimg, true);
+ fbcon_putImage_in_location(fbimg, x, y);
+ }
+ else
+ {
+ dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
+ display_error_msg();
+ }
}
-/* Show the "Verifying Firmware" image */
-static void display_image_on_screen_CHECKING()
+/**
+ * Display initial delay message
+ */
+static void display_initial_delay()
{
- struct fbimage *fbimg;
+ uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_MAIN_TEXT_WIDTH,fb_config->width);
+ uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
- fbcon_clear();
- fbimg = mdtp_images_mmc_CHECKING();
- fbimg->header.width = MDTP_IMAGE_WIDTH;
- fbimg->header.height = MDTP_IMAGE_HEIGHT;
-
- dprintf(CRITICAL, "display_image_on_screen_CHECKING\n");
- fbcon_putImage(fbimg, true);
+ display_image(MDTP_INITIAL_DELAY_OFFSET, MDTP_MAIN_TEXT_WIDTH, MDTP_MAIN_TEXT_HEIGHT, x, y);
}
-/* Show the "Verifying Firmware" image */
-static void display_image_on_screen_RECOVERED()
+/**
+ * Display "enter PIN" message
+ */
+static void display_enter_pin()
{
- struct fbimage *fbimg;
+ uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_MAIN_TEXT_WIDTH,fb_config->width);
+ uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
- fbcon_clear();
- fbimg = mdtp_images_mmc_RECOVERED();
- fbimg->header.width = MDTP_IMAGE_WIDTH;
- fbimg->header.height = MDTP_IMAGE_HEIGHT;
-
- dprintf(CRITICAL, "display_image_on_screen_RECOVERED\n");
- fbcon_putImage(fbimg, true);
+ display_image(MDTP_ENTER_PIN_OFFSET, MDTP_MAIN_TEXT_WIDTH, MDTP_MAIN_TEXT_HEIGHT, x, y);
}
-/* Display the "Firmware Valid" screen */
-void show_OK_msg()
+/**
+ * Display invalid PIN message
+ */
+static void display_invalid_pin()
{
- display_image_on_screen_OK();
- mdelay(MDTP_UX_DELAY);
+ uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_MAIN_TEXT_WIDTH,fb_config->width);
+ uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
- return;
+ display_image(MDTP_INVALID_PIN_OFFSET, MDTP_MAIN_TEXT_WIDTH, MDTP_MAIN_TEXT_HEIGHT, x, y);
}
-/* Display the "Firmware Invalid" screen */
-void show_invalid_msg()
+/**
+ * Clear digits instructions
+ */
+static void display_digits_instructions()
{
- display_image_on_screen_INVALID();
+ uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_DIGITS_INSTRUCTIONS_WIDTH,fb_config->width);
+ uint32_t y = (fb_config->height)*PIN_TEXT_RELATIVE_Y_LOCATION;
+
+ display_image(MDTP_DIGITS_INSTRUCTIONS_OFFSET, MDTP_DIGITS_INSTRUCTIONS_WIDTH, MDTP_DIGITS_INSTRUCTIONS_HEIGHT, x, y);
+}
+
+/**
+ * Clear digits instructions
+ */
+static void clear_digits_instructions()
+{
+ uint32_t y = (fb_config->height)*PIN_TEXT_RELATIVE_Y_LOCATION;
+
+ fbcon_clear_section(y, MDTP_DIGITS_INSTRUCTIONS_HEIGHT);
+}
+
+/**
+ * Display a digit as un-selected.
+ */
+static void display_digit(uint32_t x, uint32_t y, uint32_t digit)
+{
+ display_image(MDTP_PIN_DIGIT_0_OFFSET + digit*MDTP_PIN_DIGITS_OFFSET,
+ MDTP_PIN_DIGIT_WIDTH, MDTP_PIN_DIGIT_HEIGHT, x, y);
+}
+
+/**
+ * Display a digit as selected.
+ */
+static void display_selected_digit(uint32_t x, uint32_t y, uint32_t digit)
+{
+ display_image(MDTP_PIN_SELECTED_DIGIT_0_OFFSET + digit*MDTP_PIN_DIGITS_OFFSET,
+ MDTP_PIN_DIGIT_WIDTH, MDTP_PIN_DIGIT_HEIGHT, x, y);
+}
+
+/**
+ * Display OK button as un-selected.
+ */
+static void display_ok_button()
+{
+ uint32_t ok_x = CENTER_IMAGE_ON_X_AXIS(MDTP_OK_BUTTON_WIDTH,fb_config->width);
+ uint32_t ok_y = (fb_config->height)*OK_BUTTON_RELATIVE_Y_LOCATION;
+
+ display_image(MDTP_OK_BUTTON_OFFSET, MDTP_OK_BUTTON_WIDTH, MDTP_OK_BUTTON_HEIGHT, ok_x, ok_y);
+}
+
+/**
+ * Display OK button as selected.
+ */
+static void display_selected_ok_button()
+{
+ uint32_t ok_x = CENTER_IMAGE_ON_X_AXIS(MDTP_OK_BUTTON_WIDTH,fb_config->width);
+ uint32_t ok_y = (fb_config->height)*OK_BUTTON_RELATIVE_Y_LOCATION;
+
+ display_image(MDTP_SELECTED_OK_BUTTON_OFFSET, MDTP_OK_BUTTON_WIDTH, MDTP_OK_BUTTON_HEIGHT, ok_x, ok_y);
+}
+
+/**
+ * Display the instructions for the OK button.
+ */
+static void display_pin_instructions()
+{
+ uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_PIN_INSTRUCTIONS_WIDTH,fb_config->width);
+ uint32_t y = (fb_config->height)*OK_TEXT_RELATIVE_Y_LOCATION;
+
+ display_image(MDTP_PIN_INSTRUCTIONS_OFFSET, MDTP_PIN_INSTRUCTIONS_WIDTH, MDTP_PIN_INSTRUCTIONS_HEIGHT, x, y);
+}
+
+/**
+ * Clear the instructions for the OK button.
+ */
+static void clear_pin_message()
+{
+ uint32_t y = (fb_config->height)*OK_TEXT_RELATIVE_Y_LOCATION;
+
+ fbcon_clear_section(y, MDTP_PIN_INSTRUCTIONS_HEIGHT);
+}
+
+/**
+ * Display the basic layout of the screen (done only once).
+ */
+static void display_initial_screen(uint32_t pin_length)
+{
+ if (g_initial_screen_displayed == true)
+ return;
+
+ fb_config = fbcon_display();
+
+ if (fb_config)
+ {
+ fbcon_clear();
+
+ if (display_error_message())
+ display_error_msg();
+ display_initial_delay();
+
+ mdelay(INITIAL_DELAY_MSECONDS);
+
+ g_pin_frames_y_location = ((fb_config->height)*PIN_RELATIVE_Y_LOCATION);
+
+ uint32_t total_pin_length = pin_length*MDTP_PIN_DIGIT_WIDTH + DIGIT_SPACE*(pin_length - 1);
+ uint32_t complete_pin_centered = (fb_config->width - total_pin_length)/2;
+
+ for (int i=0; i<(int)pin_length; i++)
+ {
+ g_pin_frames_x_location[i] = complete_pin_centered + i*(DIGIT_SPACE+MDTP_PIN_DIGIT_WIDTH);
+ }
+
+ for (int i=0; i<(int)pin_length; i++)
+ {
+ display_digit(g_pin_frames_x_location[i], g_pin_frames_y_location, 0);
+ }
+
+ display_ok_button();
+
+ g_initial_screen_displayed = true;
+ }
+ else
+ {
+ dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
+ display_error_msg();
+ return;
+ }
+}
+
+/**
+ * Display the recovery PIN screen and set received buffer
+ * with the PIN the user has entered.
+ * The entered PIN will be validated by the calling function.
+ */
+static void display_get_pin_interface(char *entered_pin, uint32_t pin_length)
+{
+ uint32_t previous_position = 0, current_position = 0;
+
+ display_initial_screen(pin_length);
+ display_enter_pin();
+
+ // Convert ascii to digits
+ for (uint32_t i=0; i<pin_length; i++)
+ {
+ entered_pin[i] -= '0';
+ }
+ display_selected_digit(g_pin_frames_x_location[0], g_pin_frames_y_location, entered_pin[0]);
+ display_digits_instructions();
while (1)
{
- if(target_volume_down())
+ if (target_volume_up())
{
- display_image_on_screen_RECOVERED();
- mdelay(MDTP_UX_DELAY);
- break;
+ // current position is the OK button
+ if (current_position == pin_length)
+ {
+ // Convert digits to ascii and
+ // validate entered PIN in the calling function
+ for (uint32_t i=0; i<pin_length; i++)
+ {
+ entered_pin[i] += '0';
+ }
+ return;
+ }
+
+ // current position is a PIN slot
+ entered_pin[current_position] = (entered_pin[current_position]+1) % 10;
+ display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
+ mdelay(MDTP_PRESSING_DELAY_MSEC);
+ }
+ if (target_volume_down())
+ {
+ previous_position = current_position;
+ current_position = (current_position+1) % (pin_length+1);
+
+ // previous position was the OK button
+ if (previous_position == pin_length)
+ {
+ clear_pin_message();
+ display_ok_button();
+
+ display_digits_instructions();
+ display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
+
+ }
+
+ // current position is the OK button
+ else if (current_position == pin_length)
+ {
+ display_digit(g_pin_frames_x_location[previous_position], g_pin_frames_y_location, entered_pin[previous_position]);
+ clear_digits_instructions();
+
+ display_selected_ok_button();
+ display_pin_instructions();
+ }
+
+ // both the previous and the current positions are PIN slots
+ else
+ {
+ display_digit(g_pin_frames_x_location[previous_position], g_pin_frames_y_location, entered_pin[previous_position]);
+
+ display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
+ }
+
+ mdelay(MDTP_PRESSING_DELAY_MSEC);
}
}
+}
+
+/*----------------------------------------------------------------------------
+ * External Functions
+ * -------------------------------------------------------------------------*/
+
+/**
+ * Display the recovery PIN screen and set received buffer
+ * with the PIN the user has entered.
+ */
+void get_pin_from_user(char *entered_pin, uint32_t pin_length)
+{
+ display_get_pin_interface(entered_pin, pin_length);
return;
}
-/* Display the "Verifying Firmware" screen */
-void show_checking_msg()
+/**
+ * User has entered invalid PIN, display error message and
+ * allow the user to try again.
+ */
+void display_invalid_pin_msg()
{
- display_image_on_screen_CHECKING();
- return;
+ clear_pin_message();
+ display_ok_button();
+
+ display_invalid_pin();
+
+ mdelay(INVALID_PIN_DELAY_MSECONDS);
}
-/* Display the "Verifying Firmware" screen */
-void show_recovered_msg()
+/**
+ * Display error message and stop boot process.
+ */
+void display_error_msg()
{
- display_image_on_screen_RECOVERED();
- return;
+ fbcon_clear();
+ display_error_message(); // No point in checking the return value here
+
+ // Invalid state. Nothing to be done but contacting the OEM.
+ // Stop boot process.
+ dprintf(CRITICAL,"ERROR: blocking boot process\n");
+ while(1)
+ {
+
+ }
}
diff --git a/app/aboot/meta_format.h b/app/aboot/meta_format.h
new file mode 100644
index 0000000..7bf6812
--- /dev/null
+++ b/app/aboot/meta_format.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ */
+
+#ifndef _META_FORMAT_H_
+#define _META_FORMAT_H_
+
+#define META_HEADER_MAGIC 0xce1ad63c
+#define MAX_GPT_NAME_SIZE 72
+typedef unsigned int u32;
+typedef unsigned short int u16;
+
+typedef struct meta_header {
+ u32 magic; /* 0xce1ad63c */
+ u16 major_version; /* (0x1) - reject images with higher major versions */
+ u16 minor_version; /* (0x0) - allow images with higer minor versions */
+ char img_version[64]; /* Top level version for images in this meta */
+ u16 meta_hdr_sz; /* size of this header */
+ u16 img_hdr_sz; /* size of img_header_entry list */
+} meta_header_t;
+
+typedef struct img_header_entry {
+ char ptn_name[MAX_GPT_NAME_SIZE];
+ u32 start_offset;
+ u32 size;
+} img_header_entry_t;
+
+#endif
diff --git a/app/aboot/rules.mk b/app/aboot/rules.mk
index 95a8865..7774788 100644
--- a/app/aboot/rules.mk
+++ b/app/aboot/rules.mk
@@ -1,9 +1,11 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
-INCLUDES += -I$(LK_TOP_DIR)/platform/msm_shared/include
+INCLUDES += -I$(LK_TOP_DIR)/platform/msm_shared/include -I$(LK_TOP_DIR)/lib/zlib_inflate
DEFINES += ASSERT_ON_TAMPER=1
+MODULES += lib/zlib_inflate
+
OBJS += \
$(LOCAL_DIR)/aboot.o \
$(LOCAL_DIR)/fastboot.o \
diff --git a/app/rpmbtests/qseecom_lk_test.c b/app/rpmbtests/qseecom_lk_test.c
new file mode 100644
index 0000000..0bfcb9b
--- /dev/null
+++ b/app/rpmbtests/qseecom_lk_test.c
@@ -0,0 +1,358 @@
+/* Copyright (c) 2015, 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 <partition_parser.h>
+#include <qseecom_lk.h>
+#include <scm.h>
+
+//#include "qseecom_legacy.h"
+#include "qseecom_lk_api.h"
+#include <debug.h>
+#include <kernel/mutex.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <arch/defines.h>
+#include <string.h>
+
+/* commands supported from sample client */
+#define CLIENT_CMD0_GET_VERSION 0
+#define CLIENT_CMD1_BASIC_DATA 1
+#define CLIENT_CMD2_REGISTER_SB_PTR 2
+#define CLIENT_CMD3_RUN_CRYTPO_TEST 3
+#define CLIENT_CMD4_RUN_CRYTPO_PERF 4
+#define CLIENT_CMD5_RUN_SFS_TEST 5
+#define CLIENT_CMD6_RUN_BUF_ALIGNMENT_TEST 6
+#define CLIENT_CMD7_RUN_CRYPTO_RSA_TEST 7
+#define CLIENT_CMD8_RUN_RSA_PERF_TEST 8
+#define CLIENT_CMD9_RUN_CMNLIB_TEST 9
+#define CLIENT_CMD10_RUN_CORE_TEST 10
+#define CLIENT_CMD11_RUN_SECURECHANNEL_TEST 11
+#define CLIENT_CMD12_RUN_SERVICES_TEST 12
+#define CLIENT_CMD13_RUN_MISC_TEST 13
+#define CLIENT_CMD17_RUN_STORAGE_TEST 17
+#define CLIENT_APPSBL_QSEECOM_RUN_LISTENER_FRAMEWORK_TEST_1 50
+
+#define __64KB__ 0x10000
+#define __32KB__ 0x8000
+#define __16KB__ 0x4000
+#define __8KB__ 0x2000
+#define __4KB__ 0x1000
+#define __2KB__ 0x800
+#define __1KB__ 0x400
+
+#define LISTENER_TEST_SERVICE 0x100
+
+struct qsc_send_cmd {
+ unsigned int cmd_id;
+ unsigned int data;
+ unsigned int data2;
+ unsigned int len;
+ unsigned int start_pkt;
+ unsigned int end_pkt;
+ unsigned int test_buf_size;
+};
+
+struct qsc_send_cmd_rsp {
+ unsigned int data;
+ int status;
+};
+
+
+int listener_test_cmd_handler (void* buf, uint32_t size)
+{
+ uint32 *req = 0;
+ uint32 rsp = 0;
+
+ if ((!buf) || (size < 4)) {
+ dprintf(CRITICAL, "Invalid listener cmd handler inputs\n");
+ return -1;
+ }
+
+ req = (uint32 *)buf;
+ if (*req == (100 * 100)) {
+ dprintf(CRITICAL, "Listener Success\n");
+ rsp = *req * 100;
+ dprintf(CRITICAL, "rsp = %u\n", rsp);
+ memcpy (buf, &rsp, sizeof(uint32));
+ return 0;
+ } else {
+ dprintf(CRITICAL, "Listener Failure, req:%u\n", *req);
+ rsp = 0;
+ memcpy (buf, &rsp, sizeof(uint32));
+ return 0;
+ }
+}
+
+static struct qseecom_listener_services listeners[] = {
+ {
+ .service_name = "Listener Test service",
+ .id = LISTENER_TEST_SERVICE,
+ .sb_size = (20 * 1024),
+ .service_cmd_handler = listener_test_cmd_handler,
+ },
+};
+
+int qsc_run_get_version(char *appname, uint32_t iterations)
+{
+ struct qsc_send_cmd send_cmd;
+ struct qsc_send_cmd_rsp msgrsp={0}; /* response data sent from QSEE */
+ uint32_t i = 0, ret = 0, err = -1;
+
+ dprintf(CRITICAL, "%s:Get_version\n", __func__);
+
+ dprintf(CRITICAL, "(This may take a few minutes please wait....)\n");
+ /* Start the application */
+ for (i = 0; i < iterations; i++) {
+ dprintf(CRITICAL, "iteration %d\n", i);
+ ret = qseecom_start_app(appname);
+ if (ret <= 0) {
+ dprintf(CRITICAL, "Start app: fail: ret:%d\n", ret);
+ err = -1;
+ goto err_ret;
+ }
+ dprintf(CRITICAL, "apphandle %u\n", ret);
+ ret = qseecom_start_app(appname);
+ if (ret <= 0) {
+ dprintf(CRITICAL, "Start app: fail: ret:%d\n", ret);
+ err = -1;
+ goto err_ret_shutdown;
+ }
+ dprintf(CRITICAL, "apphandle %u\n", ret);
+ send_cmd.cmd_id = CLIENT_CMD0_GET_VERSION;
+ err = qseecom_send_command(ret, &send_cmd, sizeof(struct qsc_send_cmd), &msgrsp, sizeof(struct qsc_send_cmd_rsp));
+ if (err) {
+ dprintf(CRITICAL, "Send app: fail\n");
+ goto err_ret_shutdown;
+ }
+ dprintf(ALWAYS, "The version of %s is: %u\n", appname, msgrsp.data);
+ /* Shutdown the application */
+ dprintf(ALWAYS, "Shutting down %s\n", appname);
+ err = qseecom_shutdown_app(ret);
+ if (err) {
+ dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+ goto err_ret;
+ }
+ dprintf(ALWAYS, "Shutting down %s\n", appname);
+ err = qseecom_shutdown_app(ret);
+ if (err) {
+ dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+ goto err_ret;
+ }
+
+ }
+err_ret_shutdown:
+ if (err) {
+ if (qseecom_shutdown_app(ret))
+ dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+ }
+err_ret:
+ if (err)
+ dprintf(CRITICAL, "Test %u failed with error %d, shutting down %s\n", CLIENT_CMD0_GET_VERSION, err, appname);
+ else
+ dprintf(CRITICAL, "Test %u passed for iterations %u executing %s\n", CLIENT_CMD0_GET_VERSION, iterations, appname);
+ return err;
+}
+
+
+int qsc_run_start_stop_app_basic_test(char *appname, uint32_t iterations)
+{
+ uint32_t i = 0;
+ int ret = 0; /* return value */
+ int err = 0; /* return value */
+ struct qsc_send_cmd send_cmd = {0};
+ struct qsc_send_cmd_rsp msgrsp={0}; /* response data sent from QSEE */
+
+ dprintf(CRITICAL, "%s:Basic_start_stop_test\n", __func__);
+
+ dprintf(CRITICAL, "(This may take a few minutes please wait....)\n");
+ /* Start the application */
+ for (i = 0; i < iterations; i++) {
+ dprintf(CRITICAL, "iteration %d\n", i);
+ ret = qseecom_start_app(appname);
+ if (ret <= 0) {
+ dprintf(CRITICAL, "Start app: fail: ret:%d\n", ret);
+ err = -1;
+ goto err_ret;
+ }
+ /* Send data using send command to QSEE application */
+ send_cmd.cmd_id = CLIENT_CMD1_BASIC_DATA;
+ send_cmd.start_pkt = 0;
+ send_cmd.end_pkt = 0;
+ send_cmd.test_buf_size = 0;
+ send_cmd.data = 100;
+ err = qseecom_send_command(ret, &send_cmd, sizeof(struct qsc_send_cmd), &msgrsp, sizeof(struct qsc_send_cmd_rsp));
+ if (err) {
+ dprintf(CRITICAL, "Send app: fail\n");
+ goto err_ret_shutdown;
+ }
+ if (((msgrsp.data)/100) != 10) {
+ dprintf(CRITICAL, "App Comm Error:%u\n", msgrsp.data);
+ err = -1;
+ goto err_ret_shutdown;
+ }
+ dprintf(CRITICAL, "msg.rsp:%u\n", msgrsp.data);
+ /* Shutdown the application */
+ err = qseecom_shutdown_app(ret);
+ if (err) {
+ dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+ goto err_ret;
+ }
+ }
+err_ret_shutdown:
+ if (err) {
+ if (qseecom_shutdown_app(ret))
+ dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+ }
+err_ret:
+ if (err)
+ dprintf(CRITICAL, "Test %u failed with error %d, shutting down %s\n", CLIENT_CMD0_GET_VERSION, err, appname);
+ else
+ dprintf(CRITICAL, "Test %u passed for iterations %u executing %s\n", CLIENT_CMD0_GET_VERSION, iterations, appname);
+ return err;
+}
+
+
+
+int qsc_run_start_stop_app_listener_test(char *appname, uint32_t iterations)
+{
+ uint32_t i = 0;
+ int ret = 0; /* return value */
+ int err = 0; /* return value */
+ struct qsc_send_cmd send_cmd;
+ struct qsc_send_cmd_rsp msgrsp={0}; /* response data sent from QSEE */
+
+ dprintf(CRITICAL, "%s:qsc_run_start_stop_app_listener_test\n", __func__);
+
+ dprintf(CRITICAL, "(This may take a few minutes please wait....)\n");
+
+ ret = qseecom_register_listener(&listeners[0]);
+ if (ret < 0) {
+ dprintf(CRITICAL, "Reg Listener: fail: ret:%d\n", ret);
+ err = -1;
+ goto err_ret;
+ }
+ /* Start the application */
+ for (i = 0; i < iterations; i++) {
+ dprintf(CRITICAL, "iteration %d\n", i);
+ ret = qseecom_start_app(appname);
+ if (ret <= 0) {
+ dprintf(CRITICAL, "Start app: fail: ret:%d\n", ret);
+ err = -1;
+ goto err_dereg;
+ }
+ /* Send data using send command to QSEE application */
+ send_cmd.cmd_id = CLIENT_APPSBL_QSEECOM_RUN_LISTENER_FRAMEWORK_TEST_1;
+ send_cmd.start_pkt = 0;
+ send_cmd.end_pkt = 0;
+ send_cmd.test_buf_size = 0;
+ send_cmd.data = 100;
+ err = qseecom_send_command(ret, &send_cmd, sizeof(struct qsc_send_cmd), &msgrsp, sizeof(struct qsc_send_cmd_rsp));
+ if (err) {
+ dprintf(CRITICAL, "Send app: fail\n");
+ goto err_ret_shutdown;
+ }
+ if (((msgrsp.data)/100) != 10) {
+ dprintf(CRITICAL, "App Comm Error:%u Status:%d\n", msgrsp.data, msgrsp.status);
+ err = -1;
+ goto err_ret_shutdown;
+ }
+ /* Shutdown the application */
+ err = qseecom_shutdown_app(ret);
+ if (err) {
+ dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+ goto err_dereg;
+ }
+ }
+
+err_ret_shutdown:
+ if (err) {
+ if (qseecom_shutdown_app(ret))
+ dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+ }
+err_dereg:
+ ret = qseecom_deregister_listener(listeners[0].id);
+ if (ret < 0) {
+ dprintf(CRITICAL, "DeReg Listener: fail: ret:%d\n", ret);
+ err = -1;
+ }
+err_ret:
+ if (err)
+ dprintf(CRITICAL, "Test %u failed with error %d, shutting down %s\n", CLIENT_CMD0_GET_VERSION, err, appname);
+ else
+ dprintf(CRITICAL, "Test %u passed for iterations %u executing %s\n", CLIENT_CMD0_GET_VERSION, iterations, appname);
+ return err;
+}
+
+int qseecom_test_cmd_handler(const char *arg) {
+ char *token = NULL;
+ char * appname = NULL;
+ uint32_t test = 0;
+ uint32_t iterations = 0;
+
+ token = strtok((char *)arg, " ");
+ if (!token) {
+ dprintf(CRITICAL, "Appname not provided, error\n");
+ return -1;
+ }
+ appname = token;
+
+ token = strtok(NULL, " ");
+ if (!token) {
+ dprintf(CRITICAL, "Test not provided, error\n");
+ return -1;
+ }
+ test = atoi(token);
+
+ token = strtok(NULL, " ");
+ if (token)
+ iterations = atoi(token);
+ else
+ dprintf(CRITICAL, "iterations not provided\n");
+
+ switch (test) {
+ case CLIENT_CMD0_GET_VERSION:
+ {
+ qsc_run_get_version(appname, iterations);
+ break;
+ }
+ case CLIENT_CMD1_BASIC_DATA:
+ {
+ qsc_run_start_stop_app_basic_test(appname, iterations);
+ break;
+ }
+
+ case CLIENT_APPSBL_QSEECOM_RUN_LISTENER_FRAMEWORK_TEST_1:
+ {
+ qsc_run_start_stop_app_listener_test(appname, iterations);
+ break;
+ }
+ }
+ dprintf(CRITICAL, "test:%u iterations:%u\n", test, iterations);
+ return 0;
+}
+
diff --git a/app/rpmbtests/rules.mk b/app/rpmbtests/rules.mk
index b59dee9..f43c488 100644
--- a/app/rpmbtests/rules.mk
+++ b/app/rpmbtests/rules.mk
@@ -5,4 +5,5 @@
DEFINES += ASSERT_ON_TAMPER=1
OBJS += \
- $(LOCAL_DIR)/ufs_rpmb.o
+ $(LOCAL_DIR)/ufs_rpmb.o \
+ $(LOCAL_DIR)/qseecom_lk_test.o
diff --git a/app/rpmbtests/ufs_rpmb.c b/app/rpmbtests/ufs_rpmb.c
index 7342a82..d951933 100644
--- a/app/rpmbtests/ufs_rpmb.c
+++ b/app/rpmbtests/ufs_rpmb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015 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
@@ -99,9 +99,11 @@
}
memset(&data_frame, 0, sizeof(data_frame));
memset(&result_frame, 0, sizeof(result_frame));
- data_frame.address = BE16(address);
- data_frame.blockcount = BE16(rpmb_num_blocks);
- data_frame.requestresponse = BE16(AUTH_READ);
+ data_frame.address[0] = (address & 0xff00) >> 8;
+ data_frame.address[1] = address & 0x00ff;
+ data_frame.blockcount[0] = (rpmb_num_blocks & 0xff00) >> 8;
+ data_frame.blockcount[1] = rpmb_num_blocks & 0x00ff;
+ data_frame.requestresponse[1] = AUTH_READ;
for(i = 0 ; i < 16; i++)
{
data_frame.nonce[i] = (rand() % 256) + 1;
diff --git a/arch/arm/cache-ops.S b/arch/arm/cache-ops.S
index 22d9a2b..cfcbaa4 100644
--- a/arch/arm/cache-ops.S
+++ b/arch/arm/cache-ops.S
@@ -328,6 +328,7 @@
/* void arch_flush_invalidate_cache_range(addr_t start, size_t len); */
FUNCTION(arch_clean_invalidate_cache_range)
+ dsb
add r2, r0, r1 // Calculate the end address
bic r0,#(CACHE_LINE-1) // Align start with cache line
0:
diff --git a/dev/fbcon/fbcon.c b/dev/fbcon/fbcon.c
index e95036e..ce79a3e 100644
--- a/dev/fbcon/fbcon.c
+++ b/dev/fbcon/fbcon.c
@@ -2,7 +2,7 @@
* Copyright (c) 2008, Google Inc.
* All rights reserved.
*
- * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2015, 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
@@ -35,6 +35,7 @@
#include <splash.h>
#include <platform.h>
#include <string.h>
+#include <arch/ops.h>
#include "font5x12.h"
@@ -300,6 +301,8 @@
memcpy (config->base + ((image_base + (i * (config->width))) * bytes_per_bpp),
logo_base + (i * pitch * bytes_per_bpp), width * bytes_per_bpp);
}
+ /* Flush the contents to memory before giving the data to dma */
+ arch_clean_invalidate_cache_range((addr_t) config->base, (total_x * total_y * bytes_per_bpp));
}
fbcon_flush();
@@ -323,6 +326,8 @@
(header->height * bytes_per_bpp));
}
}
+ /* Flush the contents to memory before giving the data to dma */
+ arch_clean_invalidate_cache_range((addr_t) config->base, (total_x * total_y * bytes_per_bpp));
fbcon_flush();
#endif
}
diff --git a/dev/gcdb/display/gcdb_display.c b/dev/gcdb/display/gcdb_display.c
index 8e521b1..4a49b1b 100755
--- a/dev/gcdb/display/gcdb_display.c
+++ b/dev/gcdb/display/gcdb_display.c
@@ -210,6 +210,8 @@
goto splash_err;
}
+ mmc_set_lun(partition_get_lun(index));
+
blocksize = mmc_get_device_blocksize();
if (blocksize == 0) {
dprintf(CRITICAL, "ERROR:splash Partition invalid blocksize\n");
@@ -269,6 +271,8 @@
goto store_err;
}
+ mmc_set_lun(partition_get_lun(index));
+
ret = mmc_write(ptn, sizeof(uint32_t), &pinfo->dfps);
if (ret)
dprintf(CRITICAL, "mmc write failed!\n");
diff --git a/dev/gcdb/display/include/panel_auo_qvga_cmd.h b/dev/gcdb/display/include/panel_auo_qvga_cmd.h
new file mode 100644
index 0000000..4215108
--- /dev/null
+++ b/dev/gcdb/display/include/panel_auo_qvga_cmd.h
@@ -0,0 +1,310 @@
+/* Copyright (c) 2015, 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 AND FITNESS
+ * FOR A PARTICULAR PURPOSE 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 _PANEL_AUO_QVGA_CMD_H_
+#define _PANEL_AUO_QVGA_CMD_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration */
+/*---------------------------------------------------------------------------*/
+static struct panel_config auo_qvga_cmd_panel_data = {
+ "qcom,mdss_dsi_auo_qvga_cmd", "dsi:0:", "qcom,mdss-dsi-panel",
+ 10, 1, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ""
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution auo_qvga_cmd_panel_res = {
+ 320, 320, 4, 4, 4, 0, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information */
+/*---------------------------------------------------------------------------*/
+static struct color_info auo_qvga_cmd_color = {
+ 24, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel on/off command information */
+/*---------------------------------------------------------------------------*/
+static char auo_qvga_cmd_on_cmd0[] = {
+ 0x06, 0x00, 0x39, 0xC0,
+ 0xF0, 0x55, 0xAA, 0x52,
+ 0x08, 0x00, 0xFF, 0xFF,
+};
+
+static char auo_qvga_cmd_on_cmd1[] = {
+ 0x06, 0x00, 0x39, 0xC0,
+ 0xBD, 0x01, 0x90, 0x14,
+ 0x14, 0x00, 0xFF, 0xFF,
+};
+
+static char auo_qvga_cmd_on_cmd2[] = {
+ 0x06, 0x00, 0x39, 0xC0,
+ 0xBE, 0x01, 0x90, 0x14,
+ 0x14, 0x01, 0xFF, 0xFF,
+};
+
+static char auo_qvga_cmd_on_cmd3[] = {
+ 0x06, 0x00, 0x39, 0xC0,
+ 0xBF, 0x01, 0x90, 0x14,
+ 0x14, 0x00, 0xFF, 0xFF,
+};
+
+static char auo_qvga_cmd_on_cmd4[] = {
+ 0x04, 0x00, 0x39, 0xC0,
+ 0xBB, 0x07, 0x07, 0x07,
+};
+
+static char auo_qvga_cmd_on_cmd5[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0xC7, 0x40, 0xFF, 0xFF,
+};
+
+static char auo_qvga_cmd_on_cmd6[] = {
+ 0x06, 0x00, 0x39, 0xC0,
+ 0xF0, 0x55, 0xAA, 0x52,
+ 0x08, 0x02, 0xFF, 0xFF,
+};
+
+static char auo_qvga_cmd_on_cmd7[] = {
+ 0x03, 0x00, 0x39, 0xC0,
+ 0xFE, 0x08, 0x50, 0xFF,
+};
+
+static char auo_qvga_cmd_on_cmd8[] = {
+ 0x04, 0x00, 0x39, 0xC0,
+ 0xC3, 0xF2, 0x95, 0x04,
+};
+
+static char auo_qvga_cmd_on_cmd9[] = {
+ 0x04, 0x00, 0x15, 0x80,
+};
+
+static char auo_qvga_cmd_on_cmd10[] = {
+ 0x06, 0x00, 0x39, 0xC0,
+ 0xF0, 0x55, 0xAA, 0x52,
+ 0x08, 0x01, 0xFF, 0xFF,
+};
+
+static char auo_qvga_cmd_on_cmd11[] = {
+ 0x04, 0x00, 0x39, 0xC0,
+ 0xB0, 0x03, 0x03, 0x03,
+};
+
+static char auo_qvga_cmd_on_cmd12[] = {
+ 0x04, 0x00, 0x39, 0xC0,
+ 0xB1, 0x05, 0x05, 0x05,
+};
+
+static char auo_qvga_cmd_on_cmd13[] = {
+ 0x04, 0x00, 0x39, 0xC0,
+ 0xB2, 0x01, 0x01, 0x01,
+};
+
+static char auo_qvga_cmd_on_cmd14[] = {
+ 0x04, 0x00, 0x39, 0xC0,
+ 0xB4, 0x07, 0x07, 0x07,
+};
+
+static char auo_qvga_cmd_on_cmd15[] = {
+ 0x04, 0x00, 0x39, 0xC0,
+ 0xB5, 0x03, 0x03, 0x03,
+};
+
+static char auo_qvga_cmd_on_cmd16[] = {
+ 0x04, 0x00, 0x39, 0xC0,
+ 0xB6, 0x53, 0x53, 0x53,
+};
+
+static char auo_qvga_cmd_on_cmd17[] = {
+ 0x04, 0x00, 0x39, 0xC0,
+ 0xB7, 0x33, 0x33, 0x33,
+};
+
+static char auo_qvga_cmd_on_cmd18[] = {
+ 0x04, 0x00, 0x39, 0xC0,
+ 0xB8, 0x23, 0x23, 0x23,
+};
+
+static char auo_qvga_cmd_on_cmd19[] = {
+ 0x04, 0x00, 0x39, 0xC0,
+ 0xB9, 0x03, 0x03, 0x03,
+};
+
+static char auo_qvga_cmd_on_cmd20[] = {
+ 0x04, 0x00, 0x39, 0xC0,
+ 0xBA, 0x03, 0x03, 0x03,
+};
+
+static char auo_qvga_cmd_on_cmd21[] = {
+ 0x04, 0x00, 0x39, 0xC0,
+ 0xBE, 0x32, 0x30, 0x70,
+};
+
+static char auo_qvga_cmd_on_cmd22[] = {
+ 0x08, 0x00, 0x39, 0xC0,
+ 0xCF, 0xFF, 0xD4, 0x95,
+ 0xEF, 0x4F, 0x00, 0x04,
+};
+
+static char auo_qvga_cmd_on_cmd23[] = {
+ 0x35, 0x01, 0x15, 0x80,
+};
+
+static char auo_qvga_cmd_on_cmd24[] = {
+ 0x36, 0x01, 0x15, 0x80,
+};
+
+static char auo_qvga_cmd_on_cmd25[] = {
+ 0xC0, 0x20, 0x15, 0x80,
+};
+
+static char auo_qvga_cmd_on_cmd26[] = {
+ 0x07, 0x00, 0x39, 0xC0,
+ 0xC2, 0x17, 0x17, 0x17,
+ 0x17, 0x17, 0x0B, 0xFF,
+};
+
+static char auo_qvga_cmd_on_cmd27[] = {
+ 0x00, 0x00, 0x32, 0x80,
+};
+
+static char auo_qvga_cmd_on_cmd28[] = {
+ 0x11, 0x00, 0x05, 0x80,
+};
+
+static char auo_qvga_cmd_on_cmd29[] = {
+ 0x29, 0x00, 0x05, 0x80,
+};
+
+static struct mipi_dsi_cmd auo_qvga_cmd_on_command[] = {
+ {0xc, auo_qvga_cmd_on_cmd0, 0x00},
+ {0xc, auo_qvga_cmd_on_cmd1, 0x00},
+ {0xc, auo_qvga_cmd_on_cmd2, 0x00},
+ {0xc, auo_qvga_cmd_on_cmd3, 0x10},
+ {0x8, auo_qvga_cmd_on_cmd4, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd5, 0x00},
+ {0xc, auo_qvga_cmd_on_cmd6, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd7, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd8, 0x00},
+ {0x4, auo_qvga_cmd_on_cmd9, 0x00},
+ {0xc, auo_qvga_cmd_on_cmd10, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd11, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd12, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd13, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd14, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd15, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd16, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd17, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd18, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd19, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd20, 0x00},
+ {0x8, auo_qvga_cmd_on_cmd21, 0x00},
+ {0xc, auo_qvga_cmd_on_cmd22, 0x00},
+ {0x4, auo_qvga_cmd_on_cmd23, 0x00},
+ {0x4, auo_qvga_cmd_on_cmd24, 0x00},
+ {0x4, auo_qvga_cmd_on_cmd25, 0x00},
+ {0xc, auo_qvga_cmd_on_cmd26, 0x00},
+ {0x4, auo_qvga_cmd_on_cmd27, 0x00},
+ {0x4, auo_qvga_cmd_on_cmd28, 0xFF},
+ {0x4, auo_qvga_cmd_on_cmd29, 0x00}
+};
+
+#define auo_QVGA_CMD_ON_COMMAND 30
+
+static char auo_qvga_cmdoff_cmd0[] = {
+ 0x28, 0x00, 0x05, 0x80
+};
+
+static char auo_qvga_cmdoff_cmd1[] = {
+ 0x10, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd auo_qvga_cmd_off_command[] = {
+ {0x4, auo_qvga_cmdoff_cmd0, 0x32},
+ {0x4, auo_qvga_cmdoff_cmd1, 0x78}
+};
+
+#define auo_QVGA_CMD_OFF_COMMAND 2
+
+static struct command_state auo_qvga_cmd_state = {
+ 0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info auo_qvga_cmd_command_panel = {
+ 1, 1, 1, 0, 0, 0x2c, 0, 0, 0, 1, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info auo_qvga_cmd_video_panel = {
+ 1, 0, 0, 0, 1, 1, 2, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration auo_qvga_cmd_lane_config = {
+ 1, 0, 1, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing */
+/*---------------------------------------------------------------------------*/
+static const uint32_t auo_qvga_cmd_timings[] = {
+ 0x5F, 0x12, 0x0A, 0x00, 0x32, 0x34, 0x10, 0x16, 0x0F, 0x03, 0x04, 0x00
+};
+
+static struct panel_timing auo_qvga_cmd_timing_info = {
+ 0, 4, 0x05, 0x15
+};
+
+static struct panel_reset_sequence auo_qvga_cmd_panel_reset_seq = {
+ { 1, 0, 1, }, { 20, 20, 20, }, 2
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight setting */
+/*---------------------------------------------------------------------------*/
+static struct backlight auo_qvga_cmd_backlight = {
+ 2, 1, 255, 100, 1, "PMIC_8941"
+};
+
+#endif /*_PANEL_AUO_QVGA_CMD_H_*/
diff --git a/dev/gcdb/display/include/panel_hx8394d_720p_video.h b/dev/gcdb/display/include/panel_hx8394d_720p_video.h
index 3ab32f8..ac4806f 100644
--- a/dev/gcdb/display/include/panel_hx8394d_720p_video.h
+++ b/dev/gcdb/display/include/panel_hx8394d_720p_video.h
@@ -283,6 +283,6 @@
1, 1, 4095, 100, 1, "PMIC_8941"
};
-#define HX8394D_720P_VIDEO_SIGNATURE 0xFFFF
+#define HX8394D_720P_VIDEO_SIGNATURE 0xa0087
#endif /*_HX8394D_720P_VIDEO_H_*/
diff --git a/dev/gcdb/display/include/panel_hx8394d_qhd_video.h b/dev/gcdb/display/include/panel_hx8394d_qhd_video.h
index 82d3b41..c04fccb 100644
--- a/dev/gcdb/display/include/panel_hx8394d_qhd_video.h
+++ b/dev/gcdb/display/include/panel_hx8394d_qhd_video.h
@@ -207,6 +207,21 @@
};
#define HX8394D_QHD_VIDEO_ON_COMMAND 16
+static char hx8394d_qhd_video_off_cmd0[] = {
+ 0x28, 0x00, 0x05, 0x80
+};
+
+static char hx8394d_qhd_video_off_cmd1[] = {
+ 0x10, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd hx8394d_qhd_video_off_command[] = {
+ {0x4, hx8394d_qhd_video_off_cmd0, 0x32},
+ {0x4, hx8394d_qhd_video_off_cmd1, 0x78}
+};
+
+#define HX8394D_QHD_VIDEO_OFF_COMMAND 2
+
static struct command_state hx8394d_qhd_video_state = {
0, 1
};
diff --git a/dev/gcdb/display/include/panel_ili9806e_fwvga_video.h b/dev/gcdb/display/include/panel_ili9806e_fwvga_video.h
index c4941c5..1055c3c 100644
--- a/dev/gcdb/display/include/panel_ili9806e_fwvga_video.h
+++ b/dev/gcdb/display/include/panel_ili9806e_fwvga_video.h
@@ -87,12 +87,12 @@
static char ili9806e_fwvga_video_on_cmd4[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x31, 0x00, 0xFF, 0xFF,
+ 0x31, 0x02, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd5[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x40, 0x16, 0xFF, 0xFF,
+ 0x40, 0x1A, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd6[] = {
@@ -107,22 +107,22 @@
static char ili9806e_fwvga_video_on_cmd8[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x43, 0x89, 0xFF, 0xFF,
+ 0x43, 0x09, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd9[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x44, 0x06, 0xFF, 0xFF,
+ 0x44, 0x09, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd10[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x50, 0x80, 0xFF, 0xFF,
+ 0x50, 0x78, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd11[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x51, 0x80, 0xFF, 0xFF,
+ 0x51, 0x78, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd12[] = {
@@ -132,497 +132,2791 @@
static char ili9806e_fwvga_video_on_cmd13[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x53, 0x43, 0xFF, 0xFF,
+ 0x53, 0x2B, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd14[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x60, 0x07, 0xFF, 0xFF,
+ 0x57, 0x50, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd15[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x61, 0x00, 0xFF, 0xFF,
+ 0x60, 0x07, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd16[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x62, 0x07, 0xFF, 0xFF,
+ 0x61, 0x00, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd17[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x63, 0x00, 0xFF, 0xFF,
+ 0x62, 0x08, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd18[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xA0, 0x00, 0xFF, 0xFF,
+ 0x63, 0x00, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd19[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xA1, 0x01, 0xFF, 0xFF,
+ 0xA0, 0x00, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd20[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xA2, 0x0A, 0xFF, 0xFF,
+ 0xA1, 0x06, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd21[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xA3, 0x10, 0xFF, 0xFF,
+ 0xA2, 0x10, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd22[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xA4, 0x0B, 0xFF, 0xFF,
+ 0xA3, 0x11, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd23[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xA5, 0x1C, 0xFF, 0xFF,
+ 0xA4, 0x08, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd24[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xA6, 0x0B, 0xFF, 0xFF,
+ 0xA5, 0x1A, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd25[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xA7, 0x09, 0xFF, 0xFF,
+ 0xA6, 0x09, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd26[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xA8, 0x05, 0xFF, 0xFF,
+ 0xA7, 0x08, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd27[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xA9, 0x0B, 0xFF, 0xFF,
+ 0xA8, 0x05, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd28[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xAA, 0x07, 0xFF, 0xFF,
+ 0xA9, 0x0A, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd29[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xAB, 0x06, 0xFF, 0xFF,
+ 0xAA, 0x04, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd30[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xAC, 0x0E, 0xFF, 0xFF,
+ 0xAB, 0x08, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd31[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xAD, 0x29, 0xFF, 0xFF,
+ 0xAC, 0x10, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd32[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xAE, 0x25, 0xFF, 0xFF,
+ 0xAD, 0x38, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd33[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xAF, 0x00, 0xFF, 0xFF,
+ 0xAE, 0x34, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd34[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xC0, 0x00, 0xFF, 0xFF,
+ 0xAF, 0x00, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd35[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xC1, 0x02, 0xFF, 0xFF,
+ 0xC0, 0x00, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd36[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xC2, 0x07, 0xFF, 0xFF,
+ 0xC1, 0x07, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd37[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xC3, 0x0C, 0xFF, 0xFF,
+ 0xC2, 0x15, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd38[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xC4, 0x06, 0xFF, 0xFF,
+ 0xC3, 0x11, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd39[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xC5, 0x18, 0xFF, 0xFF,
+ 0xC4, 0x0A, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd40[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xC6, 0x0B, 0xFF, 0xFF,
+ 0xC5, 0x18, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd41[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xC7, 0x0A, 0xFF, 0xFF,
+ 0xC6, 0x08, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd42[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xC8, 0x02, 0xFF, 0xFF,
+ 0xC7, 0x07, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd43[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xC9, 0x06, 0xFF, 0xFF,
+ 0xC8, 0x03, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd44[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xCA, 0x03, 0xFF, 0xFF,
+ 0xC9, 0x08, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd45[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xCB, 0x03, 0xFF, 0xFF,
+ 0xCA, 0x07, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd46[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xCC, 0x0B, 0xFF, 0xFF,
+ 0xCB, 0x05, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd47[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xCD, 0x2A, 0xFF, 0xFF,
+ 0xCC, 0x0C, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd48[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xCE, 0x25, 0xFF, 0xFF,
+ 0xCD, 0x1E, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd49[] = {
0x02, 0x00, 0x39, 0xC0,
- 0xCF, 0x00, 0xFF, 0xFF,
+ 0xCE, 0x1A, 0xFF, 0xFF,
};
static char ili9806e_fwvga_video_on_cmd50[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0xCF, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd51[] = {
+ 0x06, 0x00, 0x39, 0xC0,
+ 0xFF, 0xFF, 0x98, 0x06,
+ 0x04, 0x02, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd52[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x40, 0x01, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd53[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd54[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x01, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd55[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x02, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd56[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x03, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd57[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x04, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd58[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x05, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd59[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x06, 0x09, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd60[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x07, 0x19, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd61[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x08, 0x19, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd62[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x09, 0x19, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd63[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0A, 0x19, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd64[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0B, 0x19, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd65[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0C, 0x1C, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd66[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0D, 0x1C, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd67[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0E, 0x1C, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd68[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0F, 0x1C, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd69[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x10, 0x1D, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd70[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x11, 0x1D, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd71[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x12, 0x1D, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd72[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x13, 0x1D, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd73[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x14, 0x1D, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd74[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x15, 0x3E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd75[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x16, 0x3E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd76[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x17, 0x3E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd77[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x18, 0x3E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd78[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x19, 0x4E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd79[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1A, 0x4E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd80[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1B, 0x4E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd81[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1C, 0x4E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd82[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1D, 0x4E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd83[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1E, 0x4E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd84[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1F, 0x4E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd85[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x20, 0x4E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd86[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x21, 0x4E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd87[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x22, 0x4E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd88[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x23, 0x4E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd89[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x24, 0x4E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd90[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x25, 0x4E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd91[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x26, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd92[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x27, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd93[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x28, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd94[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x29, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd95[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2A, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd96[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2B, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd97[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2C, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd98[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2D, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd99[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2E, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd100[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2F, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd101[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x30, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd102[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x31, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd103[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x32, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd104[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x33, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd105[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x34, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd106[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x35, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd107[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x36, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd108[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x37, 0x5E, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd109[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x38, 0x5C, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd110[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x39, 0x4C, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd111[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3A, 0x4C, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd112[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3B, 0x3B, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd113[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3C, 0x3B, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd114[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3D, 0x2A, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd115[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3E, 0x10, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd116[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd117[] = {
+ 0x06, 0x00, 0x39, 0xC0,
+ 0xFF, 0xFF, 0x98, 0x06,
+ 0x04, 0x03, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd118[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd119[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x01, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd120[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x02, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd121[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x03, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd122[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x04, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd123[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x05, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd124[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x06, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd125[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x07, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd126[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x08, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd127[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x09, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd128[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd129[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd130[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd131[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd132[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd133[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd134[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x10, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd135[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x11, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd136[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x12, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd137[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x13, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd138[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x14, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd139[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x15, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd140[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x16, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd141[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x17, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd142[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x18, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd143[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x19, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd144[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd145[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd146[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd147[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd148[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd149[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd150[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x20, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd151[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x21, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd152[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x22, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd153[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x23, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd154[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x24, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd155[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x25, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd156[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x26, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd157[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x27, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd158[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x28, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd159[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x29, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd160[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd161[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd162[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd163[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd164[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd165[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd166[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x30, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd167[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x31, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd168[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x32, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd169[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x33, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd170[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x34, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd171[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x35, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd172[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x36, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd173[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x37, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd174[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x38, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd175[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x39, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd176[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd177[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd178[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd179[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd180[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd181[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd182[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x40, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd183[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x41, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd184[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x42, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd185[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x43, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd186[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x44, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd187[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x45, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd188[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x46, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd189[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x47, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd190[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x48, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd191[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x49, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd192[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd193[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd194[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd195[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd196[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd197[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd198[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x50, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd199[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x51, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd200[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x52, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd201[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x53, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd202[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x54, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd203[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x55, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd204[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x56, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd205[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x57, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd206[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x58, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd207[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x59, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd208[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd209[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd210[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd211[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd212[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd213[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd214[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x60, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd215[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x61, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd216[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x62, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd217[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x63, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd218[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x64, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd219[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x65, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd220[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x66, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd221[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x67, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd222[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x68, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd223[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x69, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd224[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd225[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd226[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd227[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd228[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd229[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd230[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x70, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd231[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x71, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd232[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x72, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd233[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x73, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd234[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x74, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd235[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x75, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd236[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x76, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd237[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x77, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd238[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x78, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd239[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x79, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd240[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd241[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd242[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd243[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd244[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd245[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd246[] = {
+ 0x06, 0x00, 0x39, 0xC0,
+ 0xFF, 0xFF, 0x98, 0x06,
+ 0x04, 0x04, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd247[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd248[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x01, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd249[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x02, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd250[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x03, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd251[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x04, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd252[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x05, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd253[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x06, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd254[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x07, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd255[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x08, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd256[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x09, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd257[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd258[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd259[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd260[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd261[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd262[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd263[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x10, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd264[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x11, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd265[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x12, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd266[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x13, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd267[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x14, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd268[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x15, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd269[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x16, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd270[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x17, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd271[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x18, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd272[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x19, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd273[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd274[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd275[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd276[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd277[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd278[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd279[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x20, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd280[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x21, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd281[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x22, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd282[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x23, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd283[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x24, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd284[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x25, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd285[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x26, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd286[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x27, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd287[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x28, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd288[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x29, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd289[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd290[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd291[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd292[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd293[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd294[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd295[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x30, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd296[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x31, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd297[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x32, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd298[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x33, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd299[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x34, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd300[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x35, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd301[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x36, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd302[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x37, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd303[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x38, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd304[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x39, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd305[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd306[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd307[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd308[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd309[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd310[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd311[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x40, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd312[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x41, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd313[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x42, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd314[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x43, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd315[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x44, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd316[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x45, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd317[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x46, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd318[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x47, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd319[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x48, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd320[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x49, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd321[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd322[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd323[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd324[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd325[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd326[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd327[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x50, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd328[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x51, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd329[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x52, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd330[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x53, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd331[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x54, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd332[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x55, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd333[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x56, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd334[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x57, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd335[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x58, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd336[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x59, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd337[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd338[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd339[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd340[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd341[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd342[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd343[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x60, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd344[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x61, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd345[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x62, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd346[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x63, 0x10, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd347[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x64, 0x10, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd348[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x65, 0x20, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd349[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x66, 0x10, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd350[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x67, 0x10, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd351[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x68, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd352[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x69, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd353[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd354[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd355[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd356[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd357[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd358[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd359[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x70, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd360[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x71, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd361[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x72, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd362[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x73, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd363[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x74, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd364[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x75, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd365[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x76, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd366[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x77, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd367[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x78, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd368[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x79, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd369[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd370[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd371[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd372[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd373[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd374[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd375[] = {
+ 0x06, 0x00, 0x39, 0xC0,
+ 0xFF, 0xFF, 0x98, 0x06,
+ 0x04, 0x04, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd376[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd377[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x01, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd378[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x02, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd379[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x03, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd380[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x04, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd381[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x05, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd382[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x06, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd383[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x07, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd384[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x08, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd385[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x09, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd386[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd387[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd388[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd389[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd390[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd391[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x0F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd392[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x10, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd393[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x11, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd394[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x12, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd395[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x13, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd396[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x14, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd397[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x15, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd398[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x16, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd399[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x17, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd400[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x18, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd401[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x19, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd402[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd403[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd404[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd405[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd406[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd407[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x1F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd408[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x20, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd409[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x21, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd410[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x22, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd411[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x23, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd412[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x24, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd413[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x25, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd414[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x26, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd415[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x27, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd416[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x28, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd417[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x29, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd418[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd419[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd420[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd421[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd422[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd423[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x2F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd424[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x30, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd425[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x31, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd426[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x32, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd427[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x33, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd428[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x34, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd429[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x35, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd430[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x36, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd431[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x37, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd432[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x38, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd433[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x39, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd434[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd435[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd436[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd437[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd438[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd439[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x3F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd440[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x40, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd441[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x41, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd442[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x42, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd443[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x43, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd444[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x44, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd445[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x45, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd446[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x46, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd447[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x47, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd448[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x48, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd449[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x49, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd450[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd451[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd452[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd453[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd454[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd455[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x4F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd456[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x50, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd457[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x51, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd458[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x52, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd459[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x53, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd460[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x54, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd461[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x55, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd462[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x56, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd463[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x57, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd464[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x58, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd465[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x59, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd466[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd467[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd468[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd469[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd470[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd471[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x5F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd472[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x60, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd473[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x61, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd474[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x62, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd475[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x63, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd476[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x64, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd477[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x65, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd478[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x66, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd479[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x67, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd480[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x68, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd481[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x69, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd482[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd483[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd484[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd485[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd486[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd487[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x6F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd488[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x70, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd489[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x71, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd490[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x72, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd491[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x73, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd492[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x74, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd493[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x75, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd494[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x76, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd495[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x77, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd496[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x78, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd497[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x79, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd498[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7A, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd499[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7B, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd500[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7C, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd501[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7D, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd502[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7E, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd503[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x7F, 0x00, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd504[] = {
0x06, 0x00, 0x39, 0xC0,
0xFF, 0xFF, 0x98, 0x06,
0x04, 0x06, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd51[] = {
+static char ili9806e_fwvga_video_on_cmd505[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x00, 0x20, 0xFF, 0xFF,
+ 0x00, 0x21, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd52[] = {
+static char ili9806e_fwvga_video_on_cmd506[] = {
0x02, 0x00, 0x39, 0xC0,
0x01, 0x0A, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd53[] = {
+static char ili9806e_fwvga_video_on_cmd507[] = {
0x02, 0x00, 0x39, 0xC0,
0x02, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd54[] = {
+static char ili9806e_fwvga_video_on_cmd508[] = {
0x02, 0x00, 0x39, 0xC0,
0x03, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd55[] = {
+static char ili9806e_fwvga_video_on_cmd509[] = {
0x02, 0x00, 0x39, 0xC0,
0x04, 0x01, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd56[] = {
+static char ili9806e_fwvga_video_on_cmd510[] = {
0x02, 0x00, 0x39, 0xC0,
0x05, 0x01, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd57[] = {
+static char ili9806e_fwvga_video_on_cmd511[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x06, 0x98, 0xFF, 0xFF,
+ 0x06, 0x80, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd58[] = {
+static char ili9806e_fwvga_video_on_cmd512[] = {
0x02, 0x00, 0x39, 0xC0,
0x07, 0x06, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd59[] = {
+static char ili9806e_fwvga_video_on_cmd513[] = {
0x02, 0x00, 0x39, 0xC0,
0x08, 0x01, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd60[] = {
+static char ili9806e_fwvga_video_on_cmd514[] = {
0x02, 0x00, 0x39, 0xC0,
0x09, 0x80, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd61[] = {
+static char ili9806e_fwvga_video_on_cmd515[] = {
0x02, 0x00, 0x39, 0xC0,
0x0A, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd62[] = {
+static char ili9806e_fwvga_video_on_cmd516[] = {
0x02, 0x00, 0x39, 0xC0,
0x0B, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd63[] = {
+static char ili9806e_fwvga_video_on_cmd517[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x0C, 0x01, 0xFF, 0xFF,
+ 0x0C, 0x0A, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd64[] = {
+static char ili9806e_fwvga_video_on_cmd518[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x0D, 0x01, 0xFF, 0xFF,
+ 0x0D, 0x0A, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd65[] = {
+static char ili9806e_fwvga_video_on_cmd519[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x0E, 0x05, 0xFF, 0xFF,
+ 0x0E, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd66[] = {
+static char ili9806e_fwvga_video_on_cmd520[] = {
0x02, 0x00, 0x39, 0xC0,
0x0F, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd67[] = {
+static char ili9806e_fwvga_video_on_cmd521[] = {
0x02, 0x00, 0x39, 0xC0,
0x10, 0xF0, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd68[] = {
+static char ili9806e_fwvga_video_on_cmd522[] = {
0x02, 0x00, 0x39, 0xC0,
0x11, 0xF4, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd69[] = {
+static char ili9806e_fwvga_video_on_cmd523[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x12, 0x01, 0xFF, 0xFF,
+ 0x12, 0x04, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd70[] = {
+static char ili9806e_fwvga_video_on_cmd524[] = {
0x02, 0x00, 0x39, 0xC0,
0x13, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd71[] = {
+static char ili9806e_fwvga_video_on_cmd525[] = {
0x02, 0x00, 0x39, 0xC0,
0x14, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd72[] = {
+static char ili9806e_fwvga_video_on_cmd526[] = {
0x02, 0x00, 0x39, 0xC0,
0x15, 0xC0, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd73[] = {
+static char ili9806e_fwvga_video_on_cmd527[] = {
0x02, 0x00, 0x39, 0xC0,
0x16, 0x08, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd74[] = {
+static char ili9806e_fwvga_video_on_cmd528[] = {
0x02, 0x00, 0x39, 0xC0,
0x17, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd75[] = {
+static char ili9806e_fwvga_video_on_cmd529[] = {
0x02, 0x00, 0x39, 0xC0,
0x18, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd76[] = {
+static char ili9806e_fwvga_video_on_cmd530[] = {
0x02, 0x00, 0x39, 0xC0,
0x19, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd77[] = {
+static char ili9806e_fwvga_video_on_cmd531[] = {
0x02, 0x00, 0x39, 0xC0,
0x1A, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd78[] = {
+static char ili9806e_fwvga_video_on_cmd532[] = {
0x02, 0x00, 0x39, 0xC0,
0x1B, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd79[] = {
+static char ili9806e_fwvga_video_on_cmd533[] = {
0x02, 0x00, 0x39, 0xC0,
0x1C, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd80[] = {
+static char ili9806e_fwvga_video_on_cmd534[] = {
0x02, 0x00, 0x39, 0xC0,
0x1D, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd81[] = {
+static char ili9806e_fwvga_video_on_cmd535[] = {
0x02, 0x00, 0x39, 0xC0,
0x20, 0x01, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd82[] = {
+static char ili9806e_fwvga_video_on_cmd536[] = {
0x02, 0x00, 0x39, 0xC0,
0x21, 0x23, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd83[] = {
+static char ili9806e_fwvga_video_on_cmd537[] = {
0x02, 0x00, 0x39, 0xC0,
0x22, 0x45, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd84[] = {
+static char ili9806e_fwvga_video_on_cmd538[] = {
0x02, 0x00, 0x39, 0xC0,
0x23, 0x67, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd85[] = {
+static char ili9806e_fwvga_video_on_cmd539[] = {
0x02, 0x00, 0x39, 0xC0,
0x24, 0x01, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd86[] = {
+static char ili9806e_fwvga_video_on_cmd540[] = {
0x02, 0x00, 0x39, 0xC0,
0x25, 0x23, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd87[] = {
+static char ili9806e_fwvga_video_on_cmd541[] = {
0x02, 0x00, 0x39, 0xC0,
0x26, 0x45, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd88[] = {
+static char ili9806e_fwvga_video_on_cmd542[] = {
0x02, 0x00, 0x39, 0xC0,
0x27, 0x67, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd89[] = {
+static char ili9806e_fwvga_video_on_cmd543[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x30, 0x11, 0xFF, 0xFF,
+ 0x30, 0x01, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd90[] = {
+static char ili9806e_fwvga_video_on_cmd544[] = {
0x02, 0x00, 0x39, 0xC0,
0x31, 0x11, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd91[] = {
+static char ili9806e_fwvga_video_on_cmd545[] = {
0x02, 0x00, 0x39, 0xC0,
0x32, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd92[] = {
+static char ili9806e_fwvga_video_on_cmd546[] = {
0x02, 0x00, 0x39, 0xC0,
0x33, 0xEE, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd93[] = {
+static char ili9806e_fwvga_video_on_cmd547[] = {
0x02, 0x00, 0x39, 0xC0,
0x34, 0xFF, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd94[] = {
+static char ili9806e_fwvga_video_on_cmd548[] = {
0x02, 0x00, 0x39, 0xC0,
0x35, 0xBB, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd95[] = {
+static char ili9806e_fwvga_video_on_cmd549[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x36, 0xAA, 0xFF, 0xFF,
+ 0x36, 0xCA, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd96[] = {
+static char ili9806e_fwvga_video_on_cmd550[] = {
0x02, 0x00, 0x39, 0xC0,
0x37, 0xDD, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd97[] = {
+static char ili9806e_fwvga_video_on_cmd551[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x38, 0xCC, 0xFF, 0xFF,
+ 0x38, 0xAC, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd98[] = {
+static char ili9806e_fwvga_video_on_cmd552[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x39, 0x66, 0xFF, 0xFF,
+ 0x39, 0x76, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd99[] = {
+static char ili9806e_fwvga_video_on_cmd553[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x3A, 0x77, 0xFF, 0xFF,
+ 0x3A, 0x67, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd100[] = {
+static char ili9806e_fwvga_video_on_cmd554[] = {
0x02, 0x00, 0x39, 0xC0,
0x3B, 0x22, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd101[] = {
+static char ili9806e_fwvga_video_on_cmd555[] = {
0x02, 0x00, 0x39, 0xC0,
0x3C, 0x22, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd102[] = {
+static char ili9806e_fwvga_video_on_cmd556[] = {
0x02, 0x00, 0x39, 0xC0,
0x3D, 0x22, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd103[] = {
+static char ili9806e_fwvga_video_on_cmd557[] = {
0x02, 0x00, 0x39, 0xC0,
0x3E, 0x22, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd104[] = {
+static char ili9806e_fwvga_video_on_cmd558[] = {
0x02, 0x00, 0x39, 0xC0,
0x3F, 0x22, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd105[] = {
+static char ili9806e_fwvga_video_on_cmd559[] = {
0x02, 0x00, 0x39, 0xC0,
0x40, 0x22, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd106[] = {
+static char ili9806e_fwvga_video_on_cmd560[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x52, 0x10, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd561[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x53, 0x10, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd562[] = {
0x06, 0x00, 0x39, 0xC0,
0xFF, 0xFF, 0x98, 0x06,
0x04, 0x07, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd107[] = {
+static char ili9806e_fwvga_video_on_cmd563[] = {
0x02, 0x00, 0x39, 0xC0,
0x17, 0x22, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd108[] = {
+static char ili9806e_fwvga_video_on_cmd564[] = {
0x02, 0x00, 0x39, 0xC0,
0x02, 0x77, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd109[] = {
+static char ili9806e_fwvga_video_on_cmd565[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0xE1, 0x79, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd566[] = {
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x06, 0x01, 0xFF, 0xFF,
+};
+
+static char ili9806e_fwvga_video_on_cmd567[] = {
0x06, 0x00, 0x39, 0xC0,
0xFF, 0xFF, 0x98, 0x06,
0x04, 0x00, 0xFF, 0xFF,
};
-static char ili9806e_fwvga_video_on_cmd110[] = {
+static char ili9806e_fwvga_video_on_cmd568[] = {
0x11, 0x00, 0x05, 0x80
};
-static char ili9806e_fwvga_video_on_cmd111[] = {
+static char ili9806e_fwvga_video_on_cmd569[] = {
0x29, 0x00, 0x05, 0x80
};
@@ -677,8 +2971,8 @@
{0x8, ili9806e_fwvga_video_on_cmd47, 0x00},
{0x8, ili9806e_fwvga_video_on_cmd48, 0x00},
{0x8, ili9806e_fwvga_video_on_cmd49, 0x00},
- {0xc, ili9806e_fwvga_video_on_cmd50, 0x00},
- {0x8, ili9806e_fwvga_video_on_cmd51, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd50, 0x00},
+ {0xc, ili9806e_fwvga_video_on_cmd51, 0x00},
{0x8, ili9806e_fwvga_video_on_cmd52, 0x00},
{0x8, ili9806e_fwvga_video_on_cmd53, 0x00},
{0x8, ili9806e_fwvga_video_on_cmd54, 0x00},
@@ -733,15 +3027,472 @@
{0x8, ili9806e_fwvga_video_on_cmd103, 0x00},
{0x8, ili9806e_fwvga_video_on_cmd104, 0x00},
{0x8, ili9806e_fwvga_video_on_cmd105, 0x00},
- {0xc, ili9806e_fwvga_video_on_cmd106, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd106, 0x00},
{0x8, ili9806e_fwvga_video_on_cmd107, 0x00},
{0x8, ili9806e_fwvga_video_on_cmd108, 0x00},
- {0xc, ili9806e_fwvga_video_on_cmd109, 0x00},
- {0x4, ili9806e_fwvga_video_on_cmd110, 0x96},
- {0x4, ili9806e_fwvga_video_on_cmd111, 0x78}
+ {0x8, ili9806e_fwvga_video_on_cmd109, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd110, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd111, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd112, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd113, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd114, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd115, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd116, 0x00},
+ {0xc, ili9806e_fwvga_video_on_cmd117, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd118, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd119, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd120, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd121, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd122, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd123, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd124, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd125, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd126, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd127, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd128, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd129, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd130, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd131, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd132, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd133, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd134, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd135, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd136, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd137, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd138, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd139, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd140, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd141, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd142, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd143, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd144, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd145, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd146, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd147, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd148, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd149, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd150, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd151, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd152, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd153, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd154, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd155, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd156, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd157, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd158, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd159, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd160, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd161, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd162, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd163, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd164, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd165, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd166, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd167, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd168, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd169, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd170, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd171, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd172, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd173, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd174, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd175, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd176, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd177, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd178, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd179, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd180, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd181, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd182, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd183, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd184, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd185, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd186, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd187, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd188, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd189, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd190, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd191, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd192, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd193, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd194, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd195, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd196, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd197, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd198, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd199, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd200, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd201, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd202, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd203, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd204, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd205, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd206, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd207, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd208, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd209, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd210, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd211, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd212, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd213, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd214, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd215, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd216, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd217, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd218, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd219, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd220, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd221, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd222, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd223, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd224, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd225, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd226, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd227, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd228, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd229, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd230, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd231, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd232, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd233, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd234, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd235, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd236, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd237, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd238, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd239, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd240, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd241, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd242, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd243, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd244, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd245, 0x00},
+ {0xc, ili9806e_fwvga_video_on_cmd246, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd247, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd248, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd249, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd250, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd251, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd252, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd253, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd254, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd255, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd256, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd257, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd258, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd259, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd260, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd261, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd262, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd263, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd264, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd265, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd266, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd267, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd268, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd269, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd270, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd271, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd272, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd273, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd274, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd275, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd276, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd277, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd278, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd279, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd280, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd281, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd282, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd283, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd284, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd285, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd286, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd287, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd288, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd289, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd290, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd291, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd292, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd293, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd294, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd295, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd296, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd297, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd298, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd299, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd300, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd301, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd302, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd303, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd304, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd305, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd306, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd307, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd308, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd309, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd310, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd311, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd312, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd313, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd314, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd315, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd316, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd317, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd318, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd319, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd320, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd321, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd322, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd323, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd324, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd325, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd326, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd327, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd328, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd329, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd330, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd331, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd332, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd333, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd334, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd335, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd336, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd337, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd338, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd339, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd340, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd341, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd342, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd343, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd344, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd345, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd346, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd347, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd348, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd349, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd350, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd351, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd352, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd353, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd354, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd355, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd356, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd357, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd358, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd359, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd360, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd361, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd362, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd363, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd364, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd365, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd366, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd367, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd368, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd369, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd370, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd371, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd372, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd373, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd374, 0x00},
+ {0xc, ili9806e_fwvga_video_on_cmd375, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd376, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd377, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd378, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd379, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd380, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd381, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd382, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd383, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd384, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd385, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd386, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd387, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd388, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd389, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd390, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd391, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd392, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd393, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd394, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd395, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd396, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd397, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd398, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd399, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd400, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd401, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd402, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd403, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd404, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd405, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd406, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd407, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd408, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd409, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd410, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd411, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd412, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd413, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd414, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd415, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd416, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd417, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd418, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd419, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd420, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd421, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd422, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd423, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd424, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd425, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd426, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd427, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd428, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd429, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd430, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd431, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd432, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd433, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd434, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd435, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd436, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd437, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd438, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd439, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd440, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd441, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd442, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd443, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd444, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd445, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd446, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd447, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd448, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd449, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd450, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd451, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd452, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd453, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd454, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd455, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd456, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd457, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd458, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd459, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd460, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd461, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd462, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd463, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd464, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd465, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd466, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd467, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd468, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd469, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd470, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd471, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd472, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd473, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd474, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd475, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd476, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd477, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd478, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd479, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd480, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd481, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd482, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd483, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd484, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd485, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd486, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd487, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd488, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd489, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd490, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd491, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd492, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd493, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd494, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd495, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd496, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd497, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd498, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd499, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd500, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd501, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd502, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd503, 0x00},
+ {0xc, ili9806e_fwvga_video_on_cmd504, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd505, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd506, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd507, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd508, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd509, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd510, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd511, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd512, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd513, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd514, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd515, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd516, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd517, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd518, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd519, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd520, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd521, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd522, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd523, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd524, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd525, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd526, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd527, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd528, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd529, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd530, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd531, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd532, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd533, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd534, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd535, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd536, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd537, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd538, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd539, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd540, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd541, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd542, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd543, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd544, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd545, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd546, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd547, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd548, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd549, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd550, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd551, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd552, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd553, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd554, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd555, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd556, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd557, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd558, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd559, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd560, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd561, 0x00},
+ {0xc, ili9806e_fwvga_video_on_cmd562, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd563, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd564, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd565, 0x00},
+ {0x8, ili9806e_fwvga_video_on_cmd566, 0x00},
+ {0xc, ili9806e_fwvga_video_on_cmd567, 0x00},
+ {0x4, ili9806e_fwvga_video_on_cmd568, 0x78},
+ {0x4, ili9806e_fwvga_video_on_cmd569, 0x0A}
};
-
-#define ILI9806E_FWVGA_VIDEO_ON_COMMAND 112
+#define ILI9806E_FWVGA_VIDEO_ON_COMMAND 570
static char ili9806e_fwvga_videooff_cmd0[] = {
diff --git a/dev/gcdb/display/include/panel_jdi_a216_fhd_video.h b/dev/gcdb/display/include/panel_jdi_a216_fhd_video.h
index 6f09f38..484edac 100755
--- a/dev/gcdb/display/include/panel_jdi_a216_fhd_video.h
+++ b/dev/gcdb/display/include/panel_jdi_a216_fhd_video.h
@@ -85,15 +85,28 @@
0x11, 0x00, 0x05, 0x80
};
+static char jdi_a216_fhd_video_on_cmd5[] = {
+ 0xB0, 0x04, 0x29, 0x80
+};
+
+static char jdi_a216_fhd_video_on_cmd6[] = {
+ 0x06, 0x00, 0x29, 0xC0,
+ 0xD0, 0x10, 0x93, 0xBB,
+ 0x12, 0x8E, 0xFF, 0xFF
+};
+
+
static struct mipi_dsi_cmd jdi_a216_fhd_video_on_command[] = {
{0x4, jdi_a216_fhd_video_on_cmd0, 0x0a},
{0x4, jdi_a216_fhd_video_on_cmd1, 0x0a},
{0x4, jdi_a216_fhd_video_on_cmd2, 0x0a},
{0x4, jdi_a216_fhd_video_on_cmd3, 0x28},
{0x4, jdi_a216_fhd_video_on_cmd4, 0xc8},
+ {0x4, jdi_a216_fhd_video_on_cmd5, 0x0a},
+ {0xc, jdi_a216_fhd_video_on_cmd6, 0x0a}
};
-#define JDI_A216_FHD_VIDEO_ON_COMMAND 5
+#define JDI_A216_FHD_VIDEO_ON_COMMAND 7
static char jdi_a216_fhd_videooff_cmd0[] = {
@@ -113,7 +126,7 @@
static struct command_state jdi_a216_fhd_video_state = {
- 0, 1
+ 1, 1
};
/*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_r61318_hd_video.h b/dev/gcdb/display/include/panel_r61318_hd_video.h
index 72c27c2..5ac2c74 100644
--- a/dev/gcdb/display/include/panel_r61318_hd_video.h
+++ b/dev/gcdb/display/include/panel_r61318_hd_video.h
@@ -172,7 +172,7 @@
static char r61318_hd_video_on_cmd17[] = {
0x02, 0x00, 0x29, 0xC0,
- 0xD4, 0x50, 0xFF, 0xFF,
+ 0xD4, 0x4D, 0xFF, 0xFF,
};
static char r61318_hd_video_on_cmd18[] = {
@@ -181,20 +181,25 @@
};
static char r61318_hd_video_on_cmd19[] = {
- 0x02, 0x00, 0x39, 0xC0,
- 0x53, 0x24, 0xFF, 0xFF,
+ 0x02, 0x00, 0x29, 0xC0,
+ 0xBB, 0x2E, 0xFF, 0xFF
};
static char r61318_hd_video_on_cmd20[] = {
0x02, 0x00, 0x39, 0xC0,
- 0x51, 0xff, 0xFF, 0xFF,
+ 0x53, 0x2C, 0xFF, 0xFF
};
static char r61318_hd_video_on_cmd21[] = {
- 0x11, 0x00, 0x05, 0x80
+ 0x02, 0x00, 0x39, 0xC0,
+ 0x51, 0xff, 0xFF, 0xFF,
};
static char r61318_hd_video_on_cmd22[] = {
+ 0x11, 0x00, 0x05, 0x80
+};
+
+static char r61318_hd_video_on_cmd23[] = {
0x29, 0x00, 0x05, 0x80
};
@@ -220,11 +225,12 @@
{0x8, r61318_hd_video_on_cmd18, 0x00},
{0x8, r61318_hd_video_on_cmd19, 0x00},
{0x8, r61318_hd_video_on_cmd20, 0x00},
- {0x4, r61318_hd_video_on_cmd21, 0x78},
- {0x4, r61318_hd_video_on_cmd22, 0x32}
+ {0x8, r61318_hd_video_on_cmd21, 0x00},
+ {0x4, r61318_hd_video_on_cmd22, 0x78},
+ {0x4, r61318_hd_video_on_cmd23, 0x32}
};
-#define R61318_HD_VIDEO_ON_COMMAND 23
+#define R61318_HD_VIDEO_ON_COMMAND 24
static char r61318_hd_videooff_cmd0[] = {
diff --git a/dev/gcdb/display/include/panel_sharp_1080p_cmd.h b/dev/gcdb/display/include/panel_sharp_1080p_cmd.h
new file mode 100644
index 0000000..353cbc3
--- /dev/null
+++ b/dev/gcdb/display/include/panel_sharp_1080p_cmd.h
@@ -0,0 +1,200 @@
+/* Copyright (c) 2015, 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 AND FITNESS
+ * FOR A PARTICULAR PURPOSE 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 _PANEL_SHARP_1080P_CMD_H_
+#define _PANEL_SHARP_1080P_CMD_H_
+
+/*---------------------------------------------------------------------------*/
+/* HEADER files */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration */
+/*---------------------------------------------------------------------------*/
+static struct panel_config sharp_1080p_cmd_panel_data = {
+ "qcom,mdss_dsi_sharp_1080p_cmd", "dsi:0:", "qcom,mdss-dsi-panel",
+ 10, 1, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution sharp_1080p_cmd_panel_res = {
+ 1080, 1920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel Color Information */
+/*---------------------------------------------------------------------------*/
+static struct color_info sharp_1080p_cmd_color = {
+ 24, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel Command information */
+/*---------------------------------------------------------------------------*/
+static char sharp_1080p_cmd_on_cmd0[] = {
+ 0xbb, 0x10, 0x15, 0x80
+};
+
+static char sharp_1080p_cmd_on_cmd1[] = {
+ 0xb0, 0x03, 0x15, 0x80
+};
+
+static char sharp_1080p_cmd_on_cmd2[] = {
+ 0x11, 0x00, 0x05, 0x80
+};
+
+static char sharp_1080p_cmd_on_cmd3[] = {
+ 0x51, 0xff, 0x15, 0x80
+};
+
+static char sharp_1080p_cmd_on_cmd4[] = {
+ 0x53, 0x24, 0x15, 0x80
+};
+
+static char sharp_1080p_cmd_on_cmd5[] = {
+ 0xff, 0x23, 0x15, 0x80
+};
+
+static char sharp_1080p_cmd_on_cmd6[] = {
+ 0x08, 0x05, 0x15, 0x80
+};
+
+static char sharp_1080p_cmd_on_cmd7[] = {
+ 0x46, 0x90, 0x15, 0x80
+};
+
+static char sharp_1080p_cmd_on_cmd8[] = {
+ 0xff, 0x10, 0x15, 0x80
+};
+
+static char sharp_1080p_cmd_on_cmd9[] = {
+ 0xff, 0xf0, 0x15, 0x80
+};
+
+static char sharp_1080p_cmd_on_cmd10[] = {
+ 0x92, 0x01, 0x15, 0x80
+};
+
+static char sharp_1080p_cmd_on_cmd11[] = {
+ 0xff, 0x10, 0x15, 0x80
+};
+
+static char sharp_1080p_cmd_on_cmd12[] = {
+ 0x29, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd sharp_1080p_cmd_on_command[] = {
+ {0x4 , sharp_1080p_cmd_on_cmd0, 0x00},
+ {0x4 , sharp_1080p_cmd_on_cmd1, 0x00},
+ {0x3 , sharp_1080p_cmd_on_cmd2, 0x78},
+ {0x4 , sharp_1080p_cmd_on_cmd3, 0x00},
+ {0x4 , sharp_1080p_cmd_on_cmd4, 0x00},
+ {0x4 , sharp_1080p_cmd_on_cmd5, 0x00},
+ {0x4 , sharp_1080p_cmd_on_cmd6, 0x00},
+ {0x4 , sharp_1080p_cmd_on_cmd7, 0x00},
+ {0x4 , sharp_1080p_cmd_on_cmd8, 0x00},
+ {0x4 , sharp_1080p_cmd_on_cmd9, 0x00},
+ {0x4 , sharp_1080p_cmd_on_cmd10, 0x00},
+ {0x4 , sharp_1080p_cmd_on_cmd11, 0x00},
+ {0x3 , sharp_1080p_cmd_on_cmd12, 0x28}
+};
+
+#define SHARP_1080P_CMD_ON_COMMAND 13
+
+
+static char sharp_1080p_cmdoff_cmd0[] = {
+ 0x28, 0x00, 0x05, 0x80
+};
+
+static char sharp_1080p_cmdoff_cmd1[] = {
+ 0x10, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd sharp_1080p_cmd_off_command[] = {
+ {0x4 , sharp_1080p_cmdoff_cmd0, 0},
+ {0x4 , sharp_1080p_cmdoff_cmd1, 0}
+};
+
+#define SHARP_1080P_CMD_OFF_COMMAND 2
+
+
+static struct command_state sharp_1080p_cmd_state = {
+ 0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info sharp_1080p_cmd_command_panel = {
+ 1, 1, 1, 0, 0, 0x2c, 0x3c, 0, 0, 1, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info sharp_1080p_cmd_video_panel = {
+ 0, 0, 0, 0, 1, 1, 2, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane Configuration */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration sharp_1080p_cmd_lane_config = {
+ 4, 0, 1, 1, 1, 1, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel Timing */
+/*---------------------------------------------------------------------------*/
+static const uint32_t sharp_1080p_cmd_timings[] = {
+ 0xe7, 0x36, 0x24, 0x00, 0x66, 0x6a, 0x2a, 0x3a, 0x2d, 0x03, 0x04, 0x00
+};
+
+static struct panel_timing sharp_1080p_cmd_timing_info = {
+ 0x0, 0x04, 0x04, 0x1b
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel reset sequence */
+/*---------------------------------------------------------------------------*/
+static struct panel_reset_sequence sharp_1080p_cmd_panel_reset_seq = {
+ { 1, 0, 1, }, { 10, 10, 10, }, 2
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight Settings */
+/*---------------------------------------------------------------------------*/
+static struct backlight sharp_1080p_cmd_backlight = {
+ 1, 1, 4095, 100, 1, "PMIC_8941"
+};
+
+#endif /*_PANEL_sharp_1080P_CMD_H_*/
diff --git a/dev/pmic/pm8x41/include/pm8x41.h b/dev/pmic/pm8x41/include/pm8x41.h
index 717f09b..6e89f57 100644
--- a/dev/pmic/pm8x41/include/pm8x41.h
+++ b/dev/pmic/pm8x41/include/pm8x41.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 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
@@ -219,6 +219,7 @@
uint32_t pm8x41_v2_resin_status();
uint32_t pm8x41_resin_status();
void pm8x41_reset_configure(uint8_t);
+void pm8994_reset_configure(uint8_t);
void pm8x41_v2_reset_configure(uint8_t);
int pm8x41_ldo_set_voltage(struct pm8x41_ldo *ldo, uint32_t voltage);
int pm8x41_ldo_control(struct pm8x41_ldo *ldo, uint8_t enable);
diff --git a/dev/pmic/pm8x41/include/pm8x41_wled.h b/dev/pmic/pm8x41/include/pm8x41_wled.h
index 0fe7975..f112085 100644
--- a/dev/pmic/pm8x41/include/pm8x41_wled.h
+++ b/dev/pmic/pm8x41/include/pm8x41_wled.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 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
@@ -49,6 +49,11 @@
#define PM_WLED_CURRENT_SINK PM_WLED_CTNL_REG(0x4F)
#define LEDn_FULL_SCALE_CURRENT(n) (PM_WLED_LED_CTNL_REG(n) + 0x2)
+#define PM_LAB_BASE 0X1DE00
+#define PM_LAB_CNTL(n) (PM_LAB_BASE + n)
+#define PM_LAB_CURRENT_SENSE PM_LAB_CNTL(0X4C)
+#define PM_LAB_PS_CTL PM_LAB_CNTL(0X50)
+
#define PM_WLED_LED1_SINK_MASK BIT(5)
#define PM_WLED_LED2_SINK_MASK BIT(6)
#define PM_WLED_LED3_SINK_MASK BIT(7)
diff --git a/dev/pmic/pm8x41/pm8x41.c b/dev/pmic/pm8x41/pm8x41.c
index 5886161..e753f6c 100644
--- a/dev/pmic/pm8x41/pm8x41.c
+++ b/dev/pmic/pm8x41/pm8x41.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 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
@@ -33,7 +33,7 @@
#include <string.h>
#include <pm8x41_hw.h>
#include <pm8x41.h>
-#include <rpm-smd.h>
+#include <rpm-ipc.h>
#include <regulator.h>
#include <platform/timer.h>
@@ -77,6 +77,24 @@
return val;
}
+/* SPMI helper function which takes slave id as the i/p */
+void pm8xxx_reg_write(uint8_t slave_id, uint32_t addr, uint8_t val)
+{
+ struct pmic_arb_cmd cmd;
+ struct pmic_arb_param param;
+
+ cmd.address = PERIPH_ID(addr);
+ cmd.offset = REG_OFFSET(addr);
+ cmd.slave_id = slave_id;
+
+ cmd.priority = 0;
+
+ param.buffer = &val;
+ param.size = 1;
+
+ pmic_arb_write_cmd(&cmd, ¶m);
+}
+
void pm8x41_reg_write(uint32_t addr, uint8_t val)
{
struct pmic_arb_cmd cmd;
@@ -333,6 +351,31 @@
return 0;
}
+void pm8994_reset_configure(uint8_t reset_type)
+{
+ /* Slave ID of pm8994 and pmi8994 */
+ uint8_t slave_id[] = {0, 2};
+ uint8_t i;
+
+ /* Reset sequence
+ 1. Disable the ps hold for pm8994
+ 2. set reset type for both pm8994 & pmi8994
+ 3. Enable ps hold for pm8994 to trigger the reset
+ */
+ /* disable PS_HOLD_RESET */
+ pm8xxx_reg_write(slave_id[0], PON_PS_HOLD_RESET_CTL2, 0x0);
+
+ /* Delay needed for disable to kick in. */
+ udelay(300);
+
+ /* configure reset type */
+ for (i = 0; i < ARRAY_SIZE(slave_id); i++)
+ pm8xxx_reg_write(slave_id[i], PON_PS_HOLD_RESET_CTL, reset_type);
+
+ /* enable PS_HOLD_RESET */
+ pm8xxx_reg_write(slave_id[0], PON_PS_HOLD_RESET_CTL2, BIT(S2_RESET_EN_BIT));
+}
+
void pm8x41_v2_reset_configure(uint8_t reset_type)
{
uint8_t val;
diff --git a/dev/pmic/pm8x41/pm8x41_wled.c b/dev/pmic/pm8x41/pm8x41_wled.c
index 9c3b6d3..c6c48e2 100644
--- a/dev/pmic/pm8x41/pm8x41_wled.c
+++ b/dev/pmic/pm8x41/pm8x41_wled.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 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
@@ -88,6 +88,11 @@
pm8x41_wled_reg_write(LEDn_FULL_SCALE_CURRENT(3), wled_ctrl->full_current_scale);
pm8x41_wled_reg_write(PM_WLED_FDBCK_CONTROL, wled_ctrl->fdbck);
+
+ // Override default values for ISENSE and PS Threshold
+ pm8x41_wled_reg_write(PM_LAB_CURRENT_SENSE, 0x0A);
+ pm8x41_wled_reg_write(PM_LAB_PS_CTL, 0x80);
+
dprintf(SPEW, "WLED Configuration Success.\n");
}
diff --git a/dev/qpnp_wled/include/qpnp_wled.h b/dev/qpnp_wled/include/qpnp_wled.h
index 3584a32..a04680d 100644
--- a/dev/qpnp_wled/include/qpnp_wled.h
+++ b/dev/qpnp_wled/include/qpnp_wled.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 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
@@ -168,6 +168,8 @@
#define QPNP_WLED_MIN_MSLEEP 20
#define QPNP_WLED_MAX_BR_LEVEL 1638
+#define PWRDN_DLY2_MASK 0x3
+
/* output feedback mode */
enum qpnp_wled_fdbk_op {
QPNP_WLED_FDBK_AUTO,
diff --git a/dev/qpnp_wled/qpnp_wled.c b/dev/qpnp_wled/qpnp_wled.c
index b96150c..2f4b196 100644
--- a/dev/qpnp_wled/qpnp_wled.c
+++ b/dev/qpnp_wled/qpnp_wled.c
@@ -1,4 +1,4 @@
- /* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ /* Copyright (c) 2014-2015, 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
@@ -408,6 +408,10 @@
temp = wled->ibb_pwrup_dly_ms;
reg &= QPNP_WLED_IBB_PWRUP_DLY_MASK;
reg |= (temp << QPNP_WLED_IBB_PWRUP_DLY_SHIFT);
+ /* Power down delay bits could already be set, clear them before
+ * or'ing new values
+ */
+ reg &= ~(PWRDN_DLY2_MASK);
reg |= wled->ibb_pwrdn_dly_ms;
reg |= (wled->ibb_discharge_en << 2);
diff --git a/include/dev/udc.h b/include/dev/udc.h
index 42ced0e..31d9755 100644
--- a/include/dev/udc.h
+++ b/include/dev/udc.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2009, Google Inc.
* All rights reserved.
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 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
@@ -50,6 +50,8 @@
#define UDC_TYPE_BULK_IN 1
#define UDC_TYPE_BULK_OUT 2
+#define UDC_TYPE_INTR_IN 3
+#define UDC_TYPE_INTR_OUT 4
struct udc_endpoint *udc_endpoint_alloc(unsigned type, unsigned maxpkt);
void udc_endpoint_free(struct udc_endpoint *ept);
diff --git a/include/platform.h b/include/platform.h
index e71c407..623473b 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -54,6 +54,7 @@
unsigned board_platform_id(void);
unsigned check_reboot_mode(void);
unsigned check_hard_reboot_mode(void);
+uint32_t check_alarm_boot(void);
void platform_uninit_timer(void);
void reboot_device(unsigned);
int set_download_mode(enum dload_mode mode);
@@ -65,4 +66,5 @@
int platform_is_msm8992();
int boot_device_mask(int);
uint32_t platform_detect_panel();
+uint32_t platform_get_max_periph();
#endif
diff --git a/include/string.h b/include/string.h
index 661e746..593ecf2 100644
--- a/include/string.h
+++ b/include/string.h
@@ -33,6 +33,8 @@
void *memchr (void const *, int, size_t) __PURE;
int memcmp (void const *, const void *, size_t) __PURE;
void *memcpy (void *, void const *, size_t);
+/* secure memcpy, does not copy beyong size of dest buffer*/
+size_t memscpy (void *, size_t, void const *, size_t);
void *memmove(void *, void const *, size_t);
void *memset (void *, int, size_t);
diff --git a/include/target.h b/include/target.h
index 4a2891c..772afdf 100644
--- a/include/target.h
+++ b/include/target.h
@@ -85,4 +85,5 @@
void ulpi_write(unsigned val, unsigned reg);
void target_crypto_init_params(void);
int target_cont_splash_screen(void);
+bool target_build_variant_user();
#endif
diff --git a/lib/libc/malloc.c b/lib/libc/malloc.c
index 6f05f63..9cec44c 100644
--- a/lib/libc/malloc.c
+++ b/lib/libc/malloc.c
@@ -24,6 +24,7 @@
#include <malloc.h>
#include <string.h>
#include <lib/heap.h>
+#include <arch/ops.h>
void *malloc(size_t size)
{
@@ -32,7 +33,11 @@
void *memalign(size_t boundary, size_t size)
{
- return heap_alloc(size, boundary);
+ void *ptr;
+ ptr = heap_alloc(size, boundary);
+ /* Clean the cache before giving the memory */
+ arch_invalidate_cache_range((addr_t) ptr, size);
+ return ptr;
}
void *calloc(size_t count, size_t size)
diff --git a/lib/libc/string/memscpy.c b/lib/libc/string/memscpy.c
new file mode 100644
index 0000000..3dd4d6b
--- /dev/null
+++ b/lib/libc/string/memscpy.c
@@ -0,0 +1,37 @@
+/* Copyright (c) 2015, 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 Fundation, Inc. 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 <string.h>
+
+size_t memscpy(void *dest, size_t dst_size, const void *src, size_t src_size)
+{
+ size_t copy_size = dst_size < src_size ? dst_size : src_size;
+ memcpy(dest, src, copy_size);
+ return copy_size;
+}
diff --git a/lib/libc/string/rules.mk b/lib/libc/string/rules.mk
index fc1ceb2..97a5db8 100644
--- a/lib/libc/string/rules.mk
+++ b/lib/libc/string/rules.mk
@@ -8,6 +8,7 @@
memcpy \
memmove \
memset \
+ memscpy \
strcat \
strchr \
strcmp \
diff --git a/lib/zlib_inflate/adler32.c b/lib/zlib_inflate/adler32.c
new file mode 100644
index 0000000..a868f07
--- /dev/null
+++ b/lib/zlib_inflate/adler32.c
@@ -0,0 +1,179 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#define local static
+
+local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
+
+#define BASE 65521 /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware --
+ try it both ways to see which is faster */
+#ifdef NO_DIVIDE
+/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
+ (thank you to John Reiser for pointing this out) */
+# define CHOP(a) \
+ do { \
+ unsigned long tmp = a >> 16; \
+ a &= 0xffffUL; \
+ a += (tmp << 4) - tmp; \
+ } while (0)
+# define MOD28(a) \
+ do { \
+ CHOP(a); \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+# define MOD(a) \
+ do { \
+ CHOP(a); \
+ MOD28(a); \
+ } while (0)
+# define MOD63(a) \
+ do { /* this assumes a is not negative */ \
+ z_off64_t tmp = a >> 32; \
+ a &= 0xffffffffL; \
+ a += (tmp << 8) - (tmp << 5) + tmp; \
+ tmp = a >> 16; \
+ a &= 0xffffL; \
+ a += (tmp << 4) - tmp; \
+ tmp = a >> 16; \
+ a &= 0xffffL; \
+ a += (tmp << 4) - tmp; \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+#else
+# define MOD(a) a %= BASE
+# define MOD28(a) a %= BASE
+# define MOD63(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ uInt len;
+{
+ unsigned long sum2;
+ unsigned n;
+
+ /* split Adler-32 into component sums */
+ sum2 = (adler >> 16) & 0xffff;
+ adler &= 0xffff;
+
+ /* in case user likes doing a byte at a time, keep it fast */
+ if (len == 1) {
+ adler += buf[0];
+ if (adler >= BASE)
+ adler -= BASE;
+ sum2 += adler;
+ if (sum2 >= BASE)
+ sum2 -= BASE;
+ return adler | (sum2 << 16);
+ }
+
+ /* initial Adler-32 value (deferred check for len == 1 speed) */
+ if (buf == Z_NULL)
+ return 1L;
+
+ /* in case short lengths are provided, keep it somewhat fast */
+ if (len < 16) {
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ if (adler >= BASE)
+ adler -= BASE;
+ MOD28(sum2); /* only added so many BASE's */
+ return adler | (sum2 << 16);
+ }
+
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while (len >= NMAX) {
+ len -= NMAX;
+ n = NMAX / 16; /* NMAX is divisible by 16 */
+ do {
+ DO16(buf); /* 16 sums unrolled */
+ buf += 16;
+ } while (--n);
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if (len) { /* avoid modulos if none remaining */
+ while (len >= 16) {
+ len -= 16;
+ DO16(buf);
+ buf += 16;
+ }
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* return recombined sums */
+ return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+local uLong adler32_combine_(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off64_t len2;
+{
+ unsigned long sum1;
+ unsigned long sum2;
+ unsigned rem;
+
+ /* for negative len, return invalid adler32 as a clue for debugging */
+ if (len2 < 0)
+ return 0xffffffffUL;
+
+ /* the derivation of this formula is left as an exercise for the reader */
+ MOD63(len2); /* assumes len2 >= 0 */
+ rem = (unsigned)len2;
+ sum1 = adler1 & 0xffff;
+ sum2 = rem * sum1;
+ MOD(sum2);
+ sum1 += (adler2 & 0xffff) + BASE - 1;
+ sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
+ if (sum2 >= BASE) sum2 -= BASE;
+ return sum1 | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off_t len2;
+{
+ return adler32_combine_(adler1, adler2, len2);
+}
+
+uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off64_t len2;
+{
+ return adler32_combine_(adler1, adler2, len2);
+}
diff --git a/lib/zlib_inflate/crc32.c b/lib/zlib_inflate/crc32.c
new file mode 100644
index 0000000..979a719
--- /dev/null
+++ b/lib/zlib_inflate/crc32.c
@@ -0,0 +1,425 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors. This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+ Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+ protection on the static variables used to control the first-use generation
+ of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+ first call get_crc_table() to initialize the tables before allowing more than
+ one thread to use crc32().
+
+ DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
+ */
+
+#ifdef MAKECRCH
+# include <stdio.h>
+# ifndef DYNAMIC_CRC_TABLE
+# define DYNAMIC_CRC_TABLE
+# endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h" /* for STDC and FAR definitions */
+
+#define local static
+
+/* Definitions for doing the crc four data bytes at a time. */
+#if !defined(NOBYFOUR) && defined(Z_U4)
+# define BYFOUR
+#endif
+#ifdef BYFOUR
+ local unsigned long crc32_little OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+ local unsigned long crc32_big OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+# define TBLS 8
+#else
+# define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+ unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
+
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local z_crc_t FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+ local void write_table OF((FILE *, const z_crc_t FAR *));
+#endif /* MAKECRCH */
+/*
+ Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+ 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.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ out is a one). We start with the highest power (least significant bit) of
+ q and repeat for all eight bits of q.
+
+ The first table is simply the CRC of all possible eight bit values. This is
+ all the information needed to generate CRCs on data a byte at a time for all
+ combinations of CRC register values and incoming bytes. The remaining tables
+ allow for word-at-a-time CRC calculation for both big-endian and little-
+ endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+ z_crc_t c;
+ int n, k;
+ z_crc_t poly; /* polynomial exclusive-or pattern */
+ /* terms of polynomial defining this crc (except x^32): */
+ static volatile int first = 1; /* flag to limit concurrent making */
+ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* See if another task is already doing this (not thread-safe, but better
+ than nothing -- significantly reduces duration of vulnerability in
+ case the advice about DYNAMIC_CRC_TABLE is ignored) */
+ if (first) {
+ first = 0;
+
+ /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+ poly = 0;
+ for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
+ poly |= (z_crc_t)1 << (31 - p[n]);
+
+ /* generate a crc for every 8-bit value */
+ for (n = 0; n < 256; n++) {
+ c = (z_crc_t)n;
+ for (k = 0; k < 8; k++)
+ c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+ crc_table[0][n] = c;
+ }
+
+#ifdef BYFOUR
+ /* generate crc for each value followed by one, two, and three zeros,
+ and then the byte reversal of those as well as the first table */
+ for (n = 0; n < 256; n++) {
+ c = crc_table[0][n];
+ crc_table[4][n] = ZSWAP32(c);
+ for (k = 1; k < 4; k++) {
+ c = crc_table[0][c & 0xff] ^ (c >> 8);
+ crc_table[k][n] = c;
+ crc_table[k + 4][n] = ZSWAP32(c);
+ }
+ }
+#endif /* BYFOUR */
+
+ crc_table_empty = 0;
+ }
+ else { /* not first */
+ /* wait for the other guy to finish (not efficient, but rare) */
+ while (crc_table_empty)
+ ;
+ }
+
+#ifdef MAKECRCH
+ /* write out CRC tables to crc32.h */
+ {
+ FILE *out;
+
+ out = fopen("crc32.h", "w");
+ if (out == NULL) return;
+ fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+ fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+ fprintf(out, "local const z_crc_t FAR ");
+ fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
+ write_table(out, crc_table[0]);
+# ifdef BYFOUR
+ fprintf(out, "#ifdef BYFOUR\n");
+ for (k = 1; k < 8; k++) {
+ fprintf(out, " },\n {\n");
+ write_table(out, crc_table[k]);
+ }
+ fprintf(out, "#endif\n");
+# endif /* BYFOUR */
+ fprintf(out, " }\n};\n");
+ fclose(out);
+ }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+ FILE *out;
+ const z_crc_t FAR *table;
+{
+ int n;
+
+ for (n = 0; n < 256; n++)
+ fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
+ (unsigned long)(table[n]),
+ n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const z_crc_t FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+ return (const z_crc_t FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ uInt len;
+{
+ if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+ if (sizeof(void *) == sizeof(ptrdiff_t)) {
+ z_crc_t endian;
+
+ endian = 1;
+ if (*((unsigned char *)(&endian)))
+ return crc32_little(crc, buf, len);
+ else
+ return crc32_big(crc, buf, len);
+ }
+#endif /* BYFOUR */
+ crc = crc ^ 0xffffffffUL;
+ while (len >= 8) {
+ DO8;
+ len -= 8;
+ }
+ if (len) do {
+ DO1;
+ } while (--len);
+ return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ register z_crc_t c;
+ register const z_crc_t FAR *buf4;
+
+ c = (z_crc_t)crc;
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ len--;
+ }
+
+ buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+ while (len >= 32) {
+ DOLIT32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOLIT4;
+ len -= 4;
+ }
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ register z_crc_t c;
+ register const z_crc_t FAR *buf4;
+
+ c = ZSWAP32((z_crc_t)crc);
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ len--;
+ }
+
+ buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+ buf4--;
+ while (len >= 32) {
+ DOBIG32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOBIG4;
+ len -= 4;
+ }
+ buf4++;
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)(ZSWAP32(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+ unsigned long *mat;
+ unsigned long vec;
+{
+ unsigned long sum;
+
+ sum = 0;
+ while (vec) {
+ if (vec & 1)
+ sum ^= *mat;
+ vec >>= 1;
+ mat++;
+ }
+ return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+ unsigned long *square;
+ unsigned long *mat;
+{
+ int n;
+
+ for (n = 0; n < GF2_DIM; n++)
+ square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+local uLong crc32_combine_(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off64_t len2;
+{
+ int n;
+ unsigned long row;
+ unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
+ unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
+
+ /* degenerate case (also disallow negative lengths) */
+ if (len2 <= 0)
+ return crc1;
+
+ /* put operator for one zero bit in odd */
+ odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
+ row = 1;
+ for (n = 1; n < GF2_DIM; n++) {
+ odd[n] = row;
+ row <<= 1;
+ }
+
+ /* put operator for two zero bits in even */
+ gf2_matrix_square(even, odd);
+
+ /* put operator for four zero bits in odd */
+ gf2_matrix_square(odd, even);
+
+ /* apply len2 zeros to crc1 (first square will put the operator for one
+ zero byte, eight zero bits, in even) */
+ do {
+ /* apply zeros operator for this bit of len2 */
+ gf2_matrix_square(even, odd);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(even, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ if (len2 == 0)
+ break;
+
+ /* another iteration of the loop with odd and even swapped */
+ gf2_matrix_square(odd, even);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(odd, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ } while (len2 != 0);
+
+ /* return combined crc */
+ crc1 ^= crc2;
+ return crc1;
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off_t len2;
+{
+ return crc32_combine_(crc1, crc2, len2);
+}
+
+uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off64_t len2;
+{
+ return crc32_combine_(crc1, crc2, len2);
+}
diff --git a/lib/zlib_inflate/crc32.h b/lib/zlib_inflate/crc32.h
new file mode 100644
index 0000000..9e0c778
--- /dev/null
+++ b/lib/zlib_inflate/crc32.h
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const z_crc_t FAR crc_table[TBLS][256] =
+{
+ {
+ 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+ 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+ 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+ 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+ 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+ 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+ 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+ 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+ 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+ 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+ 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+ 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+ 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+ 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+ 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+ 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+ 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+ 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+ 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+ 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+ 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+ 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+ 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+ 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+ 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+ 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+ 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+ 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+ 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+ 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+ 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+ 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+ 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+ 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+ 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+ 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+ 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+ 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+ 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+ 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+ 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+ 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+ 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+ 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+ 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+ 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+ 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+ 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+ 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+ 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+ 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+ 0x2d02ef8dUL
+#ifdef BYFOUR
+ },
+ {
+ 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+ 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+ 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+ 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+ 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+ 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+ 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+ 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+ 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+ 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+ 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+ 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+ 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+ 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+ 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+ 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+ 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+ 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+ 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+ 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+ 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+ 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+ 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+ 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+ 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+ 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+ 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+ 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+ 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+ 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+ 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+ 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+ 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+ 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+ 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+ 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+ 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+ 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+ 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+ 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+ 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+ 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+ 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+ 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+ 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+ 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+ 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+ 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+ 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+ 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+ 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+ 0x9324fd72UL
+ },
+ {
+ 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+ 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+ 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+ 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+ 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+ 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+ 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+ 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+ 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+ 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+ 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+ 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+ 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+ 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+ 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+ 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+ 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+ 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+ 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+ 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+ 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+ 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+ 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+ 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+ 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+ 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+ 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+ 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+ 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+ 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+ 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+ 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+ 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+ 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+ 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+ 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+ 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+ 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+ 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+ 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+ 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+ 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+ 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+ 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+ 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+ 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+ 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+ 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+ 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+ 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+ 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+ 0xbe9834edUL
+ },
+ {
+ 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+ 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+ 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+ 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+ 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+ 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+ 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+ 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+ 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+ 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+ 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+ 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+ 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+ 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+ 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+ 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+ 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+ 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+ 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+ 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+ 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+ 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+ 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+ 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+ 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+ 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+ 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+ 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+ 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+ 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+ 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+ 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+ 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+ 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+ 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+ 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+ 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+ 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+ 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+ 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+ 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+ 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+ 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+ 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+ 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+ 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+ 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+ 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+ 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+ 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+ 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+ 0xde0506f1UL
+ },
+ {
+ 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+ 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+ 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+ 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+ 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+ 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+ 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+ 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+ 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+ 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+ 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+ 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+ 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+ 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+ 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+ 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+ 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+ 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+ 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+ 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+ 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+ 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+ 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+ 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+ 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+ 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+ 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+ 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+ 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+ 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+ 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+ 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+ 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+ 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+ 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+ 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+ 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+ 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+ 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+ 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+ 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+ 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+ 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+ 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+ 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+ 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+ 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+ 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+ 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+ 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+ 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+ 0x8def022dUL
+ },
+ {
+ 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+ 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+ 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+ 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+ 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+ 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+ 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+ 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+ 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+ 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+ 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+ 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+ 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+ 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+ 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+ 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+ 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+ 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+ 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+ 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+ 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+ 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+ 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+ 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+ 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+ 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+ 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+ 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+ 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+ 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+ 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+ 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+ 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+ 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+ 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+ 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+ 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+ 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+ 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+ 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+ 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+ 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+ 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+ 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+ 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+ 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+ 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+ 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+ 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+ 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+ 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+ 0x72fd2493UL
+ },
+ {
+ 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+ 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+ 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+ 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+ 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+ 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+ 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+ 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+ 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+ 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+ 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+ 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+ 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+ 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+ 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+ 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+ 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+ 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+ 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+ 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+ 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+ 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+ 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+ 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+ 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+ 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+ 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+ 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+ 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+ 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+ 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+ 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+ 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+ 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+ 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+ 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+ 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+ 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+ 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+ 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+ 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+ 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+ 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+ 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+ 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+ 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+ 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+ 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+ 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+ 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+ 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+ 0xed3498beUL
+ },
+ {
+ 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+ 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+ 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+ 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+ 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+ 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+ 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+ 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+ 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+ 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+ 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+ 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+ 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+ 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+ 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+ 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+ 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+ 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+ 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+ 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+ 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+ 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+ 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+ 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+ 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+ 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+ 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+ 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+ 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+ 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+ 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+ 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+ 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+ 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+ 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+ 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+ 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+ 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+ 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+ 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+ 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+ 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+ 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+ 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+ 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+ 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+ 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+ 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+ 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+ 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+ 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+ 0xf10605deUL
+#endif
+ }
+};
diff --git a/lib/zlib_inflate/decompress.c b/lib/zlib_inflate/decompress.c
new file mode 100644
index 0000000..4a7ccc3
--- /dev/null
+++ b/lib/zlib_inflate/decompress.c
@@ -0,0 +1,154 @@
+/* Copyright (c) 2015, 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, Inc. 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 NO_GZIP
+
+#include "zutil.h"
+
+#ifdef DYNAMIC_CRC_TABLE
+#include "crc32.h"
+#endif
+
+#include "zconf.h"
+#include "zlib.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+#include "decompress.h"
+#include <sys/types.h> /* for size_t */
+#include <string.h>
+#include <debug.h>
+#include <malloc.h>
+
+#define GZIP_HEADER_LEN 10
+#define GZIP_FILENAME_LIMIT 256
+
+static void zlib_free(voidpf qpaque, void *addr)
+{
+ return free(addr);
+}
+
+static void *zlib_alloc(voidpf qpaque, uInt items, size_t size)
+{
+ return malloc(items * size);
+}
+
+/* decompress gzip file "in_buf", return 0 if decompressed successful,
+ * return -1 if decompressed failed.
+ * in_buf - input gzip file
+ * in_len - input the length file
+ * out_buf - output the decompressed data
+ * out_buf_len - the available length of out_buf
+ * pos - position of the end of gzip file
+ * out_len - the length of decompressed data
+ */
+int decompress(unsigned char *in_buf, unsigned int in_len,
+ unsigned char *out_buf,
+ unsigned int out_buf_len,
+ unsigned int *pos,
+ unsigned int *out_len) {
+ struct z_stream_s *stream;
+ int rc = -1;
+ int i;
+
+ if (in_len < GZIP_HEADER_LEN) {
+ dprintf(INFO, "the input data is not a gzip package.\n");
+ return rc;
+ }
+ if (out_buf_len < in_len) {
+ dprintf(INFO, "the avaiable length of out_buf is not enough.\n");
+ return rc;
+ }
+
+ stream = malloc(sizeof(*stream));
+ if (stream == NULL) {
+ dprintf(INFO, "allocating z_stream failed.\n");
+ return rc;
+ }
+
+ stream->zalloc = zlib_alloc;
+ stream->zfree = zlib_free;
+ stream->next_out = out_buf;
+ stream->avail_out = out_buf_len;
+
+ /* skip over gzip header */
+ stream->next_in = in_buf + GZIP_HEADER_LEN;
+ stream->avail_in = out_buf_len - GZIP_HEADER_LEN;
+ /* skip over asciz filename */
+ if (in_buf[3] & 0x8) {
+ for (i = 0; i < GZIP_FILENAME_LIMIT && *stream->next_in++; i++) {
+ if (stream->avail_in == 0) {
+ dprintf(INFO, "header error\n");
+ goto gunzip_end;
+ }
+ --stream->avail_in;
+ }
+ }
+
+ rc = inflateInit2(stream, -MAX_WBITS);
+ if (rc != Z_OK) {
+ dprintf(INFO, "inflateInit2 failed!\n");
+ goto gunzip_end;
+ }
+
+ rc = inflate(stream, 0);
+ /* Z_STREAM_END is "we unpacked it all" */
+ if (rc == Z_STREAM_END) {
+ rc = 0;
+ } else if (rc != Z_OK) {
+ dprintf(INFO, "uncompression error \n");
+ rc = -1;
+ }
+
+ inflateEnd(stream);
+ if (pos)
+ /* alculation the length of the compressed package */
+ *pos = stream->next_in - in_buf + 8;
+
+ if (out_len)
+ *out_len = stream->total_out;
+
+gunzip_end:
+ free(stream);
+ return rc; /* returns 0 if decompressed successful */
+}
+
+/* check if the input "buf" file was a gzip package.
+ * Return true if the input "buf" is a gzip package.
+ */
+int is_gzip_package(unsigned char *buf, unsigned int len)
+{
+ if (len < 10 || !buf || buf[0] != 0x1f ||
+ buf[1] != 0x8b || buf[2] != 0x08)
+ {
+ dprintf(INFO, "Not a gzip file\n");
+ return false;
+ }
+
+ return true;
+}
diff --git a/platform/thulium/include/platform/partial_goods.h b/lib/zlib_inflate/decompress.h
similarity index 64%
copy from platform/thulium/include/platform/partial_goods.h
copy to lib/zlib_inflate/decompress.h
index 03c16ec..1cdd011 100644
--- a/platform/thulium/include/platform/partial_goods.h
+++ b/lib/zlib_inflate/decompress.h
@@ -1,5 +1,5 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
-
+/* Copyright (c) 2015, 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:
@@ -9,7 +9,7 @@
* 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
+ * * Neither the name of The Linux Foundation, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -26,21 +26,10 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <partial_goods.h>
+#ifndef __PLATFORM_MSM_SHARED_DECOMPRESS_H
+#define __PLATFORM_MSM_SHARED_DECOMPRESS_H
-#define QFPROM_PTE_PART_ADDR 0x0007013C
+int is_gzip_package(unsigned char *, unsigned int);
-/* Look up table for partial goods */
-struct partial_goods table[] =
-{
- {0x1, "/cpus", {{"cpu@100", "device_type"},}},
- {0x2, "/cpus", {{"cpu@101", "device_type"},}},
- {0x3, "/cpus", {{"cpu@100", "device_type"},
- {"cpu@101","device_type"},}},
- {0x4, "/cpus", {{"cpu@100", "device_type"},
- {"cpu@101", "device_type"},
- {"cpu@1", "device_type"},}},
- {0x10, "/soc", {{"qcom,kgsl-3d0", "status"},}},
- {0x11, "/soc", {{"qcom,vidc", "status"},}},
- {0x12, "/soc", {{"qcom,msm-adsp-loader", "status"},}},
-};
+int decompress(unsigned char *, unsigned int, unsigned char *, unsigned int, unsigned int *, unsigned int *);
+#endif /* __PLATFORM_MSM_SHARED_DECOMPRESS_H */
diff --git a/lib/zlib_inflate/inffast.c b/lib/zlib_inflate/inffast.c
new file mode 100644
index 0000000..bda59ce
--- /dev/null
+++ b/lib/zlib_inflate/inffast.c
@@ -0,0 +1,340 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2008, 2010, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+ Based on testing to date,
+ Pre-increment preferred for:
+ - PowerPC G3 (Adler)
+ - MIPS R5000 (Randers-Pehrson)
+ Post-increment preferred for:
+ - none
+ No measurable difference:
+ - Pentium III (Anderson)
+ - M68060 (Nikl)
+ */
+#ifdef POSTINC
+# define OFF 0
+# define PUP(a) *(a)++
+#else
+# define OFF 1
+# define PUP(a) *++(a)
+#endif
+
+/*
+ Decode literal, length, and distance codes and write out the resulting
+ literal and match bytes until either not enough input or output is
+ available, an end-of-block is encountered, or a data error is encountered.
+ When large enough input and output buffers are supplied to inflate(), for
+ example, a 16K input buffer and a 64K output buffer, more than 95% of the
+ inflate execution time is spent in this routine.
+
+ Entry assumptions:
+
+ state->mode == LEN
+ strm->avail_in >= 6
+ strm->avail_out >= 258
+ start >= strm->avail_out
+ state->bits < 8
+
+ On return, state->mode is one of:
+
+ LEN -- ran out of enough output space or enough available input
+ TYPE -- reached end of block code, inflate() to interpret next block
+ BAD -- error in block data
+
+ Notes:
+
+ - The maximum input bits used by a length/distance pair is 15 bits for the
+ length code, 5 bits for the length extra, 15 bits for the distance code,
+ and 13 bits for the distance extra. This totals 48 bits, or six bytes.
+ Therefore if strm->avail_in >= 6, then there is enough input to avoid
+ checking for available input while decoding.
+
+ - The maximum bytes that a single length/distance pair can output is 258
+ bytes, which is the maximum length that can be coded. inflate_fast()
+ requires strm->avail_out >= 258 for each loop to avoid checking for
+ output space.
+ */
+void ZLIB_INTERNAL inflate_fast(strm, start)
+z_streamp strm;
+unsigned start; /* inflate()'s starting value for strm->avail_out */
+{
+ struct inflate_state FAR *state;
+ z_const unsigned char FAR *in; /* local strm->next_in */
+ z_const unsigned char FAR *last; /* have enough input while in < last */
+ unsigned char FAR *out; /* local strm->next_out */
+ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
+ unsigned char FAR *end; /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+ unsigned dmax; /* maximum distance from zlib header */
+#endif
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned wnext; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
+ unsigned long hold; /* local strm->hold */
+ unsigned bits; /* local strm->bits */
+ code const FAR *lcode; /* local strm->lencode */
+ code const FAR *dcode; /* local strm->distcode */
+ unsigned lmask; /* mask for first level of length codes */
+ unsigned dmask; /* mask for first level of distance codes */
+ code here; /* retrieved table entry */
+ unsigned op; /* code bits, operation, extra bits, or */
+ /* window position, window bytes to copy */
+ unsigned len; /* match length, unused bytes */
+ unsigned dist; /* match distance */
+ unsigned char FAR *from; /* where to copy match from */
+
+ /* copy state to local variables */
+ state = (struct inflate_state FAR *)strm->state;
+ in = strm->next_in - OFF;
+ last = in + (strm->avail_in - 5);
+ out = strm->next_out - OFF;
+ beg = out - (start - strm->avail_out);
+ end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+ dmax = state->dmax;
+#endif
+ wsize = state->wsize;
+ whave = state->whave;
+ wnext = state->wnext;
+ window = state->window;
+ hold = state->hold;
+ bits = state->bits;
+ lcode = state->lencode;
+ dcode = state->distcode;
+ lmask = (1U << state->lenbits) - 1;
+ dmask = (1U << state->distbits) - 1;
+
+ /* decode literals and length/distances until end-of-block or not enough
+ input data or output space */
+ do {
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ here = lcode[hold & lmask];
+ dolen:
+ op = (unsigned)(here.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(here.op);
+ if (op == 0) { /* literal */
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", here.val));
+ PUP(out) = (unsigned char)(here.val);
+ }
+ else if (op & 16) { /* length base */
+ len = (unsigned)(here.val);
+ op &= 15; /* number of extra bits */
+ if (op) {
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ len += (unsigned)hold & ((1U << op) - 1);
+ hold >>= op;
+ bits -= op;
+ }
+ Tracevv((stderr, "inflate: length %u\n", len));
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ here = dcode[hold & dmask];
+ dodist:
+ op = (unsigned)(here.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(here.op);
+ if (op & 16) { /* distance base */
+ dist = (unsigned)(here.val);
+ op &= 15; /* number of extra bits */
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ }
+ dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+ if (dist > dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ hold >>= op;
+ bits -= op;
+ Tracevv((stderr, "inflate: distance %u\n", dist));
+ op = (unsigned)(out - beg); /* max distance in output */
+ if (dist > op) { /* see if copy from window */
+ op = dist - op; /* distance back in window */
+ if (op > whave) {
+ if (state->sane) {
+ strm->msg =
+ (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ if (len <= op - whave) {
+ do {
+ PUP(out) = 0;
+ } while (--len);
+ continue;
+ }
+ len -= op - whave;
+ do {
+ PUP(out) = 0;
+ } while (--op > whave);
+ if (op == 0) {
+ from = out - dist;
+ do {
+ PUP(out) = PUP(from);
+ } while (--len);
+ continue;
+ }
+#endif
+ }
+ from = window - OFF;
+ if (wnext == 0) { /* very common case */
+ from += wsize - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ else if (wnext < op) { /* wrap around window */
+ from += wsize + wnext - op;
+ op -= wnext;
+ if (op < len) { /* some from end of window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = window - OFF;
+ if (wnext < len) { /* some from start of window */
+ op = wnext;
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ }
+ else { /* contiguous in window */
+ from += wnext - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ while (len > 2) {
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ }
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ else {
+ from = out - dist; /* copy direct from output */
+ do { /* minimum length is three */
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ } while (len > 2);
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level distance code */
+ here = dcode[here.val + (hold & ((1U << op) - 1))];
+ goto dodist;
+ }
+ else {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level length code */
+ here = lcode[here.val + (hold & ((1U << op) - 1))];
+ goto dolen;
+ }
+ else if (op & 32) { /* end-of-block */
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ else {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ } while (in < last && out < end);
+
+ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+ len = bits >> 3;
+ in -= len;
+ bits -= len << 3;
+ hold &= (1U << bits) - 1;
+
+ /* update state and return */
+ strm->next_in = in + OFF;
+ strm->next_out = out + OFF;
+ strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+ strm->avail_out = (unsigned)(out < end ?
+ 257 + (end - out) : 257 - (out - end));
+ state->hold = hold;
+ state->bits = bits;
+ return;
+}
+
+/*
+ inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+ - Using bit fields for code structure
+ - Different op definition to avoid & for extra bits (do & for table bits)
+ - Three separate decoding do-loops for direct, window, and wnext == 0
+ - Special case for distance > 1 copies to do overlapped load and store copy
+ - Explicit branch predictions (based on measured branch probabilities)
+ - Deferring match copy and interspersed it with decoding subsequent codes
+ - Swapping literal/length else
+ - Swapping window/direct else
+ - Larger unrolled copy loops (three is about right)
+ - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/lib/zlib_inflate/inffast.h b/lib/zlib_inflate/inffast.h
new file mode 100644
index 0000000..e5c1aa4
--- /dev/null
+++ b/lib/zlib_inflate/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/lib/zlib_inflate/inffixed.h b/lib/zlib_inflate/inffixed.h
new file mode 100644
index 0000000..d628327
--- /dev/null
+++ b/lib/zlib_inflate/inffixed.h
@@ -0,0 +1,94 @@
+ /* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by makefixed().
+ */
+
+ /* WARNING: this file should *not* be used by applications.
+ It is part of the implementation of this library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+ static const code lenfix[512] = {
+ {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+ {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+ {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+ {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+ {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+ {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+ {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+ {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+ {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+ {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+ {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+ {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+ {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+ {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+ {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+ {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+ {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+ {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+ {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+ {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+ {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+ {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+ {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+ {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+ {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+ {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+ {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+ {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+ {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+ {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+ {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+ {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+ {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+ {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+ {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+ {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+ {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+ {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+ {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+ {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+ {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+ {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+ {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+ {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+ {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+ {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+ {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+ {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+ {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+ {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+ {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+ {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+ {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+ {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+ {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+ {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+ {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+ {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+ {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+ {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+ {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+ {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+ {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+ {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+ {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+ {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+ {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+ {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+ {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+ {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+ {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+ {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+ {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+ {0,9,255}
+ };
+
+ static const code distfix[32] = {
+ {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+ {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+ {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+ {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+ {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+ {22,5,193},{64,5,0}
+ };
diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c
new file mode 100644
index 0000000..e341300
--- /dev/null
+++ b/lib/zlib_inflate/inflate.c
@@ -0,0 +1,1514 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2012 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0 24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ * creation of window when not needed, minimize use of window when it is
+ * needed, make inffast.c even faster, implement gzip decoding, and to
+ * improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1 25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2 4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ * to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3 22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ * buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4 1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common wnext == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ * source file infback.c to provide a call-back interface to inflate for
+ * programs like gzip and unzip -- uses window as output buffer to avoid
+ * window copying
+ *
+ * 1.2.beta5 1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ * input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6 4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ * make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7 27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0 9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ * for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ * and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#define NO_GZIP
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+# ifndef BUILDFIXED
+# define BUILDFIXED
+# endif
+#endif
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
+ unsigned copy));
+#ifdef BUILDFIXED
+ void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
+ unsigned len));
+
+int ZEXPORT inflateResetKeep(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ strm->total_in = strm->total_out = state->total = 0;
+ strm->msg = Z_NULL;
+ if (state->wrap) /* to support ill-conceived Java test suite */
+ strm->adler = state->wrap & 1;
+ state->mode = HEAD;
+ state->last = 0;
+ state->havedict = 0;
+ state->dmax = 32768U;
+ state->head = Z_NULL;
+ state->hold = 0;
+ state->bits = 0;
+ state->lencode = state->distcode = state->next = state->codes;
+ state->sane = 1;
+ state->back = -1;
+ Tracev((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ state->wsize = 0;
+ state->whave = 0;
+ state->wnext = 0;
+ return inflateResetKeep(strm);
+}
+
+int ZEXPORT inflateReset2(strm, windowBits)
+z_streamp strm;
+int windowBits;
+{
+ int wrap;
+ struct inflate_state FAR *state;
+
+ /* get the state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* extract wrap request from windowBits parameter */
+ if (windowBits < 0) {
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+ else {
+ wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+ if (windowBits < 48)
+ windowBits &= 15;
+#endif
+ }
+
+ /* set number of window bits, free window if different */
+ if (windowBits && (windowBits < 8 || windowBits > 15))
+ return Z_STREAM_ERROR;
+ if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
+ ZFREE(strm, state->window);
+ state->window = Z_NULL;
+ }
+
+ /* update state and reset the rest of it */
+ state->wrap = wrap;
+ state->wbits = (unsigned)windowBits;
+ return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+ int ret;
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+#endif
+ }
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
+ state = (struct inflate_state FAR *)
+ ZALLOC(strm, 1, sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (struct internal_state FAR *)state;
+ state->window = Z_NULL;
+ ret = inflateReset2(strm, windowBits);
+ if (ret != Z_OK) {
+ ZFREE(strm, state);
+ strm->state = Z_NULL;
+ }
+ return ret;
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+ return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (bits < 0) {
+ state->hold = 0;
+ state->bits = 0;
+ return Z_OK;
+ }
+ if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
+ value &= (1L << bits) - 1;
+ state->hold += value << state->bits;
+ state->bits += bits;
+ return Z_OK;
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+ Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
+ defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
+ those tables to stdout, which would be piped to inffixed.h. A small program
+ can simply call makefixed to do this:
+
+ void makefixed(void);
+
+ int main(void)
+ {
+ makefixed();
+ return 0;
+ }
+
+ Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+ a.out > inffixed.h
+ */
+void makefixed()
+{
+ unsigned low, size;
+ struct inflate_state state;
+
+ fixedtables(&state);
+ puts(" /* inffixed.h -- table for decoding fixed codes");
+ puts(" * Generated automatically by makefixed().");
+ puts(" */");
+ puts("");
+ puts(" /* WARNING: this file should *not* be used by applications.");
+ puts(" It is part of the implementation of this library and is");
+ puts(" subject to change. Applications should only use zlib.h.");
+ puts(" */");
+ puts("");
+ size = 1U << 9;
+ printf(" static const code lenfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 7) == 0) printf("\n ");
+ printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
+ state.lencode[low].bits, state.lencode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+ size = 1U << 5;
+ printf("\n static const code distfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 6) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+ state.distcode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+}
+#endif /* MAKEFIXED */
+
+/*
+ Update the window with the last wsize (normally 32K) bytes written before
+ returning. If window does not exist yet, create it. This is only called
+ when a window is already in use, or when output has been written during this
+ inflate call, but the end of the deflate stream has not been reached yet.
+ It is also called to create a window for dictionary data when a dictionary
+ is loaded.
+
+ Providing output buffers larger than 32K to inflate() should provide a speed
+ advantage, since only the last 32K of output is copied to the sliding window
+ upon return from inflate(), and since all distances after the first 32K of
+ output will fall in the output data, making match copies simpler and faster.
+ The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, end, copy)
+z_streamp strm;
+const Bytef *end;
+unsigned copy;
+{
+ struct inflate_state FAR *state;
+ unsigned dist;
+
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* if it hasn't been done already, allocate space for the window */
+ if (state->window == Z_NULL) {
+ state->window = (unsigned char FAR *)
+ ZALLOC(strm, 1U << state->wbits,
+ sizeof(unsigned char));
+ if (state->window == Z_NULL) return 1;
+ }
+
+ /* if window not in use yet, initialize */
+ if (state->wsize == 0) {
+ state->wsize = 1U << state->wbits;
+ state->wnext = 0;
+ state->whave = 0;
+ }
+
+ /* copy state->wsize or less output bytes into the circular window */
+ if (copy >= state->wsize) {
+ zmemcpy(state->window, end - state->wsize, state->wsize);
+ state->wnext = 0;
+ state->whave = state->wsize;
+ }
+ else {
+ dist = state->wsize - state->wnext;
+ if (dist > copy) dist = copy;
+ zmemcpy(state->window + state->wnext, end - copy, dist);
+ copy -= dist;
+ if (copy) {
+ zmemcpy(state->window, end - copy, copy);
+ state->wnext = copy;
+ state->whave = state->wsize;
+ }
+ else {
+ state->wnext += dist;
+ if (state->wnext == state->wsize) state->wnext = 0;
+ if (state->whave < state->wsize) state->whave += dist;
+ }
+ }
+ return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+# define UPDATE(check, buf, len) \
+ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+# define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+# define CRC2(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ check = crc32(check, hbuf, 2); \
+ } while (0)
+
+# define CRC4(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ hbuf[2] = (unsigned char)((word) >> 16); \
+ hbuf[3] = (unsigned char)((word) >> 24); \
+ check = crc32(check, hbuf, 4); \
+ } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+ if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ if (have == 0) goto inf_leave; \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/*
+ inflate() uses a state machine to process as much input data and generate as
+ much output data as possible before returning. The state machine is
+ structured roughly as follows:
+
+ for (;;) switch (state) {
+ ...
+ case STATEn:
+ if (not enough input data or output space to make progress)
+ return;
+ ... make progress ...
+ state = STATEm;
+ break;
+ ...
+ }
+
+ so when inflate() is called again, the same case is attempted again, and
+ if the appropriate resources are provided, the machine proceeds to the
+ next state. The NEEDBITS() macro is usually the way the state evaluates
+ whether it can proceed or should return. NEEDBITS() does the return if
+ the requested bits are not available. The typical use of the BITS macros
+ is:
+
+ NEEDBITS(n);
+ ... do something with BITS(n) ...
+ DROPBITS(n);
+
+ where NEEDBITS(n) either returns from inflate() if there isn't enough
+ input left to load n bits into the accumulator, or it continues. BITS(n)
+ gives the low n bits in the accumulator. When done, DROPBITS(n) drops
+ the low n bits off the accumulator. INITBITS() clears the accumulator
+ and sets the number of available bits to zero. BYTEBITS() discards just
+ enough bits to put the accumulator on a byte boundary. After BYTEBITS()
+ and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+ NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+ if there is no input available. The decoding of variable length codes uses
+ PULLBYTE() directly in order to pull just enough bytes to decode the next
+ code, and no more.
+
+ Some states loop until they get enough input, making sure that enough
+ state information is maintained to continue the loop where it left off
+ if NEEDBITS() returns in the loop. For example, want, need, and keep
+ would all have to actually be part of the saved state in case NEEDBITS()
+ returns:
+
+ case STATEw:
+ while (want < need) {
+ NEEDBITS(n);
+ keep[want++] = BITS(n);
+ DROPBITS(n);
+ }
+ state = STATEx;
+ case STATEx:
+
+ As shown above, if the next state is also the next case, then the break
+ is omitted.
+
+ A state may also return if there is not enough output space available to
+ complete that state. Those states are copying stored data, writing a
+ literal byte, and copying a matching string.
+
+ When returning, a "goto inf_leave" is used to update the total counters,
+ update the check value, and determine whether any progress has been made
+ during that inflate() call in order to return the proper return code.
+ Progress is defined as a change in either strm->avail_in or strm->avail_out.
+ When there is a window, goto inf_leave will update the window with the last
+ output written. If a goto inf_leave occurs in the middle of decompression
+ and there is no window currently, goto inf_leave will create one and copy
+ output to the window for the next call of inflate().
+
+ In this implementation, the flush parameter of inflate() only affects the
+ return code (per zlib.h). inflate() always writes as much as possible to
+ strm->next_out, given the space available and the provided input--the effect
+ documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
+ the allocation of and copying into a sliding window until necessary, which
+ provides the effect documented in zlib.h for Z_FINISH when the entire input
+ stream available. So the only thing the flush parameter actually does is:
+ when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
+ will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+ struct inflate_state FAR *state;
+ z_const unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned in, out; /* save starting available input and output */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code here; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+#ifdef GUNZIP
+ unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
+#endif
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0))
+ return Z_STREAM_ERROR;
+
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
+ LOAD();
+ in = have;
+ out = left;
+ ret = Z_OK;
+ for (;;)
+ switch (state->mode) {
+ case HEAD:
+ if (state->wrap == 0) {
+ state->mode = TYPEDO;
+ break;
+ }
+ NEEDBITS(16);
+#ifdef GUNZIP
+ if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
+ state->check = crc32(0L, Z_NULL, 0);
+ CRC2(state->check, hold);
+ INITBITS();
+ state->mode = FLAGS;
+ break;
+ }
+ state->flags = 0; /* expect zlib header */
+ if (state->head != Z_NULL)
+ state->head->done = -1;
+ if (!(state->wrap & 1) || /* check if zlib header allowed */
+#else
+ if (
+#endif
+ ((BITS(8) << 8) + (hold >> 8)) % 31) {
+ strm->msg = (char *)"incorrect header check";
+ state->mode = BAD;
+ break;
+ }
+ if (BITS(4) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ DROPBITS(4);
+ len = BITS(4) + 8;
+ if (state->wbits == 0)
+ state->wbits = len;
+ else if (len > state->wbits) {
+ strm->msg = (char *)"invalid window size";
+ state->mode = BAD;
+ break;
+ }
+ state->dmax = 1U << len;
+ Tracev((stderr, "inflate: zlib header ok\n"));
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = hold & 0x200 ? DICTID : TYPE;
+ INITBITS();
+ break;
+#ifdef GUNZIP
+ case FLAGS:
+ NEEDBITS(16);
+ state->flags = (int)(hold);
+ if ((state->flags & 0xff) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ if (state->flags & 0xe000) {
+ strm->msg = (char *)"unknown header flags set";
+ state->mode = BAD;
+ break;
+ }
+ if (state->head != Z_NULL)
+ state->head->text = (int)((hold >> 8) & 1);
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = TIME;
+ case TIME:
+ NEEDBITS(32);
+ if (state->head != Z_NULL)
+ state->head->time = hold;
+ if (state->flags & 0x0200) CRC4(state->check, hold);
+ INITBITS();
+ state->mode = OS;
+ case OS:
+ NEEDBITS(16);
+ if (state->head != Z_NULL) {
+ state->head->xflags = (int)(hold & 0xff);
+ state->head->os = (int)(hold >> 8);
+ }
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = EXLEN;
+ case EXLEN:
+ if (state->flags & 0x0400) {
+ NEEDBITS(16);
+ state->length = (unsigned)(hold);
+ if (state->head != Z_NULL)
+ state->head->extra_len = (unsigned)hold;
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ }
+ else if (state->head != Z_NULL)
+ state->head->extra = Z_NULL;
+ state->mode = EXTRA;
+ case EXTRA:
+ if (state->flags & 0x0400) {
+ copy = state->length;
+ if (copy > have) copy = have;
+ if (copy) {
+ if (state->head != Z_NULL &&
+ state->head->extra != Z_NULL) {
+ len = state->head->extra_len - state->length;
+ zmemcpy(state->head->extra + len, next,
+ len + copy > state->head->extra_max ?
+ state->head->extra_max - len : copy);
+ }
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ state->length -= copy;
+ }
+ if (state->length) goto inf_leave;
+ }
+ state->length = 0;
+ state->mode = NAME;
+ case NAME:
+ if (state->flags & 0x0800) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->name != Z_NULL &&
+ state->length < state->head->name_max)
+ state->head->name[state->length++] = len;
+ } while (len && copy < have);
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->name = Z_NULL;
+ state->length = 0;
+ state->mode = COMMENT;
+ case COMMENT:
+ if (state->flags & 0x1000) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->comment != Z_NULL &&
+ state->length < state->head->comm_max)
+ state->head->comment[state->length++] = len;
+ } while (len && copy < have);
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->comment = Z_NULL;
+ state->mode = HCRC;
+ case HCRC:
+ if (state->flags & 0x0200) {
+ NEEDBITS(16);
+ if (hold != (state->check & 0xffff)) {
+ strm->msg = (char *)"header crc mismatch";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ }
+ if (state->head != Z_NULL) {
+ state->head->hcrc = (int)((state->flags >> 9) & 1);
+ state->head->done = 1;
+ }
+ strm->adler = state->check = crc32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ break;
+#endif
+ case DICTID:
+ NEEDBITS(32);
+ strm->adler = state->check = ZSWAP32(hold);
+ INITBITS();
+ state->mode = DICT;
+ case DICT:
+ if (state->havedict == 0) {
+ RESTORE();
+ return Z_NEED_DICT;
+ }
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ case TYPE:
+ if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
+ case TYPEDO:
+ if (state->last) {
+ BYTEBITS();
+ state->mode = CHECK;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN_; /* decode codes */
+ if (flush == Z_TREES) {
+ DROPBITS(2);
+ goto inf_leave;
+ }
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+ case STORED:
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+ state->mode = COPY_;
+ if (flush == Z_TREES) goto inf_leave;
+ case COPY_:
+ state->mode = COPY;
+ case COPY:
+ copy = state->length;
+ if (copy) {
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ if (copy == 0) goto inf_leave;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ break;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+ case TABLE:
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ state->have = 0;
+ state->mode = LENLENS;
+ case LENLENS:
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (const code FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+ state->have = 0;
+ state->mode = CODELENS;
+ case CODELENS:
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.val < 16) {
+ DROPBITS(here.bits);
+ state->lens[state->have++] = here.val;
+ }
+ else {
+ if (here.val == 16) {
+ NEEDBITS(here.bits + 2);
+ DROPBITS(here.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = state->lens[state->have - 1];
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (here.val == 17) {
+ NEEDBITS(here.bits + 3);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(here.bits + 7);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* check for end-of-block code (better have one) */
+ if (state->lens[256] == 0) {
+ strm->msg = (char *)"invalid code -- missing end-of-block";
+ state->mode = BAD;
+ break;
+ }
+
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftrees.h
+ concerning the ENOUGH constants, which depend on those values */
+ state->next = state->codes;
+ state->lencode = (const code FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (const code FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN_;
+ if (flush == Z_TREES) goto inf_leave;
+ case LEN_:
+ state->mode = LEN;
+ case LEN:
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ inflate_fast(strm, out);
+ LOAD();
+ if (state->mode == TYPE)
+ state->back = -1;
+ break;
+ }
+ state->back = 0;
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ state->back += last.bits;
+ }
+ DROPBITS(here.bits);
+ state->back += here.bits;
+ state->length = (unsigned)here.val;
+ if ((int)(here.op) == 0) {
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", here.val));
+ state->mode = LIT;
+ break;
+ }
+ if (here.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->back = -1;
+ state->mode = TYPE;
+ break;
+ }
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ state->extra = (unsigned)(here.op) & 15;
+ state->mode = LENEXT;
+ case LENEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ state->back += state->extra;
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+ state->was = state->length;
+ state->mode = DIST;
+ case DIST:
+ for (;;) {
+ here = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ state->back += last.bits;
+ }
+ DROPBITS(here.bits);
+ state->back += here.bits;
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)here.val;
+ state->extra = (unsigned)(here.op) & 15;
+ state->mode = DISTEXT;
+ case DISTEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ state->back += state->extra;
+ }
+#ifdef INFLATE_STRICT
+ if (state->offset > state->dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+ state->mode = MATCH;
+ case MATCH:
+ if (left == 0) goto inf_leave;
+ copy = out - left;
+ if (state->offset > copy) { /* copy from window */
+ copy = state->offset - copy;
+ if (copy > state->whave) {
+ if (state->sane) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ Trace((stderr, "inflate.c too far\n"));
+ copy -= state->whave;
+ if (copy > state->length) copy = state->length;
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = 0;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+#endif
+ }
+ if (copy > state->wnext) {
+ copy -= state->wnext;
+ from = state->window + (state->wsize - copy);
+ }
+ else
+ from = state->window + (state->wnext - copy);
+ if (copy > state->length) copy = state->length;
+ }
+ else { /* copy from output */
+ from = put - state->offset;
+ copy = state->length;
+ }
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+ case LIT:
+ if (left == 0) goto inf_leave;
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ case CHECK:
+ if (state->wrap) {
+ NEEDBITS(32);
+ out -= left;
+ strm->total_out += out;
+ state->total += out;
+ if (out)
+ strm->adler = state->check =
+ UPDATE(state->check, put - out, out);
+ out = left;
+ if ((
+#ifdef GUNZIP
+ state->flags ? hold :
+#endif
+ ZSWAP32(hold)) != state->check) {
+ strm->msg = (char *)"incorrect data check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: check matches trailer\n"));
+ }
+#ifdef GUNZIP
+ state->mode = LENGTH;
+ case LENGTH:
+ if (state->wrap && state->flags) {
+ NEEDBITS(32);
+ if (hold != (state->total & 0xffffffffUL)) {
+ strm->msg = (char *)"incorrect length check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: length matches trailer\n"));
+ }
+#endif
+ state->mode = DONE;
+ case DONE:
+ ret = Z_STREAM_END;
+ goto inf_leave;
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+ case MEM:
+ return Z_MEM_ERROR;
+ case SYNC:
+ default:
+ return Z_STREAM_ERROR;
+ }
+
+ /*
+ Return from inflate(), updating the total counts and the check value.
+ If there was no progress during the inflate() call, return a buffer
+ error. Call updatewindow() to create and/or update the window state.
+ Note: a memory error from inflate() is non-recoverable.
+ */
+ inf_leave:
+ RESTORE();
+ if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
+ (state->mode < CHECK || flush != Z_FINISH)))
+ if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ in -= strm->avail_in;
+ out -= strm->avail_out;
+ strm->total_in += in;
+ strm->total_out += out;
+ state->total += out;
+ if (state->wrap && out)
+ strm->adler = state->check =
+ UPDATE(state->check, strm->next_out - out, out);
+ strm->data_type = state->bits + (state->last ? 64 : 0) +
+ (state->mode == TYPE ? 128 : 0) +
+ (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
+ if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+ ret = Z_BUF_ERROR;
+ return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->window != Z_NULL) ZFREE(strm, state->window);
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+Bytef *dictionary;
+uInt *dictLength;
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* copy dictionary */
+ if (state->whave && dictionary != Z_NULL) {
+ zmemcpy(dictionary, state->window + state->wnext,
+ state->whave - state->wnext);
+ zmemcpy(dictionary + state->whave - state->wnext,
+ state->window, state->wnext);
+ }
+ if (dictLength != Z_NULL)
+ *dictLength = state->whave;
+ return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+ struct inflate_state FAR *state;
+ unsigned long dictid;
+ int ret;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->wrap != 0 && state->mode != DICT)
+ return Z_STREAM_ERROR;
+
+ /* check for correct dictionary identifier */
+ if (state->mode == DICT) {
+ dictid = adler32(0L, Z_NULL, 0);
+ dictid = adler32(dictid, dictionary, dictLength);
+ if (dictid != state->check)
+ return Z_DATA_ERROR;
+ }
+
+ /* copy dictionary to window using updatewindow(), which will amend the
+ existing dictionary if appropriate */
+ ret = updatewindow(strm, dictionary + dictLength, dictLength);
+ if (ret) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ state->havedict = 1;
+ Tracev((stderr, "inflate: dictionary set\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+ /* save header structure */
+ state->head = head;
+ head->done = 0;
+ return Z_OK;
+}
+
+/*
+ Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
+ or when out of input. When called, *have is the number of pattern bytes
+ found in order so far, in 0..3. On return *have is updated to the new
+ state. If on return *have equals four, then the pattern was found and the
+ return value is how many bytes were read including the last byte of the
+ pattern. If *have is less than four, then the pattern has not been found
+ yet and the return value is len. In the latter case, syncsearch() can be
+ called again with more data and the *have state. *have is initialized to
+ zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+const unsigned char FAR *buf;
+unsigned len;
+{
+ unsigned got;
+ unsigned next;
+
+ got = *have;
+ next = 0;
+ while (next < len && got < 4) {
+ if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+ got++;
+ else if (buf[next])
+ got = 0;
+ else
+ got = 4 - got;
+ next++;
+ }
+ *have = got;
+ return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+ unsigned len; /* number of bytes to look at or looked at */
+ unsigned long in, out; /* temporary to save total_in and total_out */
+ unsigned char buf[4]; /* to restore bit buffer to byte string */
+ struct inflate_state FAR *state;
+
+ /* check parameters */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+ /* if first time, start search in bit buffer */
+ if (state->mode != SYNC) {
+ state->mode = SYNC;
+ state->hold <<= state->bits & 7;
+ state->bits -= state->bits & 7;
+ len = 0;
+ while (state->bits >= 8) {
+ buf[len++] = (unsigned char)(state->hold);
+ state->hold >>= 8;
+ state->bits -= 8;
+ }
+ state->have = 0;
+ syncsearch(&(state->have), buf, len);
+ }
+
+ /* search available input */
+ len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+ strm->avail_in -= len;
+ strm->next_in += len;
+ strm->total_in += len;
+
+ /* return no joy or set up to restart inflate() on a new block */
+ if (state->have != 4) return Z_DATA_ERROR;
+ in = strm->total_in; out = strm->total_out;
+ inflateReset(strm);
+ strm->total_in = in; strm->total_out = out;
+ state->mode = TYPE;
+ return Z_OK;
+}
+
+/*
+ Returns true if inflate is currently at the end of a block generated by
+ Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ implementation to provide an additional safety check. PPP uses
+ Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+ block. When decompressing, PPP checks that at the end of input packet,
+ inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+ struct inflate_state FAR *state;
+ struct inflate_state FAR *copy;
+ unsigned char FAR *window;
+ unsigned wsize;
+
+ /* check input */
+ if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
+ source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)source->state;
+
+ /* allocate space */
+ copy = (struct inflate_state FAR *)
+ ZALLOC(source, 1, sizeof(struct inflate_state));
+ if (copy == Z_NULL) return Z_MEM_ERROR;
+ window = Z_NULL;
+ if (state->window != Z_NULL) {
+ window = (unsigned char FAR *)
+ ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+ if (window == Z_NULL) {
+ ZFREE(source, copy);
+ return Z_MEM_ERROR;
+ }
+ }
+
+ /* copy state */
+ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+ zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
+ if (state->lencode >= state->codes &&
+ state->lencode <= state->codes + ENOUGH - 1) {
+ copy->lencode = copy->codes + (state->lencode - state->codes);
+ copy->distcode = copy->codes + (state->distcode - state->codes);
+ }
+ copy->next = copy->codes + (state->next - state->codes);
+ if (window != Z_NULL) {
+ wsize = 1U << state->wbits;
+ zmemcpy(window, state->window, wsize);
+ }
+ copy->window = window;
+ dest->state = (struct internal_state FAR *)copy;
+ return Z_OK;
+}
+
+int ZEXPORT inflateUndermine(strm, subvert)
+z_streamp strm;
+int subvert;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ state->sane = !subvert;
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ return Z_OK;
+#else
+ state->sane = 1;
+ return Z_DATA_ERROR;
+#endif
+}
+
+long ZEXPORT inflateMark(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
+ state = (struct inflate_state FAR *)strm->state;
+ return ((long)(state->back) << 16) +
+ (state->mode == COPY ? state->length :
+ (state->mode == MATCH ? state->was - state->length : 0));
+}
diff --git a/lib/zlib_inflate/inflate.h b/lib/zlib_inflate/inflate.h
new file mode 100644
index 0000000..95f4986
--- /dev/null
+++ b/lib/zlib_inflate/inflate.h
@@ -0,0 +1,122 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2009 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip decoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+ HEAD, /* i: waiting for magic header */
+ FLAGS, /* i: waiting for method and flags (gzip) */
+ TIME, /* i: waiting for modification time (gzip) */
+ OS, /* i: waiting for extra flags and operating system (gzip) */
+ EXLEN, /* i: waiting for extra length (gzip) */
+ EXTRA, /* i: waiting for extra bytes (gzip) */
+ NAME, /* i: waiting for end of file name (gzip) */
+ COMMENT, /* i: waiting for end of comment (gzip) */
+ HCRC, /* i: waiting for header crc (gzip) */
+ DICTID, /* i: waiting for dictionary check value */
+ DICT, /* waiting for inflateSetDictionary() call */
+ TYPE, /* i: waiting for type bits, including last-flag bit */
+ TYPEDO, /* i: same, but skip check to exit inflate on new block */
+ STORED, /* i: waiting for stored size (length and complement) */
+ COPY_, /* i/o: same as COPY below, but only first time in */
+ COPY, /* i/o: waiting for input or output to copy stored block */
+ TABLE, /* i: waiting for dynamic block table lengths */
+ LENLENS, /* i: waiting for code length code lengths */
+ CODELENS, /* i: waiting for length/lit and distance code lengths */
+ LEN_, /* i: same as LEN below, but only first time in */
+ LEN, /* i: waiting for length/lit/eob code */
+ LENEXT, /* i: waiting for length extra bits */
+ DIST, /* i: waiting for distance code */
+ DISTEXT, /* i: waiting for distance extra bits */
+ MATCH, /* o: waiting for output space to copy string */
+ LIT, /* o: waiting for output space to write literal */
+ CHECK, /* i: waiting for 32-bit check value */
+ LENGTH, /* i: waiting for 32-bit length (gzip) */
+ DONE, /* finished check, done -- remain here until reset */
+ BAD, /* got a data error -- remain here until reset */
+ MEM, /* got an inflate() memory error -- remain here until reset */
+ SYNC /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+ State transitions between above modes -
+
+ (most modes can go to BAD or MEM on error -- not shown for clarity)
+
+ Process header:
+ HEAD -> (gzip) or (zlib) or (raw)
+ (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
+ HCRC -> TYPE
+ (zlib) -> DICTID or TYPE
+ DICTID -> DICT -> TYPE
+ (raw) -> TYPEDO
+ Read deflate blocks:
+ TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
+ STORED -> COPY_ -> COPY -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN_
+ LEN_ -> LEN
+ Read deflate codes in fixed or dynamic block:
+ LEN -> LENEXT or LIT or TYPE
+ LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+ LIT -> LEN
+ Process trailer:
+ CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls. Approximately 10K bytes. */
+struct inflate_state {
+ inflate_mode mode; /* current inflate mode */
+ int last; /* true if processing last block */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ int havedict; /* true if dictionary provided */
+ int flags; /* gzip header method and flags (0 if zlib) */
+ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
+ unsigned long check; /* protected copy of check value */
+ unsigned long total; /* protected copy of output count */
+ gz_headerp head; /* where to save gzip header information */
+ /* sliding window */
+ unsigned wbits; /* log base 2 of requested window size */
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned wnext; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if needed */
+ /* bit accumulator */
+ unsigned long hold; /* input bit accumulator */
+ unsigned bits; /* number of bits in "in" */
+ /* for string and stored block copying */
+ unsigned length; /* literal or length of data to copy */
+ unsigned offset; /* distance back to copy string from */
+ /* for table and code decoding */
+ unsigned extra; /* extra bits needed */
+ /* fixed and dynamic code tables */
+ code const FAR *lencode; /* starting table for length/literal codes */
+ code const FAR *distcode; /* starting table for distance codes */
+ unsigned lenbits; /* index bits for lencode */
+ unsigned distbits; /* index bits for distcode */
+ /* dynamic table building */
+ unsigned ncode; /* number of code length code lengths */
+ unsigned nlen; /* number of length code lengths */
+ unsigned ndist; /* number of distance code lengths */
+ unsigned have; /* number of code lengths in lens[] */
+ code FAR *next; /* next available space in codes[] */
+ unsigned short lens[320]; /* temporary storage for code lengths */
+ unsigned short work[288]; /* work area for code table building */
+ code codes[ENOUGH]; /* space for code tables */
+ int sane; /* if false, allow invalid distance too far */
+ int back; /* bits back of last unprocessed length/lit */
+ unsigned was; /* initial length of match */
+};
diff --git a/lib/zlib_inflate/inftrees.c b/lib/zlib_inflate/inftrees.c
new file mode 100644
index 0000000..44d89cf
--- /dev/null
+++ b/lib/zlib_inflate/inftrees.c
@@ -0,0 +1,306 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+ " inflate 1.2.8 Copyright 1995-2013 Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/*
+ Build a set of tables to decode the provided canonical Huffman code.
+ The code lengths are lens[0..codes-1]. The result starts at *table,
+ whose indices are 0..2^bits-1. work is a writable array of at least
+ lens shorts, which is used as a work area. type is the type of code
+ to be generated, CODES, LENS, or DISTS. On return, zero is success,
+ -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
+ on return points to the next available entry's address. bits is the
+ requested root table index bits, and on return it is the actual root
+ table index bits. It will differ if the request is greater than the
+ longest code or if it is less than the shortest code.
+ */
+int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+ unsigned len; /* a code's length in bits */
+ unsigned sym; /* index of code symbols */
+ unsigned min, max; /* minimum and maximum code lengths */
+ unsigned root; /* number of index bits for root table */
+ unsigned curr; /* number of index bits for current table */
+ unsigned drop; /* code bits to drop for sub-table */
+ int left; /* number of prefix codes available */
+ unsigned used; /* code entries in table used */
+ unsigned huff; /* Huffman code */
+ unsigned incr; /* for incrementing code, index */
+ unsigned fill; /* index for replicating entries */
+ unsigned low; /* low bits for current root entry */
+ unsigned mask; /* mask for low root bits */
+ code here; /* table entry for duplication */
+ code FAR *next; /* next available space in table */
+ const unsigned short FAR *base; /* base value table to use */
+ const unsigned short FAR *extra; /* extra bits table to use */
+ int end; /* use base and extra for symbol > end */
+ unsigned short count[MAXBITS+1]; /* number of codes of each length */
+ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
+ static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78};
+ static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577, 0, 0};
+ static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+ 28, 28, 29, 29, 64, 64};
+
+ /*
+ Process a set of code lengths to create a canonical Huffman code. The
+ code lengths are lens[0..codes-1]. Each length corresponds to the
+ symbols 0..codes-1. The Huffman code is generated by first sorting the
+ symbols by length from short to long, and retaining the symbol order
+ for codes with equal lengths. Then the code starts with all zero bits
+ for the first code of the shortest length, and the codes are integer
+ increments for the same length, and zeros are appended as the length
+ increases. For the deflate format, these bits are stored backwards
+ from their more natural integer increment ordering, and so when the
+ decoding tables are built in the large loop below, the integer codes
+ are incremented backwards.
+
+ This routine assumes, but does not check, that all of the entries in
+ lens[] are in the range 0..MAXBITS. The caller must assure this.
+ 1..MAXBITS is interpreted as that code length. zero means that that
+ symbol does not occur in this code.
+
+ The codes are sorted by computing a count of codes for each length,
+ creating from that a table of starting indices for each length in the
+ sorted table, and then entering the symbols in order in the sorted
+ table. The sorted table is work[], with that space being provided by
+ the caller.
+
+ The length counts are used for other purposes as well, i.e. finding
+ the minimum and maximum length codes, determining if there are any
+ codes at all, checking for a valid set of lengths, and looking ahead
+ at length counts to determine sub-table sizes when building the
+ decoding tables.
+ */
+
+ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+ for (len = 0; len <= MAXBITS; len++)
+ count[len] = 0;
+ for (sym = 0; sym < codes; sym++)
+ count[lens[sym]]++;
+
+ /* bound code lengths, force root to be within code lengths */
+ root = *bits;
+ for (max = MAXBITS; max >= 1; max--)
+ if (count[max] != 0) break;
+ if (root > max) root = max;
+ if (max == 0) { /* no symbols to code at all */
+ here.op = (unsigned char)64; /* invalid code marker */
+ here.bits = (unsigned char)1;
+ here.val = (unsigned short)0;
+ *(*table)++ = here; /* make a table to force an error */
+ *(*table)++ = here;
+ *bits = 1;
+ return 0; /* no symbols, but wait for decoding to report error */
+ }
+ for (min = 1; min < max; min++)
+ if (count[min] != 0) break;
+ if (root < min) root = min;
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1;
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1;
+ left -= count[len];
+ if (left < 0) return -1; /* over-subscribed */
+ }
+ if (left > 0 && (type == CODES || max != 1))
+ return -1; /* incomplete set */
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + count[len];
+
+ /* sort symbols by length, by symbol order within each length */
+ for (sym = 0; sym < codes; sym++)
+ if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+ /*
+ Create and fill in decoding tables. In this loop, the table being
+ filled is at next and has curr index bits. The code being used is huff
+ with length len. That code is converted to an index by dropping drop
+ bits off of the bottom. For codes where len is less than drop + curr,
+ those top drop + curr - len bits are incremented through all values to
+ fill the table with replicated entries.
+
+ root is the number of index bits for the root table. When len exceeds
+ root, sub-tables are created pointed to by the root entry with an index
+ of the low root bits of huff. This is saved in low to check for when a
+ new sub-table should be started. drop is zero when the root table is
+ being filled, and drop is root when sub-tables are being filled.
+
+ When a new sub-table is needed, it is necessary to look ahead in the
+ code lengths to determine what size sub-table is needed. The length
+ counts are used for this, and so count[] is decremented as codes are
+ entered in the tables.
+
+ used keeps track of how many table entries have been allocated from the
+ provided *table space. It is checked for LENS and DIST tables against
+ the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+ the initial root table size constants. See the comments in inftrees.h
+ for more information.
+
+ sym increments through all symbols, and the loop terminates when
+ all codes of length max, i.e. all codes, have been processed. This
+ routine permits incomplete codes, so another loop after this one fills
+ in the rest of the decoding tables with invalid code markers.
+ */
+
+ /* set up for code type */
+ switch (type) {
+ case CODES:
+ base = extra = work; /* dummy value--not used */
+ end = 19;
+ break;
+ case LENS:
+ base = lbase;
+ base -= 257;
+ extra = lext;
+ extra -= 257;
+ end = 256;
+ break;
+ default: /* DISTS */
+ base = dbase;
+ extra = dext;
+ end = -1;
+ }
+
+ /* initialize state for loop */
+ huff = 0; /* starting code */
+ sym = 0; /* starting code symbol */
+ len = min; /* starting code length */
+ next = *table; /* current table to fill in */
+ curr = root; /* current table index bits */
+ drop = 0; /* current bits to drop from code for index */
+ low = (unsigned)(-1); /* trigger new sub-table when len > root */
+ used = 1U << root; /* use root table entries */
+ mask = used - 1; /* mask for comparing low */
+
+ /* check available table space */
+ if ((type == LENS && used > ENOUGH_LENS) ||
+ (type == DISTS && used > ENOUGH_DISTS))
+ return 1;
+
+ /* process all codes and make table entries */
+ for (;;) {
+ /* create table entry */
+ here.bits = (unsigned char)(len - drop);
+ if ((int)(work[sym]) < end) {
+ here.op = (unsigned char)0;
+ here.val = work[sym];
+ }
+ else if ((int)(work[sym]) > end) {
+ here.op = (unsigned char)(extra[work[sym]]);
+ here.val = base[work[sym]];
+ }
+ else {
+ here.op = (unsigned char)(32 + 64); /* end of block */
+ here.val = 0;
+ }
+
+ /* replicate for those indices with low len bits equal to huff */
+ incr = 1U << (len - drop);
+ fill = 1U << curr;
+ min = fill; /* save offset to next table */
+ do {
+ fill -= incr;
+ next[(huff >> drop) + fill] = here;
+ } while (fill != 0);
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+
+ /* go to next symbol, update count, len */
+ sym++;
+ if (--(count[len]) == 0) {
+ if (len == max) break;
+ len = lens[work[sym]];
+ }
+
+ /* create new sub-table if needed */
+ if (len > root && (huff & mask) != low) {
+ /* if first time, transition to sub-tables */
+ if (drop == 0)
+ drop = root;
+
+ /* increment past last table */
+ next += min; /* here min is 1 << curr */
+
+ /* determine length of next table */
+ curr = len - drop;
+ left = (int)(1 << curr);
+ while (curr + drop < max) {
+ left -= count[curr + drop];
+ if (left <= 0) break;
+ curr++;
+ left <<= 1;
+ }
+
+ /* check for enough space */
+ used += 1U << curr;
+ if ((type == LENS && used > ENOUGH_LENS) ||
+ (type == DISTS && used > ENOUGH_DISTS))
+ return 1;
+
+ /* point entry in root table to sub-table */
+ low = huff & mask;
+ (*table)[low].op = (unsigned char)curr;
+ (*table)[low].bits = (unsigned char)root;
+ (*table)[low].val = (unsigned short)(next - *table);
+ }
+ }
+
+ /* fill in remaining table entry if code is incomplete (guaranteed to have
+ at most one remaining entry, since if the code is incomplete, the
+ maximum code length that was allowed to get this far is one bit) */
+ if (huff != 0) {
+ here.op = (unsigned char)64; /* invalid code marker */
+ here.bits = (unsigned char)(len - drop);
+ here.val = (unsigned short)0;
+ next[huff] = here;
+ }
+
+ /* set return parameters */
+ *table += used;
+ *bits = root;
+ return 0;
+}
diff --git a/lib/zlib_inflate/inftrees.h b/lib/zlib_inflate/inftrees.h
new file mode 100644
index 0000000..baa53a0
--- /dev/null
+++ b/lib/zlib_inflate/inftrees.h
@@ -0,0 +1,62 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables. Each entry provides either the
+ information needed to do the operation requested by the code that
+ indexed that table entry, or it provides a pointer to another
+ table that indexes more bits of the code. op indicates whether
+ the entry is a pointer to another table, a literal, a length or
+ distance, an end-of-block, or an invalid code. For a table
+ pointer, the low four bits of op is the number of index bits of
+ that table. For a length or distance, the low four bits of op
+ is the number of extra bits to get after the code. bits is
+ the number of bits in this code or part of the code to drop off
+ of the bit buffer. val is the actual byte to output in the case
+ of a literal, the base length or distance, or the offset from
+ the current table to the next table. Each entry is four bytes. */
+typedef struct {
+ unsigned char op; /* operation, extra bits, table bits */
+ unsigned char bits; /* bits in this part of the code */
+ unsigned short val; /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+ 00000000 - literal
+ 0000tttt - table link, tttt != 0 is the number of table index bits
+ 0001eeee - length or distance, eeee is the number of extra bits
+ 01100000 - end of block
+ 01000000 - invalid code
+ */
+
+/* Maximum size of the dynamic table. The maximum number of code structures is
+ 1444, which is the sum of 852 for literal/length codes and 592 for distance
+ codes. These values were found by exhaustive searches using the program
+ examples/enough.c found in the zlib distribtution. The arguments to that
+ program are the number of symbols, the initial root table size, and the
+ maximum bit length of a code. "enough 286 9 15" for literal/length codes
+ returns returns 852, and "enough 30 6 15" for distance codes returns 592.
+ The initial root table size (9 or 6) is found in the fifth argument of the
+ inflate_table() calls in inflate.c and infback.c. If the root table size is
+ changed, then these maximum sizes would be need to be recalculated and
+ updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 592
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
+
+/* Type of code to build for inflate_table() */
+typedef enum {
+ CODES,
+ LENS,
+ DISTS
+} codetype;
+
+int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
+ unsigned codes, code FAR * FAR *table,
+ unsigned FAR *bits, unsigned short FAR *work));
diff --git a/lib/zlib_inflate/rules.mk b/lib/zlib_inflate/rules.mk
new file mode 100755
index 0000000..96d2383
--- /dev/null
+++ b/lib/zlib_inflate/rules.mk
@@ -0,0 +1,9 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+OBJS += \
+ $(LOCAL_DIR)/zutil.o \
+ $(LOCAL_DIR)/adler32.o \
+ $(LOCAL_DIR)/inftrees.o \
+ $(LOCAL_DIR)/inflate.o \
+ $(LOCAL_DIR)/inffast.o \
+ $(LOCAL_DIR)/decompress.o
diff --git a/lib/zlib_inflate/zconf.h b/lib/zlib_inflate/zconf.h
new file mode 100644
index 0000000..9987a77
--- /dev/null
+++ b/lib/zlib_inflate/zconf.h
@@ -0,0 +1,511 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
+
+/* all linked symbols */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_bits z__tr_flush_bits
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzvprintf z_gzvprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzwrite z_gzwrite
+# endif
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateGetDictionary z_inflateGetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflateResetKeep z_inflateResetKeep
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# endif
+# define zError z_zError
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# elif (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# elif (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+# ifndef Z_SOLO
+# include <sys/types.h> /* for off_t */
+# endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+# include <stdarg.h> /* for va_list */
+# endif
+#endif
+
+#ifdef _WIN32
+# ifndef Z_SOLO
+# include <stddef.h> /* for wchar_t */
+# endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+# endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+# define z_off64_t off64_t
+#else
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/lib/zlib_inflate/zlib.h b/lib/zlib_inflate/zlib.h
new file mode 100644
index 0000000..8da7aa5
--- /dev/null
+++ b/lib/zlib_inflate/zlib.h
@@ -0,0 +1,1768 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.8, April 28th, 2013
+
+ Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+ (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.8"
+#define ZLIB_VERNUM 0x1280
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 8
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed data.
+ This version of the library supports only one compression method (deflation)
+ but other algorithms will be added later and will have the same stream
+ interface.
+
+ Compression can be done in a single step if the buffers are large enough,
+ or can be done by repeated calls of the compression function. In the latter
+ case, the application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip streams in memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never crash
+ even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ z_const Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total number of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total number of bytes output so far */
+
+ z_const char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: binary or text */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ gzip header information passed to and from zlib routines. See RFC 1952
+ for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+ int text; /* true if compressed data believed to be text */
+ uLong time; /* modification time */
+ int xflags; /* extra flags (not used when writing a gzip file) */
+ int os; /* operating system */
+ Bytef *extra; /* pointer to extra field or Z_NULL if none */
+ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
+ uInt extra_max; /* space at extra (only when reading header) */
+ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
+ uInt name_max; /* space at name (only when reading header) */
+ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
+ uInt comm_max; /* space at comment (only when reading header) */
+ int hcrc; /* true if there was or will be a header crc */
+ int done; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+ The application must update next_in and avail_in when avail_in has dropped
+ to zero. It must update next_out and avail_out when avail_out has dropped
+ to zero. The application must initialize zalloc, zfree and opaque before
+ calling the init function. All other fields are set by the compression
+ library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this if
+ the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers
+ returned by zalloc for objects of exactly 65536 bytes *must* have their
+ offset normalized to zero. The default allocation function provided by this
+ library ensures this (see zutil.c). To reduce memory requirements and avoid
+ any allocation of 64K objects, at the expense of compression ratio, compile
+ the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or progress
+ reports. After compression, total_in holds the total size of the
+ uncompressed data and may be saved for use in the decompressor (particularly
+ if the decompressor wants to decompress everything in a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+#define Z_TREES 6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_FIXED 4
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_TEXT 1
+#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is not
+ compatible with the zlib.h header file used by the application. This check
+ is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller. If
+ zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+ allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at all
+ (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION
+ requests a default compromise between speed and compression (currently
+ equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if level is not a valid compression level, or
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION). msg is set to null
+ if there is no error message. deflateInit does not perform any compression:
+ this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications). Some
+ output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating avail_in or avail_out accordingly; avail_out should
+ never be zero before the call. The application can consume the compressed
+ output when it wants, for example when the output buffer is full (avail_out
+ == 0), or after each call of deflate(). If deflate returns Z_OK and with
+ zero avail_out, it must be called again after making room in the output
+ buffer because there might be more output pending.
+
+ Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+ decide how much data to accumulate before producing output, in order to
+ maximize compression.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In
+ particular avail_in is zero after the call if enough output space has been
+ provided before the call.) Flushing may degrade compression for some
+ compression algorithms and so it should be used only when necessary. This
+ completes the current deflate block and follows it with an empty stored block
+ that is three bits plus filler bits to the next byte, followed by four bytes
+ (00 00 ff ff).
+
+ If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+ output buffer, but the output is not aligned to a byte boundary. All of the
+ input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+ This completes the current deflate block and follows it with an empty fixed
+ codes block that is 10 bits long. This assures that enough bytes are output
+ in order for the decompressor to finish the block before the empty fixed code
+ block.
+
+ If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+ for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+ seven bits of the current block are held to be written as the next byte after
+ the next deflate block is completed. In this case, the decompressor may not
+ be provided enough bits at this point in order to complete decompression of
+ the data provided so far to the compressor. It may need to wait for the next
+ block to be emitted. This is for advanced applications that need to control
+ the emission of deflate blocks.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there was
+ enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the stream
+ are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least the
+ value returned by deflateBound (see below). Then deflate is guaranteed to
+ return Z_STREAM_END. If not enough output space is provided, deflate will
+ not return Z_STREAM_END, and it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update strm->data_type if it can make a good guess about
+ the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect the
+ compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+ fatal, and deflate() can be called again with more input and more output
+ space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case, msg
+ may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the
+ exact value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit() does not process any header information -- that is deferred
+ until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing will
+ resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there is
+ no more input data or no more space in the output buffer (see below about
+ the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating the next_* and avail_* values accordingly. The
+ application can consume the uncompressed output when it wants, for example
+ when the output buffer is full (avail_out == 0), or after each call of
+ inflate(). If inflate returns Z_OK and with zero avail_out, it must be
+ called again after making room in the output buffer because there might be
+ more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+ Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate()
+ stop if and when it gets to the next deflate block boundary. When decoding
+ the zlib or gzip format, this will cause inflate() to return immediately
+ after the header and before the first block. When doing a raw inflate,
+ inflate() will go ahead and process the first block, and will return when it
+ gets to the end of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ Also to assist in this, on return inflate() will set strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64 if
+ inflate() is currently decoding the last block in the deflate stream, plus
+ 128 if inflate() returned immediately after decoding an end-of-block code or
+ decoding the complete header up to just before the first byte of the deflate
+ stream. The end-of-block will not be indicated until all of the uncompressed
+ data from that block has been written to strm->next_out. The number of
+ unused bits may in general be greater than seven, except when bit 7 of
+ data_type is set, in which case the number of unused bits will be less than
+ eight. data_type is set as noted here every time inflate() returns for all
+ flush options, and so can be used to determine the amount of currently
+ consumed input in bits.
+
+ The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+ end of each deflate block header is reached, before any actual data in that
+ block is decoded. This allows the caller to determine the length of the
+ deflate block header for later use in random access within a deflate block.
+ 256 is added to the value of strm->data_type when inflate() returns
+ immediately after reaching the end of the deflate block header.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step (a
+ single call of inflate), the parameter flush should be set to Z_FINISH. In
+ this case all pending input is processed and all pending output is flushed;
+ avail_out must be large enough to hold all of the uncompressed data for the
+ operation to complete. (The size of the uncompressed data may have been
+ saved by the compressor for this purpose.) The use of Z_FINISH is not
+ required to perform an inflation in one step. However it may be used to
+ inform inflate that a faster approach can be used for the single inflate()
+ call. Z_FINISH also informs inflate to not maintain a sliding window if the
+ stream completes, which reduces inflate's memory footprint. If the stream
+ does not complete, either because not all of the stream is provided or not
+ enough output space is provided, then a sliding window will be allocated and
+ inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+ been used.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the effects of the flush parameter in this implementation are
+ on the return value of inflate() as noted below, when inflate() returns early
+ when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+ memory for a sliding window when Z_FINISH is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the Adler-32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed adler32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically, if requested when
+ initializing with inflateInit2(). Any information contained in the gzip
+ header is not retained, so applications that need that information should
+ instead use raw inflate, see inflateInit2() below, or inflateBack() and
+ perform their own processing of the gzip header and trailer. When processing
+ gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+ producted so far. The CRC-32 is checked against the gzip trailer.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
+ Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may
+ then call inflateSync() to look for a good compression block if a partial
+ recovery of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by the
+ caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute an adler32 check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero), no
+ header crc, and the operating system will be set to 255 (unknown). If a
+ gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but is
+ slow and reduces compression ratio; memLevel=9 uses maximum memory for
+ optimal speed. The default value is 8. See zconf.h for total memory usage
+ as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
+ fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
+ strategy parameter only affects the compression ratio but not the
+ correctness of the compressed output even if it is not set appropriately.
+ Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+ decoder for special applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+ method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+ incompatible with the version assumed by the caller (ZLIB_VERSION). msg is
+ set to null if there is no error message. deflateInit2 does not perform any
+ compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. When using the zlib format, this
+ function must be called immediately after deflateInit, deflateInit2 or
+ deflateReset, and before any call of deflate. When doing raw deflate, this
+ function must be called either before any call of deflate, or immediately
+ after the completion of a deflate block, i.e. after all input has been
+ consumed and all output has been delivered when using any of the flush
+ options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
+ compressor and decompressor must use exactly the same dictionary (see
+ inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size
+ provided in deflateInit or deflateInit2. Thus the strings most likely to be
+ useful should be put at the end of the dictionary, not at the front. In
+ addition, the current implementation of deflate will use at most the window
+ size minus 262 bytes of the provided dictionary.
+
+ Upon return of this function, strm->adler is set to the adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ adler32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if not at a block boundary for raw deflate). deflateSetDictionary does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and can
+ consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state. The
+ stream will keep the same compression level and any other attributes that
+ may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different strategy.
+ If the compression level is changed, the input available so far is
+ compressed with the old level (and may be flushed); the new level will take
+ effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to be
+ compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if
+ strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain));
+/*
+ Fine tune deflate's internal compression parameters. This should only be
+ used by someone who understands the algorithm used by zlib's deflate for
+ searching for the best matching string, and even then only by the most
+ fanatic optimizer trying to squeeze out the last compressed bit for their
+ specific input data. Read the deflate.c source code for the meaning of the
+ max_lazy, good_length, nice_length, and max_chain parameters.
+
+ deflateTune() can be called after deflateInit() or deflateInit2(), and
+ returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit() or
+ deflateInit2(), and after deflateSetHeader(), if used. This would be used
+ to allocate an output buffer for deflation in a single pass, and so would be
+ called before deflate(). If that first deflate() call is provided the
+ sourceLen input bytes, an output buffer allocated to the size returned by
+ deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+ to return Z_STREAM_END. Note that it is possible for the compressed size to
+ be larger than the value returned by deflateBound() if flush options other
+ than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+ unsigned *pending,
+ int *bits));
+/*
+ deflatePending() returns the number of bytes and bits of output that have
+ been generated, but not yet provided in the available output. The bytes not
+ provided would be due to the available output space having being consumed.
+ The number of bits of output not provided are between 0 and 7, where they
+ await more bits to join them in order to fill out a full byte. If pending
+ or bits are Z_NULL, then those values are not set.
+
+ deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+ */
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the bits
+ leftover from a previous deflate stream when appending to it. As such, this
+ function can only be used for raw deflate, and must be used before the first
+ deflate() call after a deflateInit2() or deflateReset(). bits must be less
+ than or equal to 16, and that many of the least significant bits of value
+ will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+ room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ deflateSetHeader() provides gzip header information for when a gzip
+ stream is requested by deflateInit2(). deflateSetHeader() may be called
+ after deflateInit2() or deflateReset() and before the first call of
+ deflate(). The text, time, os, extra field, name, and comment information
+ in the provided gz_header structure are written to the gzip header (xflag is
+ ignored -- the extra flags are set according to the compression level). The
+ caller must assure that, if not Z_NULL, name and comment are terminated with
+ a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+ available there. If hcrc is true, a gzip header crc is included. Note that
+ the current versions of the command-line version of gzip (up through version
+ 1.3.x) do not support header crc's, and will report that it is a "multi-part
+ gzip file" and give up.
+
+ If deflateSetHeader is not used, the default gzip header has text false,
+ the time set to zero, and os set to 255, with no extra, name, or comment
+ fields. The gzip header is returned to the default state by deflateReset().
+
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be zero to request that inflate use the window size in
+ the zlib header of the compressed stream.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an adler32 or a crc32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
+ crc32 instead of an adler32.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit2 does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit2() does not process any header information -- that is
+ deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called at any
+ time to set the dictionary. If the provided dictionary is smaller than the
+ window and there is already data in the window, then the provided dictionary
+ will amend what's there. The application must insure that the dictionary
+ that was used for compression is provided.
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+ Bytef *dictionary,
+ uInt *dictLength));
+/*
+ Returns the sliding dictionary being maintained by inflate. dictLength is
+ set to the number of bytes in the dictionary, and that many bytes are copied
+ to dictionary. dictionary must have enough space, where 32768 bytes is
+ always enough. If inflateGetDictionary() is called with dictionary equal to
+ Z_NULL, then only the dictionary length is returned, and nothing is copied.
+ Similary, if dictLength is Z_NULL, then it is not set.
+
+ inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+ stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a possible full flush point (see above
+ for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+ All full flush points have this pattern, but not all occurrences of this
+ pattern are full flush points.
+
+ inflateSync returns Z_OK if a possible full flush point has been found,
+ Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+ has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+ In the success case, the application may save the current current value of
+ total_in which indicates where valid compressed data was found. In the
+ error case, the application may repeatedly call inflateSync, providing more
+ input each time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state. The
+ stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+ int windowBits));
+/*
+ This function is the same as inflateReset, but it also permits changing
+ the wrap and window size requests. The windowBits parameter is interpreted
+ the same as it is for inflateInit2.
+
+ inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+ the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ This function inserts bits in the inflate input stream. The intent is
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ If bits is negative, then the input stream bit buffer is emptied. Then
+ inflatePrime() can be called again to put bits in the buffer. This is used
+ to clear out bits leftover after feeding inflate a block description prior
+ to feeding inflate codes.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+ This function returns two values, one in the lower 16 bits of the return
+ value, and the other in the remaining upper bits, obtained by shifting the
+ return value down 16 bits. If the upper value is -1 and the lower value is
+ zero, then inflate() is currently decoding information outside of a block.
+ If the upper value is -1 and the lower value is non-zero, then inflate is in
+ the middle of a stored block, with the lower value equaling the number of
+ bytes from the input remaining to copy. If the upper value is not -1, then
+ it is the number of bits back from the current bit position in the input of
+ the code (literal or length/distance pair) currently being processed. In
+ that case the lower value is the number of bytes already emitted for that
+ code.
+
+ A code is being processed if inflate is waiting for more input to complete
+ decoding of the code, or if it has completed decoding but is waiting for
+ more output space to write the literal or match data.
+
+ inflateMark() is used to mark locations in the input data for random
+ access, which may be at bit positions, and to note those cases where the
+ output of a code may span boundaries of random access blocks. The current
+ location in the input stream can be determined from avail_in and data_type
+ as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+ inflateMark returns the value noted above or -1 << 16 if the provided
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ inflateGetHeader() requests that gzip header information be stored in the
+ provided gz_header structure. inflateGetHeader() may be called after
+ inflateInit2() or inflateReset(), and before the first call of inflate().
+ As inflate() processes the gzip stream, head->done is zero until the header
+ is completed, at which time head->done is set to one. If a zlib stream is
+ being decoded, then head->done is set to -1 to indicate that there will be
+ no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
+ used to force inflate() to return immediately after header processing is
+ complete and before any actual data is decompressed.
+
+ The text, time, xflags, and os fields are filled in with the gzip header
+ contents. hcrc is set to true if there is a header CRC. (The header CRC
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ contains the maximum number of bytes to write to extra. Once done is true,
+ extra_len contains the actual extra field length, and extra contains the
+ extra field, or that field truncated if extra_max is less than extra_len.
+ If name is not Z_NULL, then up to name_max characters are written there,
+ terminated with a zero unless the length is greater than name_max. If
+ comment is not Z_NULL, then up to comm_max characters are written there,
+ terminated with a zero unless the length is greater than comm_max. When any
+ of extra, name, or comment are not Z_NULL and the respective field is not
+ present in the header, then that field is set to Z_NULL to signal its
+ absence. This allows the use of deflateSetHeader() with the returned
+ structure to duplicate the header. However if those fields are set to
+ allocated memory, then the application will need to save those pointers
+ elsewhere so that they can be eventually freed.
+
+ If inflateGetHeader is not used, then the header information is simply
+ discarded. The header is always checked for validity, including the header
+ CRC if present. inflateReset() will reset the process to discard the header
+ information. The application would need to call inflateGetHeader() again to
+ retrieve the header from the next gzip stream.
+
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+ allocated, or Z_VERSION_ERROR if the version of the library does not match
+ the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *,
+ z_const unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is potentially more efficient than
+ inflate() for file i/o applications, in that it avoids copying between the
+ output and the sliding window by simply making the window itself the output
+ buffer. inflate() can be faster on modern CPUs when used with large
+ buffers. inflateBack() trusts the application to not change the output
+ buffer passed by the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free the
+ allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects only
+ the raw deflate stream to decompress. This is different from the normal
+ behavior of inflate(), which expects either a zlib or gzip header and
+ trailer around the deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero--buf is ignored in that
+ case--and inflateBack() will return a buffer error. inflateBack() will call
+ out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
+ should return zero on success, or non-zero on failure. If out() returns
+ non-zero, inflateBack() will return with an error. Neither in() nor out()
+ are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+ in the deflate stream (in which case strm->msg is set to indicate the nature
+ of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+ In the case of Z_BUF_ERROR, an input or output error can be distinguished
+ using strm->next_in which will be Z_NULL only if in() returned an error. If
+ strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+ non-zero. (in() will always be called before out(), so strm->next_in is
+ assured to be defined if out() returns non-zero.) Note that inflateBack()
+ cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: DEBUG/ZLIB_DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+#ifndef Z_SOLO
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the basic
+ stream-oriented functions. To simplify the interface, some default options
+ are assumed (compression level and memory usage, standard memory allocation
+ functions). The source code of these utility functions can be modified if
+ you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before a
+ compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit, destLen
+ is the actual size of the uncompressed buffer.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
+ the case where there is not enough room, uncompress() will fill the output
+ buffer with the uncompressed data up to that point.
+*/
+
+ /* gzip file access functions */
+
+/*
+ This library supports reading and writing files in gzip (.gz) format with
+ an interface similar to that of stdio, using the functions that start with
+ "gz". The gzip format is different from the zlib format. gzip is a gzip
+ wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+ Opens a gzip (.gz) file for reading or writing. The mode parameter is as
+ in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+ a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+ compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+ for fixed code compression as in "wb9F". (See the description of
+ deflateInit2 for more information about the strategy parameter.) 'T' will
+ request transparent writing or appending with no compression and not using
+ the gzip format.
+
+ "a" can be used instead of "w" to request that the gzip stream that will
+ be written be appended to the file. "+" will result in an error, since
+ reading and writing to the same gzip file is not supported. The addition of
+ "x" when writing will create the file exclusively, which fails if the file
+ already exists. On systems that support it, the addition of "e" when
+ reading or writing will set the flag to close the file on an execve() call.
+
+ These functions, as well as gzip, will read and decode a sequence of gzip
+ streams in a file. The append function of gzopen() can be used to create
+ such a file. (Also see gzflush() for another way to do this.) When
+ appending, gzopen does not test whether the file begins with a gzip stream,
+ nor does it look for the end of the gzip streams to begin appending. gzopen
+ will simply append a gzip stream to the existing file.
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression. When
+ reading, this will be detected automatically by looking for the magic two-
+ byte gzip header.
+
+ gzopen returns NULL if the file could not be opened, if there was
+ insufficient memory to allocate the gzFile state, or if an invalid mode was
+ specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+ errno can be checked to determine if the reason gzopen failed was that the
+ file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen associates a gzFile with the file descriptor fd. File descriptors
+ are obtained from calls like open, dup, creat, pipe or fileno (if the file
+ has been previously opened with fopen). The mode parameter is as in gzopen.
+
+ The next call of gzclose on the returned gzFile will also close the file
+ descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+ fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+ mode);. The duplicated descriptor should be saved to avoid a leak, since
+ gzdopen does not close fd if it fails. If you are using fileno() to get the
+ file descriptor from a FILE *, then you will have to use dup() to avoid
+ double-close()ing the file descriptor. Both gzclose() and fclose() will
+ close the associated file descriptor, so they need to have different file
+ descriptors.
+
+ gzdopen returns NULL if there was insufficient memory to allocate the
+ gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+ provided, or '+' was provided), or if fd is -1. The file descriptor is not
+ used until the next gz* read, write, seek, or close operation, so gzdopen
+ will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+ Set the internal buffer size used by this library's functions. The
+ default buffer size is 8192 bytes. This function must be called after
+ gzopen() or gzdopen(), and before any other calls that read or write the
+ file. The buffer memory allocation is always deferred to the first read or
+ write. Two buffers are allocated, either both of the specified size when
+ writing, or one of the specified size and the other twice that size when
+ reading. A larger buffer size of, for example, 64K or 128K bytes will
+ noticeably increase the speed of decompression (reading).
+
+ The new buffer size also affects the maximum length for gzprintf().
+
+ gzbuffer() returns 0 on success, or -1 on failure, such as being called
+ too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file. If
+ the input file is not in gzip format, gzread copies the given number of
+ bytes into the buffer directly from the file.
+
+ After reaching the end of a gzip stream in the input, gzread will continue
+ to read, looking for another gzip stream. Any number of gzip streams may be
+ concatenated in the input file, and will all be decompressed by gzread().
+ If something other than a gzip stream is encountered after a gzip stream,
+ that remaining trailing garbage is ignored (and no error is returned).
+
+ gzread can be used to read a gzip file that is being concurrently written.
+ Upon reaching the end of the input, gzread will return with the available
+ data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+ gzclearerr can be used to clear the end of file indicator in order to permit
+ gzread to be tried again. Z_OK indicates that a gzip stream was completed
+ on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
+ middle of a gzip stream. Note that gzread does not return -1 in the event
+ of an incomplete gzip stream. This error is deferred until gzclose(), which
+ will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+ stream. Alternatively, gzerror can be used before gzclose to detect this
+ case.
+
+ gzread returns the number of uncompressed bytes actually read, less than
+ len for end of file, or -1 for error.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes written or 0 in case of
+ error.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the arguments to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written, or 0 in case of error. The number of
+ uncompressed bytes written is limited to 8191, or one less than the buffer
+ size given to gzbuffer(). The caller should assure that this limit is not
+ exceeded. If it is exceeded, then gzprintf() will return an error (0) with
+ nothing written. In this case, there may also be a buffer overflow with
+ unpredictable consequences, which is possible only if zlib was compiled with
+ the insecure functions sprintf() or vsprintf() because the secure snprintf()
+ or vsnprintf() functions were not available. This can be determined using
+ zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or a
+ newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. If any characters are read or if len == 1, the
+ string is terminated with a null character. If no characters are read due
+ to an end-of-file or len < 1, then the buffer is left untouched.
+
+ gzgets returns buf which is a null-terminated string, or it returns NULL
+ for end-of-file or in case of error. If there was an error, the contents at
+ buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file. gzputc
+ returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte or -1
+ in case of end of file or error. This is implemented as a macro for speed.
+ As such, it does not do all of the checking the other functions do. I.e.
+ it does not check to see if file is NULL, nor whether the structure file
+ points to has been clobbered or not.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read as the first character
+ on the next read. At least one character of push-back is allowed.
+ gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
+ fail if c is -1, and may fail if a character has been pushed but not read
+ yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
+ output buffer size of pushed characters is allowed. (See gzbuffer above.)
+ The pushed character will be discarded if the stream is repositioned with
+ gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter flush
+ is as in the deflate() function. The return value is the zlib error number
+ (see function gzerror below). gzflush is only permitted when writing.
+
+ If the flush parameter is Z_FINISH, the remaining data is written and the
+ gzip stream is completed in the output. If gzwrite() is called again, a new
+ gzip stream will be started in the output. gzread() is able to read such
+ concatented gzip streams.
+
+ gzflush should be called only when strictly necessary because it will
+ degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+
+ Returns the starting position for the next gzread or gzwrite on the given
+ compressed file. This position represents a number of bytes in the
+ uncompressed data stream, and is zero when starting, even if appending or
+ reading a gzip stream from the middle of a file using gzdopen().
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+ Returns the current offset in the file being read or written. This offset
+ includes the count of bytes that precede the gzip stream, for example when
+ appending or when using gzdopen() for reading. When reading, the offset
+ does not include as yet unused buffered input. This information can be used
+ for a progress indicator. On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns true (1) if the end-of-file indicator has been set while reading,
+ false (0) otherwise. Note that the end-of-file indicator is set only if the
+ read tried to go past the end of the input, but came up short. Therefore,
+ just like feof(), gzeof() may return false even if there is no more data to
+ read, in the event that the last read request was for the exact number of
+ bytes remaining in the input file. This will happen if the input file size
+ is an exact multiple of the buffer size.
+
+ If gzeof() returns true, then the read functions will return no more data,
+ unless the end-of-file indicator is reset by gzclearerr() and the input file
+ has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns true (1) if file is being copied directly while reading, or false
+ (0) if file is a gzip stream being decompressed.
+
+ If the input file is empty, gzdirect() will return true, since the input
+ does not contain a gzip stream.
+
+ If gzdirect() is used immediately after gzopen() or gzdopen() it will
+ cause buffers to be allocated to allow reading the file to determine if it
+ is a gzip file. Therefore if gzbuffer() is used, it should be called before
+ gzdirect().
+
+ When writing, gzdirect() returns true (1) if transparent writing was
+ requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
+ gzdirect() is not needed when writing. Transparent writing must be
+ explicitly requested, so the application already knows the answer. When
+ linking statically, using gzdirect() will include all of the zlib code for
+ gzip file reading and decompression, which may not be desired.)
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file and
+ deallocates the (de)compression state. Note that once file is closed, you
+ cannot call gzerror with file, since its structures have been deallocated.
+ gzclose must not be called more than once on the same file, just as free
+ must not be called more than once on the same allocation.
+
+ gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+ file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+ last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+ Same as gzclose(), but gzclose_r() is only for use when reading, and
+ gzclose_w() is only for use when writing or appending. The advantage to
+ using these instead of gzclose() is that they avoid linking in zlib
+ compression or decompression code that is not used when only reading or only
+ writing respectively. If gzclose() is used, then both compression and
+ decompression code will be included the application when linking to a static
+ zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the given
+ compressed file. errnum is set to zlib error number. If an error occurred
+ in the file system and not in the compression library, errnum is set to
+ Z_ERRNO and the application may consult errno to get the exact error code.
+
+ The application must not modify the returned string. Future calls to
+ this function may invalidate the previously returned string. If file is
+ closed, then the string previously returned by gzerror will no longer be
+ available.
+
+ gzerror() should be used to distinguish errors from end-of-file for those
+ functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+#endif /* !Z_SOLO */
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the compression
+ library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is Z_NULL, this function returns the
+ required initial value for the checksum.
+
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster.
+
+ Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+ z_off_t len2));
+
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
+ that the z_off_t type (like off_t) is a signed integer. If len2 is
+ negative, the result has no meaning or utility.
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running CRC-32 with the bytes buf[0..len-1] and return the
+ updated CRC-32. If buf is Z_NULL, this function returns the required
+ initial value for the crc. Pre- and post-conditioning (one's complement) is
+ performed within this function so it shouldn't be done by the application.
+
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+ (int)sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, (int)sizeof(z_stream))
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure. Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro. The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously. They can
+ * only be used by the gzgetc() macro. You have been warned.
+ */
+struct gzFile_s {
+ unsigned have;
+ unsigned char *next;
+ z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+# define z_gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#else
+# define gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+# ifdef Z_PREFIX_SET
+# define z_gzopen z_gzopen64
+# define z_gzseek z_gzseek64
+# define z_gztell z_gztell64
+# define z_gzoffset z_gzoffset64
+# define z_adler32_combine z_adler32_combine64
+# define z_crc32_combine z_crc32_combine64
+# else
+# define gzopen gzopen64
+# define gzseek gzseek64
+# define gztell gztell64
+# define gzoffset gzoffset64
+# define adler32_combine adler32_combine64
+# define crc32_combine crc32_combine64
+# endif
+# ifndef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+# endif
+#else
+ ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+#else /* Z_SOLO */
+
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
+/* hack for buggy compilers */
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;};
+#endif
+
+/* undocumented functions */
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
+ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
+#if defined(_WIN32) && !defined(Z_SOLO)
+ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
+ const char *mode));
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+ const char *format,
+ va_list va));
+# endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/lib/zlib_inflate/zutil.c b/lib/zlib_inflate/zutil.c
new file mode 100644
index 0000000..5f21a24
--- /dev/null
+++ b/lib/zlib_inflate/zutil.c
@@ -0,0 +1,326 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+#ifndef Z_SOLO
+/* Comment because LK does not contain gzguts.h */
+// # include "gzguts.h"
+#endif
+
+#ifndef NO_DUMMY_DECL
+struct internal_state {int dummy;}; /* for buggy compilers */
+#endif
+
+z_const char * const z_errmsg[10] = {
+"need dictionary", /* Z_NEED_DICT 2 */
+"stream end", /* Z_STREAM_END 1 */
+"", /* Z_OK 0 */
+"file error", /* Z_ERRNO (-1) */
+"stream error", /* Z_STREAM_ERROR (-2) */
+"data error", /* Z_DATA_ERROR (-3) */
+"insufficient memory", /* Z_MEM_ERROR (-4) */
+"buffer error", /* Z_BUF_ERROR (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+ return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+ uLong flags;
+
+ flags = 0;
+ switch ((int)(sizeof(uInt))) {
+ case 2: break;
+ case 4: flags += 1; break;
+ case 8: flags += 2; break;
+ default: flags += 3;
+ }
+ switch ((int)(sizeof(uLong))) {
+ case 2: break;
+ case 4: flags += 1 << 2; break;
+ case 8: flags += 2 << 2; break;
+ default: flags += 3 << 2;
+ }
+ switch ((int)(sizeof(voidpf))) {
+ case 2: break;
+ case 4: flags += 1 << 4; break;
+ case 8: flags += 2 << 4; break;
+ default: flags += 3 << 4;
+ }
+ switch ((int)(sizeof(z_off_t))) {
+ case 2: break;
+ case 4: flags += 1 << 6; break;
+ case 8: flags += 2 << 6; break;
+ default: flags += 3 << 6;
+ }
+/* replace DEBUG with ZLIB_DEBUG since the former is already used in lk */
+#ifdef ZLIB_DEBUG
+ flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+ flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+ flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+ flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+ flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+ flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+ flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+ flags += 1L << 20;
+#endif
+#ifdef FASTEST
+ flags += 1L << 21;
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifdef NO_vsnprintf
+ flags += 1L << 25;
+# ifdef HAS_vsprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_vsnprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#else
+ flags += 1L << 24;
+# ifdef NO_snprintf
+ flags += 1L << 25;
+# ifdef HAS_sprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_snprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#endif
+ return flags;
+}
+
+#ifdef ZLIB_DEBUG
+
+# ifndef verbose
+# define verbose 0
+# endif
+int ZLIB_INTERNAL z_verbose = verbose;
+
+void ZLIB_INTERNAL z_error (m)
+ char *m;
+{
+ fprintf(stderr, "%s\n", m);
+ exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+ int err;
+{
+ return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+ /* The Microsoft C Run-Time Library for Windows CE doesn't have
+ * errno. We define it as a global variable to simplify porting.
+ * Its value is always 0 and should not be used.
+ */
+ int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void ZLIB_INTERNAL zmemcpy(dest, source, len)
+ Bytef* dest;
+ const Bytef* source;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = *source++; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+
+int ZLIB_INTERNAL zmemcmp(s1, s2, len)
+ const Bytef* s1;
+ const Bytef* s2;
+ uInt len;
+{
+ uInt j;
+
+ for (j = 0; j < len; j++) {
+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+ }
+ return 0;
+}
+
+void ZLIB_INTERNAL zmemzero(dest, len)
+ Bytef* dest;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = 0; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+#endif
+
+#ifndef Z_SOLO
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+ voidpf org_ptr;
+ voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ voidpf buf = opaque; /* just to make some compilers happy */
+ ulg bsize = (ulg)items*size;
+
+ /* If we allocate less than 65520 bytes, we assume that farmalloc
+ * will return a usable pointer which doesn't have to be normalized.
+ */
+ if (bsize < 65520L) {
+ buf = farmalloc(bsize);
+ if (*(ush*)&buf != 0) return buf;
+ } else {
+ buf = farmalloc(bsize + 16L);
+ }
+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+ table[next_ptr].org_ptr = buf;
+
+ /* Normalize the pointer to seg:0 */
+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+ *(ush*)&buf = 0;
+ table[next_ptr++].new_ptr = buf;
+ return buf;
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+ int n;
+ if (*(ush*)&ptr != 0) { /* object < 64K */
+ farfree(ptr);
+ return;
+ }
+ /* Find the original pointer */
+ for (n = 0; n < next_ptr; n++) {
+ if (ptr != table[n].new_ptr) continue;
+
+ farfree(table[n].org_ptr);
+ while (++n < next_ptr) {
+ table[n-1] = table[n];
+ }
+ next_ptr--;
+ return;
+ }
+ ptr = opaque; /* just to make some compilers happy */
+ Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+# define _halloc halloc
+# define _hfree hfree
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ return _halloc((long)items, size);
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp malloc OF((uInt size));
+extern voidp calloc OF((uInt items, uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
+ voidpf opaque;
+ unsigned items;
+ unsigned size;
+{
+ if (opaque) items += size - size; /* make compiler happy */
+ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+ (voidpf)calloc(items, size);
+}
+
+void ZLIB_INTERNAL zcfree (opaque, ptr)
+ voidpf opaque;
+ voidpf ptr;
+{
+ free(ptr);
+ if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
+
+#endif /* !Z_SOLO */
diff --git a/lib/zlib_inflate/zutil.h b/lib/zlib_inflate/zutil.h
new file mode 100644
index 0000000..4de61bb
--- /dev/null
+++ b/lib/zlib_inflate/zutil.h
@@ -0,0 +1,254 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#ifdef HAVE_HIDDEN
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+# define ZLIB_INTERNAL
+#endif
+
+#include "zlib.h"
+
+#if defined(STDC) && !defined(Z_SOLO)
+# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
+# include <stddef.h>
+# endif
+# include <string.h>
+# include <stdlib.h>
+#endif
+
+#ifdef Z_SOLO
+ typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+ return (strm->msg = ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+ /* common constants */
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+ /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+# define OS_CODE 0x00
+# ifndef Z_SOLO
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include <alloc.h>
+# endif
+# else /* MSC or DJGPP */
+# include <malloc.h>
+# endif
+# endif
+#endif
+
+#ifdef AMIGA
+# define OS_CODE 0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+# define OS_CODE 0x02
+# define F_OPEN(name, mode) \
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+# define OS_CODE 0x05
+#endif
+
+#ifdef OS2
+# define OS_CODE 0x06
+# if defined(M_I86) && !defined(Z_SOLO)
+# include <malloc.h>
+# endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+# define OS_CODE 0x07
+# ifndef Z_SOLO
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
+# endif
+# endif
+#endif
+
+#ifdef TOPS20
+# define OS_CODE 0x0a
+#endif
+
+#ifdef WIN32
+# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
+# define OS_CODE 0x0b
+# endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+# define OS_CODE 0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
+# if defined(_WIN32_WCE)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# ifndef _PTRDIFF_T_DEFINED
+ typedef int ptrdiff_t;
+# define _PTRDIFF_T_DEFINED
+# endif
+# else
+# define fdopen(fd,type) _fdopen(fd,type)
+# endif
+#endif
+
+#if defined(__BORLANDC__) && !defined(MSDOS)
+ #pragma warn -8004
+ #pragma warn -8008
+ #pragma warn -8066
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_WIN32) && \
+ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#endif
+
+ /* common defaults */
+
+#ifndef OS_CODE
+# define OS_CODE 0x03 /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+# define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+ /* functions */
+
+#if defined(pyr) || defined(Z_SOLO)
+# define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+ * You may have to use the same strategy for Borland C (untested).
+ * The __SC__ check is for Symantec.
+ */
+# define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+# define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+# define zmemcpy _fmemcpy
+# define zmemcmp _fmemcmp
+# define zmemzero(dest, len) _fmemset(dest, 0, len)
+# else
+# define zmemcpy memcpy
+# define zmemcmp memcmp
+# define zmemzero(dest, len) memset(dest, 0, len)
+# endif
+#else
+ void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+/* replace DEBUG with ZLIB_DEBUG since the former is already used in lk. */
+#ifdef ZLIB_DEBUG
+# include <stdio.h>
+ extern int ZLIB_INTERNAL z_verbose;
+ extern void ZLIB_INTERNAL z_error OF((char *m));
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+#ifndef Z_SOLO
+ voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+ unsigned size));
+ void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
+#endif
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+/* Reverse the bytes in a 32-bit value */
+#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+#endif /* ZUTIL_H */
diff --git a/makefile b/makefile
index 252903e..1e818a8 100644
--- a/makefile
+++ b/makefile
@@ -105,6 +105,10 @@
endif
endif
+ifeq ($(USER_BUILD_VARIANT),true)
+ DEFINES += USER_BUILD_VARIANT=1
+endif
+
# these need to be filled out by the project/target/platform rules.mk files
TARGET :=
PLATFORM :=
diff --git a/platform/init.c b/platform/init.c
index 34c5726..9919b22 100644
--- a/platform/init.c
+++ b/platform/init.c
@@ -145,3 +145,12 @@
{
return 0;
}
+
+__WEAK uint32_t check_alarm_boot()
+{
+ return 0;
+}
+__WEAK uint32_t platform_get_max_periph()
+{
+ return 128;
+}
diff --git a/platform/mdm9640/include/platform/iomap.h b/platform/mdm9640/include/platform/iomap.h
index 3d63543..c5eab42 100644
--- a/platform/mdm9640/include/platform/iomap.h
+++ b/platform/mdm9640/include/platform/iomap.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 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
@@ -193,4 +193,7 @@
/* QPIC DISPLAY */
#define QPIC_BASE 0x7980000
#define APCS_ALIAS0_IPC_INTERRUPT 0xB011008
+/* eMMC Display */
+#define TLMM_EBI2_EMMC_GPIO_CFG 0x01111000
+#define EBI2_BOOT_SELECT 0x2
#endif
diff --git a/platform/msm8909/include/platform/iomap.h b/platform/msm8909/include/platform/iomap.h
index e2a66fe..bca7c54 100644
--- a/platform/msm8909/include/platform/iomap.h
+++ b/platform/msm8909/include/platform/iomap.h
@@ -280,4 +280,5 @@
#define SECURITY_CONTROL_CORE_FEATURE_CONFIG0 0x0005E004
/* EBI2 */
#define TLMM_EBI2_EMMC_GPIO_CFG (TLMM_BASE_ADDR + 0x00111000)
+#define TCSR_BOOT_MISC_DETECT 0x193D100
#endif
diff --git a/platform/msm8916/include/platform/iomap.h b/platform/msm8916/include/platform/iomap.h
index fd56c0e..2d9197c 100644
--- a/platform/msm8916/include/platform/iomap.h
+++ b/platform/msm8916/include/platform/iomap.h
@@ -51,9 +51,6 @@
#define ABOOT_FORCE_RAMDISK_ADDR DDR_START + 0x2000000
#define ABOOT_FORCE_TAGS_ADDR DDR_START + 0x1E00000
-/* 3GB DDR devices consider 0x40000000 as new mem base */
-#define BASE_ADDR_1 0x40000000
-
#define MSM_GIC_DIST_BASE APPS_SS_BASE
#define MSM_GIC_CPU_BASE (APPS_SS_BASE + 0x2000)
#define APPS_APCS_QTMR_AC_BASE (APPS_SS_BASE + 0x00020000)
@@ -265,4 +262,5 @@
#define HS_TIMER_CTRL 0x0BC
#define TCSR_TZ_WONCE 0x193D000
+#define TCSR_BOOT_MISC_DETECT 0x193D100
#endif
diff --git a/platform/msm8916/platform.c b/platform/msm8916/platform.c
index 66c703f..1531b28 100644
--- a/platform/msm8916/platform.c
+++ b/platform/msm8916/platform.c
@@ -39,12 +39,13 @@
#include <board.h>
#include <boot_stats.h>
#include <platform.h>
+#include <target/display.h>
#define MSM_IOMAP_SIZE ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
#define A53_SS_SIZE ((A53_SS_END - A53_SS_BASE)/MB)
/* LK memory - cacheable, write through */
-#define LK_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+#define LK_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \
MMU_MEMORY_AP_READ_WRITE)
/* Peripherals - non-shared device */
@@ -55,6 +56,9 @@
#define COMMON_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+#define SCRATCH_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \
+ MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+
static mmu_section_t mmu_section_table[] = {
/* Physical addr, Virtual addr, Size (in MB), Flags */
{ MEMBASE, MEMBASE, (MEMSIZE / MB), LK_MEMORY},
@@ -62,9 +66,8 @@
{ A53_SS_BASE, A53_SS_BASE, A53_SS_SIZE, IOMAP_MEMORY},
{ SYSTEM_IMEM_BASE, SYSTEM_IMEM_BASE, 1, COMMON_MEMORY},
{ MSM_SHARED_BASE, MSM_SHARED_BASE, 1, COMMON_MEMORY},
- { BASE_ADDR, BASE_ADDR, 90, COMMON_MEMORY},
{ SCRATCH_ADDR, SCRATCH_ADDR, 256, COMMON_MEMORY},
- { BASE_ADDR_1, BASE_ADDR_1, 1024, COMMON_MEMORY},
+ { MIPI_FB_ADDR, MIPI_FB_ADDR, 10, COMMON_MEMORY},
};
@@ -119,7 +122,14 @@
uint32_t i;
uint32_t sections;
uint32_t table_size = ARRAY_SIZE(mmu_section_table);
+ uint32_t ddr_start = get_ddr_start();
+ /*Mapping the ddr start address for loading the kernel about 90 MB*/
+ sections = 90;
+ while(sections--)
+ {
+ arm_mmu_map_section(ddr_start + sections * MB, ddr_start + sections* MB, COMMON_MEMORY);
+ }
/* Configure the MMU page entries for memory read from the
mmu_section_table */
for (i = 0; i < table_size; i++)
@@ -208,30 +218,3 @@
else
return MSM_SHARED_BASE;
}
-uint32_t get_ddr_start()
-{
- uint32_t i;
- ram_partition ptn_entry;
- uint32_t len = 0;
-
- ASSERT(smem_ram_ptable_init_v1());
-
- len = smem_get_ram_ptable_len();
-
- /* Determine the Start addr of the DDR RAM */
- for(i = 0; i < len; i++)
- {
- smem_get_ram_ptable_entry(&ptn_entry, i);
- if(ptn_entry.type == SYS_MEMORY)
- {
- if((ptn_entry.category == SDRAM) ||
- (ptn_entry.category == IMEM))
- {
- /* Check to ensure that start address is 1MB aligned */
- ASSERT((ptn_entry.start & (MB-1)) == 0);
- return ptn_entry.start;
- }
- }
- }
- ASSERT("DDR Start Mem Not found\n");
-}
diff --git a/platform/msm8952/acpuclock.c b/platform/msm8952/acpuclock.c
new file mode 100644
index 0000000..ff25ac0
--- /dev/null
+++ b/platform/msm8952/acpuclock.c
@@ -0,0 +1,287 @@
+/* Copyright (c) 2015, 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 <err.h>
+#include <assert.h>
+#include <debug.h>
+#include <reg.h>
+#include <platform/timer.h>
+#include <platform/iomap.h>
+#include <mmc.h>
+#include <clock.h>
+#include <platform/clock.h>
+#include <platform.h>
+
+void hsusb_clock_init(void)
+{
+ int ret;
+ struct clk *iclk, *cclk;
+
+ ret = clk_get_set_enable("usb_iface_clk", 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set usb_iface_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ ret = clk_get_set_enable("usb_core_clk", 80000000, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set usb_core_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ mdelay(20);
+
+ iclk = clk_get("usb_iface_clk");
+ cclk = clk_get("usb_core_clk");
+
+ clk_disable(iclk);
+ clk_disable(cclk);
+
+ mdelay(20);
+
+ /* Start the block reset for usb */
+ writel(1, USB_HS_BCR);
+
+ mdelay(20);
+
+ /* Take usb block out of reset */
+ writel(0, USB_HS_BCR);
+
+ mdelay(20);
+
+ ret = clk_enable(iclk);
+
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ ret = clk_enable(cclk);
+
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
+ ASSERT(0);
+ }
+}
+
+void clock_init_mmc(uint32_t interface)
+{
+ char clk_name[64];
+ int ret;
+
+ snprintf(clk_name, sizeof(clk_name), "sdc%u_iface_clk", interface);
+
+ /* enable interface clock */
+ ret = clk_get_set_enable(clk_name, 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set sdc1_iface_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+}
+
+/* Configure MMC clock */
+void clock_config_mmc(uint32_t interface, uint32_t freq)
+{
+ int ret = 1;
+ char clk_name[64];
+
+ snprintf(clk_name, sizeof(clk_name), "sdc%u_core_clk", interface);
+
+ if(freq == MMC_CLK_400KHZ)
+ {
+ ret = clk_get_set_enable(clk_name, 400000, 1);
+ }
+ else if(freq == MMC_CLK_50MHZ)
+ {
+ ret = clk_get_set_enable(clk_name, 50000000, 1);
+ }
+ else if(freq == MMC_CLK_177MHZ)
+ {
+ ret = clk_get_set_enable(clk_name, 177770000, 1);
+ }
+ else if(freq == MMC_CLK_192MHZ)
+ {
+ ret = clk_get_set_enable(clk_name, 192000000, 1);
+ }
+ else if(freq == MMC_CLK_200MHZ)
+ {
+ ret = clk_get_set_enable(clk_name, 200000000, 1);
+ }
+ else if(freq == MMC_CLK_400MHZ)
+ {
+ ret = clk_get_set_enable(clk_name, 384000000, 1);
+ }
+ else
+ {
+ dprintf(CRITICAL, "sdc frequency (%u) is not supported\n", freq);
+ ASSERT(0);
+ }
+
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set %s ret = %d\n", clk_name, ret);
+ ASSERT(0);
+ }
+}
+
+/* Configure UART clock based on the UART block id*/
+void clock_config_uart_dm(uint8_t id)
+{
+ int ret;
+ char iclk[64];
+ char cclk[64];
+
+ snprintf(iclk, sizeof(iclk), "uart%u_iface_clk", id);
+ snprintf(cclk, sizeof(cclk), "uart%u_core_clk", id);
+
+ ret = clk_get_set_enable(iclk, 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set %s ret = %d\n", iclk, ret);
+ ASSERT(0);
+ }
+
+ ret = clk_get_set_enable(cclk, 7372800, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set %s ret = %d\n", cclk, ret);
+ ASSERT(0);
+ }
+}
+
+/* Function to asynchronously reset CE.
+ * Function assumes that all the CE clocks are off.
+ */
+static void ce_async_reset(uint8_t instance)
+{
+ /* Start the block reset for CE */
+ writel(1, GCC_CRYPTO_BCR);
+
+ udelay(2);
+
+ /* Take CE block out of reset */
+ writel(0, GCC_CRYPTO_BCR);
+
+ udelay(2);
+}
+
+void clock_ce_enable(uint8_t instance)
+{
+ int ret;
+ char clk_name[64];
+
+ snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
+ ret = clk_get_set_enable(clk_name, 160000000, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set ce%u_src_clk ret = %d\n", instance, ret);
+ ASSERT(0);
+ }
+
+ snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
+ ret = clk_get_set_enable(clk_name, 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set ce%u_core_clk ret = %d\n", instance, ret);
+ ASSERT(0);
+ }
+
+ snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
+ ret = clk_get_set_enable(clk_name, 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set ce%u_ahb_clk ret = %d\n", instance, ret);
+ ASSERT(0);
+ }
+
+ snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
+ ret = clk_get_set_enable(clk_name, 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set ce%u_axi_clk ret = %d\n", instance, ret);
+ ASSERT(0);
+ }
+
+ /* Wait for 48 * #pipes cycles.
+ * This is necessary as immediately after an access control reset (boot up)
+ * or a debug re-enable, the Crypto core sequentially clears its internal
+ * pipe key storage memory. If pipe key initialization writes are attempted
+ * during this time, they may be overwritten by the internal clearing logic.
+ */
+ udelay(1);
+
+}
+
+void clock_ce_disable(uint8_t instance)
+{
+ struct clk *ahb_clk;
+ struct clk *cclk;
+ struct clk *axi_clk;
+ struct clk *src_clk;
+ char clk_name[64];
+
+ snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
+ src_clk = clk_get(clk_name);
+
+ snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
+ ahb_clk = clk_get(clk_name);
+
+ snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
+ axi_clk = clk_get(clk_name);
+
+ snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
+ cclk = clk_get(clk_name);
+
+ clk_disable(ahb_clk);
+ clk_disable(axi_clk);
+ clk_disable(cclk);
+ clk_disable(src_clk);
+
+ /* Some delay for the clocks to stabalize. */
+ udelay(1);
+
+}
+
+void clock_config_ce(uint8_t instance)
+{
+ /* Need to enable the clock before disabling since the clk_disable()
+ * has a check to default to nop when the clk_enable() is not called
+ * on that particular clock.
+ */
+ clock_ce_enable(instance);
+
+ clock_ce_disable(instance);
+
+ ce_async_reset(instance);
+
+ clock_ce_enable(instance);
+}
diff --git a/platform/msm8952/gpio.c b/platform/msm8952/gpio.c
new file mode 100644
index 0000000..05b4977
--- /dev/null
+++ b/platform/msm8952/gpio.c
@@ -0,0 +1,72 @@
+/* Copyright (c) 2015, 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 <debug.h>
+#include <reg.h>
+#include <platform/iomap.h>
+#include <platform/gpio.h>
+#include <blsp_qup.h>
+
+void gpio_tlmm_config(uint32_t gpio, uint8_t func,
+ uint8_t dir, uint8_t pull,
+ uint8_t drvstr, uint32_t enable)
+{
+ uint32_t val = 0;
+
+ val |= pull;
+ val |= func << 2;
+ val |= drvstr << 6;
+ val |= enable << 9;
+
+ writel(val, (uint32_t *)GPIO_CONFIG_ADDR(gpio));
+ return;
+}
+
+void gpio_set_dir(uint32_t gpio, uint32_t dir)
+{
+ writel(dir, (uint32_t *)GPIO_IN_OUT_ADDR(gpio));
+
+ return;
+}
+
+uint32_t gpio_status(uint32_t gpio)
+{
+ return readl(GPIO_IN_OUT_ADDR(gpio)) & GPIO_IN;
+}
+
+/* Configure gpio for blsp uart 2 */
+void gpio_config_uart_dm(uint8_t id)
+{
+ /* configure rx gpio */
+ gpio_tlmm_config(5, 2, GPIO_INPUT, GPIO_NO_PULL,
+ GPIO_8MA, GPIO_DISABLE);
+
+ /* configure tx gpio */
+ gpio_tlmm_config(4, 2, GPIO_OUTPUT, GPIO_NO_PULL,
+ GPIO_8MA, GPIO_DISABLE);
+}
diff --git a/platform/msm8952/include/platform/clock.h b/platform/msm8952/include/platform/clock.h
new file mode 100644
index 0000000..c7efe6e
--- /dev/null
+++ b/platform/msm8952/include/platform/clock.h
@@ -0,0 +1,44 @@
+/* Copyright (c) 2015, 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 __MSM8952_CLOCK_H
+#define __MSM8952_CLOCK_H
+
+#include <clock.h>
+#include <clock_lib2.h>
+
+#define UART_DM_CLK_RX_TX_BIT_RATE 0xCC
+
+void platform_clock_init(void);
+
+void clock_init_mmc(uint32_t interface);
+void clock_config_mmc(uint32_t interface, uint32_t freq);
+void clock_config_uart_dm(uint8_t id);
+void hsusb_clock_init(void);
+void clock_config_ce(uint8_t instance);
+#endif
diff --git a/platform/msm8952/include/platform/gpio.h b/platform/msm8952/include/platform/gpio.h
new file mode 100644
index 0000000..b4d12e8
--- /dev/null
+++ b/platform/msm8952/include/platform/gpio.h
@@ -0,0 +1,72 @@
+/* Copyright (c) 2015, 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 __PLATFORM_MSM8952_GPIO_H
+#define __PLATFORM_MSM8952_GPIO_H
+
+#include <bits.h>
+#include <gpio.h>
+
+/* GPIO TLMM: Direction */
+#define GPIO_INPUT 0
+#define GPIO_OUTPUT 1
+
+/* GPIO TLMM: Pullup/Pulldown */
+#define GPIO_NO_PULL 0
+#define GPIO_PULL_DOWN 1
+#define GPIO_KEEPER 2
+#define GPIO_PULL_UP 3
+
+/* GPIO TLMM: Drive Strength */
+#define GPIO_2MA 0
+#define GPIO_4MA 1
+#define GPIO_6MA 2
+#define GPIO_8MA 3
+#define GPIO_10MA 4
+#define GPIO_12MA 5
+#define GPIO_14MA 6
+#define GPIO_16MA 7
+
+/* GPIO TLMM: Status */
+#define GPIO_ENABLE 0
+#define GPIO_DISABLE 1
+
+/* GPIO_IN_OUT register shifts. */
+#define GPIO_IN BIT(0)
+#define GPIO_OUT BIT(1)
+
+void gpio_config_uart_dm(uint8_t id);
+uint32_t gpio_status(uint32_t gpio);
+void gpio_set_dir(uint32_t gpio, uint32_t dir);
+void gpio_tlmm_config(uint32_t gpio,
+ uint8_t func,
+ uint8_t dir,
+ uint8_t pull,
+ uint8_t drvstr,
+ uint32_t enable);
+#endif
diff --git a/platform/msm8952/include/platform/iomap.h b/platform/msm8952/include/platform/iomap.h
new file mode 100644
index 0000000..f4712d7
--- /dev/null
+++ b/platform/msm8952/include/platform/iomap.h
@@ -0,0 +1,149 @@
+/* Copyright (c) 2015, 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 _PLATFORM_MSM8952_IOMAP_H_
+#define _PLATFORM_MSM8952_IOMAP_H_
+
+#define MSM_IOMAP_BASE 0x00000000
+#define MSM_IOMAP_END 0x08000000
+
+#define SDRAM_START_ADDR 0x80000000
+
+#define DDR_START get_ddr_start()
+#define ABOOT_FORCE_KERNEL_ADDR DDR_START + 0x8000
+#define ABOOT_FORCE_KERNEL64_ADDR DDR_START + 0x80000
+#define ABOOT_FORCE_RAMDISK_ADDR DDR_START + 0x2000000
+#define ABOOT_FORCE_TAGS_ADDR DDR_START + 0x1E00000
+
+#define MSM_SHARED_BASE 0x86300000
+#define MSM_SHARED_IMEM_BASE 0x08600000
+
+#define BS_INFO_OFFSET (0x6B0)
+#define BS_INFO_ADDR (MSM_SHARED_IMEM_BASE + BS_INFO_OFFSET)
+
+#define RESTART_REASON_ADDR (MSM_SHARED_IMEM_BASE + 0x65C)
+
+#define APPS_SS_BASE 0x0B000000
+#define APPS_SS_END 0x0B200000
+
+#define MSM_GIC_DIST_BASE APPS_SS_BASE
+#define MSM_GIC_CPU_BASE (APPS_SS_BASE + 0x2000)
+#define APPS_APCS_QTMR_AC_BASE (APPS_SS_BASE + 0x00020000)
+#define APPS_APCS_F0_QTMR_V1_BASE (APPS_SS_BASE + 0x00021000)
+#define QTMR_BASE APPS_APCS_F0_QTMR_V1_BASE
+
+#define PERIPH_SS_BASE 0x07800000
+
+#define MSM_SDC1_BASE (PERIPH_SS_BASE + 0x00024000)
+#define MSM_SDC2_BASE (PERIPH_SS_BASE + 0x00064000)
+
+/* UART */
+#define BLSP1_UART0_BASE (PERIPH_SS_BASE + 0x000AF000)
+#define BLSP1_UART1_BASE (PERIPH_SS_BASE + 0x000B0000)
+#define MSM_USB_BASE (PERIPH_SS_BASE + 0x000DB000)
+
+#define CLK_CTL_BASE 0x1800000
+
+#define SPMI_BASE 0x02000000
+#define SPMI_GENI_BASE (SPMI_BASE + 0xA000)
+#define SPMI_PIC_BASE (SPMI_BASE + 0x01800000)
+#define PMIC_ARB_CORE 0x200F000
+
+#define TLMM_BASE_ADDR 0x1000000
+#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + (x)*0x1000)
+#define GPIO_IN_OUT_ADDR(x) (TLMM_BASE_ADDR + 0x00000004 + (x)*0x1000)
+
+#define MPM2_MPM_CTRL_BASE 0x004A0000
+#define MPM2_MPM_PS_HOLD 0x004AB000
+#define MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL 0x004A3000
+
+/* CRYPTO ENGINE */
+#define MSM_CE1_BASE 0x073A000
+#define MSM_CE1_BAM_BASE 0x0704000
+#define GCC_CRYPTO_BCR (CLK_CTL_BASE + 0x16000)
+#define GCC_CRYPTO_CMD_RCGR (CLK_CTL_BASE + 0x16004)
+#define GCC_CRYPTO_CFG_RCGR (CLK_CTL_BASE + 0x16008)
+#define GCC_CRYPTO_CBCR (CLK_CTL_BASE + 0x1601C)
+#define GCC_CRYPTO_AXI_CBCR (CLK_CTL_BASE + 0x16020)
+#define GCC_CRYPTO_AHB_CBCR (CLK_CTL_BASE + 0x16024)
+
+/* GPLL */
+#define GPLL0_STATUS (CLK_CTL_BASE + 0x2101C)
+#define APCS_GPLL_ENA_VOTE (CLK_CTL_BASE + 0x45000)
+#define APCS_CLOCK_BRANCH_ENA_VOTE (CLK_CTL_BASE + 0x45004)
+#define GPLL4_MODE (CLK_CTL_BASE + 0x24000)
+
+/* SDCC */
+#define SDC1_HDRV_PULL_CTL (TLMM_BASE_ADDR + 0x10A000)
+#define SDCC1_BCR (CLK_CTL_BASE + 0x42000) /* block reset*/
+#define SDCC1_APPS_CBCR (CLK_CTL_BASE + 0x42018) /* branch ontrol */
+#define SDCC1_AHB_CBCR (CLK_CTL_BASE + 0x4201C)
+#define SDCC1_CMD_RCGR (CLK_CTL_BASE + 0x42004) /* cmd */
+#define SDCC1_CFG_RCGR (CLK_CTL_BASE + 0x42008) /* cfg */
+#define SDCC1_M (CLK_CTL_BASE + 0x4200C) /* m */
+#define SDCC1_N (CLK_CTL_BASE + 0x42010) /* n */
+#define SDCC1_D (CLK_CTL_BASE + 0x42014) /* d */
+
+/* SDHCI */
+#define MSM_SDC1_SDHCI_BASE (PERIPH_SS_BASE + 0x00024900)
+#define MSM_SDC2_SDHCI_BASE (PERIPH_SS_BASE + 0x00064900)
+
+#define SDCC_MCI_HC_MODE (0x00000078)
+#define SDCC_HC_PWRCTL_STATUS_REG (0x000000DC)
+#define SDCC_HC_PWRCTL_MASK_REG (0x000000E0)
+#define SDCC_HC_PWRCTL_CLEAR_REG (0x000000E4)
+#define SDCC_HC_PWRCTL_CTL_REG (0x000000E8)
+
+#define SDCC2_BCR (CLK_CTL_BASE + 0x43000) /* block reset */
+#define SDCC2_APPS_CBCR (CLK_CTL_BASE + 0x43018) /* branch control */
+#define SDCC2_AHB_CBCR (CLK_CTL_BASE + 0x4301C)
+#define SDCC2_CMD_RCGR (CLK_CTL_BASE + 0x43004) /* cmd */
+#define SDCC2_CFG_RCGR (CLK_CTL_BASE + 0x43008) /* cfg */
+#define SDCC2_M (CLK_CTL_BASE + 0x4300C) /* m */
+#define SDCC2_N (CLK_CTL_BASE + 0x43010) /* n */
+#define SDCC2_D (CLK_CTL_BASE + 0x43014) /* d */
+
+/* UART */
+#define BLSP1_AHB_CBCR (CLK_CTL_BASE + 0x1008)
+#define BLSP1_UART2_APPS_CBCR (CLK_CTL_BASE + 0x302C)
+#define BLSP1_UART2_APPS_CMD_RCGR (CLK_CTL_BASE + 0x3034)
+#define BLSP1_UART2_APPS_CFG_RCGR (CLK_CTL_BASE + 0x3038)
+#define BLSP1_UART2_APPS_M (CLK_CTL_BASE + 0x303C)
+#define BLSP1_UART2_APPS_N (CLK_CTL_BASE + 0x3040)
+#define BLSP1_UART2_APPS_D (CLK_CTL_BASE + 0x3044)
+
+/* USB */
+#define USB_HS_BCR (CLK_CTL_BASE + 0x41000)
+#define USB_HS_SYSTEM_CBCR (CLK_CTL_BASE + 0x41004)
+#define USB_HS_AHB_CBCR (CLK_CTL_BASE + 0x41008)
+#define USB_HS_SYSTEM_CMD_RCGR (CLK_CTL_BASE + 0x41010)
+#define USB_HS_SYSTEM_CFG_RCGR (CLK_CTL_BASE + 0x41014)
+
+#define TCSR_TZ_WONCE 0x193D000
+#define TCSR_BOOT_MISC_DETECT 0x193D100
+#endif
diff --git a/platform/thulium/include/platform/irqs.h b/platform/msm8952/include/platform/irqs.h
similarity index 64%
copy from platform/thulium/include/platform/irqs.h
copy to platform/msm8952/include/platform/irqs.h
index 696c83f..810f113 100644
--- a/platform/thulium/include/platform/irqs.h
+++ b/platform/msm8952/include/platform/irqs.h
@@ -1,17 +1,17 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
-
+/* Copyright (c) 2015, 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, Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
+ * * 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
@@ -26,9 +26,8 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
-#ifndef __IRQS_THULIUM_H
-#define __IRQS_THULIUM_H
+#ifndef __IRQS_MSM8952_H
+#define __IRQS_MSM8952_H
/* MSM ACPU Interrupt Numbers */
@@ -43,23 +42,18 @@
#define INT_QTMR_NON_SECURE_PHY_TIMER_EXP (GIC_PPI_START + 3)
#define INT_QTMR_VIRTUAL_TIMER_EXP (GIC_PPI_START + 4)
-#define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP (GIC_SPI_START + 31)
+#define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP (GIC_SPI_START + 257)
-#define USB30_EE1_IRQ (GIC_SPI_START + 131)
-
-#define GLINK_IPC_IRQ (GIC_SPI_START + 168)
-
-/* Retrofit universal macro names */
-#define INT_USB_HS USB30_EE1_IRQ
-
-#define SDCC1_PWRCTL_IRQ (GIC_SPI_START + 134)
+#define USB1_HS_BAM_IRQ (GIC_SPI_START + 135)
+#define USB1_HS_IRQ (GIC_SPI_START + 134)
+#define SDCC1_PWRCTL_IRQ (GIC_SPI_START + 138)
#define SDCC2_PWRCTL_IRQ (GIC_SPI_START + 221)
-#define UFS_IRQ (GIC_SPI_START + 265)
+/* Retrofit universal macro names */
+#define INT_USB_HS USB1_HS_IRQ
-#define EE0_KRAIT_HLOS_SPMI_PERIPH_IRQ (GIC_SPI_START + 265)
+#define EE0_KRAIT_HLOS_SPMI_PERIPH_IRQ (GIC_SPI_START + 190)
-/* Fix this: where this comes from? */
#define NR_MSM_IRQS 256
#define NR_GPIO_IRQS 173
#define NR_BOARD_IRQS 0
@@ -67,4 +61,4 @@
#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + \
NR_BOARD_IRQS)
-#endif /* __IRQS_THULIUM_H */
+#endif /* __IRQS_MSM8952_H */
diff --git a/platform/msm8952/msm8952-clock.c b/platform/msm8952/msm8952-clock.c
new file mode 100644
index 0000000..f464cc8
--- /dev/null
+++ b/platform/msm8952/msm8952-clock.c
@@ -0,0 +1,418 @@
+/* Copyright (c) 2015, 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 <assert.h>
+#include <reg.h>
+#include <err.h>
+#include <clock.h>
+#include <clock_pll.h>
+#include <clock_lib2.h>
+#include <platform/clock.h>
+#include <platform/iomap.h>
+#include <platform.h>
+
+/* Mux source select values */
+#define cxo_source_val 0
+#define gpll0_source_val 1
+#define gpll4_source_val 2
+#define cxo_mm_source_val 0
+#define gpll0_mm_source_val 1
+
+struct clk_freq_tbl rcg_dummy_freq = F_END;
+
+
+/* Clock Operations */
+static struct clk_ops clk_ops_branch =
+{
+ .enable = clock_lib2_branch_clk_enable,
+ .disable = clock_lib2_branch_clk_disable,
+ .set_rate = clock_lib2_branch_set_rate,
+};
+
+static struct clk_ops clk_ops_rcg_mnd =
+{
+ .enable = clock_lib2_rcg_enable,
+ .set_rate = clock_lib2_rcg_set_rate,
+};
+
+static struct clk_ops clk_ops_rcg =
+{
+ .enable = clock_lib2_rcg_enable,
+ .set_rate = clock_lib2_rcg_set_rate,
+};
+
+static struct clk_ops clk_ops_cxo =
+{
+ .enable = cxo_clk_enable,
+ .disable = cxo_clk_disable,
+};
+
+static struct clk_ops clk_ops_pll_vote =
+{
+ .enable = pll_vote_clk_enable,
+ .disable = pll_vote_clk_disable,
+ .auto_off = pll_vote_clk_disable,
+ .is_enabled = pll_vote_clk_is_enabled,
+};
+
+static struct clk_ops clk_ops_vote =
+{
+ .enable = clock_lib2_vote_clk_enable,
+ .disable = clock_lib2_vote_clk_disable,
+};
+
+/* Clock Sources */
+static struct fixed_clk cxo_clk_src =
+{
+ .c = {
+ .rate = 19200000,
+ .dbg_name = "cxo_clk_src",
+ .ops = &clk_ops_cxo,
+ },
+};
+
+static struct pll_vote_clk gpll0_clk_src =
+{
+ .en_reg = (void *) APCS_GPLL_ENA_VOTE,
+ .en_mask = BIT(0),
+ .status_reg = (void *) GPLL0_STATUS,
+ .status_mask = BIT(17),
+ .parent = &cxo_clk_src.c,
+
+ .c = {
+ .rate = 800000000,
+ .dbg_name = "gpll0_clk_src",
+ .ops = &clk_ops_pll_vote,
+ },
+};
+
+static struct pll_vote_clk gpll4_clk_src =
+{
+ .en_reg = (void *) APCS_GPLL_ENA_VOTE,
+ .en_mask = BIT(5),
+ .status_reg = (void *) GPLL4_MODE,
+ .status_mask = BIT(30),
+ .parent = &cxo_clk_src.c,
+
+ .c = {
+ .rate = 1152000000,
+ .dbg_name = "gpll4_clk_src",
+ .ops = &clk_ops_pll_vote,
+ },
+};
+
+/* SDCC Clocks */
+static struct clk_freq_tbl ftbl_gcc_sdcc1_apps_clk[] =
+{
+ F( 144000, cxo, 16, 3, 25),
+ F( 400000, cxo, 12, 1, 4),
+ F( 20000000, gpll0, 10, 1, 4),
+ F( 25000000, gpll0, 16, 1, 2),
+ F( 50000000, gpll0, 16, 0, 0),
+ F(100000000, gpll0, 8, 0, 0),
+ F(177770000, gpll0, 4.5, 0, 0),
+ F(192000000, gpll0, 6, 0, 0),
+ F(384000000, gpll4, 3, 0, 0),
+ F_END
+};
+
+static struct rcg_clk sdcc1_apps_clk_src =
+{
+ .cmd_reg = (uint32_t *) SDCC1_CMD_RCGR,
+ .cfg_reg = (uint32_t *) SDCC1_CFG_RCGR,
+ .m_reg = (uint32_t *) SDCC1_M,
+ .n_reg = (uint32_t *) SDCC1_N,
+ .d_reg = (uint32_t *) SDCC1_D,
+
+ .set_rate = clock_lib2_rcg_set_rate_mnd,
+ .freq_tbl = ftbl_gcc_sdcc1_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+
+ .c = {
+ .dbg_name = "sdc1_clk",
+ .ops = &clk_ops_rcg_mnd,
+ },
+};
+
+static struct branch_clk gcc_sdcc1_apps_clk =
+{
+ .cbcr_reg = (uint32_t *) SDCC1_APPS_CBCR,
+ .parent = &sdcc1_apps_clk_src.c,
+
+ .c = {
+ .dbg_name = "gcc_sdcc1_apps_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct branch_clk gcc_sdcc1_ahb_clk =
+{
+ .cbcr_reg = (uint32_t *) SDCC1_AHB_CBCR,
+ .has_sibling = 1,
+
+ .c = {
+ .dbg_name = "gcc_sdcc1_ahb_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_sdcc2_apps_clk[] =
+{
+ F( 144000, cxo, 16, 3, 25),
+ F( 400000, cxo, 12, 1, 4),
+ F( 20000000, gpll0, 10, 1, 4),
+ F( 25000000, gpll0, 16, 1, 2),
+ F( 50000000, gpll0, 16, 0, 0),
+ F(100000000, gpll0, 8, 0, 0),
+ F(177770000, gpll0, 4.5, 0, 0),
+ F(200000000, gpll0, 4, 0, 0),
+ F_END
+};
+
+static struct rcg_clk sdcc2_apps_clk_src =
+{
+ .cmd_reg = (uint32_t *) SDCC2_CMD_RCGR,
+ .cfg_reg = (uint32_t *) SDCC2_CFG_RCGR,
+ .m_reg = (uint32_t *) SDCC2_M,
+ .n_reg = (uint32_t *) SDCC2_N,
+ .d_reg = (uint32_t *) SDCC2_D,
+
+ .set_rate = clock_lib2_rcg_set_rate_mnd,
+ .freq_tbl = ftbl_gcc_sdcc2_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+
+ .c = {
+ .dbg_name = "sdc2_clk",
+ .ops = &clk_ops_rcg_mnd,
+ },
+};
+
+static struct branch_clk gcc_sdcc2_apps_clk =
+{
+ .cbcr_reg = (uint32_t *) SDCC2_APPS_CBCR,
+ .parent = &sdcc2_apps_clk_src.c,
+
+ .c = {
+ .dbg_name = "gcc_sdcc2_apps_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct branch_clk gcc_sdcc2_ahb_clk =
+{
+ .cbcr_reg = (uint32_t *) SDCC2_AHB_CBCR,
+ .has_sibling = 1,
+
+ .c = {
+ .dbg_name = "gcc_sdcc2_ahb_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+/* UART Clocks */
+static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart1_2_apps_clk[] =
+{
+ F( 3686400, gpll0, 1, 72, 15625),
+ F( 7372800, gpll0, 1, 144, 15625),
+ F(14745600, gpll0, 1, 288, 15625),
+ F(16000000, gpll0, 10, 1, 5),
+ F(19200000, cxo, 1, 0, 0),
+ F(24000000, gpll0, 1, 3, 100),
+ F(25000000, gpll0, 16, 1, 2),
+ F(32000000, gpll0, 1, 1, 25),
+ F(40000000, gpll0, 1, 1, 20),
+ F(46400000, gpll0, 1, 29, 500),
+ F(48000000, gpll0, 1, 3, 50),
+ F(51200000, gpll0, 1, 8, 125),
+ F(56000000, gpll0, 1, 7, 100),
+ F(58982400, gpll0, 1,1152, 15625),
+ F(60000000, gpll0, 1, 3, 40),
+ F_END
+};
+
+static struct rcg_clk blsp1_uart2_apps_clk_src =
+{
+ .cmd_reg = (uint32_t *) BLSP1_UART2_APPS_CMD_RCGR,
+ .cfg_reg = (uint32_t *) BLSP1_UART2_APPS_CFG_RCGR,
+ .m_reg = (uint32_t *) BLSP1_UART2_APPS_M,
+ .n_reg = (uint32_t *) BLSP1_UART2_APPS_N,
+ .d_reg = (uint32_t *) BLSP1_UART2_APPS_D,
+
+ .set_rate = clock_lib2_rcg_set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_2_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+
+ .c = {
+ .dbg_name = "blsp1_uart2_apps_clk",
+ .ops = &clk_ops_rcg_mnd,
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart2_apps_clk =
+{
+ .cbcr_reg = (uint32_t *) BLSP1_UART2_APPS_CBCR,
+ .parent = &blsp1_uart2_apps_clk_src.c,
+
+ .c = {
+ .dbg_name = "gcc_blsp1_uart2_apps_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct vote_clk gcc_blsp1_ahb_clk = {
+ .cbcr_reg = (uint32_t *) BLSP1_AHB_CBCR,
+ .vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(10),
+
+ .c = {
+ .dbg_name = "gcc_blsp1_ahb_clk",
+ .ops = &clk_ops_vote,
+ },
+};
+
+/* USB Clocks */
+static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] =
+{
+ F(133330000, gpll0, 6, 0, 0),
+ F_END
+};
+
+static struct rcg_clk usb_hs_system_clk_src =
+{
+ .cmd_reg = (uint32_t *) USB_HS_SYSTEM_CMD_RCGR,
+ .cfg_reg = (uint32_t *) USB_HS_SYSTEM_CFG_RCGR,
+
+ .set_rate = clock_lib2_rcg_set_rate_hid,
+ .freq_tbl = ftbl_gcc_usb_hs_system_clk,
+ .current_freq = &rcg_dummy_freq,
+
+ .c = {
+ .dbg_name = "usb_hs_system_clk",
+ .ops = &clk_ops_rcg,
+ },
+};
+
+static struct branch_clk gcc_usb_hs_system_clk =
+{
+ .cbcr_reg = (uint32_t *) USB_HS_SYSTEM_CBCR,
+ .parent = &usb_hs_system_clk_src.c,
+
+ .c = {
+ .dbg_name = "gcc_usb_hs_system_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct branch_clk gcc_usb_hs_ahb_clk =
+{
+ .cbcr_reg = (uint32_t *) USB_HS_AHB_CBCR,
+ .has_sibling = 1,
+
+ .c = {
+ .dbg_name = "gcc_usb_hs_ahb_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
+ F(160000000, gpll0, 5, 0, 0),
+ F_END
+};
+
+static struct rcg_clk ce1_clk_src = {
+ .cmd_reg = (uint32_t *) GCC_CRYPTO_CMD_RCGR,
+ .cfg_reg = (uint32_t *) GCC_CRYPTO_CFG_RCGR,
+ .set_rate = clock_lib2_rcg_set_rate_hid,
+ .freq_tbl = ftbl_gcc_ce1_clk,
+ .current_freq = &rcg_dummy_freq,
+
+ .c = {
+ .dbg_name = "ce1_clk_src",
+ .ops = &clk_ops_rcg,
+ },
+};
+
+static struct vote_clk gcc_ce1_clk = {
+ .cbcr_reg = (uint32_t *) GCC_CRYPTO_CBCR,
+ .vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(2),
+
+ .c = {
+ .dbg_name = "gcc_ce1_clk",
+ .ops = &clk_ops_vote,
+ },
+};
+
+static struct vote_clk gcc_ce1_ahb_clk = {
+ .cbcr_reg = (uint32_t *) GCC_CRYPTO_AHB_CBCR,
+ .vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(0),
+
+ .c = {
+ .dbg_name = "gcc_ce1_ahb_clk",
+ .ops = &clk_ops_vote,
+ },
+};
+
+static struct vote_clk gcc_ce1_axi_clk = {
+ .cbcr_reg = (uint32_t *) GCC_CRYPTO_AXI_CBCR,
+ .vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(1),
+
+ .c = {
+ .dbg_name = "gcc_ce1_axi_clk",
+ .ops = &clk_ops_vote,
+ },
+};
+
+/* Clock lookup table */
+static struct clk_lookup msm_clocks_8952[] =
+{
+ CLK_LOOKUP("sdc1_iface_clk", gcc_sdcc1_ahb_clk.c),
+ CLK_LOOKUP("sdc1_core_clk", gcc_sdcc1_apps_clk.c),
+
+ CLK_LOOKUP("sdc2_iface_clk", gcc_sdcc2_ahb_clk.c),
+ CLK_LOOKUP("sdc2_core_clk", gcc_sdcc2_apps_clk.c),
+
+ CLK_LOOKUP("uart2_iface_clk", gcc_blsp1_ahb_clk.c),
+ CLK_LOOKUP("uart2_core_clk", gcc_blsp1_uart2_apps_clk.c),
+
+ CLK_LOOKUP("usb_iface_clk", gcc_usb_hs_ahb_clk.c),
+ CLK_LOOKUP("usb_core_clk", gcc_usb_hs_system_clk.c),
+
+
+ CLK_LOOKUP("ce1_ahb_clk", gcc_ce1_ahb_clk.c),
+ CLK_LOOKUP("ce1_axi_clk", gcc_ce1_axi_clk.c),
+ CLK_LOOKUP("ce1_core_clk", gcc_ce1_clk.c),
+ CLK_LOOKUP("ce1_src_clk", ce1_clk_src.c),
+};
+
+void platform_clock_init(void)
+{
+ clk_init(msm_clocks_8952, ARRAY_SIZE(msm_clocks_8952));
+}
diff --git a/platform/msm8952/platform.c b/platform/msm8952/platform.c
new file mode 100644
index 0000000..1ee7cdc
--- /dev/null
+++ b/platform/msm8952/platform.c
@@ -0,0 +1,169 @@
+/* Copyright (c) 2015, 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 <debug.h>
+#include <reg.h>
+#include <platform/iomap.h>
+#include <platform/irqs.h>
+#include <platform/clock.h>
+#include <qgic.h>
+#include <qtimer.h>
+#include <mmu.h>
+#include <arch/arm/mmu.h>
+#include <smem.h>
+#include <board.h>
+#include <boot_stats.h>
+#include <platform.h>
+
+#define MSM_IOMAP_SIZE ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
+#define APPS_SS_SIZE ((APPS_SS_END - APPS_SS_BASE)/MB)
+
+/* LK memory - cacheable, write through */
+#define LK_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \
+ MMU_MEMORY_AP_READ_WRITE)
+
+/* Peripherals - non-shared device */
+#define IOMAP_MEMORY (MMU_MEMORY_TYPE_DEVICE_SHARED | \
+ MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+
+/* IMEM memory - cacheable, write through */
+#define COMMON_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+ MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+
+#define SCRATCH_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \
+ MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+
+static mmu_section_t mmu_section_table[] = {
+/* Physical addr, Virtual addr, Size (in MB), Flags */
+ { MEMBASE, MEMBASE, (MEMSIZE / MB), LK_MEMORY},
+ { MSM_IOMAP_BASE, MSM_IOMAP_BASE, MSM_IOMAP_SIZE, IOMAP_MEMORY},
+ { APPS_SS_BASE, APPS_SS_BASE, APPS_SS_SIZE, IOMAP_MEMORY},
+ { MSM_SHARED_IMEM_BASE, MSM_SHARED_IMEM_BASE, 1, COMMON_MEMORY},
+ { SCRATCH_ADDR, SCRATCH_ADDR, 256, SCRATCH_MEMORY},
+};
+
+void platform_early_init(void)
+{
+ board_init();
+ platform_clock_init();
+ qgic_init();
+ qtimer_init();
+ scm_init();
+}
+
+void platform_init(void)
+{
+ dprintf(INFO, "platform_init()\n");
+}
+
+void platform_uninit(void)
+{
+ qtimer_uninit();
+}
+
+uint32_t platform_get_sclk_count(void)
+{
+ return readl(MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL);
+}
+
+addr_t get_bs_info_addr()
+{
+ return ((addr_t)BS_INFO_ADDR);
+}
+
+int platform_use_identity_mmu_mappings(void)
+{
+ /* Use only the mappings specified in this file. */
+ return 0;
+}
+
+/* Setup MMU mapping for this platform */
+void platform_init_mmu_mappings(void)
+{
+ uint32_t i;
+ uint32_t sections;
+ uint32_t table_size = ARRAY_SIZE(mmu_section_table);
+ uint32_t ddr_start = get_ddr_start();
+ uint32_t smem_addr = platform_get_smem_base_addr();
+
+ /*Mapping the ddr start address for loading the kernel about 90 MB*/
+ sections = 90;
+ while(sections--)
+ {
+ arm_mmu_map_section(ddr_start + sections * MB, ddr_start + sections* MB, COMMON_MEMORY);
+ }
+
+
+ /* Mapping the SMEM addr */
+ arm_mmu_map_section(smem_addr, smem_addr, COMMON_MEMORY);
+
+ /* Configure the MMU page entries for memory read from the
+ mmu_section_table */
+ for (i = 0; i < table_size; i++)
+ {
+ sections = mmu_section_table[i].num_of_sections;
+
+ while (sections--)
+ {
+ arm_mmu_map_section(mmu_section_table[i].paddress +
+ sections * MB,
+ mmu_section_table[i].vaddress +
+ sections * MB,
+ mmu_section_table[i].flags);
+ }
+ }
+}
+
+addr_t platform_get_virt_to_phys_mapping(addr_t virt_addr)
+{
+ /* Using 1-1 mapping on this platform. */
+ return virt_addr;
+}
+
+addr_t platform_get_phys_to_virt_mapping(addr_t phys_addr)
+{
+ /* Using 1-1 mapping on this platform. */
+ return phys_addr;
+}
+
+/* DYNAMIC SMEM REGION feature enables LK to dynamically
+ * read the SMEM addr info from TCSR_TZ_WONCE register.
+ * The first word read, if indicates a MAGIC number, then
+ * Dynamic SMEM is assumed to be enabled. Read the remaining
+ * SMEM info for SMEM Size and Phy_addr from the other bytes.
+ */
+uint32_t platform_get_smem_base_addr()
+{
+ struct smem_addr_info *smem_info = NULL;
+
+ smem_info = (struct smem_addr_info *)readl(TCSR_TZ_WONCE);
+ if(smem_info && (smem_info->identifier == SMEM_TARGET_INFO_IDENTIFIER))
+ return smem_info->phy_addr;
+ else
+ return MSM_SHARED_BASE;
+}
diff --git a/platform/msm8952/rules.mk b/platform/msm8952/rules.mk
new file mode 100644
index 0000000..a337b97
--- /dev/null
+++ b/platform/msm8952/rules.mk
@@ -0,0 +1,27 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+ARCH := arm
+#Compiling this as cortex-a8 until the compiler supports krait
+ARM_CPU := cortex-a8
+CPU := generic
+
+DEFINES += ARM_CPU_CORE_A7
+DEFINES += ARM_CORE_V8
+
+MMC_SLOT := 1
+
+DEFINES += PERIPH_BLK_BLSP=1
+DEFINES += WITH_CPU_EARLY_INIT=0 WITH_CPU_WARM_BOOT=0 \
+ MMC_SLOT=$(MMC_SLOT) SSD_ENABLE
+
+INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared/include
+
+OBJS += \
+ $(LOCAL_DIR)/platform.o \
+ $(LOCAL_DIR)/acpuclock.o \
+ $(LOCAL_DIR)/msm8952-clock.o \
+ $(LOCAL_DIR)/gpio.o
+
+LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld
+
+include platform/msm_shared/rules.mk
diff --git a/platform/msm8994/acpuclock.c b/platform/msm8994/acpuclock.c
index 6b77ea0..c59e61a 100644
--- a/platform/msm8994/acpuclock.c
+++ b/platform/msm8994/acpuclock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 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
@@ -37,6 +37,7 @@
#include <platform/timer.h>
#include <rpm-smd.h>
#include <regulator.h>
+#include <platform.h>
#define RPM_CE_CLK_TYPE 0x6563
#define CE2_CLK_ID 0x1
@@ -161,7 +162,10 @@
}
else if(freq == MMC_CLK_192MHZ)
{
- ret = clk_get_set_enable(clk_name, 192000000, 1);
+ if (platform_is_msm8992())
+ ret = clk_get_set_enable(clk_name, 172000000, 1);
+ else
+ ret = clk_get_set_enable(clk_name, 192000000, 1);
}
else if(freq == MMC_CLK_200MHZ)
{
@@ -169,7 +173,10 @@
}
else if(freq == MMC_CLK_400MHZ)
{
- ret = clk_get_set_enable(clk_name, 384000000, 1);
+ if (platform_is_msm8992())
+ ret = clk_get_set_enable(clk_name, 344000000, 1);
+ else
+ ret = clk_get_set_enable(clk_name, 384000000, 1);
}
else
{
diff --git a/platform/msm8994/msm8994-clock.c b/platform/msm8994/msm8994-clock.c
index 358db25..8653f8d 100644
--- a/platform/msm8994/msm8994-clock.c
+++ b/platform/msm8994/msm8994-clock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 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
@@ -34,6 +34,7 @@
#include <clock_lib2.h>
#include <platform/clock.h>
#include <platform/iomap.h>
+#include <platform.h>
/* Mux source select values */
@@ -256,6 +257,19 @@
F_END
};
+static struct clk_freq_tbl ftbl_gcc_sdcc1_apps_clk_8992[] =
+{
+ F( 144000, cxo, 16, 3, 25),
+ F( 400000, cxo, 12, 1, 4),
+ F( 20000000, gpll0, 15, 1, 2),
+ F( 25000000, gpll0, 12, 1, 2),
+ F( 50000000, gpll0, 12, 0, 0),
+ F( 96000000, gpll4, 6, 0, 0),
+ F(172000000, gpll4, 2, 0, 0),
+ F(344000000, gpll4, 1, 0, 0),
+ F_END
+};
+
static struct clk_freq_tbl ftbl_gcc_sdcc2_4_apps_clk[] =
{
F( 144000, cxo, 16, 3, 25),
@@ -825,7 +839,16 @@
CLK_LOOKUP("edp_aux_clk", mdss_edpaux_clk.c),
};
+void msm8992_sdc1_clock_override()
+{
+ sdcc1_apps_clk_src.freq_tbl = ftbl_gcc_sdcc1_apps_clk_8992;
+}
+
void platform_clock_init(void)
{
+ if (platform_is_msm8992())
+ {
+ msm8992_sdc1_clock_override();
+ }
clk_init(msm_8994_clocks, ARRAY_SIZE(msm_8994_clocks));
}
diff --git a/platform/msm8994/platform.c b/platform/msm8994/platform.c
index 507158b..eaaadc0 100644
--- a/platform/msm8994/platform.c
+++ b/platform/msm8994/platform.c
@@ -40,7 +40,7 @@
#define MSM_IOMAP_SIZE ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
/* LK memory - cacheable, write through */
-#define LK_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+#define LK_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \
MMU_MEMORY_AP_READ_WRITE)
/* Peripherals - non-shared device */
@@ -123,7 +123,7 @@
sections * MB,
ptn_entry.start +
sections * MB,
- (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+ (MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \
MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN));
}
}
diff --git a/platform/thulium/acpuclock.c b/platform/msm8996/acpuclock.c
similarity index 95%
rename from platform/thulium/acpuclock.c
rename to platform/msm8996/acpuclock.c
index e2ee7d5..15ebd30 100644
--- a/platform/thulium/acpuclock.c
+++ b/platform/msm8996/acpuclock.c
@@ -123,6 +123,20 @@
*/
static void ce_async_reset(uint8_t instance)
{
+ if (instance == 1)
+ {
+ /* Start the block reset for CE */
+ writel(1, GCC_CE1_BCR);
+ udelay(2);
+ /* Take CE block out of reset */
+ writel(0, GCC_CE1_BCR);
+ udelay(2);
+ }
+ else
+ {
+ dprintf(CRITICAL, "Unsupported CE instance: %u\n", instance);
+ ASSERT(0);
+ }
}
void clock_ce_enable(uint8_t instance)
diff --git a/platform/thulium/gpio.c b/platform/msm8996/gpio.c
similarity index 100%
rename from platform/thulium/gpio.c
rename to platform/msm8996/gpio.c
diff --git a/platform/thulium/include/platform/clock.h b/platform/msm8996/include/platform/clock.h
similarity index 100%
rename from platform/thulium/include/platform/clock.h
rename to platform/msm8996/include/platform/clock.h
diff --git a/platform/thulium/include/platform/gpio.h b/platform/msm8996/include/platform/gpio.h
similarity index 96%
rename from platform/thulium/include/platform/gpio.h
rename to platform/msm8996/include/platform/gpio.h
index c00512b..5626d50 100644
--- a/platform/thulium/include/platform/gpio.h
+++ b/platform/msm8996/include/platform/gpio.h
@@ -9,7 +9,7 @@
* 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, Inc. nor the names of its
+ * * 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.
*
diff --git a/platform/thulium/include/platform/iomap.h b/platform/msm8996/include/platform/iomap.h
similarity index 94%
rename from platform/thulium/include/platform/iomap.h
rename to platform/msm8996/include/platform/iomap.h
index 276841d..180b237 100644
--- a/platform/thulium/include/platform/iomap.h
+++ b/platform/msm8996/include/platform/iomap.h
@@ -153,8 +153,9 @@
#define SPMI_PIC_BASE (SPMI_BASE + 0x1800000)
#define PMIC_ARB_CORE 0x400F000
-#define MSM_CE_BAM_BASE 0x67A000
-#define MSM_CE_BASE 0x644000
+#define MSM_CE_BAM_BASE 0x644000
+#define MSM_CE_BASE 0x67A000
+#define GCC_CE1_BCR (CLK_CTL_BASE + 0x00041000)
#define TLMM_BASE_ADDR 0x1010000
#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + (x)*0x1000)
@@ -164,6 +165,10 @@
#define MPM2_MPM_PS_HOLD 0x4AB000
#define MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL 0x4A3000
+/* QSEECOM: Secure app region notification */
+#define APP_REGION_ADDR 0x86600000
+#define APP_REGION_SIZE 0xd00000
+
/* DRV strength for sdcc */
#define SDC1_HDRV_PULL_CTL (TLMM_BASE_ADDR + 0x0012C000)
@@ -188,4 +193,12 @@
/* Dummy macro needed for compilation only */
#define PLATFORM_QMP_OFFSET 0x0
+/* RPMB send receive buffer needs to be mapped
+ * as device memory, define the start address
+ * and size in MB
+ */
+#define RPMB_SND_RCV_BUF 0x8F200000
+#define RPMB_SND_RCV_BUF_SZ 0x1
+
+#define TCSR_BOOT_MISC_DETECT 0x007B3000
#endif
diff --git a/platform/thulium/include/platform/irqs.h b/platform/msm8996/include/platform/irqs.h
similarity index 97%
rename from platform/thulium/include/platform/irqs.h
rename to platform/msm8996/include/platform/irqs.h
index 696c83f..ab5e2ff 100644
--- a/platform/thulium/include/platform/irqs.h
+++ b/platform/msm8996/include/platform/irqs.h
@@ -9,7 +9,7 @@
* 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, Inc. nor the names of its
+ * * 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.
*
diff --git a/platform/thulium/include/platform/partial_goods.h b/platform/msm8996/include/platform/partial_goods.h
similarity index 96%
rename from platform/thulium/include/platform/partial_goods.h
rename to platform/msm8996/include/platform/partial_goods.h
index 03c16ec..926c0c6 100644
--- a/platform/thulium/include/platform/partial_goods.h
+++ b/platform/msm8996/include/platform/partial_goods.h
@@ -9,7 +9,7 @@
* 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
+ * * 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.
*
diff --git a/platform/thulium/thulium-clock.c b/platform/msm8996/msm8996-clock.c
similarity index 98%
rename from platform/thulium/thulium-clock.c
rename to platform/msm8996/msm8996-clock.c
index d0a23ed..c082dc5 100644
--- a/platform/thulium/thulium-clock.c
+++ b/platform/msm8996/msm8996-clock.c
@@ -405,7 +405,7 @@
/* Clock lookup table */
-static struct clk_lookup msm_thulium_clocks[] =
+static struct clk_lookup msm_msm8996_clocks[] =
{
CLK_LOOKUP("sdc1_iface_clk", gcc_sdcc1_ahb_clk.c),
CLK_LOOKUP("sdc1_core_clk", gcc_sdcc1_apps_clk.c),
@@ -428,5 +428,5 @@
void platform_clock_init(void)
{
- clk_init(msm_thulium_clocks, ARRAY_SIZE(msm_thulium_clocks));
+ clk_init(msm_msm8996_clocks, ARRAY_SIZE(msm_msm8996_clocks));
}
diff --git a/platform/thulium/platform.c b/platform/msm8996/platform.c
similarity index 81%
rename from platform/thulium/platform.c
rename to platform/msm8996/platform.c
index be0678c..a82357b 100644
--- a/platform/thulium/platform.c
+++ b/platform/msm8996/platform.c
@@ -13,17 +13,17 @@
* 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.
+ * 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 <debug.h>
@@ -59,6 +59,7 @@
{ KERNEL_ADDR, KERNEL_ADDR, KERNEL_SIZE, SCRATCH_MEMORY},
{ SCRATCH_ADDR, SCRATCH_ADDR, SCRATCH_SIZE, SCRATCH_MEMORY},
{ MSM_SHARED_BASE, MSM_SHARED_BASE, MSM_SHARED_SIZE, SCRATCH_MEMORY},
+ { RPMB_SND_RCV_BUF, RPMB_SND_RCV_BUF, RPMB_SND_RCV_BUF_SZ, IOMAP_MEMORY},
};
void platform_early_init(void)
@@ -141,3 +142,8 @@
return readl(USB3_PHY_REVISION_ID3) << 24 | readl(USB3_PHY_REVISION_ID2) << 16 |
readl(USB3_PHY_REVISION_ID1) << 8 | readl(USB3_PHY_REVISION_ID0);
}
+
+uint32_t platform_get_max_periph()
+{
+ return 256;
+}
diff --git a/platform/thulium/rules.mk b/platform/msm8996/rules.mk
similarity index 94%
rename from platform/thulium/rules.mk
rename to platform/msm8996/rules.mk
index 10afc50..8db37d5 100644
--- a/platform/thulium/rules.mk
+++ b/platform/msm8996/rules.mk
@@ -20,7 +20,7 @@
OBJS += \
$(LOCAL_DIR)/platform.o \
$(LOCAL_DIR)/acpuclock.o \
- $(LOCAL_DIR)/thulium-clock.o \
+ $(LOCAL_DIR)/msm8996-clock.o \
$(LOCAL_DIR)/gpio.o
LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld
diff --git a/platform/msm_shared/crypto5_eng.c b/platform/msm_shared/crypto5_eng.c
index 0f592f9..8caad79 100644
--- a/platform/msm_shared/crypto5_eng.c
+++ b/platform/msm_shared/crypto5_eng.c
@@ -139,6 +139,8 @@
#else
ret = (uint32_t)bam_add_cmd_element(&cmd_list_ptr, reg_addr, val, CE_WRITE_TYPE);
+ arch_clean_invalidate_cache_range((addr_t)&cmd_list_ptr, sizeof(struct cmd_element));
+
/* Enqueue the desc for the above command */
ret = bam_add_one_desc(bam_core,
CRYPTO_WRITE_PIPE_INDEX,
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
index 0abf723..27296b4 100755
--- a/platform/msm_shared/dev_tree.c
+++ b/platform/msm_shared/dev_tree.c
@@ -414,7 +414,7 @@
* Return Value: DTB address : If appended device tree is found
* 'NULL' : Otherwise
*/
-void *dev_tree_appended(void *kernel, uint32_t kernel_size, void *tags)
+void *dev_tree_appended(void *kernel, uint32_t kernel_size, uint32_t dtb_offset, void *tags)
{
void *kernel_end = kernel + kernel_size;
uint32_t app_dtb_offset = 0;
@@ -437,8 +437,10 @@
}
list_initialize(&dt_entry_queue->node);
-
- memcpy((void*) &app_dtb_offset, (void*) (kernel + DTB_OFFSET), sizeof(uint32_t));
+ if (dtb_offset)
+ app_dtb_offset = dtb_offset;
+ else
+ memcpy((void*) &app_dtb_offset, (void*) (kernel + DTB_OFFSET), sizeof(uint32_t));
if (((uintptr_t)kernel + (uintptr_t)app_dtb_offset) < (uintptr_t)kernel) {
return NULL;
diff --git a/platform/msm_shared/glink/glink_api.c b/platform/msm_shared/glink/glink_api.c
new file mode 100644
index 0000000..24f777d
--- /dev/null
+++ b/platform/msm_shared/glink/glink_api.c
@@ -0,0 +1,1532 @@
+/* Copyright (c) 2015, 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 FILES
+===========================================================================*/
+#include <glink.h>
+#include <glink_rpm.h>
+#include <glink_os_utils.h>
+#include <glink_internal.h>
+#include <glink_vector.h>
+#include <glink_channel_migration.h>
+#include <smem_list.h>
+#include <smem_type.h>
+
+#define GLINK_NOT_INITIALIZED 0
+#define GLINK_INITIALIZED 1
+
+/*===========================================================================
+ GLOBAL DATA DECLARATIONS
+===========================================================================*/
+int glink_core_status = GLINK_NOT_INITIALIZED;
+
+os_cs_type *glink_transport_q_cs;
+os_cs_type *glink_mem_log_cs;
+
+glink_mem_log_entry_type glink_mem_log_arr[GLINK_MEM_LOG_SIZE];
+uint32 glink_mem_log_idx = 0;
+
+/* Keep a list of registered transport for each edge allowed for this host */
+smem_list_type glink_registered_transports[GLINK_NUM_HOSTS];
+
+smem_list_type glink_link_notif_list;
+
+/* List of supported hosts */
+const char* glink_hosts_supported[] = { "apss",
+ "mpss",
+ "lpass",
+ "dsps",
+ "wcnss",
+ "tz",
+ "rpm",
+ };
+
+/* Forward function declarations */
+void glinki_free_intents(glink_channel_ctx_type *open_ch_ctx);
+
+/*===========================================================================
+ LOCAL FUNCTION DEFINITIONS
+===========================================================================*/
+
+glink_err_type glinki_add_ch_to_xport
+(
+ glink_transport_if_type *if_ptr,
+ glink_transport_if_type *req_if_ptr,
+ glink_channel_ctx_type *ch_ctx,
+ glink_channel_ctx_type **allocated_ch_ctx,
+ unsigned int local_open,
+ boolean migration_state,
+ glink_xport_priority migrated_ch_prio
+)
+{
+ glink_err_type status = 0;
+ glink_channel_ctx_type *open_ch_ctx;
+ glink_core_xport_ctx_type *xport_ctx = if_ptr->glink_core_priv;
+
+ /* See if channel already exists in open_list */
+ glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+ open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+ while(open_ch_ctx != NULL)
+ {
+ if (strcmp(open_ch_ctx->name, ch_ctx->name) == 0)
+ {
+ /* We've found a channel name is already in the list of open channel */
+ /* increase reference open count for channel */
+ *allocated_ch_ctx = open_ch_ctx;
+ open_ch_ctx->ref_count++;
+
+ /* Case A: Channel was opened before on the same host */
+ if((open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN) && local_open) {
+
+ open_ch_ctx->req_if_ptr = req_if_ptr;
+
+ /* Copy local open ctx params */
+ open_ch_ctx->notify_rx = ch_ctx->notify_rx;
+ open_ch_ctx->notify_rxv = ch_ctx->notify_rxv;
+ open_ch_ctx->notify_tx_done = ch_ctx->notify_tx_done;
+ open_ch_ctx->notify_state = ch_ctx->notify_state;
+ open_ch_ctx->notify_rx_intent_req = ch_ctx->notify_rx_intent_req;
+ open_ch_ctx->notify_rx_intent = ch_ctx->notify_rx_intent;
+ open_ch_ctx->notify_rx_sigs = ch_ctx->notify_rx_sigs;
+ open_ch_ctx->priv = ch_ctx->priv;
+ open_ch_ctx->ch_open_options = ch_ctx->ch_open_options;
+
+ /* release lock before context switch otherwise it is causing
+ * deadlock */
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+ /* Send open cmd to transport */
+ status = if_ptr->tx_cmd_ch_open(if_ptr,
+ open_ch_ctx->lcid, open_ch_ctx->name,
+ open_ch_ctx->req_if_ptr->glink_priority);
+ }
+ else if ((open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN) &&
+ (!local_open))
+ {
+ /* Case B: Channel was opened on this end and we got a remote open */
+ open_ch_ctx->rcid = ch_ctx->rcid;
+
+ status = xport_ctx->channel_init(open_ch_ctx);
+
+ /* release lock before context switch otherwise it is causing deadlock */
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+ if (status == GLINK_STATUS_SUCCESS)
+ {
+ /* Send ACK to transport */
+ if_ptr->tx_cmd_ch_remote_open_ack(if_ptr, open_ch_ctx->rcid, migrated_ch_prio);
+ }
+ } else if ((open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE)
+ && (local_open)) {
+ /* Allocate new channel context */
+ break; /* code would break out of loop and create new ch ctx */
+ } else {
+ /* Can't handle this state */
+ ASSERT(0);
+ }
+
+ break;
+ } /* end if match found */
+ open_ch_ctx = smem_list_next(open_ch_ctx);
+ }/* end while */
+
+ if (open_ch_ctx != NULL)
+ {
+ glink_os_free(ch_ctx);
+
+ /* connect channel here if state is local open and remote open request
+ * comes up and channel migration is done; channel will be connected in
+ * remote_open_ack if channel state is remote open and local open
+ * request comes up */
+ if(open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN &&
+ migration_state == FALSE && status == GLINK_STATUS_SUCCESS)
+ {
+ /* Set the channel state to OPEN */
+ open_ch_ctx->state = GLINK_CH_STATE_OPEN;
+ /* Inform the client */
+ open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
+ GLINK_CONNECTED);
+ }
+ }
+ else
+ {
+ /* Channel not in the list - it was not previously opened */
+ ch_ctx->if_ptr = if_ptr;
+ *allocated_ch_ctx = ch_ctx;
+
+ /* Set channel state */
+ if (local_open) {
+ /* This is a local open */
+ ch_ctx->state = GLINK_CH_STATE_LOCAL_OPEN;
+ ch_ctx->req_if_ptr = req_if_ptr;
+ }
+ else {
+ ch_ctx->state = GLINK_CH_STATE_REMOTE_OPEN;
+ }
+
+ glink_os_cs_init(&ch_ctx->tx_cs);
+
+ /* Append the channel to the transport interface's open_list */
+ ch_ctx->ref_count++;
+ ch_ctx->lcid = xport_ctx->free_lcid;
+ xport_ctx->free_lcid++;
+ smem_list_append(&if_ptr->glink_core_priv->open_list, ch_ctx);
+
+ /* release lock before context switch otherwise it is causing deadlock */
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+ /* Send the OPEN command to transport */
+ if (local_open)
+ {
+ status = if_ptr->tx_cmd_ch_open(if_ptr, ch_ctx->lcid,
+ ch_ctx->name,
+ ch_ctx->req_if_ptr->glink_priority);
+ }
+ else
+ {
+ /* initialize channel resources */
+ status = xport_ctx->channel_init(ch_ctx);
+
+ /* ACK the transport for remote open */
+ if (status == GLINK_STATUS_SUCCESS)
+ {
+ if_ptr->tx_cmd_ch_remote_open_ack(if_ptr, ch_ctx->rcid,
+ migrated_ch_prio);
+ }
+ }
+
+ if (status != GLINK_STATUS_SUCCESS)
+ {
+ /* Remove the channel from the transport interface's open_list */
+ xport_ctx->free_lcid--;
+
+ glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+ smem_list_delete(&if_ptr->glink_core_priv->open_list, ch_ctx);
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+ /* free the ch_ctx structure and return */
+ xport_ctx->channel_cleanup(ch_ctx);
+ glink_os_free(ch_ctx);
+ }
+ }
+
+ return status;
+}
+
+/** Default implementation of optional callbacks */
+
+static void glink_default_notify_rx_sigs
+(
+ glink_handle_type handle,
+ const void *priv,
+ uint32 prev,
+ uint32 curr
+)
+{
+ return;
+}
+
+static void glinki_call_link_notifier
+(
+ glink_link_notif_data_type *link_notif_data,
+ glink_core_xport_ctx_type *xport_ctx,
+ glink_link_state_type state
+)
+{
+ glink_link_info_type link_info;
+
+ ASSERT(xport_ctx);
+ ASSERT(link_notif_data);
+
+ link_info.xport = xport_ctx->xport;
+ link_info.remote_ss = xport_ctx->remote_ss;
+ link_info.link_state = state;
+ link_notif_data->link_notifier(&link_info, link_notif_data->priv);
+}
+
+static uint32 glinki_find_remote_host
+(
+ const char *remote_ss
+)
+{
+ uint32 remote_host;
+ ASSERT(remote_ss);
+
+ for(remote_host = 0;
+ remote_host < sizeof(glink_hosts_supported)/sizeof(char *);
+ remote_host++) {
+ if( 0 == strcmp(glink_hosts_supported[remote_host], remote_ss) ) {
+ /* Match found, break out of loop */
+ break;
+ }
+ }
+ return remote_host;
+}
+
+static void glinki_check_xport_and_notify
+(
+ glink_link_notif_data_type *link_notif_data,
+ glink_core_xport_ctx_type *xport_ctx,
+ glink_link_state_type state
+)
+{
+ glink_link_info_type link_info;
+
+ ASSERT(xport_ctx);
+ ASSERT(link_notif_data);
+
+ link_info.xport = xport_ctx->xport;
+ link_info.remote_ss = xport_ctx->remote_ss;
+ link_info.link_state = state;
+
+ if(link_notif_data->xport == NULL ||
+ 0 == strcmp(xport_ctx->xport, link_notif_data->xport)) {
+ /* xport not specified, or it is specified and matches the current xport */
+ /* Invoke registered callback */
+ link_notif_data->link_notifier(&link_info, link_notif_data->priv);
+ }
+}
+
+
+static void glinki_scan_xports_and_notify
+(
+ glink_link_notif_data_type *link_notif_data
+)
+{
+ unsigned int remote_host;
+ glink_transport_if_type *if_ptr;
+ glink_core_xport_ctx_type *xport_ctx;
+
+ ASSERT(link_notif_data);
+
+ /* Find matching subsystem */
+ if(link_notif_data->remote_ss) {
+ remote_host = glinki_find_remote_host(link_notif_data->remote_ss);
+
+ /* Find the xport and give link UP notification */
+ if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
+ if(if_ptr == NULL) {
+ /* No registered xports at this time, return without doing anything */
+ return;
+ }
+
+ if(link_notif_data->xport) {
+ do {
+ xport_ctx = if_ptr->glink_core_priv;
+ if( 0 == strcmp(xport_ctx->xport, link_notif_data->xport) ) {
+ /* Match found, break out of loop */
+ break;
+ }
+ }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
+
+ if((if_ptr != NULL) && (xport_ctx->status == GLINK_XPORT_LINK_UP)) {
+ /* Invoke registered callback */
+ glinki_call_link_notifier(link_notif_data, xport_ctx,
+ GLINK_LINK_STATE_UP);
+ }
+ } else {
+ /* No xport has been specified, invoke notifier for all registered
+ * xports */
+ do {
+ xport_ctx = if_ptr->glink_core_priv;
+ if(xport_ctx->status == GLINK_XPORT_LINK_UP) {
+ /* Invoke registered callback */
+ glinki_call_link_notifier(link_notif_data, xport_ctx,
+ GLINK_LINK_STATE_UP);
+ }
+ }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
+ }
+ } else {
+ /* No remote ss is specified, invoke notifier for all remote_ss */
+ for(remote_host = 0;
+ remote_host < sizeof(glink_hosts_supported)/sizeof(char *);
+ remote_host++) {
+ /* Find the xport and give link UP notification */
+ if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
+ if(if_ptr == NULL) {
+ /* No registered xports at this time, continue with next remote_ss */
+ continue;
+ }
+
+ if(link_notif_data->xport) {
+ do {
+ xport_ctx = if_ptr->glink_core_priv;
+ if( 0 == strcmp(xport_ctx->xport, link_notif_data->xport) ) {
+ /* Match found, break out of loop */
+ break;
+ }
+ }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
+
+ if((if_ptr != NULL) && (xport_ctx->status == GLINK_XPORT_LINK_UP)) {
+ /* Invoke registered callback */
+ glinki_call_link_notifier(link_notif_data, xport_ctx,
+ GLINK_LINK_STATE_UP);
+ }
+ } else {
+ /* No xport has been specified, invoke notifier for all registered
+ * xports */
+ do {
+ xport_ctx = if_ptr->glink_core_priv;
+ if(xport_ctx->status == GLINK_XPORT_LINK_UP) {
+ /* Invoke registered callback */
+ glinki_call_link_notifier(link_notif_data, xport_ctx,
+ GLINK_LINK_STATE_UP);
+ }
+ }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
+ }
+ } /* end for remote_host */
+ }/* end if else (link_notif_data->remote_ss) */
+} /* glinki_scan_xports_and_notify */
+
+void glinki_scan_notif_list_and_notify
+(
+ glink_transport_if_type *if_ptr,
+ glink_link_state_type state
+)
+{
+ glink_link_notif_data_type *link_notif_data;
+ glink_core_xport_ctx_type *xport_ctx = if_ptr->glink_core_priv;
+
+ link_notif_data = smem_list_first(&glink_link_notif_list);
+
+ if(link_notif_data == NULL) {
+ /* list empty */
+ return;
+ }
+
+ do {
+ if(link_notif_data->remote_ss &&
+ 0 == strcmp(xport_ctx->remote_ss, link_notif_data->remote_ss)) {
+ /* remote_ss specified and matches */
+ glinki_check_xport_and_notify(link_notif_data, xport_ctx, state);
+ } else if(link_notif_data->remote_ss == NULL) {
+ /* remote_ss not specified, invoke link notif for any remote_ss */
+ if(link_notif_data->xport) {
+ glinki_check_xport_and_notify(link_notif_data, xport_ctx, state);
+ } /* if else link_notif_data->xport */
+ } /* if else link_notif_data->remote_ss */
+ } while ( (link_notif_data = smem_list_next(link_notif_data)) != NULL);
+
+} /* glinki_scan_notif_list_and_notify */
+
+void glinki_scan_channels_and_notify_discon
+(
+ glink_transport_if_type *if_ptr
+)
+{
+ glink_channel_ctx_type *open_ch_ctx;
+ glink_core_xport_ctx_type *xport_ctx;
+
+ ASSERT(if_ptr != NULL);
+
+ xport_ctx = if_ptr->glink_core_priv;
+
+ /* Find channel in the open_list */
+ glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+ open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+ while(open_ch_ctx != NULL)
+ {
+ /* Found channel, transition it to appropriate state based
+ * on current state */
+ if(open_ch_ctx->state == GLINK_CH_STATE_OPEN) {
+ open_ch_ctx->state = GLINK_CH_STATE_LOCAL_OPEN;
+
+ /* Inform the client */
+ open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
+ GLINK_REMOTE_DISCONNECTED);
+ } else if (open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN) {
+ /* Local side never opened the channel */
+ /* Free channel resources */
+ xport_ctx->channel_cleanup(open_ch_ctx);
+
+ smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+
+ glink_os_free(open_ch_ctx);
+ }
+ open_ch_ctx = smem_list_next(open_ch_ctx);
+ }/* end while */
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+}
+
+void glink_ssr(const char* remote_ss)
+{
+ unsigned int remote_host;
+ glink_transport_if_type *if_ptr;
+
+ remote_host = glinki_find_remote_host(remote_ss);
+
+ /* Scan through the registered interfaces with the crashing ss
+ and let the clients know about the crash via LINK_DOWN
+ notification followed by REMOTE_DISCONNECT */
+ if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
+
+ while(if_ptr != NULL) {
+ /* Invoke LINK_DOWN notification for any registered notifiers */
+ glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_DOWN);
+
+ /* Invoke REMOTE_DISCONNECT for all channels associated with if_ptr */
+ glinki_scan_channels_and_notify_discon(if_ptr);
+
+ /* Let the xport know about ssr */
+ if_ptr->ssr(if_ptr);
+
+ if_ptr = smem_list_next(if_ptr);
+ }
+}
+
+
+/*===========================================================================
+ EXTERNAL FUNCTION DEFINITIONS
+===========================================================================*/
+/*===========================================================================
+FUNCTION glink_init
+
+DESCRIPTION Initializes the GLink core library.
+
+ARGUMENTS None
+
+RETURN VALUE None
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_init(void)
+{
+ uint32 i;
+
+ glink_mem_log_cs = glink_os_cs_create();
+
+ glink_core_status = GLINK_INITIALIZED;
+
+ /* Create/Initalize crtitical sections */
+ glink_transport_q_cs = glink_os_cs_create();
+ if(glink_transport_q_cs == NULL) {
+ return;
+ }
+
+ glink_os_cs_acquire(glink_transport_q_cs);
+ for(i= 0; i < sizeof(glink_registered_transports)/sizeof(smem_list_type);
+ i++)
+ {
+ smem_list_init(&glink_registered_transports[i]);
+ }
+ glink_os_cs_release(glink_transport_q_cs);
+}
+
+/*===========================================================================
+FUNCTION glink_core_register_transport
+
+DESCRIPTION Transport calls this API to register its interface with GLINK
+ Core
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ *cfg Pointer to transport configuration structure.
+
+RETURN VALUE Standard GLINK error codes.
+
+SIDE EFFECTS None
+===========================================================================*/
+glink_err_type glink_core_register_transport
+(
+ glink_transport_if_type *if_ptr,
+ glink_core_transport_cfg_type *cfg
+)
+{
+ unsigned int remote_host = 0;
+ glink_core_xport_ctx_type *xport_ctx;
+ /* Param validation */
+ if(if_ptr == NULL || cfg == NULL)
+ {
+ GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, "", "",
+ GLINK_STATUS_INVALID_PARAM);
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+
+ if(cfg->name == NULL ||
+ cfg->remote_ss == NULL ||
+ cfg->version == NULL ||
+ cfg->version_count == 0 ||
+ cfg->max_cid == 0)
+ {
+ GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, "", "",
+ GLINK_STATUS_INVALID_PARAM);
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+
+
+ if(if_ptr->tx_cmd_version == NULL ||
+ if_ptr->tx_cmd_version_ack == NULL ||
+ if_ptr->set_version == NULL ||
+ if_ptr->tx_cmd_ch_open == NULL ||
+ if_ptr->tx_cmd_ch_close == NULL ||
+ if_ptr->tx_cmd_ch_remote_open_ack == NULL ||
+ if_ptr->tx_cmd_ch_remote_close_ack == NULL ||
+ if_ptr->tx_cmd_set_sigs == NULL ||
+ if_ptr->ssr == NULL)
+ {
+ GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
+ cfg->remote_ss, GLINK_STATUS_INVALID_PARAM);
+ return GLINK_STATUS_INVALID_PARAM;;
+ }
+
+
+ /* Allocate/fill out the GLink Core interface structure */
+ {
+ glink_core_if_type *core_if = glink_os_calloc(sizeof(glink_core_if_type));
+ if(core_if == NULL) {
+ GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
+ cfg->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
+ return GLINK_STATUS_OUT_OF_RESOURCES;
+ }
+ core_if->link_up = glink_link_up;
+ core_if->rx_cmd_version = glink_rx_cmd_version;
+ core_if->rx_cmd_version_ack = glink_rx_cmd_version_ack;
+ core_if->rx_cmd_ch_remote_open = glink_rx_cmd_ch_remote_open;
+ core_if->rx_cmd_ch_open_ack = glink_rx_cmd_ch_open_ack;
+ core_if->rx_cmd_ch_close_ack = glink_rx_cmd_ch_close_ack;
+ core_if->rx_cmd_ch_remote_close = glink_rx_cmd_ch_remote_close;
+ core_if->ch_state_local_trans = glink_ch_state_local_trans;
+ core_if->rx_put_pkt_ctx = glink_rx_put_pkt_ctx;
+ core_if->rx_cmd_remote_sigs = glink_rx_cmd_remote_sigs;
+ core_if->tx_resume = glink_tx_resume;
+ core_if->set_core_version = glink_set_core_version;
+
+ /* Set the glink_core_if_ptr to point to the allocated structure */
+ if_ptr->glink_core_if_ptr = core_if;
+ }
+
+ /* Allocate/fill out the GLink private context data */
+ {
+ xport_ctx = glink_os_calloc(sizeof(glink_core_xport_ctx_type));
+ if(xport_ctx == NULL) {
+ /* Free previously allocated memory */
+ glink_os_free(if_ptr->glink_core_if_ptr);
+
+ GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
+ cfg->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
+
+ return GLINK_STATUS_OUT_OF_RESOURCES;
+ }
+
+ glink_os_string_copy(xport_ctx->xport, cfg->name,
+ sizeof(xport_ctx->xport));
+ glink_os_string_copy(xport_ctx->remote_ss, cfg->remote_ss,
+ sizeof(xport_ctx->xport));
+ xport_ctx->free_lcid = 1; /* lcid 0 is reserved for invalid channel */
+ xport_ctx->version_array = cfg->version;
+ xport_ctx->version_indx = cfg->version_count - 1;
+
+ glink_os_cs_init(&xport_ctx->channel_q_cs);
+ glink_os_cs_init(&xport_ctx->liid_cs);
+
+ glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+ smem_list_init(&xport_ctx->open_list);
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+ /* Set the glink_core_if_ptr to point to the allocated structure */
+ if_ptr->glink_core_priv = xport_ctx;
+ xport_ctx->status = GLINK_XPORT_REGISTERED;
+ }
+
+ /* Push the transport interface into appropriate queue */
+ remote_host = glinki_find_remote_host(cfg->remote_ss);
+
+ if(remote_host == GLINK_NUM_HOSTS ) {
+ /* Unknown transport name trying to register with GLink */
+ GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_INVALID_PARAM);
+
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+ glink_os_cs_acquire(glink_transport_q_cs);
+ smem_list_append(&glink_registered_transports[remote_host], if_ptr);
+ glink_os_cs_release(glink_transport_q_cs);
+
+ GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
+
+ return GLINK_STATUS_SUCCESS;
+}
+
+/**
+ * Regsiters a client specified callback to be invoked when the specified
+ * transport (link) is up/down.
+ *
+ * @param[in] link_id Pointer to the configuration structure for the
+ * xport(link) to be monitored. See glink.h
+ * @param[in] priv Callback data returned to client when callback
+ * is invoked.
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects Puts the callback in a queue which gets scanned when a
+ * transport(link) comes up OR an SSR happnes.
+ */
+glink_err_type glink_register_link_state_cb
+(
+ glink_link_id_type *link_id,
+ void* priv
+)
+{
+ glink_link_notif_data_type* link_notif_data;
+ unsigned int remote_host;
+
+ /* Input validation */
+ ASSERT(link_id != NULL);
+
+ /* Make sure client provided us with the correct version of the input
+ * structure */
+ if(link_id->version != GLINK_LINK_ID_VER || link_id->link_notifier == NULL) {
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+
+ /* Save the callback on the notification list */
+ if((link_notif_data = glink_os_malloc(sizeof(glink_link_notif_data_type)))
+ == NULL) {
+ return GLINK_STATUS_OUT_OF_RESOURCES;
+ }
+
+ /* Check for remote_ss validity */
+ if(link_id->remote_ss != NULL) {
+ remote_host = glinki_find_remote_host(link_id->remote_ss);
+
+ if(remote_host == sizeof(glink_hosts_supported)/sizeof(char *)) {
+ glink_os_free(link_notif_data);
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+ }
+
+ link_notif_data->xport = link_id->xport;
+ link_notif_data->remote_ss = link_id->remote_ss;
+ link_notif_data->link_notifier = link_id->link_notifier;
+ link_notif_data->priv = priv; /* private client data */
+
+ /* Append the request to the list for link UP/DOWN notifications */
+ smem_list_append(&glink_link_notif_list, link_notif_data);
+
+ /* Scan the list of available transport to see if this link is already up */
+ glinki_scan_xports_and_notify(link_notif_data);
+
+ return GLINK_STATUS_SUCCESS;
+}
+
+/**
+ * Degsiter the link UP/DOWN notification callback associated with the
+ * provided handle.
+ *
+ * @param[in] handle Callback handler returned by
+ * glink_register_link_state_cb
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects Removes the callback in a queue which gets scanned when a
+ * transport(link) comes up OR an SSR happnes.
+ */
+glink_err_type glink_deregister_link_state_cb
+(
+ glink_link_handle_type handle
+)
+{
+ ASSERT(handle);
+
+ smem_list_delete(&glink_link_notif_list,
+ (glink_link_notif_data_type*)handle);
+
+ glink_os_free(handle);
+
+ return GLINK_STATUS_SUCCESS;
+}
+
+/**
+ * This function gives best available transport for give edge
+ *
+ * @param[in] remote_host Index into glink_registered_transports array of
+ * registered transports list per edge
+ *
+ * @return pointer to glink_transport_if_type
+ *
+ * @sideeffects NONE
+ */
+glink_transport_if_type* glink_get_best_xport
+(
+ unsigned int remote_host
+)
+{
+ glink_transport_if_type *if_ptr = NULL, *best_if_ptr = NULL;
+ glink_xport_priority priority = GLINK_MIN_PRIORITY;
+ glink_core_xport_ctx_type *xport_ctx = NULL;
+
+ best_if_ptr = if_ptr = smem_list_first(
+ &glink_registered_transports[remote_host]);
+
+ while(if_ptr != NULL)
+ {
+ /* check if priority of current transport is higher than
+ * current highest priority (0 = highest priority)
+ */
+ xport_ctx = if_ptr->glink_core_priv;
+ if( xport_ctx->status == GLINK_XPORT_LINK_UP &&
+ if_ptr->glink_priority < priority )
+ {
+ best_if_ptr = if_ptr;
+ priority = if_ptr->glink_priority;
+ }
+
+ if_ptr = smem_list_next(if_ptr);
+ } /* end while() */
+
+ return best_if_ptr;
+}
+
+/**
+ * Opens a logical GLink based on the specified config params
+ *
+ * @param[in] cfg_ptr Pointer to the configuration structure for the
+ * GLink. See glink.h
+ * @param[out] handle GLink handle associated with the logical channel
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects Allocates channel resources and informs remote host about
+ * channel open.
+ */
+glink_err_type glink_open
+(
+ glink_open_config_type *cfg_ptr,
+ glink_handle_type *handle
+)
+{
+ glink_transport_if_type *if_ptr, *req_if_ptr;
+ glink_channel_ctx_type *ch_ctx;
+ unsigned int remote_host;
+
+ /* Param validation */
+ if(cfg_ptr == NULL)
+ {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN, NULL, "", "",
+ GLINK_STATUS_INVALID_PARAM);
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+
+ if(cfg_ptr->remote_ss == NULL ||
+ cfg_ptr->name == NULL ||
+ cfg_ptr->notify_state == NULL)
+ {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN, NULL, "", "",
+ GLINK_STATUS_INVALID_PARAM);
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+
+ /* Evaluate the equivalent edge name->enum for future use */
+ remote_host = glinki_find_remote_host(cfg_ptr->remote_ss);
+
+ if(remote_host == GLINK_NUM_HOSTS ) {
+ /* Unknown transport name trying to register with GLink */
+ GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, cfg_ptr->name, "",
+ cfg_ptr->remote_ss, GLINK_STATUS_INVALID_PARAM);
+
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+
+ /* Allocate and initialize channel info structure */
+ ch_ctx = glink_os_calloc(sizeof(glink_channel_ctx_type));
+ if(ch_ctx == NULL) {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN, cfg_ptr->name, "",
+ "", GLINK_STATUS_OUT_OF_RESOURCES);
+ return GLINK_STATUS_OUT_OF_RESOURCES;
+ }
+
+ /* Fill in the channel info structure */
+ glink_os_string_copy(ch_ctx->name, cfg_ptr->name, sizeof(ch_ctx->name));
+ ch_ctx->priv = cfg_ptr->priv;
+ ch_ctx->notify_rx = cfg_ptr->notify_rx;
+ ch_ctx->notify_rxv = cfg_ptr->notify_rxv;
+ ch_ctx->notify_tx_done = cfg_ptr->notify_tx_done;
+ ch_ctx->notify_state = cfg_ptr->notify_state;
+ ch_ctx->notify_rx_intent_req = cfg_ptr->notify_rx_intent_req;
+ ch_ctx->notify_rx_intent = cfg_ptr->notify_rx_intent;
+ ch_ctx->notify_rx_sigs = cfg_ptr->notify_rx_sigs;
+ ch_ctx->ch_open_options = cfg_ptr->options;
+ ch_ctx->notify_rx_abort = cfg_ptr->notify_rx_abort;
+ ch_ctx->notify_tx_abort = cfg_ptr->notify_tx_abort;
+
+ if (ch_ctx->notify_rx_sigs == NULL) {
+ /* set default callback */
+ ch_ctx->notify_rx_sigs = glink_default_notify_rx_sigs;
+ }
+
+ glink_os_cs_acquire(glink_transport_q_cs);
+
+ /* Check to see if requested transport is available */
+ for (if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
+ if_ptr != NULL;
+ if_ptr = smem_list_next(if_ptr))
+ {
+ glink_core_xport_ctx_type *xport_ctx = if_ptr->glink_core_priv;
+ glink_channel_ctx_type *allocated_ch_ctx;
+
+ if (xport_ctx->status == GLINK_XPORT_LINK_UP &&
+ (cfg_ptr->transport == NULL ||
+ 0 == strcmp(cfg_ptr->transport, xport_ctx->xport)) &&
+ xport_ctx->verify_open_cfg(ch_ctx))
+ {
+ glink_err_type status;
+
+ if(cfg_ptr->transport == NULL)
+ {
+ /* get best available transport */
+ if_ptr = req_if_ptr = glink_get_best_xport(remote_host);
+ }
+ else
+ {
+ if(cfg_ptr->options & GLINK_OPT_INITIAL_XPORT)
+ {
+ /* xport suggested by client is optional.
+ * get best available xport */
+ req_if_ptr = glink_get_best_xport(remote_host);
+ }
+ else
+ {
+ req_if_ptr = if_ptr;
+ }
+ }
+ /* Xport match found */
+ status = glinki_add_ch_to_xport( if_ptr,
+ req_if_ptr,
+ ch_ctx,
+ &allocated_ch_ctx,
+ TRUE,
+ TRUE,
+ if_ptr->glink_priority );
+
+ if (status == GLINK_STATUS_SUCCESS) {
+ /* Set the handle and return */
+ *handle = allocated_ch_ctx;
+ }
+ else {
+ *handle = NULL;
+ }
+
+ glink_os_cs_release(glink_transport_q_cs);
+
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN, ch_ctx->name, xport_ctx->xport,
+ xport_ctx->remote_ss, status);
+ return status;
+ }
+ } /* end for() */
+
+ glink_os_cs_release(glink_transport_q_cs);
+
+ /* Code gets here if we are not able to find reqeusted transport */
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN, cfg_ptr->name, cfg_ptr->transport,
+ cfg_ptr->remote_ss, GLINK_STATUS_NO_TRANSPORT);
+ glink_os_free(ch_ctx);
+ return GLINK_STATUS_NO_TRANSPORT;
+}
+
+/**
+ * Closes the GLink logical channel specified by the handle.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects Closes local end of the channel and informs remote host
+ */
+glink_err_type glink_close
+(
+ glink_handle_type handle
+)
+{
+ glink_err_type status;
+ glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
+ glink_ch_state_type ch_state;
+
+ if(handle == NULL) {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, NULL, "",
+ "", GLINK_STATUS_INVALID_PARAM);
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+
+ ch_state = handle->state;
+
+ /* Check to see if channel is in open/opening state */
+ if (ch_state != GLINK_CH_STATE_OPEN &&
+ ch_state != GLINK_CH_STATE_LOCAL_OPEN &&
+ ch_state != GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE &&
+ ch_state != GLINK_CH_STATE_REMOTE_OPEN)
+ {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
+ xport_ctx->remote_ss, ch_state);
+ return GLINK_STATUS_FAILURE;
+ }
+
+ /* Transition to closing */
+ //handle->state = GLINK_CH_STATE_CLOSING;
+
+ /* Send CLOSE cmd to the transport interface */
+ status = handle->if_ptr->tx_cmd_ch_close(handle->if_ptr, handle->lcid);
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
+ xport_ctx->remote_ss, status);
+ return status;
+
+}
+
+/**
+ * Transmit the provided buffer over GLink.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[in] *pkt_priv Per packet private data
+ *
+ * @param[in] *data Pointer to the data buffer to be transmitted
+ *
+ * @param[in] size Size of buffer
+ *
+ * @param[in] req_intent Whether to block and request for remote rx intent in
+ * case it is not available for this pkt tx
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects Causes remote host to wake-up and process rx pkt
+ */
+glink_err_type glink_tx
+(
+ glink_handle_type handle,
+ const void *pkt_priv,
+ const void *data,
+ size_t size,
+ uint32 options
+)
+{
+ return glink_txv(handle, pkt_priv, (void*)data, size,
+ &glink_dummy_tx_vprovider, NULL, options);
+
+}
+
+/**
+ * Transmit the provided vector buffer over GLink.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[in] *pkt_priv Per packet private data
+ *
+ * @param[in] *iovec Pointer to the vector buffer to be transmitted
+ *
+ * @param[in] size Size of buffer
+ *
+ * @param[in] vprovider Buffer provider for virtual space
+ *
+ * @param[in] pprovider Buffer provider for physical space
+ *
+ * @param[in] req_intent Whether to block and request for remote rx intent in
+ * case it is not available for this pkt tx
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects Causes remote host to wake-up and process rx pkt
+ */
+glink_err_type glink_txv
+(
+ glink_handle_type handle,
+ const void *pkt_priv,
+ void *iovec,
+ size_t size,
+ glink_buffer_provider_fn vprovider,
+ glink_buffer_provider_fn pprovider,
+ uint32 options
+)
+{
+ glink_err_type status;
+ glink_core_tx_pkt_type pctx;
+ boolean req_intent = options & GLINK_TX_REQ_INTENT;
+ glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
+
+ /* Input validation */
+ if(handle == NULL || iovec == NULL || size == 0 ||
+ (vprovider == NULL && pprovider == NULL)) {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_TX, NULL, "",
+ "", GLINK_STATUS_INVALID_PARAM);
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+
+ /* Make sure channel is in OPEN state */
+ if(handle->state != GLINK_CH_STATE_OPEN )
+ {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
+ return GLINK_STATUS_FAILURE;
+ }
+
+ /* Protect the entire tx operation under a lock as a client may call
+ tx in different thread context */
+ glink_os_cs_acquire(&handle->tx_cs);
+
+ pctx.pkt_priv = pkt_priv;
+ pctx.size = size;
+ pctx.size_remaining = size;
+ pctx.vprovider = vprovider;
+ pctx.pprovider = pprovider;
+
+ if (vprovider == &glink_dummy_tx_vprovider)
+ {
+ pctx.data = (void*)iovec;
+ pctx.iovec = &pctx;
+ }
+ else
+ {
+ pctx.data = (void*)iovec;
+ pctx.iovec = iovec;
+ }
+
+ status = xport_ctx->use_rm_intent(handle, &pctx, req_intent);
+
+ /* Call transport API to transmit data */
+ while (pctx.size_remaining != 0 && status == GLINK_STATUS_SUCCESS)
+ {
+ status = handle->if_ptr->tx(handle->if_ptr, handle->lcid, &pctx);
+ }
+
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_TX, handle->name, xport_ctx->xport,
+ xport_ctx->remote_ss, status);
+
+ glink_os_cs_release(&handle->tx_cs);
+ return status;
+}
+
+/**
+ * Queue one or more Rx intent for the logical GPIC Link channel.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[in] *pkt_priv Per packet private data
+ *
+ * @param[in] size Size of buffer
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects GLink XAL allocates rx buffers for receiving packets
+ */
+glink_err_type glink_queue_rx_intent
+(
+ glink_handle_type handle,
+ const void *pkt_priv,
+ size_t size
+)
+{
+ glink_err_type status;
+ glink_rx_intent_type *lc_intent;
+ glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
+ size_t tmp;
+
+ /* Input validation */
+ if(handle == NULL || size == 0) {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, NULL, "",
+ "", GLINK_STATUS_INVALID_PARAM);
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+
+ /* short circuit for intentless mode */
+ if(xport_ctx->xport_capabilities & GLINK_CAPABILITY_INTENTLESS) {
+ return GLINK_STATUS_FAILURE;
+ }
+
+ /* Make sure channel is in OPEN state */
+ if(handle->state != GLINK_CH_STATE_OPEN)
+ {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
+ return GLINK_STATUS_FAILURE;
+ }
+
+ /* Allocate an intent structure */
+ lc_intent = glink_os_calloc(sizeof(glink_rx_intent_type));
+ if(lc_intent == NULL) {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
+ return GLINK_STATUS_OUT_OF_RESOURCES;
+ }
+
+ glink_os_cs_acquire(&handle->if_ptr->glink_core_priv->liid_cs);
+
+ /* Call transport API to allocate rx intent buffer */
+ status = handle->if_ptr->allocate_rx_intent(handle->if_ptr, size, lc_intent);
+ if(status != GLINK_STATUS_SUCCESS) {
+ glink_os_free(lc_intent);
+ glink_os_cs_release(&handle->if_ptr->glink_core_priv->liid_cs);
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name, xport_ctx->xport,
+ xport_ctx->remote_ss, status);
+ return status;
+ }
+
+ if (handle->notify_rxv == NULL &&
+ (lc_intent->vprovider(lc_intent->iovec, 0, &tmp) == NULL || tmp < size)) {
+ /* Allocate bounce buffer for non-vectored Rx */
+ lc_intent->data = glink_os_malloc(size);
+
+ if(lc_intent->data == NULL) {
+ handle->if_ptr->deallocate_rx_intent(handle->if_ptr, lc_intent);
+ glink_os_free(lc_intent);
+ glink_os_cs_release(&handle->if_ptr->glink_core_priv->liid_cs);
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name,
+ xport_ctx->xport, xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
+ return GLINK_STATUS_OUT_OF_RESOURCES;
+ }
+ }
+
+ /* push the intent on local queue. Do this before calling tx cmd
+ as transport may try to read data into the newly queued rx_buffer */
+ lc_intent->iid = handle->if_ptr->glink_core_priv->liid;
+ lc_intent->size = size;
+ lc_intent->pkt_priv = pkt_priv;
+ glink_os_cs_acquire(&handle->pintents->intent_q_cs);
+ smem_list_append(&handle->pintents->local_intent_q, lc_intent);
+ glink_os_cs_release(&handle->pintents->intent_q_cs);
+
+ /* Call transport API to queue rx intent */
+ /* Increment the local intent ID counter associated with this channel */
+ handle->if_ptr->glink_core_priv->liid++;
+
+ status = handle->if_ptr->tx_cmd_local_rx_intent(handle->if_ptr,
+ handle->lcid, size, lc_intent->iid);
+ if(status != GLINK_STATUS_SUCCESS) {
+ /* Failure */
+ glink_os_cs_acquire(&handle->pintents->intent_q_cs);
+ smem_list_delete(&handle->pintents->local_intent_q, lc_intent);
+ glink_os_cs_release(&handle->pintents->intent_q_cs);
+
+ handle->if_ptr->deallocate_rx_intent(handle->if_ptr, lc_intent);
+ glink_os_free(lc_intent->data);
+ glink_os_free(lc_intent);
+ }
+ glink_os_cs_release(&handle->if_ptr->glink_core_priv->liid_cs);
+
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name, xport_ctx->xport,
+ xport_ctx->remote_ss, status);
+ return status;
+}
+
+/**
+ * Client uses this to signal to GLink layer that it is done with the received
+ * data buffer. This API should be called to free up the receive buffer, which,
+ * in zero-copy mode is actually remote-side's transmit buffer.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[in] *ptr Pointer to the received buffer
+ *
+ * @param[in] reuse Reuse intent
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects GLink XAL frees the Rx buffer
+ */
+glink_err_type glink_rx_done
+(
+ glink_handle_type handle,
+ const void *ptr,
+ boolean reuse
+)
+{
+ glink_rx_intent_type *lc_intent;
+ glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
+
+ /* Input validation */
+ if(handle == NULL || ptr == NULL) {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_RX_DONE, NULL, "",
+ "", GLINK_STATUS_INVALID_PARAM);
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+
+ /* short circuit for intentless mode */
+ if(xport_ctx->xport_capabilities & GLINK_CAPABILITY_INTENTLESS) {
+ return GLINK_STATUS_SUCCESS;
+ }
+
+ /* Make sure channel is in OPEN state */
+ if(handle->state != GLINK_CH_STATE_OPEN)
+ {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_RX_DONE, handle->name, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
+ return GLINK_STATUS_FAILURE;
+ }
+
+ /* Free the intent */
+ lc_intent = smem_list_first(&handle->pintents->local_intent_client_q);
+ while(lc_intent != NULL) {
+ size_t tmp;
+
+ if(lc_intent->iovec == ptr || (handle->notify_rxv == NULL &&
+ (lc_intent->data == ptr ||
+ ptr == lc_intent->vprovider(lc_intent->iovec, 0, &tmp)))) {
+
+ uint32 iid;
+
+ /* Found intent, delete it */
+ glink_os_cs_acquire(&handle->pintents->intent_q_cs);
+ smem_list_delete(&handle->pintents->local_intent_client_q, lc_intent);
+ glink_os_cs_release(&handle->pintents->intent_q_cs);
+
+ iid = lc_intent->iid;
+
+ if (reuse)
+ {
+ lc_intent->used = 0;
+
+ glink_os_cs_acquire(&handle->pintents->intent_q_cs);
+ smem_list_append(&handle->pintents->local_intent_q, lc_intent);
+ glink_os_cs_release(&handle->pintents->intent_q_cs);
+ }
+ else
+ {
+ /* Free the intent */
+ handle->if_ptr->deallocate_rx_intent(handle->if_ptr, lc_intent);
+ if(lc_intent->data) {
+ /* Free the bounce buffer if we had allocated one */
+ glink_os_free(lc_intent->data);
+ }
+ glink_os_free(lc_intent);
+ }
+
+ /* Note that the actual buffer, lc_intent->data, was allocated by the
+ * transport and should be freed by the xport. We should not touch it */
+ /* Let the xport know we are done with the buffer */
+ handle->if_ptr->tx_cmd_local_rx_done(handle->if_ptr, handle->lcid,
+ iid, reuse);
+
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_RX_DONE, handle->name, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
+ return GLINK_STATUS_SUCCESS;
+ }
+ lc_intent = smem_list_next(lc_intent);
+ }
+
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_RX_DONE, handle->name, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_INVALID_PARAM);
+ return GLINK_STATUS_INVALID_PARAM;
+}
+
+/**
+ * Set the 32 bit control signal field. Depending on the transport, it may
+ * take appropriate actions on the set bit-mask, or transmit the entire
+ * 32-bit value to the remote host.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[in] sig_value 32 bit signal word
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects None
+ */
+glink_err_type glink_sigs_set
+(
+ glink_handle_type handle,
+ uint32 sig_value
+)
+{
+ glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
+ glink_err_type status;
+
+ /* Input validation */
+ if(handle == NULL) {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_SIG_SET, NULL, "",
+ "", GLINK_STATUS_INVALID_PARAM);
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+
+ /* Make sure channel is in OPEN state */
+ if(handle->state != GLINK_CH_STATE_OPEN)
+ {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_SIG_SET, handle->name, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
+ return GLINK_STATUS_FAILURE;
+ }
+
+ status = handle->if_ptr->tx_cmd_set_sigs(handle->if_ptr, handle->lcid,
+ sig_value);
+ if(GLINK_STATUS_SUCCESS == status) {
+ /* Update local copy of local control signal state */
+ handle->local_sigs = sig_value;
+ }
+
+ return status;
+}
+
+/**
+ * Get the local 32 bit control signal bit-field.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[out] *sig_value Pointer to a 32 bit signal word to get sig value
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects None
+ */
+glink_err_type glink_sigs_local_get
+(
+ glink_handle_type handle,
+ uint32 *sig_value
+)
+{
+ /* Input validation */
+ if(handle == NULL || sig_value == NULL) {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_SIG_L_GET, NULL, "",
+ "", GLINK_STATUS_INVALID_PARAM);
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+
+ *sig_value = handle->local_sigs;
+
+ return GLINK_STATUS_SUCCESS;
+}
+
+/**
+ * Get the remote 32 bit control signal bit-field.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[out] *sig_value Pointer to a 32 bit signal word to get sig value
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects None
+ */
+glink_err_type glink_sigs_remote_get
+(
+ glink_handle_type handle,
+ uint32 *sig_value
+)
+{
+ /* Input validation */
+ if(handle == NULL || sig_value == NULL) {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_SIG_R_GET, NULL, "",
+ "", GLINK_STATUS_INVALID_PARAM);
+ return GLINK_STATUS_INVALID_PARAM;
+ }
+
+ *sig_value = handle->remote_sigs;
+
+ return GLINK_STATUS_SUCCESS;
+}
+
+/*================= RESTRICTED API ==========================*/
+
+/**
+ * This API allows the RPM client to poll the transport for any new data
+ * that might have come in. It would *usually* be used when incoming interrupts
+ * are disabled.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects None
+ */
+glink_err_type glink_rpm_rx_poll
+(
+ glink_handle_type handle
+)
+{
+ ASSERT(handle);
+
+ if(handle->if_ptr->poll) {
+ return handle->if_ptr->poll(handle->if_ptr);
+ }
+ return GLINK_STATUS_FAILURE;
+}
+
+/**
+ * This API allows the RPM client to mask/unmask rx interrupts
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[in] mask Whether to mask or un-mask the incoming interrupt
+ *
+ * @param[in] platform_struct Any platform specific into that transport may
+ require
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects None
+ */
+glink_err_type glink_rpm_mask_rx_interrupt
+(
+ glink_handle_type handle,
+ boolean mask,
+ void *platform_struct
+)
+{
+ ASSERT(handle);
+
+ if(handle->if_ptr->mask_rx_irq) {
+ return handle->if_ptr->mask_rx_irq(handle->if_ptr, mask);
+ }
+ return GLINK_STATUS_FAILURE;
+}
+
+/**
+ * This API waits until link is down.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects None
+ */
+glink_err_type glink_wait_link_down
+(
+ glink_handle_type handle
+)
+{
+ ASSERT(handle && handle->if_ptr && handle->if_ptr->wait_link_down);
+
+ return handle->if_ptr->wait_link_down(handle->if_ptr) ?
+ GLINK_STATUS_SUCCESS : GLINK_STATUS_FAILURE;
+}
+
+/* ============ Internal Logging API ================ */
+void glink_mem_log
+(
+ const char *func,
+ uint32 line,
+ glink_log_event_type type,
+ const char *msg,
+ const char *xport,
+ const char *remote_ss,
+ uint32 param
+)
+{
+#ifdef DEBUG_GLINK
+ dprintf(INFO, "%s:%u, event:%d, msg:%s, xport:%s, remote_ss:%s, param:%u\n", func, line, type, msg, xport, remote_ss, param);
+#endif
+}
diff --git a/platform/msm_shared/glink/glink_core_if.c b/platform/msm_shared/glink/glink_core_if.c
new file mode 100644
index 0000000..3c66369
--- /dev/null
+++ b/platform/msm_shared/glink/glink_core_if.c
@@ -0,0 +1,983 @@
+/* Copyright (c) 2015, 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 FILES
+===========================================================================*/
+
+#include "glink_os_utils.h"
+#include "glink.h"
+#include "glink_internal.h"
+#include "glink_core_if.h"
+#include "smem_list.h"
+#include "glink_channel_migration.h"
+
+
+#define FEATURE_CH_MIGRATION_FREE
+
+void glinki_scan_notif_list_and_notify
+(
+ glink_transport_if_type *if_ptr,
+ glink_link_state_type state
+);
+
+/*===========================================================================
+ GLOBAL DATA DECLARATIONS
+===========================================================================*/
+
+/*===========================================================================
+ LOCAL FUNCTION DEFINITIONS
+===========================================================================*/
+/*===========================================================================
+FUNCTION glink_process_negotiation_complete
+===========================================================================*/
+/**
+
+ This is called when negotiation is complete.
+ It will set the version and call link up callback to notify
+
+
+ @param[in] xport_ctx transport context
+
+ @param[in] if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ @param[in] version negotiated version
+
+ @param[in] features negotiated with local side
+
+ @return None
+ @sideeffects None.
+ @dependencies None.
+*/
+/*=========================================================================*/
+static void glink_process_negotiation_complete
+(
+ glink_core_xport_ctx_type *xport_ctx,
+ glink_transport_if_type *if_ptr,
+ uint32 version,
+ uint32 features
+)
+{
+ /* Version/Feautre can be negotiated both in ver_req and ver_ack
+ * Only go through process once in case they are negotiated
+ * in ver_req before receiving ver_ack */
+ if( xport_ctx->status == GLINK_XPORT_LINK_UP )
+ {
+ return;
+ }
+
+ /* setup core based on transport capabilities*/
+ xport_ctx->xport_capabilities = if_ptr->set_version( if_ptr,
+ version,
+ features );
+ glink_core_setup(if_ptr);
+
+ /* transport is ready to open channels */
+ if_ptr->glink_core_priv->status = GLINK_XPORT_LINK_UP;
+
+ /* Scan the notification list to check is we have to let any registered
+ * clients know that link came online */
+ glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_UP);
+}
+
+static void glink_dummy_ch_migration_notification_cb
+(
+ glink_handle_type handle,
+ const void *priv,
+ glink_channel_event_type event
+)
+{
+}
+
+/*===========================================================================
+ EXTERNAL FUNCTION DEFINITIONS
+===========================================================================*/
+/*===========================================================================
+FUNCTION glink_link_up
+
+DESCRIPTION Indicates that transport is now ready to start negotiation
+ using the v0 configuration
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_link_up
+(
+ glink_transport_if_type *if_ptr
+)
+{
+ const glink_core_version_type *version_array;
+ glink_core_xport_ctx_type *xport_ctx;
+
+ ASSERT(if_ptr != NULL);
+
+ xport_ctx = if_ptr->glink_core_priv;
+
+ version_array = xport_ctx->version_array;
+
+ /* Update the transport state */
+ if_ptr->glink_core_priv->status = GLINK_XPORT_NEGOTIATING;
+
+ /* Start the negtiation */
+ if_ptr->tx_cmd_version(if_ptr, version_array->version,
+ version_array->features);
+
+ GLINK_LOG_EVENT(GLINK_EVENT_LINK_UP, NULL, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
+
+}
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_version
+
+DESCRIPTION Receive transport version for remote-initiated version
+ negotiation
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ version Remote Version
+
+ features Remote Features
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_version
+(
+ glink_transport_if_type *if_ptr,
+ uint32 version,
+ uint32 features
+)
+{
+ const glink_core_version_type *ver;
+ uint32 negotiated_features;
+ glink_core_xport_ctx_type *xport_ctx;
+
+ ASSERT(if_ptr != NULL);
+
+ xport_ctx = if_ptr->glink_core_priv;
+
+ /* The version to use must be a subset of supported version and features
+ * on this host and remote host */
+ ver = &xport_ctx->version_array[xport_ctx->version_indx];
+ ASSERT(ver);
+
+ if (version == ver->version)
+ {
+ /* Call the transport's negotiation function */
+ negotiated_features = ver->negotiate_features(if_ptr, ver, features);
+
+ /* If negotiated features match the provided features, version nogetiation
+ * is complete */
+ if(negotiated_features == features)
+ {
+ /* send version ack before allowing to open channels */
+ if_ptr->tx_cmd_version_ack(if_ptr, version, features);
+
+ glink_process_negotiation_complete( xport_ctx, if_ptr,
+ version, features );
+ return;
+ }
+ else
+ {
+ if_ptr->tx_cmd_version_ack(if_ptr, version, negotiated_features);
+ }
+ }
+ else
+ {
+ /* Next time use older version */
+ ver = &xport_ctx->version_array[xport_ctx->version_indx];
+
+ /* Versions don't match, return ACK with the feature set that we support */
+ if_ptr->tx_cmd_version_ack(if_ptr, ver->version, ver->features);
+ }
+}
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_version_ack
+
+DESCRIPTION Receive ACK to previous glink_transport_if::tx_cmd_version
+ command
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ version Remote Version
+
+ features Remote Features
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_version_ack
+(
+ glink_transport_if_type *if_ptr,
+ uint32 version,
+ uint32 features
+)
+{
+ const glink_core_version_type* ver;
+ uint32 negotiated_features;
+ glink_core_xport_ctx_type *xport_ctx;
+
+ ASSERT(if_ptr != NULL);
+
+ xport_ctx = if_ptr->glink_core_priv;
+
+ /* Check to see if version returned by remote end is supported by
+ * this host. Remote side would have acked only when the version/features
+ * sent by this host did not match the remote */
+
+ ver = &xport_ctx->version_array[xport_ctx->version_indx];
+ ASSERT(ver);
+
+ if (ver->version == version)
+ {
+ /* Call the transport's negotiation function */
+ negotiated_features = ver->negotiate_features(if_ptr, ver, features);
+
+ if(negotiated_features != features)
+ {
+ /* Continue negotiating */
+ if_ptr->tx_cmd_version(if_ptr, version, negotiated_features);
+ }
+ else
+ {
+ glink_process_negotiation_complete( xport_ctx, if_ptr,
+ version, features );
+ }
+ }
+ else
+ {
+ while (ver->version > version)
+ {
+ /* Next time use older version */
+ ASSERT(xport_ctx->version_indx > 0);
+ xport_ctx->version_indx--;
+ ver = &xport_ctx->version_array[xport_ctx->version_indx];
+ }
+
+ /* Versions don't match, return ACK with the feature set that we support */
+ if_ptr->tx_cmd_version(if_ptr, ver->version, ver->features);
+ }
+}
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_ch_remote_open
+
+DESCRIPTION Receive remote channel open request; Calls
+ glink_transport_if:: tx_cmd_ch_remote_open_ack as a result
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ rcid Remote Channel ID
+
+ *name String name for logical channel
+
+ prio xport priority requested by remote side
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_ch_remote_open
+(
+ glink_transport_if_type *if_ptr,
+ uint32 rcid,
+ const char *name,
+ glink_xport_priority priority
+)
+{
+ glink_channel_ctx_type *remote_ch_ctx;
+ glink_channel_ctx_type *allocated_ch_ctx;
+ glink_core_xport_ctx_type *xport_ctx;
+ glink_err_type status;
+ glink_xport_priority negotiated_prio;
+ boolean migration_state = TRUE;
+
+ ASSERT(if_ptr != NULL);
+ ASSERT(name != NULL);
+
+#ifndef FEATURE_CH_MIGRATION_FREE
+ glink_transport_if_type *present_if_ptr = NULL;
+ boolean channel_exist = FALSE;
+ glink_channel_ctx_type *present_ch_ctx = NULL;
+ /* search if channel with given name exists locally */
+ channel_exist = glinki_local_channel_exists(if_ptr, &present_if_ptr, name, &present_ch_ctx, TRUE);
+
+ /* start channel migration negotiation only if channel exists on local side
+ * for negotiation AND channel is willing to migrate */
+ if(channel_exist &&
+ (present_ch_ctx->ch_open_options & GLINK_OPT_INITIAL_XPORT))
+ {
+ /* channel exists on one of the xports for given remote ss */
+ current_prio = present_ch_ctx->req_if_ptr->glink_priority;
+ negotiated_prio = glinki_negotiate_ch_migration(priority, current_prio);
+
+ /* if current channel is open in same xport as negotiated xport
+ * local side wont migrate. Set migration flag to FALSE */
+ if(negotiated_prio == present_if_ptr->glink_priority)
+ {
+ migration_state = FALSE;
+ }
+ }
+ else if(channel_exist)
+ {
+ /* channel exists but channel does not want to be moved to another xport.
+ channel is set in stone */
+ negotiated_prio = present_if_ptr->glink_priority;
+ migration_state = FALSE;
+ }
+ else
+ {
+ /* channel does not exist on local side as yet
+ * return negotiated prio as current xport prio on which
+ * remote open request is received */
+ negotiated_prio = if_ptr->glink_priority;
+ migration_state = FALSE;
+ }
+#else
+ negotiated_prio = if_ptr->glink_priority;
+ migration_state = FALSE;
+#endif
+
+ xport_ctx = if_ptr->glink_core_priv;
+
+ /* Allocate and initialize channel info structure */
+ remote_ch_ctx = glink_os_calloc(sizeof(glink_channel_ctx_type));
+ if(remote_ch_ctx == NULL) {
+ GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
+ ASSERT(0);
+ }
+
+ /* Fill in the channel info structure */
+ glink_os_string_copy(remote_ch_ctx->name, name, sizeof(remote_ch_ctx->name));
+ remote_ch_ctx->rcid = rcid;
+
+ status = glinki_add_ch_to_xport(if_ptr, NULL, remote_ch_ctx,
+ &allocated_ch_ctx, FALSE,
+ migration_state, negotiated_prio);
+ ASSERT(status == GLINK_STATUS_SUCCESS);
+
+ GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
+
+#ifndef FEATURE_CH_MIGRATION_FREE
+
+ /* We are done with channel migration negotiation at this stage
+ * Tag all channels with given name on xports other than negotiated
+ * xport for deletion */
+ glinki_tag_ch_for_deletion(if_ptr, name, negotiated_prio);
+
+ if(migration_state == TRUE)
+ {
+ glink_channel_ctx_type *new_ch_ctx;
+
+ /* create a new channel context as current channel will be migrated */
+ new_ch_ctx = (glink_channel_ctx_type *)
+ glink_os_calloc(sizeof(glink_channel_ctx_type));
+
+ /* Fill in the channel info structure */
+ new_ch_ctx->req_if_ptr =
+ glinki_get_xport_from_prio(negotiated_prio,
+ if_ptr->glink_core_priv->remote_ss);
+ glink_os_string_copy(new_ch_ctx->name, present_ch_ctx->name,
+ sizeof(present_ch_ctx->name));
+ new_ch_ctx->priv = present_ch_ctx->priv;
+ new_ch_ctx->notify_rx = present_ch_ctx->notify_rx;
+ new_ch_ctx->notify_rxv = present_ch_ctx->notify_rxv;
+ new_ch_ctx->notify_tx_done = present_ch_ctx->notify_tx_done;
+ new_ch_ctx->notify_state = present_ch_ctx->notify_state;
+ new_ch_ctx->notify_rx_intent_req = present_ch_ctx->notify_rx_intent_req;
+ new_ch_ctx->notify_rx_intent = present_ch_ctx->notify_rx_intent;
+ new_ch_ctx->notify_rx_sigs = present_ch_ctx->notify_rx_sigs;
+ new_ch_ctx->ch_open_options = present_ch_ctx->ch_open_options;
+
+// glink_os_cs_init(&new_ch_ctx->intent_q_cs);
+
+ /* close current channel */
+ present_ch_ctx->notify_state = glink_dummy_ch_migration_notification_cb;
+ if_ptr->tx_cmd_ch_close( if_ptr, present_ch_ctx->lcid );
+
+ /* add new channel context on negotiated xport */
+ glinki_add_ch_to_xport(new_ch_ctx->req_if_ptr,
+ new_ch_ctx->req_if_ptr,
+ new_ch_ctx,
+ &allocated_ch_ctx,
+ TRUE,
+ TRUE,
+ new_ch_ctx->req_if_ptr->glink_priority);
+ }
+#endif
+}
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_ch_open_ack
+
+DESCRIPTION This function is invoked by the transport in response to
+ glink_transport_if:: tx_cmd_ch_open
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ lcid Local Channel ID
+
+ prio Negotiated xport priority from remote side
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_ch_open_ack
+(
+ glink_transport_if_type *if_ptr,
+ uint32 lcid,
+ glink_xport_priority migrated_ch_prio
+)
+{
+ glink_channel_ctx_type *open_ch_ctx;
+ glink_core_xport_ctx_type *xport_ctx;
+
+ ASSERT(if_ptr != NULL);
+
+ xport_ctx = if_ptr->glink_core_priv;
+
+ /* Move to closed state. Implies we clean up the channel from the
+ * open list */
+
+ /* Find channel in the open_list */
+ open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+ while(open_ch_ctx != NULL)
+ {
+ if(open_ch_ctx->lcid == lcid) {
+#ifndef FEATURE_CH_MIGRATION_FREE
+ glink_transport_if_type *present_if_ptr = NULL;
+ glink_channel_ctx_type *present_ch_ctx = NULL;
+ boolean channel_exist;
+ /* find the channel in all xport list */
+ channel_exist = glinki_local_channel_exists(if_ptr,
+ &present_if_ptr,
+ open_ch_ctx->name,
+ &present_ch_ctx,
+ FALSE);
+
+ if(if_ptr->glink_priority == migrated_ch_prio && !channel_exist)
+ {
+ /* only local side has opened the channel. Remote side has not come up yet
+ * which implies negotiation did not take place on remote side */
+ /* DO NOTHING */
+ }
+ else if(if_ptr->glink_priority == migrated_ch_prio)
+ {
+ /* remote channel exists. channel migration negotiation happened
+ * on remote side and negotitated xport is same as current xport */
+ if(present_ch_ctx->ref_count == 1)
+ {
+ /* remote channel is present on different xport than negotiated one.
+ * remote side will migrate its channel to negotiated xport */
+ /* DO NOTHING */
+ }
+ else if(present_ch_ctx->ref_count == 2)
+ {
+ /* remote channel is open on same xport as current xport.
+ * change channel state to GLINK_CH_STATE_OPEN and notify client */
+ open_ch_ctx->state = GLINK_CH_STATE_OPEN;
+ open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
+ GLINK_CONNECTED);
+ }
+ else
+ {
+ /* something went wrong in updating ref_count of channel */
+ ASSERT(0);
+ }
+ }
+ else
+ {
+
+ /* migrated xport priority <> current xport priority */
+ /* check if remote channel is opened on negotiated xport already */
+ if(migrated_ch_prio == present_if_ptr->glink_priority &&
+ (open_ch_ctx->ch_open_options & GLINK_OPT_INITIAL_XPORT))
+ {
+ /* remote channel is already on negotiated xport. remote channel
+ * will not migrate. Local side should migrate */
+
+ glink_channel_ctx_type *new_ch_ctx =
+ (glink_channel_ctx_type *)glink_os_calloc(
+ sizeof(glink_channel_ctx_type));
+
+ /* Fill in the channel info structure */
+ glink_os_string_copy(new_ch_ctx->name,
+ open_ch_ctx->name,
+ sizeof(open_ch_ctx->name));
+ new_ch_ctx->priv = open_ch_ctx->priv;
+ new_ch_ctx->notify_rx = open_ch_ctx->notify_rx;
+ new_ch_ctx->notify_rxv = open_ch_ctx->notify_rxv;
+ new_ch_ctx->notify_tx_done = open_ch_ctx->notify_tx_done;
+ new_ch_ctx->notify_state = open_ch_ctx->notify_state;
+ new_ch_ctx->notify_rx_intent_req =
+ open_ch_ctx->notify_rx_intent_req;
+ new_ch_ctx->notify_rx_intent = open_ch_ctx->notify_rx_intent;
+ new_ch_ctx->notify_rx_sigs = open_ch_ctx->notify_rx_sigs;
+ new_ch_ctx->ch_open_options = open_ch_ctx->ch_open_options;
+
+ present_ch_ctx->notify_state = glink_dummy_ch_migration_notification_cb;
+ if_ptr->tx_cmd_ch_close( if_ptr, present_ch_ctx->lcid );
+
+ /* migrate to negotiated xport */
+ glinki_add_ch_to_xport(present_if_ptr,
+ present_if_ptr,
+ new_ch_ctx,
+ NULL,
+ TRUE,
+ TRUE,
+ present_if_ptr->glink_priority);
+ }
+ else
+ {
+ /* Either our transport is "set in stone" OR */
+ /* remote side will migrate to negotiated xport and will call
+ * remote open on this side which will cause channel migration
+ * negotiation and this side will ultimately migrate */
+ /* DO NOTHING */
+ }
+ }
+#else
+ if(open_ch_ctx->ref_count == 2)
+ {
+ /* remote channel is open on same xport as current xport.
+ * change channel state to GLINK_CH_STATE_OPEN and notify client */
+ open_ch_ctx->state = GLINK_CH_STATE_OPEN;
+ open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
+ GLINK_CONNECTED);
+ }
+#endif
+
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN_ACK, open_ch_ctx->name,
+ xport_ctx->xport, xport_ctx->remote_ss, lcid);
+ return;
+ }
+ open_ch_ctx = smem_list_next(open_ch_ctx);
+ }
+ /* We are here in case we could not find the channel in the open list. */
+ ASSERT(0);
+}
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_ch_close_ack
+
+DESCRIPTION This function is invoked by the transport in response to
+ glink_transport_if_type:: tx_cmd_ch_close
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ lcid Local Channel ID
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_ch_close_ack
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid /* Local channel ID */
+)
+{
+ glink_channel_ctx_type *open_ch_ctx;
+ glink_core_xport_ctx_type *xport_ctx;
+
+ ASSERT(if_ptr != NULL);
+
+ xport_ctx = if_ptr->glink_core_priv;
+
+ /* Move to closed state. Implies we clean up the channel from the
+ * open list */
+
+ /* Find channel in the open_list */
+ glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+ open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+ while(open_ch_ctx != NULL)
+ {
+ if(open_ch_ctx->lcid == lcid) {
+ /* Found channel */
+ open_ch_ctx->ref_count--;
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE_ACK, open_ch_ctx->name,
+ xport_ctx->xport, xport_ctx->remote_ss, lcid);
+
+ /* Transition state */
+ if(open_ch_ctx->state == GLINK_CH_STATE_OPEN) {
+ /* this side initiated close procedure */
+ open_ch_ctx->state = GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE;
+ } else if(open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN ||
+ open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE ||
+ open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN) {
+ /* Other side never opened the port, or closed from its end */
+ /* Clear everything */
+ if(open_ch_ctx->ref_count == 0)
+ {
+ xport_ctx->channel_cleanup(open_ch_ctx);
+ /* re-use channel id if it can be done */
+ if(lcid == (xport_ctx->free_lcid-1)) {
+ /* If channel being closed is the last opened channel
+ re-use the lcid of this channel for any new channels */
+ xport_ctx->free_lcid--;
+ }
+ smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+
+ /* Notify the client */
+ open_ch_ctx->notify_state( open_ch_ctx, open_ch_ctx->priv,
+ GLINK_LOCAL_DISCONNECTED);
+ glink_os_free(open_ch_ctx);
+ }
+ } else {
+ /* Unsupported state */
+ ASSERT(0);
+ }
+
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+ return;
+ }
+ open_ch_ctx = smem_list_next(open_ch_ctx);
+ }/* end while */
+
+ /* We are here in case we could not find the channel in the open list. */
+ ASSERT(0);
+
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+}
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_ch_remote_close
+
+DESCRIPTION Remote channel close request; will result in sending
+ glink_transport_if_type:: tx_cmd_ch_remote_close_ack
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ rcid Remote Channel ID
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_ch_remote_close
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid /* Remote channel ID */
+)
+{
+ glink_channel_ctx_type *open_ch_ctx;
+ glink_core_xport_ctx_type *xport_ctx;
+
+ ASSERT(if_ptr != NULL);
+
+ xport_ctx = if_ptr->glink_core_priv;
+
+ /* Find channel in the open_list */
+ glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+ open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+ while(open_ch_ctx != NULL)
+ {
+ if(open_ch_ctx->rcid == rcid) {
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_REMOTE_CLOSE, open_ch_ctx->name,
+ xport_ctx->xport, xport_ctx->remote_ss, rcid);
+ /* Found channel, transition it to appropriate state based
+ * on current state */
+ open_ch_ctx->ref_count--;
+
+ if(open_ch_ctx->state == GLINK_CH_STATE_OPEN) {
+ open_ch_ctx->state = GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE;
+
+ /* Inform the client */
+ open_ch_ctx->notify_state( open_ch_ctx, open_ch_ctx->priv,
+ GLINK_REMOTE_DISCONNECTED);
+
+ /* Send the remote close ACK back to the other side */
+ if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
+
+ /* Free channel resources */
+ xport_ctx->channel_cleanup(open_ch_ctx);
+
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_REMOTE_CLOSE, open_ch_ctx->name,
+ xport_ctx->xport, xport_ctx->remote_ss, rcid);
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+ return;
+ } else if (open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN ||
+ open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE) {
+ /* Local side never opened the channel OR it opened it but closed it */
+ /* Free channel resources */
+ xport_ctx->channel_cleanup(open_ch_ctx);
+
+ /* Send the remote close ACK back to the other side */
+ if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
+
+ if(open_ch_ctx->ref_count == 0)
+ {
+ /* re-use channel id if it can be done */
+ if (open_ch_ctx->lcid == (xport_ctx->free_lcid - 1)) {
+ /* If channel being closed is the last opened channel
+ re-use the lcid of this channel for any new channels */
+ xport_ctx->free_lcid--;
+ }
+ smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+ glink_os_free(open_ch_ctx);
+ }
+
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+ return;
+ } else {
+ /* SHould not get this callback for a channel in any other state */
+
+ //OS_LOG_ERROR(3, "GLINK_RX_CMD_CH_REMOTE_CLOSE: received close cmd for invalid state"
+ // "[channel ctx: 0x%x][current channel state: %d]",
+ // open_ch_ctx, open_ch_ctx->state );
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+ if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
+ return;
+ }
+ }
+ open_ch_ctx = smem_list_next(open_ch_ctx);
+ }/* end while */
+
+ /* We are here in case we could not find the channel in the open list
+ * or OPEN state. */
+ ASSERT(0);
+
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+}
+
+/*===========================================================================
+FUNCTION glink_ch_state_local_trans
+
+DESCRIPTION Process local state transition
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ rcid Remote Channel ID
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_ch_state_local_trans
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid, /* Local channel ID */
+ glink_ch_state_type new_state /* New local channel state */
+)
+{
+ glink_channel_ctx_type *open_ch_ctx;
+ glink_core_xport_ctx_type *xport_ctx;
+
+ ASSERT(if_ptr != NULL);
+
+ xport_ctx = if_ptr->glink_core_priv;
+
+ /* Find channel in the open_list */
+ open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+ while(open_ch_ctx != NULL)
+ {
+ if(open_ch_ctx->lcid == lcid) {
+ /* Found channel, transition it to appropriate state */
+ open_ch_ctx->state = new_state;
+ }
+ open_ch_ctx = smem_list_next(open_ch_ctx);
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_STATE_TRANS, open_ch_ctx->name,
+ xport_ctx->xport, xport_ctx->remote_ss, new_state);
+ return;
+ }/* end while */
+
+ /* We are here in case we could not find the channel in the open list
+ * or OPEN state. */
+ ASSERT(0);
+}
+
+/*===========================================================================
+FUNCTION glink_rx_put_pkt_ctx
+
+DESCRIPTION Transport invokes this call to receive a packet fragment (must
+ have previously received an rx_cmd_rx_data packet)
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ rcid Remote Channel ID
+
+ *intent_ptr Pointer to the intent fragment
+
+ complete True if pkt is complete
+
+RETURN VALUE None
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_put_pkt_ctx
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid, /* Remote channel ID */
+ glink_rx_intent_type *intent_ptr, /* Fragment ptr */
+ boolean complete /* True if pkt is complete */
+)
+{
+ glink_channel_ctx_type *open_ch_ctx;
+ glink_core_xport_ctx_type *xport_ctx;
+
+ ASSERT(if_ptr != NULL && intent_ptr != NULL);
+
+ xport_ctx = if_ptr->glink_core_priv;
+
+ /* Find channel in the open_list */
+ open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+ while(open_ch_ctx != NULL)
+ {
+ if(open_ch_ctx->rcid == rcid) {
+ /* Found channel */
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_PUT_PKT_CTX, open_ch_ctx->name,
+ xport_ctx->xport, xport_ctx->remote_ss, intent_ptr->iid);
+
+ xport_ctx->channel_receive_pkt(open_ch_ctx, intent_ptr);
+
+ return;
+ }
+ open_ch_ctx = smem_list_next(open_ch_ctx);
+ }/* end while */
+
+ /* We end up here if we don't find the channel */
+ ASSERT(0);
+}
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_remote_sigs
+
+DESCRIPTION Transport invokes this call to inform GLink of remote side
+ changing its control signals
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ rcid Remote Channel ID
+
+ remote_sigs Remote signal state.
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_remote_sigs
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid, /* Remote channel ID */
+ uint32 remote_sigs /* Remote control signals */
+)
+{
+ glink_channel_ctx_type *open_ch_ctx;
+ uint32 prev_sigs;
+
+ ASSERT(if_ptr != NULL);
+
+ /* Find channel in the open_list */
+ open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+ while(open_ch_ctx != NULL)
+ {
+ if(open_ch_ctx->rcid == rcid) {
+ /* Found channel, let client know of new remote signal state */
+ prev_sigs = open_ch_ctx->remote_sigs;
+ open_ch_ctx->remote_sigs = remote_sigs;
+ open_ch_ctx->notify_rx_sigs(open_ch_ctx, open_ch_ctx->priv,
+ prev_sigs, remote_sigs);
+ return;
+ }
+ open_ch_ctx = smem_list_next(open_ch_ctx);
+ }
+
+ /* We end up here if we don't find the channel */
+ ASSERT(0);
+}
+
+
+/*===========================================================================
+FUNCTION glink_tx_resume
+
+DESCRIPTION If transport was full and could not continue a transmit
+ operation, then it will call this function to notify the core
+ that it is ready to resume transmission.
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_tx_resume
+(
+ glink_transport_if_type *if_ptr /* Pointer to the interface instance */
+)
+{
+ /* Not sure what to do here */
+}
+
+
+/*===========================================================================
+FUNCTION glink_set_core_version
+
+DESCRIPTION Sets the core version used by the transport; called after
+ completing negotiation.
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ version Negotiated transport version
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_set_core_version
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 version /* Version */
+)
+{
+}
diff --git a/platform/msm_shared/glink/glink_core_intentless_xport.c b/platform/msm_shared/glink/glink_core_intentless_xport.c
new file mode 100644
index 0000000..289ef18
--- /dev/null
+++ b/platform/msm_shared/glink/glink_core_intentless_xport.c
@@ -0,0 +1,131 @@
+/* Copyright (c) 2015, 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 FILES
+===========================================================================*/
+
+#include "glink.h"
+#include "glink_internal.h"
+
+/*===========================================================================
+LOCAL FUNCTION DEFINITIONS
+===========================================================================*/
+
+/*===========================================================================
+ FUNCTION glink_core_stub_intentless
+===========================================================================*/
+/**
+
+ Stub for intentless transport functionality.
+
+ @return GLINK_STATUS_SUCCESS.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+
+static glink_err_type glink_core_stub_intentless(void)
+{
+ return GLINK_STATUS_SUCCESS;
+}
+
+/*===========================================================================
+ FUNCTION glink_verify_open_cfg_intentless
+===========================================================================*/
+/**
+
+ Verifies open config for an intentless transport
+
+ @param[in] open_ch_ctx Channel context.
+
+ @return TRUE if config is good.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+static boolean glink_verify_open_cfg_intentless
+(
+glink_channel_ctx_type *ch_ctx
+)
+{
+ return (ch_ctx->notify_rxv != NULL);
+}
+
+/*===========================================================================
+ FUNCTION glink_channel_receive_pkt
+===========================================================================*/
+/**
+
+ Precesses Rx packet for the channel
+
+ @param[in] open_ch_ctx Channel context.
+ @param[in] intent_ptr Packet descriptor
+
+ @return None.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+static void glink_channel_receive_pkt_intentless
+(
+ glink_channel_ctx_type *open_ch_ctx,
+ glink_rx_intent_type *intent_ptr
+)
+{
+ open_ch_ctx->notify_rxv(open_ch_ctx, open_ch_ctx->priv,
+ NULL, intent_ptr->iovec, intent_ptr->pkt_sz, 0,
+ intent_ptr->vprovider, intent_ptr->pprovider);
+}
+
+/*===========================================================================
+EXTERNAL FUNCTION DEFINITIONS
+===========================================================================*/
+
+/*===========================================================================
+ FUNCTION glink_core_setup_intentless_xport
+===========================================================================*/
+/**
+
+ Initializes internal core functions for the intentless transport.
+
+ @param[in] if_ptr The Pointer to the interface instance.
+
+ @return None.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void glink_core_setup_intentless_xport(glink_transport_if_type *if_ptr)
+{
+ if_ptr->glink_core_priv->verify_open_cfg = glink_verify_open_cfg_intentless;
+ if_ptr->glink_core_priv->channel_init = (channel_init_fn)glink_core_stub_intentless;
+ if_ptr->glink_core_priv->channel_cleanup = (channel_cleanup_fn)glink_core_stub_intentless;
+ if_ptr->glink_core_priv->use_rm_intent = (use_rm_intent_fn)glink_core_stub_intentless;
+ if_ptr->glink_core_priv->channel_receive_pkt = glink_channel_receive_pkt_intentless;
+}
diff --git a/platform/msm_shared/glink/glink_os_utils_dal.c b/platform/msm_shared/glink/glink_os_utils_dal.c
new file mode 100644
index 0000000..7ad6fb7
--- /dev/null
+++ b/platform/msm_shared/glink/glink_os_utils_dal.c
@@ -0,0 +1,358 @@
+/* Copyright (c) 2015, 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 FILES
+===========================================================================*/
+
+#include "glink_os_utils.h"
+#include <arch/defines.h>
+#include <malloc.h>
+#include <kernel/thread.h>
+#include <string.h>
+#include <kernel/event.h>
+#include <platform/irqs.h>
+#include <platform/interrupts.h>
+
+/*===========================================================================
+ MACRO DEFINITIONS
+===========================================================================*/
+
+#define OS_LOG_BUFFER_SIZE ( 16384 )
+
+/*===========================================================================
+ TYPE DEFINITIONS
+===========================================================================*/
+typedef void (*glink_os_thread_fn_type)(void* param);
+
+typedef struct _glink_os_thread_info_type {
+ glink_os_thread_fn_type thread_fn;
+ void *param;
+}glink_os_thread_info_type;
+
+/*===========================================================================
+ EXTERNAL FUNCTION DEFINITIONS
+===========================================================================*/
+
+/*===========================================================================
+ FUNCTION glink_os_cs_init
+===========================================================================*/
+/**
+ Initializes a Critical Section
+
+ @param[in] cs pointer to critical section object allocated by caller.
+
+ @return
+ TRUE if critical section was initialized, FALSE otherwise
+*/
+/*=========================================================================*/
+boolean glink_os_cs_init( os_cs_type *cs )
+{
+ boolean return_value = TRUE;
+
+ /* Create the new critical section */
+
+ return ( return_value );
+}
+
+/*===========================================================================
+ FUNCTION glink_os_cs_deinit
+===========================================================================*/
+/**
+ This function de-initializes a critical section.
+
+ @param[in] cs Pointer to the critical section to be de-initialized.
+
+ @return
+ TRUE if critical section was initialized, FALSE otherwise
+
+*/
+/*=========================================================================*/
+boolean glink_os_cs_deinit( os_cs_type *cs )
+{
+ /* Deinitialize the critical section */
+
+ return TRUE;
+}
+
+/*===========================================================================
+FUNCTION glink_os_cs_acquire
+===========================================================================*/
+/**
+ Lock a critical section
+
+ @param[in] cs Pointer the the critical section
+
+ @return None.
+*/
+/*=========================================================================*/
+void glink_os_cs_acquire( os_cs_type *cs )
+{
+ enter_critical_section();
+}
+
+/*===========================================================================
+FUNCTION glink_os_cs_release
+===========================================================================*/
+/**
+ Unlock a critical section
+
+ @param[in] cs Pointer the the critical section
+
+ @return None.
+*/
+/*=========================================================================*/
+void glink_os_cs_release( os_cs_type *cs )
+{
+ exit_critical_section();
+}
+
+/*===========================================================================
+FUNCTION glink_os_cs_destroy
+===========================================================================*/
+/**
+ Destroys a Critical Section
+
+ @return none.
+*/
+/*=========================================================================*/
+void glink_os_cs_destroy( os_cs_type *cs )
+{
+ /* Initialize the critical section */
+ return;
+}
+
+/*===========================================================================
+ FUNCTION glink_os_malloc
+===========================================================================*/
+/**
+ Dynamically allocate a region of memory from the heap. The region should be
+ freed using \c glink_os_free when no longer used.
+
+ @param[in] size The number of bytes to be allocated.
+
+ @return The pointer to the region of memory that was allocated.
+ NULL if the allocation failed.
+*/
+/*=========================================================================*/
+
+void *glink_os_malloc( size_t size )
+{
+ void *pMem;
+
+ pMem = malloc(size);
+ if (pMem == NULL)
+ return NULL;
+ return pMem;
+}
+
+/*===========================================================================
+ FUNCTION glink_os_calloc
+===========================================================================*/
+/**
+ Dynamically allocate a region of memory from the heap and initialize with
+ the zeroes. The region should be freed using \c glink_os_free
+ when no longer used.
+
+ @param[in] size The number of bytes to be allocated.
+
+ @return The pointer to the region of memory that was allocated.
+ NULL if the allocation failed.
+*/
+/*=========================================================================*/
+void *glink_os_calloc( size_t size )
+{
+ void *pMem;
+ pMem = malloc(size);
+ if( pMem == NULL )
+ {
+ return NULL;
+ }
+ else
+ {
+ memset( pMem, 0, size );
+ return pMem;
+ }
+}
+
+/*===========================================================================
+ FUNCTION glink_os_free
+===========================================================================*/
+/**
+ Free a region of memory that was allocated by \c glink_os_malloc.
+
+ @param[in] pMem The reference to the region of memory to be freed.
+
+ @return NA
+*/
+/*=========================================================================*/
+void glink_os_free( void *pMem )
+{
+ free( pMem );
+}
+
+/*===========================================================================
+ FUNCTION glink_os_string_copy
+===========================================================================*/
+/**
+ Copies the source string into the destination buffer until
+ size is reached, or until a '\0' is encountered. If valid,
+ the destination string will always be NULL deliminated.
+
+ @param[in] dst The destination string, contents will be updated.
+ @param[in] src The source string
+ @param[in] size The maximum copy size (size of dst)
+
+ @return
+ The destination string pointer, dst.
+*/
+/*==========================================================================*/
+char *glink_os_string_copy( char *dst, const char *src, uint32 size )
+{
+ ( void )strlcpy( dst, src, size );
+
+ return dst;
+}
+
+/*===========================================================================
+ FUNCTION glink_os_string_compare
+===========================================================================*/
+/**
+ Compares two strings delimited by size or NULL character.
+
+ @param[in] s1 String 1
+ @param[in] s2 String 2
+ @param[in] size The maximum number of characters to compare
+
+ @return
+ 0 if strings are identical (up to size characters), non-zero otherwise
+*/
+/*==========================================================================*/
+long glink_os_string_compare( const char *s1, const char *s2, uint32 size )
+{
+ return strncmp( s1, s2, size );
+}
+
+/*===========================================================================
+ FUNCTION glink_os_copy_mem
+===========================================================================*/
+/**
+ Copies the source buffer into the destination buffer.
+
+ @param[in] dst The destination, contents will be updated.
+ @param[in] src The source
+ @param[in] size The maximum copy size (size of dst)
+
+ @return
+ The destination string pointer, dst.
+*/
+/*==========================================================================*/
+void glink_os_copy_mem( void *dst, const void *src, uint32 size )
+{
+ memcpy( dst, src, size );
+}
+
+/*===========================================================================
+ FUNCTION glink_os_register_isr
+===========================================================================*/
+/**
+ Registers ISR with the interrupt controller
+
+ @param[in] irq_in Interrupt to register for
+ @param[in] isr Callback to be invoked when interrupt fires
+ @param[in] cb_data Data to be provided to the callback
+
+ @return TRUE if registration was successful, FALSE otherwise.
+*/
+/*=========================================================================*/
+boolean glink_os_register_isr( uint32 irq_in, os_isr_cb_fn isr, void* cb_data )
+{
+ boolean return_value = TRUE;
+
+ /* Register the interrupt */
+ dprintf(SPEW, "Register interrupt: %u\n", irq_in);
+ register_int_handler(irq_in, (int_handler)(isr), cb_data);
+
+ return ( return_value );
+}
+
+/*===========================================================================
+ FUNCTION glink_os_deregister_isr
+===========================================================================*/
+/**
+ De-registers ISR with the interrupt controller
+
+ @param[in] irq_in Interrupt to deregister for
+
+ @return TRUE if de-registration was successful, FALSE otherwise.
+*/
+/*=========================================================================*/
+boolean glink_os_deregister_isr( uint32 irq_in )
+{
+ boolean return_value = TRUE;
+ mask_interrupt(irq_in);
+ return ( return_value );
+}
+
+/*===========================================================================
+ FUNCTION glink_os_enable_interrupt
+===========================================================================*/
+/**
+ Enables the interrupt in the interrupt controller
+
+ @param[in] irq_in Interrupt to enable
+
+ @return TRUE if operation was successful, FALSE otherwise.
+*/
+/*=========================================================================*/
+boolean glink_os_enable_interrupt( uint32 irq_in )
+{
+ boolean return_value = TRUE;
+ unmask_interrupt(irq_in);
+ return ( return_value );
+}
+
+/*===========================================================================
+ FUNCTION glink_os_disable_interrupt
+===========================================================================*/
+/**
+ Disables the interrupt in the interrupt controller
+
+ @param[in] irq_in Interrupt to disable
+
+ @return TRUE if operation was successful, FALSE otherwise.
+*/
+/*=========================================================================*/
+boolean glink_os_disable_interrupt( uint32 irq_in )
+{
+ boolean return_value = TRUE;
+ dprintf(INFO, "Disable IPC Interrupt\n");
+ mask_interrupt(irq_in);
+ return ( return_value );
+}
diff --git a/platform/msm_shared/glink/glink_rpmcore_setup.c b/platform/msm_shared/glink/glink_rpmcore_setup.c
new file mode 100644
index 0000000..a206afa
--- /dev/null
+++ b/platform/msm_shared/glink/glink_rpmcore_setup.c
@@ -0,0 +1,65 @@
+/* Copyright (c) 2015, 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 FILES
+===========================================================================*/
+
+#include "glink.h"
+#include "glink_internal.h"
+
+
+/*===========================================================================
+EXTERNAL FUNCTION DEFINITIONS
+===========================================================================*/
+
+/*===========================================================================
+FUNCTION glink_core_setup
+===========================================================================*/
+/**
+
+ Initializes internal core functions based on the transport capabilities.
+
+ @param[in] if_ptr The Pointer to the interface instance.
+
+ @return None.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void glink_core_setup(glink_transport_if_type *if_ptr)
+{
+ if (if_ptr->glink_core_priv->xport_capabilities & GLINK_CAPABILITY_INTENTLESS)
+ {
+ glink_core_setup_intentless_xport(if_ptr);
+ }
+ else
+ {
+ ASSERT(0);
+ }
+}
diff --git a/platform/msm_shared/glink/glink_vector.c b/platform/msm_shared/glink/glink_vector.c
new file mode 100644
index 0000000..31f0883
--- /dev/null
+++ b/platform/msm_shared/glink/glink_vector.c
@@ -0,0 +1,196 @@
+/* Copyright (c) 2015, 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 FILES
+===========================================================================*/
+#include "glink.h"
+#include "glink_core_if.h"
+#include "glink_transport_if.h"
+#include "glink_vector.h"
+#include "glink_os_utils.h"
+
+/*===========================================================================
+ LOCAL DATA DECLARATIONS
+===========================================================================*/
+
+
+/*===========================================================================
+ PRIVATE FUNCTIONS
+===========================================================================*/
+
+/*===========================================================================
+FUNCTION glink_dummy_tx_vprovider
+===========================================================================*/
+/**
+
+ Buffer provider for virtual space that operates on a non-vectored buffer.
+
+ @param[in] iovec Pointer to the dummy vector.
+ @param[in] offset Offset within the dummy vector.
+ @param[out] size Size of the provied buffer.
+
+ @return virtual address of the buffer.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void* glink_dummy_tx_vprovider
+(
+ void* iovec,
+ size_t offset,
+ size_t *size
+)
+{
+ glink_core_tx_pkt_type* pkt = (glink_core_tx_pkt_type*)iovec;
+
+ if (pkt == NULL || size == NULL || pkt->size <= offset)
+ {
+ return NULL;
+ }
+
+ *size = pkt->size - offset;
+
+ return (char*)(pkt->data) + offset;
+}
+
+/*===========================================================================
+FUNCTION glink_iovec_vprovider
+===========================================================================*/
+/**
+
+ Buffer provider for virtual space that operates on a Glink iovec.
+
+ @param[in] iovec Pointer to the dummy vector.
+ @param[in] offset Offset within the dummy vector.
+ @param[out] size Size of the provied buffer.
+
+ @return virtual address of the buffer.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void* glink_iovec_vprovider
+(
+ void* iovec,
+ size_t offset,
+ size_t *size
+)
+{
+ glink_iovector_type* iovec_l = (glink_iovector_type*)iovec;
+
+ if (iovec_l == NULL || size == NULL)
+ {
+ return NULL;
+ }
+
+ if (!iovec_l->vlist)
+ {
+ // create vlist and map virtual from physical addresses
+ ASSERT(0);
+ }
+
+ if (!iovec_l->vlast || iovec_l->vlast->start_offset > offset)
+ {
+ iovec_l->vlast = iovec_l->vlist;
+ }
+
+ while (iovec_l->vlast &&
+ iovec_l->vlast->start_offset + iovec_l->vlast->size <= offset)
+ {
+ iovec_l->vlast = iovec_l->vlast->next;
+ }
+
+ if (iovec_l->vlast == NULL)
+ {
+ return NULL;
+ }
+
+ offset -= iovec_l->vlast->start_offset;
+ *size = iovec_l->vlast->size - offset;
+
+ return (char*)(iovec_l->vlast->data) + offset;
+}
+
+/*===========================================================================
+FUNCTION glink_iovec_pprovider
+===========================================================================*/
+/**
+
+ Buffer provider for physical space that operates on a Glink iovec.
+
+ @param[in] iovec Pointer to the dummy vector.
+ @param[in] offset Offset within the dummy vector.
+ @param[out] size Size of the provied buffer.
+
+ @return physical address of the buffer.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void* glink_iovec_pprovider
+(
+ void* iovec,
+ size_t offset,
+ size_t *size
+)
+{
+ glink_iovector_type* iovec_l = (glink_iovector_type*)iovec;
+
+ if (iovec_l == NULL || size == NULL)
+ {
+ return NULL;
+ }
+
+ if (!iovec_l->plist)
+ {
+ // create plist and get physical addresses from virtual
+ ASSERT(0); // not implemented
+ }
+
+ if (!iovec_l->plast || iovec_l->plast->start_offset > offset)
+ {
+ iovec_l->plast = iovec_l->plist;
+ }
+
+ while (iovec_l->plast &&
+ iovec_l->plast->start_offset + iovec_l->plast->size <= offset)
+ {
+ iovec_l->plast = iovec_l->plast->next;
+ }
+
+ if (iovec_l->plast == NULL)
+ {
+ return NULL;
+ }
+
+ offset -= iovec_l->plast->start_offset;
+ *size = iovec_l->plast->size - offset;
+
+ return (char*)(iovec_l->plast->data) + offset;
+}
diff --git a/platform/msm_shared/glink/xport_rpm.c b/platform/msm_shared/glink/xport_rpm.c
new file mode 100644
index 0000000..05329f9
--- /dev/null
+++ b/platform/msm_shared/glink/xport_rpm.c
@@ -0,0 +1,1150 @@
+/* Copyright (c) 2015, 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 FILES
+===========================================================================*/
+
+#include "glink.h"
+#include "glink_core_if.h"
+#include "glink_transport_if.h"
+#include "glink_os_utils.h"
+#include "glink_internal.h"
+#include "glink_vector.h"
+#include "xport_rpm_config.h"
+#include "xport_rpm.h"
+#include <reg.h>
+#include <bits.h>
+#include <platform/iomap.h>
+
+/*===========================================================================
+ MACRO DEFINITIONS
+===========================================================================*/
+#define XPORT_RPM_NAME "RPM"
+
+#define XPORT_RPM_LOG(msg, remote_host, param) \
+ GLINK_LOG_EVENT(GLINK_EVENT_XPORT_INTERNAL, msg, XPORT_RPM_NAME, \
+ remote_host, (uint32)param)
+
+#define MSGRAM_READ32(ctx, ind) (*(volatile uint32*)&(ctx)->rx_fifo[ind])
+#define CHECK_INDEX_WRAP_AROUND(ind, size) \
+ {if ((ind) >= (size)) ind = 0;}
+
+#define ROUNDUP64(d) (((d) + 7) & (~7))
+#define ROUNDUP32(d) (((d) + 3) & (~3))
+
+/*===========================================================================
+ GLOBAL DATA DECLARATIONS
+===========================================================================*/
+
+extern const uint32 xport_rpm_config_num;
+extern const char* xport_rpm_msg_ram;
+extern const void* xport_rpm_msg_ram_toc;
+
+xport_rpm_config_type* xport_rpm_get_config(uint32 ind);
+
+/* RPM channel descriptor */
+typedef struct _xport_rpm_ind_type
+{
+ uint32 read_ind;
+ uint32 write_ind;
+} xport_rpm_ind_type;
+
+/* RPM transport context */
+typedef struct _xport_rpm_ctx_type
+{
+ /* context structure should start from trasport interface */
+ glink_transport_if_type xport_if;
+ const xport_rpm_config_type *pcfg;
+ volatile xport_rpm_ind_type* tx_desc;
+ volatile xport_rpm_ind_type* rx_desc;
+ char* tx_fifo;
+ char* rx_fifo;
+ uint32 tx_fifo_size;
+ uint32 rx_fifo_size;
+ os_cs_type *tx_link_lock;
+ os_cs_type *rx_link_lock;
+ uint32 pkt_start_ind;
+ uint32 pkt_size;
+ boolean reset;
+ boolean irq_mask;
+} xport_rpm_ctx_type;
+
+xport_rpm_ctx_type *xport_rpm_ctx = NULL;
+glink_core_version_type xport_rpm_version;
+
+/*===========================================================================
+ LOCAL FUNCTION DEFINITIONS
+===========================================================================*/
+
+/*===========================================================================
+FUNCTION xport_rpm_plain_pkt_provider
+===========================================================================*/
+/**
+
+ Packet provider for virtual space that operates on MSG RAM FIFO.
+
+ @param[in] iovec Pointer to the vector.
+ @param[in] offset Offset within the vector.
+ @param[out] size Size of the provied buffer.
+
+ @return virtual address of the buffer.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+static void* xport_rpm_pkt_provider
+(
+ void* iovec,
+ size_t offset,
+ size_t *size
+)
+{
+ xport_rpm_ctx_type* ctx_ptr = (xport_rpm_ctx_type*)iovec;
+ uint32 last;
+
+ if (ctx_ptr == NULL || size == NULL || ctx_ptr->pkt_size <= offset)
+ {
+ return NULL;
+ }
+
+ last = ctx_ptr->rx_fifo_size - ctx_ptr->pkt_start_ind;
+
+ if (offset >= last)
+ {
+ *size = ctx_ptr->pkt_size - offset;
+
+ return &ctx_ptr->rx_fifo[offset - last];
+ }
+
+ *size = ctx_ptr->pkt_size <= last ?
+ ctx_ptr->pkt_size - offset :
+ last - offset;
+
+ return &ctx_ptr->rx_fifo[offset + ctx_ptr->pkt_start_ind];
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_send_event
+===========================================================================*/
+/**
+
+ Updates shared write index and sends interrupt.
+
+ @param[in] ctx_ptr Pointer to transport context.
+
+ @return None.
+
+ @sideeffects None.
+
+ @dependencies It should be invoked within tx_link_lock protection.
+*/
+/*=========================================================================*/
+static void xport_rpm_send_event
+(
+ xport_rpm_ctx_type *ctx_ptr
+)
+{
+ /* read out the write index to initiate a bus transaction from MSG RAM */
+ volatile uint32 write_ind = ctx_ptr->tx_desc->write_ind;
+
+ XPORT_RPM_LOG("Send event write ind", ctx_ptr->pcfg->remote_ss, write_ind);
+
+ // notify rpm
+ dprintf(SPEW, "%s:%d: Notify RPM with IPC interrupt\n", __func__, __LINE__);
+ /* Set BIT 0 to notify RPM via IPC interrupt*/
+ writel(BIT(0), APCS_HLOS_IPC_INTERRUPT_0);
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_write_msgram
+===========================================================================*/
+/**
+
+ Copies data from local buffer into Tx FIFO located at MSG RAM
+
+ @param[in] ctx_ptr Pointer to transport context.
+ @param[in] write_ind Index to start wrting from.
+ @param[in] buffer Buffer to copy from.
+ @param[in] size Size of the data in the buffer.
+
+ @return New write index.
+
+ @sideeffects None.
+
+ @dependencies It should be invoked within tx_link_lock protection.
+*/
+/*=========================================================================*/
+static uint32 xport_rpm_write_msgram
+(
+ xport_rpm_ctx_type *ctx_ptr,
+ uint32 write_ind,
+ uint32 *buffer,
+ uint32 size
+)
+{
+ uint32 remaining = ctx_ptr->tx_fifo_size - write_ind;
+ uint32 *buffer_end;
+ volatile uint32* write_ptr = (volatile uint32*)&ctx_ptr->tx_fifo[write_ind];
+
+ if (remaining <= size)
+ {
+ buffer_end = (uint32*)((char*)buffer + remaining);
+
+ /* write in 32bit increments due to MSG RAM access requirement */
+ while (buffer < buffer_end)
+ {
+ *write_ptr++ = *buffer++;
+ }
+
+ size -= remaining;
+ write_ptr = (volatile uint32*)&ctx_ptr->tx_fifo[0];
+ }
+
+ buffer_end = (uint32*)((char*)buffer + size);
+
+ /* write in 32bit increments due to MSG RAM access requirement */
+ while (buffer < buffer_end)
+ {
+ *write_ptr++ = *buffer++;
+ }
+
+ return (char*)write_ptr - &ctx_ptr->tx_fifo[0];
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_send_cmd
+===========================================================================*/
+/**
+
+ Helper to send a single command.
+
+ @param[in] ctx_ptr Pointer to transport context.
+ @param[in] cmd buffer containing the command
+ @param[in] cmd_size Size of command buffer.
+ @param[in] data buffer containing the data
+ @param[in] data_size Size of data buffer.
+
+ @return None.
+
+ @dependencies None.
+*/
+/*=========================================================================*/
+static glink_err_type xport_rpm_send_cmd
+(
+ xport_rpm_ctx_type *ctx_ptr,
+ uint32 *cmd,
+ uint32 cmd_size,
+ uint32 *data,
+ uint32 data_size
+)
+{
+ uint32 total_size = cmd_size + data_size;
+ uint32 reserve_size = ROUNDUP64(total_size);
+ uint32 write_ind, read_ind, avail_size;
+
+ glink_os_cs_acquire(ctx_ptr->tx_link_lock);
+
+ write_ind = ctx_ptr->tx_desc->write_ind;
+ read_ind = ctx_ptr->tx_desc->read_ind;
+ avail_size = write_ind < read_ind ? read_ind - write_ind :
+ ctx_ptr->tx_fifo_size - write_ind + read_ind;
+
+ if (reserve_size + sizeof(uint64_t) > avail_size)
+ {
+ glink_os_cs_release(ctx_ptr->tx_link_lock);
+ return GLINK_STATUS_OUT_OF_RESOURCES;
+ }
+
+ XPORT_RPM_LOG("send cmd", ctx_ptr->pcfg->remote_ss, cmd[0]);
+
+ write_ind
+ = xport_rpm_write_msgram( ctx_ptr, write_ind,
+ cmd, ROUNDUP32( cmd_size ) );
+
+ if (data != NULL)
+ {
+ write_ind
+ = xport_rpm_write_msgram( ctx_ptr, write_ind,
+ data, ROUNDUP32( data_size ) );
+ }
+
+ /* add alignment bytes to Tx FIFO */
+ write_ind += (reserve_size - total_size) & (~3);
+
+ if (write_ind >= ctx_ptr->tx_fifo_size)
+ {
+ write_ind -= ctx_ptr->tx_fifo_size;
+ }
+
+ ctx_ptr->tx_desc->write_ind = write_ind;
+
+ xport_rpm_send_event(ctx_ptr);
+
+ glink_os_cs_release(ctx_ptr->tx_link_lock);
+
+ return GLINK_STATUS_SUCCESS;
+}
+
+/*===========================================================================
+ EXTERNAL FUNCTION DEFINITIONS
+===========================================================================*/
+
+/*===========================================================================
+FUNCTION xport_rpm_tx_cmd_version
+===========================================================================*/
+/**
+
+ Transmit a version command for local negotiation -
+ expected response is to be delivered via glink_rx_cmd_version_ack().
+
+ @param[in] if_ptr Pointer to transport interface instance.
+ @param[in] version Version to be sent.
+ @param[in] feature Features to be sent.
+
+ @return None.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void xport_rpm_tx_cmd_version
+(
+ glink_transport_if_type *if_ptr,
+ uint32 version,
+ uint32 features
+)
+{
+ xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
+ uint32 cmd[2];
+
+ cmd[0] = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_VERSION_REQ);
+ cmd[0] |= XPORT_RPM_SET_VERSION(version);
+ cmd[1] = features;
+
+ if(xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), NULL, 0) != GLINK_STATUS_SUCCESS)
+ {
+ dprintf(CRITICAL, "%s:%d: Send Version Failed\n", __func__, __LINE__);
+ ASSERT(0);
+ }
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_tx_cmd_version_ack
+===========================================================================*/
+/**
+
+ Transmit a version ack for remote negotiation.
+
+ @param[in] if_ptr Pointer to transport interface instance.
+ @param[in] version Version to be sent.
+ @param[in] feature Features to be sent.
+
+ @return None.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void xport_rpm_tx_cmd_version_ack
+(
+ glink_transport_if_type *if_ptr,
+ uint32 version,
+ uint32 features
+)
+{
+ xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
+ uint32 cmd[2];
+
+ cmd[0] = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_VERSION_ACK);
+ cmd[0] |= XPORT_RPM_SET_VERSION(version);
+ cmd[1] = features;
+
+ if (xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), NULL, 0) != GLINK_STATUS_SUCCESS)
+ {
+ dprintf(CRITICAL, "%s:%d: Send Version ACK Failed", __func__, __LINE__);
+ ASSERT(0);
+ }
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_set_version
+===========================================================================*/
+/**
+
+ Signals that negotiation is complete and the transport can now
+ do version-specific initialization.
+
+ @param[in] if_ptr Pointer to transport interface instance.
+ @param[in] version Version to be used.
+ @param[in] feature Features to be used.
+
+ @return Capabilities.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+uint32 xport_rpm_set_version
+(
+ glink_transport_if_type *if_ptr,
+ uint32 version,
+ uint32 features
+)
+{
+ return GLINK_CAPABILITY_SIG_SUPPORT | GLINK_CAPABILITY_INTENTLESS;
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_tx_cmd_ch_open
+===========================================================================*/
+/**
+
+ Sends the open command - expected response is to be delivered
+ via glink_rx_cmd_ch_open_ack().
+
+ @param[in] if_ptr Pointer to transport interface instance.
+ @param[in] lcid Local channel ID.
+ @param[in] name Channel name.
+ @param[in] prio Requested xport priority by channel.
+
+ @return Returns error code.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+glink_err_type xport_rpm_tx_cmd_ch_open
+(
+ glink_transport_if_type *if_ptr,
+ uint32 lcid,
+ const char *name,
+ glink_xport_priority prio
+)
+{
+ xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
+ uint32 cmd[2];
+
+ cmd[0] = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_OPEN_CHANNEL);
+ cmd[0] |= XPORT_RPM_SET_CHANNEL_ID(lcid);
+ cmd[1] = strlen(name) + 1;
+
+ return xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), (void*)name, cmd[1]);
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_tx_cmd_ch_close
+===========================================================================*/
+/**
+
+ Sends the close command - expected response is to be delivered
+ via glink_rx_cmd_ch_close_ack().
+
+ @param[in] if_ptr Pointer to transport interface instance.
+ @param[in] lcid Local channel ID.
+
+ @return Returns error code.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+glink_err_type xport_rpm_tx_cmd_ch_close
+(
+ glink_transport_if_type *if_ptr,
+ uint32 lcid
+)
+{
+ xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
+ uint32 cmd;
+
+ cmd = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_CLOSE_CHANNEL);
+ cmd |= XPORT_RPM_SET_CHANNEL_ID(lcid);
+
+ return xport_rpm_send_cmd(ctx_ptr, &cmd, sizeof(cmd), NULL, 0);
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_tx_cmd_ch_remote_open_ack
+===========================================================================*/
+/**
+
+ Sends the remote open ACK command.
+
+ @param[in] if_ptr Pointer to transport interface instance.
+ @param[in] rcid Remote channel ID.
+ @param[in] prio send negotiated xport priority to remote side.
+
+ @return None.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void xport_rpm_tx_cmd_ch_remote_open_ack
+(
+ glink_transport_if_type *if_ptr,
+ uint32 rcid,
+ glink_xport_priority prio
+)
+{
+ xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
+ uint32 cmd;
+
+ cmd = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_OPEN_CHANNEL_ACK);
+ cmd |= XPORT_RPM_SET_CHANNEL_ID(rcid);
+
+ if (xport_rpm_send_cmd(ctx_ptr, &cmd, sizeof(cmd), NULL, 0) != GLINK_STATUS_SUCCESS)
+ {
+ //ERR_FATAL("send Open Ack failed", 0, 0, 0);
+ ASSERT(0);
+ }
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_tx_cmd_ch_remote_close_ack
+===========================================================================*/
+/**
+
+ Sends the remote close ACK command.
+
+ @param[in] if_ptr Pointer to transport interface instance.
+ @param[in] rcid Remote channel ID.
+
+ @return None.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void xport_rpm_tx_cmd_ch_remote_close_ack
+(
+ glink_transport_if_type *if_ptr,
+ uint32 rcid
+)
+{
+ xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
+ uint32 cmd;
+
+ cmd = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_CLOSE_CHANNEL_ACK);
+ cmd |= XPORT_RPM_SET_CHANNEL_ID(rcid);
+
+ if (xport_rpm_send_cmd(ctx_ptr, &cmd, sizeof(cmd), NULL, 0) != GLINK_STATUS_SUCCESS)
+ {
+ dprintf(CRITICAL, "%s:%d: Send Clock ACK failed\n", __func__, __LINE__);
+ ASSERT(0);
+ }
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_tx
+===========================================================================*/
+/**
+
+ Send a data packet or a fragment of it.
+
+ @param[in] if_ptr Pointer to transport interface instance.
+ @param[in] lcid Local channel ID.
+ @param[in] pctx Packet TX context.
+
+ @return Returns error code.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+glink_err_type xport_rpm_tx
+(
+ glink_transport_if_type *if_ptr,
+ uint32 lcid,
+ glink_core_tx_pkt_type *pctx
+)
+{
+ xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
+ uint32 cmd[4];
+
+ cmd[0] = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_TX_DATA);
+ cmd[0] |= XPORT_RPM_SET_CHANNEL_ID(lcid);
+ cmd[1] = 0;
+ cmd[2] = pctx->size;
+ cmd[3] = 0;
+
+ pctx->size_remaining = 0;
+
+ return xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), (void*)pctx->data, pctx->size);
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_tx_cmd_set_sigs
+===========================================================================*/
+/**
+
+ Sends the local channel signals as per the specified 32-bit mask.
+
+ @param[in] if_ptr Pointer to transport interface instance.
+ @param[in] lcid Local channel ID.
+ @param[in] sigs Signal mask.
+
+ @return Returns error code.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+glink_err_type xport_rpm_tx_cmd_set_sigs
+(
+ glink_transport_if_type *if_ptr,
+ uint32 lcid,
+ uint32 sigs
+)
+{
+ xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
+ uint32 cmd[2];
+
+ cmd[0] = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_TX_SIGNALS);
+ cmd[0] |= XPORT_RPM_SET_CHANNEL_ID(lcid);
+ cmd[1] = sigs;
+
+ return xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), NULL, 0);
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_negotiate_features
+===========================================================================*/
+/**
+
+ Callback to verify feature set.
+
+ @param[in] if_ptr Pointer to transport interface.
+ @param[in] version_ptr Pointer to version descriptor.
+ @param[in] features Proposed feature set.
+
+ @return 0.
+
+ @sideeffects None.
+
+ @dependencies None.
+*/
+/*=========================================================================*/
+uint32 xport_rpm_negotiate_features(
+ glink_transport_if_type *if_ptr,
+ const glink_core_version_type *version_ptr,
+ uint32 features)
+{
+ return 0;
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_poll
+===========================================================================*/
+/**
+
+ Poll of RPM transport.
+
+ @param[in] ctx_ptr Pointer to transport context.
+
+ @return Returns error code.
+
+ @sideeffects None.
+
+ @dependencies None.
+*/
+/*=========================================================================*/
+glink_err_type xport_rpm_poll( xport_rpm_ctx_type *ctx_ptr )
+{
+ uint32 write_ind, read_ind;
+ boolean stop_processing = FALSE;
+
+ if (ctx_ptr->reset == TRUE)
+ {
+ /* reset flag has been set after SSR, notify link up */
+ ctx_ptr->reset = FALSE;
+ ctx_ptr->xport_if.glink_core_if_ptr->link_up((glink_transport_if_type *)ctx_ptr);
+ }
+
+ glink_os_cs_acquire(ctx_ptr->rx_link_lock);
+
+ /* Process pending commands and data */
+ write_ind = ctx_ptr->rx_desc->write_ind;
+ read_ind = ctx_ptr->rx_desc->read_ind;
+
+ XPORT_RPM_LOG("RPM ISR write ind", ctx_ptr->pcfg->remote_ss, write_ind);
+ XPORT_RPM_LOG("RPM ISR read ind", ctx_ptr->pcfg->remote_ss, read_ind);
+
+ /* Ensure the index is 64-bit aligned */
+ if ((write_ind & 0x7) != 0)
+ {
+ dprintf(CRITICAL,"%s:%d: Write Index is not aligned: %u\n",__func__, __LINE__, write_ind);
+ ASSERT(0);
+ }
+
+ while (write_ind != read_ind && !stop_processing)
+ {
+ uint32 cmd = MSGRAM_READ32(ctx_ptr, read_ind);
+ uint32 cid = XPORT_RPM_GET_CHANNEL_ID(cmd); // most commands have channel ID
+ uint32 cmd_arg;
+
+ /* it can't wrap aroud here so just inceremt the index */
+ read_ind += sizeof(cmd);
+
+ XPORT_RPM_LOG("Cmd Rx", ctx_ptr->pcfg->remote_ss, cmd);
+
+ switch (XPORT_RPM_GET_CMD_ID(cmd))
+ {
+ case XPORT_RPM_CMD_VERSION_REQ:
+
+ cmd_arg = MSGRAM_READ32(ctx_ptr, read_ind);
+
+ /* no need to incerment read_ind here since it will be rounded up */
+
+ ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_version(
+ (glink_transport_if_type *)ctx_ptr,
+ XPORT_RPM_GET_VERSION(cmd), cmd_arg);
+ break;
+
+ case XPORT_RPM_CMD_VERSION_ACK:
+
+ cmd_arg = MSGRAM_READ32(ctx_ptr, read_ind);
+
+ /* no need to increment read_ind here since it will be rounded up */
+
+ ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_version_ack(
+ (glink_transport_if_type *)ctx_ptr,
+ XPORT_RPM_GET_VERSION(cmd), cmd_arg);
+ break;
+
+ case XPORT_RPM_CMD_OPEN_CHANNEL:
+ cmd_arg = MSGRAM_READ32(ctx_ptr, read_ind);
+ cmd_arg = ROUNDUP64(cmd_arg);
+
+ read_ind += sizeof(cmd_arg);
+
+ /* channel name should fit into the FIFO */
+ if (cmd_arg == 0 || cmd_arg >= ctx_ptr->rx_fifo_size)
+ {
+ dprintf(CRITICAL, "%s:%d: Invalid name length: %u", __func__, __LINE__, cmd_arg);
+ ASSERT(0);
+ }
+ else
+ {
+ char tmpstr[ROUNDUP64(GLINK_CH_NAME_LEN)] = {0};
+ uint32 curr = 0;
+ uint32* string_ptr;
+ string_ptr = (uint32 *)&tmpstr[0];
+ while (curr < cmd_arg && curr < sizeof(tmpstr))
+ {
+ CHECK_INDEX_WRAP_AROUND(read_ind, ctx_ptr->rx_fifo_size);
+ *(string_ptr++) = MSGRAM_READ32(ctx_ptr, read_ind);
+ curr += sizeof(uint32);
+ read_ind += sizeof(uint32);
+ }
+
+ /* add all the unread stuff */
+ read_ind += cmd_arg - curr;
+
+ /* make sure the last character is NULL */
+ tmpstr[sizeof(tmpstr) - 1] = 0;
+
+ ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_remote_open(
+ (glink_transport_if_type *)ctx_ptr, cid, tmpstr, GLINK_XPORT_RPM);
+ }
+
+ break;
+
+ case XPORT_RPM_CMD_CLOSE_CHANNEL:
+
+ ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_remote_close(
+ //(glink_transport_if_type *)ctx_ptr, XPORT_RPM_GET_CHANNEL_ID(cmd));
+ (glink_transport_if_type *)ctx_ptr, cid);
+
+ /* no need to increment read_ind here since it would be rounded up */
+
+ break;
+
+ case XPORT_RPM_CMD_OPEN_CHANNEL_ACK:
+
+ /* no need to increment read_ind here since it would be rounded up */
+
+ ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_open_ack(
+ (glink_transport_if_type *)ctx_ptr, cid, GLINK_XPORT_RPM);
+
+ break;
+
+ case XPORT_RPM_CMD_CLOSE_CHANNEL_ACK:
+
+ ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_close_ack(
+ (glink_transport_if_type *)ctx_ptr, cid);
+
+ /* no need to increment read_ind here since it would be rounded up */
+
+ break;
+
+ case XPORT_RPM_CMD_TX_DATA:
+ {
+ glink_rx_intent_type desc;
+ memset( &desc, sizeof( glink_rx_intent_type), 0 );
+
+ read_ind += sizeof(cmd_arg);
+
+ CHECK_INDEX_WRAP_AROUND(read_ind, ctx_ptr->rx_fifo_size);
+
+ cmd_arg = MSGRAM_READ32(ctx_ptr, read_ind);
+
+ /* packet data should fit into the FIFO */
+ if (cmd_arg >= ctx_ptr->rx_fifo_size)
+ {
+ dprintf(CRITICAL, "%s:%d: Invalid packet length: %u",__func__, __LINE__, cmd_arg);
+ ASSERT(0);
+ }
+
+ read_ind += 2*sizeof(cmd_arg);
+
+ CHECK_INDEX_WRAP_AROUND(read_ind, ctx_ptr->rx_fifo_size);
+
+ ctx_ptr->pkt_start_ind = read_ind;
+ ctx_ptr->pkt_size = cmd_arg;
+
+ desc.size = cmd_arg;
+ desc.used = cmd_arg;
+ desc.pkt_sz = cmd_arg;
+ desc.iovec = ctx_ptr;
+ desc.vprovider = xport_rpm_pkt_provider;
+
+ read_ind += cmd_arg;
+
+ ctx_ptr->xport_if.glink_core_if_ptr->rx_put_pkt_ctx(
+ (glink_transport_if_type *)ctx_ptr, cid,
+ &desc, TRUE);
+
+ /* If interrupt was disabled then stop delivering messages */
+ stop_processing = ctx_ptr->irq_mask;
+
+ break;
+ }
+
+ case XPORT_RPM_CMD_TX_SIGNALS:
+
+ cmd_arg = MSGRAM_READ32(ctx_ptr, read_ind);
+
+ /* no need to incerement read_ind here since it will be rounded up */
+
+ ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_remote_sigs(
+ (glink_transport_if_type *)ctx_ptr,
+ cid, cmd_arg);
+ break;
+
+ default:
+ dprintf(CRITICAL, "%s:%d: Invalid Command: %u\n",__func__, __LINE__, cmd);
+ ASSERT(0);
+ break;
+ }
+
+ read_ind = ROUNDUP64(read_ind);
+
+ if (read_ind >= ctx_ptr->rx_fifo_size)
+ {
+ read_ind -= ctx_ptr->rx_fifo_size;
+ }
+
+ /* Update the shared read index */
+ ctx_ptr->rx_desc->read_ind = read_ind;
+ }
+
+ glink_os_cs_release(ctx_ptr->rx_link_lock);
+
+ return GLINK_STATUS_SUCCESS;
+}
+
+#ifdef GLINK_RPM_PROC
+/*===========================================================================
+FUNCTION xport_rpm_isr
+===========================================================================*/
+/**
+
+ ISR of RPM transport.
+
+ @return Returns error code.
+
+ @sideeffects None.
+
+ @dependencies None.
+*/
+/*=========================================================================*/
+glink_err_type xport_rpm_isr( void )
+{
+ xport_rpm_ctx_type *ctx_ptr = xport_rpm_get_context();
+
+ return xport_rpm_poll( ctx_ptr );
+}
+#else
+/*===========================================================================
+FUNCTION xport_rpm_isr
+===========================================================================*/
+/**
+
+ ISR of RPM transport.
+
+ @param[in] ctx_ptr Pointer to transport context.
+
+ @return Returns error code.
+
+ @sideeffects None.
+
+ @dependencies None.
+*/
+/*=========================================================================*/
+glink_err_type xport_rpm_isr( xport_rpm_ctx_type *ctx_ptr )
+{
+ return xport_rpm_poll( ctx_ptr );
+}
+#endif
+
+
+/*===========================================================================
+FUNCTION xport_rpm_ssr
+===========================================================================*/
+/**
+
+ Processes SSR event.
+
+ @param[in] if_ptr Pointer to transport interface instance.
+
+ @return Returns error code.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+glink_err_type xport_rpm_ssr(glink_transport_if_type *if_ptr)
+{
+ xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
+
+ ctx_ptr->tx_desc->write_ind = 0;
+ ctx_ptr->rx_desc->read_ind = 0;
+ ctx_ptr->reset = TRUE;
+
+ return GLINK_STATUS_SUCCESS;
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_wait_link_down
+===========================================================================*/
+/**
+
+ Waits for read/write indicies to be set to 0 by the remote host.
+
+ @param[in] if_ptr Pointer to transport interface instance.
+
+ @return TRUE if link is down, FALSE otherwise.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+boolean xport_rpm_wait_link_down(glink_transport_if_type *if_ptr)
+{
+ xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
+
+ return (ctx_ptr->tx_desc->write_ind == 0 &&
+ ctx_ptr->tx_desc->read_ind == 0 &&
+ ctx_ptr->rx_desc->write_ind == 0 &&
+ ctx_ptr->rx_desc->read_ind == 0);
+}
+
+
+/*===========================================================================
+FUNCTION xport_rpm_mask_interrupt
+===========================================================================*/
+/**
+
+ Enables or disables interrupts.
+
+ @param[in] if_ptr Pointer to transport interface instance.
+ @param[in] mask TRUE=mask, FALSE=unmask
+
+ @return Returns error code.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+glink_err_type xport_rpm_mask_interrupt(glink_transport_if_type *if_ptr, boolean mask)
+{
+ xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
+
+ if (ctx_ptr->irq_mask != mask)
+ {
+ if (mask)
+ {
+ glink_os_disable_interrupt(ctx_ptr->pcfg->irq_in);
+ }
+ else
+ {
+ glink_os_enable_interrupt(ctx_ptr->pcfg->irq_in);
+ }
+
+ ctx_ptr->irq_mask = mask;
+ }
+
+ return GLINK_STATUS_SUCCESS;
+}
+
+/*===========================================================================
+FUNCTION xport_rpm_init
+===========================================================================*/
+/**
+
+ Initializes RPM transport.
+ Must be called before any other operations are done.
+
+ @param[in] arg The argument.
+
+ @return Returns error code.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+glink_err_type xport_rpm_init(void *arg)
+{
+ uint32 ind;
+ glink_core_transport_cfg_type xport_rpm_cfg = { 0 };
+ uint32 *msg_ram_toc = (uint32*)xport_rpm_msg_ram_toc;
+ xport_rpm_toc_entry_type *entry;
+ uint32 msg_ram_toc_num;
+ char* msg_ram_toc_entry_start = (char*)&msg_ram_toc[XPORT_RPM_TOC_ENTRIES_IDX];
+ dprintf(SPEW, "%s:%d: RPM Transport INIT\n", __func__, __LINE__);
+
+ if (xport_rpm_config_num == 0)
+ {
+ return GLINK_STATUS_SUCCESS;
+ }
+
+ if (msg_ram_toc[XPORT_RPM_TOC_MAGIC_IDX] != XPORT_RPM_TOC_MAGIC)
+ {
+ dprintf(CRITICAL, "%s:%d: RPM Transport Failure: Invalid ToC cookie\n", __func__, __LINE__);
+ return GLINK_STATUS_FAILURE;
+ }
+
+ msg_ram_toc_num = msg_ram_toc[XPORT_RPM_TOC_LENGTH_IDX];
+
+ if (msg_ram_toc_num == 0)
+ {
+ dprintf(SPEW, "%s:%d RPM Transport Success\n", __func__, __LINE__);
+ return GLINK_STATUS_SUCCESS;
+ }
+
+ xport_rpm_ctx = glink_os_calloc(sizeof(*xport_rpm_ctx)*xport_rpm_config_num);
+
+ if (xport_rpm_ctx == NULL)
+ {
+ dprintf(INFO, "%s:%d RPM Transport Failed to allocate context\n", __func__, __LINE__);
+ ASSERT(0);
+ }
+
+ /* Initialize supported version and features */
+ xport_rpm_version.version = 1;
+ xport_rpm_version.features = 0;
+ xport_rpm_version.negotiate_features = &xport_rpm_negotiate_features;
+
+ /* Initialize edges */
+ dprintf(SPEW, "%s:%d: Initialize Edges\n", __func__, __LINE__);
+
+ for (ind = 0; ind < xport_rpm_config_num; ind++)
+ {
+ xport_rpm_ctx[ind].pcfg = xport_rpm_get_config(ind);
+
+ /* Find FIFOs in MSG RAM ToC */
+ for (entry = (xport_rpm_toc_entry_type*)msg_ram_toc_entry_start;
+ (char*)entry < msg_ram_toc_num*sizeof(*entry) + msg_ram_toc_entry_start &&
+ (xport_rpm_ctx[ind].tx_desc == NULL || xport_rpm_ctx[ind].rx_desc == NULL);
+ entry++)
+ {
+ if (entry->fifo_id == xport_rpm_ctx[ind].pcfg->tx_fifo_id)
+ {
+ xport_rpm_ctx[ind].tx_desc = (xport_rpm_ind_type*)&xport_rpm_msg_ram[entry->fifo_offset];
+ xport_rpm_ctx[ind].tx_desc->write_ind = 0;
+ xport_rpm_ctx[ind].tx_fifo = (char*)(xport_rpm_ctx[ind].tx_desc + 1);
+ xport_rpm_ctx[ind].tx_fifo_size = entry->fifo_size;
+ }
+ else if (entry->fifo_id == xport_rpm_ctx[ind].pcfg->rx_fifo_id)
+ {
+ xport_rpm_ctx[ind].rx_desc =(xport_rpm_ind_type*)&xport_rpm_msg_ram[entry->fifo_offset];
+ xport_rpm_ctx[ind].rx_desc->read_ind = 0;
+ xport_rpm_ctx[ind].rx_fifo = (char*)(xport_rpm_ctx[ind].rx_desc + 1);
+ xport_rpm_ctx[ind].rx_fifo_size = entry->fifo_size;
+ }
+ }
+
+ if (xport_rpm_ctx[ind].tx_desc == NULL || xport_rpm_ctx[ind].rx_desc == NULL)
+ {
+ /* FIFOs not found in MSG RAM ToC. */
+ xport_rpm_ctx[ind].pcfg = NULL;
+ continue;
+ }
+
+ /* Initialize context */
+ xport_rpm_ctx[ind].tx_link_lock = NULL;
+ xport_rpm_ctx[ind].rx_link_lock = NULL;
+
+ /* Initialize GLink transport interface */
+ xport_rpm_ctx[ind].xport_if.tx_cmd_version = &xport_rpm_tx_cmd_version;
+ xport_rpm_ctx[ind].xport_if.tx_cmd_version_ack = &xport_rpm_tx_cmd_version_ack;
+ xport_rpm_ctx[ind].xport_if.set_version = &xport_rpm_set_version;
+ xport_rpm_ctx[ind].xport_if.tx_cmd_ch_open = &xport_rpm_tx_cmd_ch_open;
+ xport_rpm_ctx[ind].xport_if.tx_cmd_ch_close = &xport_rpm_tx_cmd_ch_close;
+ xport_rpm_ctx[ind].xport_if.tx_cmd_ch_remote_open_ack = &xport_rpm_tx_cmd_ch_remote_open_ack;
+ xport_rpm_ctx[ind].xport_if.tx_cmd_ch_remote_close_ack = &xport_rpm_tx_cmd_ch_remote_close_ack;
+ xport_rpm_ctx[ind].xport_if.tx = &xport_rpm_tx;
+ xport_rpm_ctx[ind].xport_if.tx_cmd_set_sigs = &xport_rpm_tx_cmd_set_sigs;
+ xport_rpm_ctx[ind].xport_if.ssr = &xport_rpm_ssr;
+ xport_rpm_ctx[ind].xport_if.mask_rx_irq = &xport_rpm_mask_interrupt;
+ xport_rpm_ctx[ind].xport_if.poll = (poll_fn)&xport_rpm_poll;
+ xport_rpm_ctx[ind].xport_if.wait_link_down = &xport_rpm_wait_link_down;
+
+ /* TODO: glink transport priority */
+ xport_rpm_ctx[ind].xport_if.glink_priority = GLINK_XPORT_RPM;
+
+ /* Setup GLink configuration */
+ xport_rpm_cfg.name = XPORT_RPM_NAME;
+ xport_rpm_cfg.remote_ss = xport_rpm_ctx[ind].pcfg->remote_ss;
+ xport_rpm_cfg.version = &xport_rpm_version;
+ xport_rpm_cfg.version_count = 1;
+ xport_rpm_cfg.max_cid = 0xFF;
+ xport_rpm_cfg.max_iid = 0;
+ if (glink_core_register_transport(&xport_rpm_ctx[ind].xport_if, &xport_rpm_cfg) !=
+ GLINK_STATUS_SUCCESS)
+ {
+ /* Registration failed, set index to invalid. */
+ xport_rpm_ctx[ind].pcfg = NULL;
+ continue;
+ }
+
+ if ( !glink_os_register_isr( xport_rpm_ctx[ind].pcfg->irq_in,
+ (os_isr_cb_fn)xport_rpm_isr,
+ &xport_rpm_ctx[ind]) )
+ {
+ /* ISR registration failed, set index to invalid. */
+ xport_rpm_ctx[ind].pcfg = NULL;
+ continue;
+ }
+
+ /* send link up notification */
+ xport_rpm_ctx[ind].xport_if.glink_core_if_ptr->link_up((glink_transport_if_type *)&xport_rpm_ctx[ind].xport_if);
+ }
+
+ return GLINK_STATUS_SUCCESS;
+}
diff --git a/platform/msm_shared/glink/xport_rpm_config.c b/platform/msm_shared/glink/xport_rpm_config.c
new file mode 100644
index 0000000..1fff513
--- /dev/null
+++ b/platform/msm_shared/glink/xport_rpm_config.c
@@ -0,0 +1,92 @@
+/* Copyright (c) 2015, 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 FILES
+===========================================================================*/
+#include "xport_rpm_config.h"
+#include "smem_type.h"
+#include "glink_os_utils.h"
+#include <platform/iomap.h>
+
+/*===========================================================================
+ MACRO DEFINITIONS
+===========================================================================*/
+
+#define XPORT_RPM_MSG_RAM_BASE RPM_SS_MSG_RAM_START_ADDRESS_BASE_PHYS
+#define XPORT_RPM_MSG_RAM_SIZE RPM_SS_MSG_RAM_START_ADDRESS_BASE_SIZE
+
+/** Size of Glink RPM transport ToC in MSG RAM */
+#define XPORT_RPM_MSG_TOC_SIZE 0x100
+
+/*===========================================================================
+ DATA DECLARATIONS
+===========================================================================*/
+const xport_rpm_config_type xport_rpm_config[] =
+{
+ /* LK->Rpm */
+ {
+ "rpm", /* Remote host name */
+ XPORT_RPM_AP2R_ID, /* Tx FIFO ID in RPM ToC */
+ XPORT_RPM_R2AP_ID, /* Rx FIFO ID in RPM ToC */
+ { /* Outgoing interrupt */
+ 8, //DALIPCINT_PROC_RPM,
+ 0, //DALIPCINT_GP_0
+ },
+ 200 /* Incoming interrupt */
+ }
+};
+
+const uint32 xport_rpm_config_num = ARRAY_LENGTH(xport_rpm_config);
+const char* xport_rpm_msg_ram = (char*)XPORT_RPM_MSG_RAM_BASE;
+const uint32* xport_rpm_msg_ram_toc = (uint32*)(XPORT_RPM_MSG_RAM_BASE + XPORT_RPM_MSG_RAM_SIZE - XPORT_RPM_MSG_TOC_SIZE);
+
+/*===========================================================================
+FUNCTION xport_rpm_get_config
+===========================================================================*/
+/**
+
+ Provides a pointer to transport config strucutre.
+
+ @param[in] ind Index of the config
+
+ @return Pointer to transport config strucutre.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+const xport_rpm_config_type* xport_rpm_get_config(uint32 ind)
+{
+ if (ind >= xport_rpm_config_num)
+ {
+ return NULL;
+ }
+
+ return &xport_rpm_config[ind];
+}
diff --git a/platform/msm_shared/hsusb.c b/platform/msm_shared/hsusb.c
index 839f301..5c7d61f 100644
--- a/platform/msm_shared/hsusb.c
+++ b/platform/msm_shared/hsusb.c
@@ -2,7 +2,7 @@
* Copyright (c) 2008, Google Inc.
* All rights reserved.
*
- * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2015, 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
@@ -183,6 +183,11 @@
ept->next = ept_list;
ept_list = ept;
+ arch_clean_invalidate_cache_range((addr_t) ept,
+ sizeof(struct udc_endpoint));
+ arch_clean_invalidate_cache_range((addr_t) ept->head,
+ sizeof(struct ept_queue_head));
+
DBG("ept%d %s @%p/%p max=%d bit=%x\n",
num, in ? "in" : "out", ept, ept->head, max_pkt, ept->bit);
@@ -525,6 +530,7 @@
DBG("setup_tx %p %d\n", buf, len);
memcpy(ep0req->buf, buf, len);
ep0req->buf = (void *)PA((addr_t)ep0req->buf);
+ arch_clean_invalidate_cache_range((addr_t)ep0req->buf, len);
ep0req->complete = ep0in_complete;
ep0req->length = len;
udc_request_queue(ep0in, ep0req);
@@ -541,6 +547,7 @@
arch_clean_invalidate_cache_range((addr_t) ept->head->setup_data,
sizeof(struct ept_queue_head));
memcpy(&s, ept->head->setup_data, sizeof(s));
+ arch_clean_invalidate_cache_range((addr_t)&s, sizeof(s));
writel(ept->bit, USB_ENDPTSETUPSTAT);
DBG("handle_setup type=0x%02x req=0x%02x val=%d idx=%d len=%d (%s)\n",
@@ -559,9 +566,23 @@
case SETUP(DEVICE_READ, GET_DESCRIPTOR):
{
struct udc_descriptor *desc;
+ unsigned char* data = NULL;
+ unsigned n;
/* usb_highspeed? */
for (desc = desc_list; desc; desc = desc->next) {
if (desc->tag == s.value) {
+ /*Check for configuration type of descriptor*/
+ if (desc->tag == (TYPE_CONFIGURATION << 8)) {
+ data = desc->data;
+ data+= 9; /* skip config desc */
+ data+= 9; /* skip interface desc */
+ /* taking the max packet size based on the USB host speed connected */
+ for (n = 0; n < 2; n++) {
+ data[4] = usb_highspeed ? 512:64;
+ data[5] = (usb_highspeed ? 512:64)>>8;
+ data += 7;
+ }
+ }
unsigned len = desc->len;
if (len > s.length)
len = s.length;
diff --git a/platform/msm_shared/include/dev_tree.h b/platform/msm_shared/include/dev_tree.h
index 04ce64d..1d2bd44 100755
--- a/platform/msm_shared/include/dev_tree.h
+++ b/platform/msm_shared/include/dev_tree.h
@@ -142,5 +142,5 @@
int dev_tree_get_entry_info(struct dt_table *table, struct dt_entry *dt_entry_info);
int update_device_tree(void *fdt, const char *, void *, unsigned);
int dev_tree_add_mem_info(void *fdt, uint32_t offset, uint64_t size, uint64_t addr);
-void *dev_tree_appended(void *kernel, uint32_t kernel_size, void *tags);
+void *dev_tree_appended(void *kernel, uint32_t kernel_size, uint32_t dtb_offset, void *tags);
#endif
diff --git a/platform/msm_shared/include/glink.h b/platform/msm_shared/include/glink.h
new file mode 100644
index 0000000..fe5b823
--- /dev/null
+++ b/platform/msm_shared/include/glink.h
@@ -0,0 +1,580 @@
+/* Copyright (c) 2015, 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 GLINK_H
+#define GLINK_H
+
+/**
+ * @file glink.h
+ *
+ * Public API for the GLink
+ */
+
+/** \defgroup glink GLink
+ * \ingroup SMD
+ *
+ * GLink reliable, in-order, datagram-based interprocessor communication
+ * over a set of supported transport (Shared Memory, UART, BAM, HSIC)
+ *
+ * All ports preserve message boundaries across the interprocessor channel; one
+ * write into the port exactly matches one read from the port.
+ */
+/*@{*/
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*===========================================================================
+ INCLUDE FILES
+===========================================================================*/
+#include <stdlib.h>
+
+/*===========================================================================
+ MACRO DECLARATIONS
+===========================================================================*/
+/** GLink status/return codes */
+typedef enum {
+ GLINK_STATUS_SUCCESS = 0,
+ GLINK_STATUS_FAILURE,
+ GLINK_STATUS_INVALID_PARAM,
+ GLINK_STATUS_NOT_INIT,
+ GLINK_STATUS_OUT_OF_RESOURCES,
+ GLINK_STATUS_NO_TRANSPORT
+}glink_err_type;
+
+/** List of possible suvsystems */
+/**
+ "apss" Application Processor Subsystem
+ "mpss" Modem subsystem
+ "lpass" Low Power Audio Subsystem
+ "dsps" Sensors Processor
+ "wcnss" Wireless Connectivity Subsystem
+ "rpm" Resource Power Manager processor
+*/
+
+/** Max allowed channel name length */
+#define GLINK_CH_NAME_LEN 32
+
+/* Bit position of DTR/CTS/CD/RI bits in control sigs 32 bit signal map */
+#define SMD_DTR_SIG_SHFT 31
+#define SMD_CTS_SIG_SHFT 30
+#define SMD_CD_SIG_SHFT 29
+#define SMD_RI_SIG_SHFT 28
+
+/** Version number for the glink_link_id_type structure */
+#define GLINK_LINK_ID_VER 0x00000001
+
+/** Macro to initialize the link identifier structure with default values.
+ * It memsets the header to 0 and initializes the header field */
+#define GLINK_LINK_ID_STRUCT_INIT(link_id) \
+ (link_id).xport = 0; \
+ (link_id).remote_ss = 0; \
+ (link_id).link_notifier = 0; \
+ (link_id).handle = 0; \
+ (link_id).version = GLINK_LINK_ID_VER;
+
+/* GLink tx options */
+/* Whether to block and request for remote rx intent in
+ * case it is not available for this pkt tx */
+#define GLINK_TX_REQ_INTENT 0x00000001
+
+/* If the tx call is being made from single threaded context. GLink tries to
+ * flush data into the transport in glink_tx() context, or returns error if
+ * it is not able to do so */
+#define GLINK_TX_SINGLE_THREADED 0x00000002
+
+/* ======================= glink open cfg options ==================*/
+
+/* Specified transport is just the initial transport and migration is possible
+ * to higher-priority transports. Without this flag, the open will fail if
+ * the transport does not exist. */
+#define GLINK_OPT_INITIAL_XPORT 0x00000001
+
+/*===========================================================================
+ TYPE DECLARATIONS
+===========================================================================*/
+/** Enums to identify link state */
+typedef enum {
+ GLINK_LINK_STATE_UP, /* Called after specified link is online */
+ GLINK_LINK_STATE_DOWN /* Called after SSR (before REMOTE_DISCONNECT) */
+} glink_link_state_type;
+
+/** Data structure holding the link state information */
+typedef struct glink_link_info_t {
+ const char* xport; /* Transport name */
+ const char* remote_ss; /* Remote subsystem name */
+ glink_link_state_type link_state; /* Link state */
+}glink_link_info_type;
+
+/* Callback function invoked when link goes up/down */
+typedef void (*glink_link_state_notif_cb)
+(
+ glink_link_info_type *link_info, /* Ptr to link information strcuture */
+ void* priv /* Client private data */
+);
+
+/**
+ * Opaque handle returned by glink_register_link_state_cb. Client uses this
+ * handle to call glink_deregister_link_state_cb() to deregister their
+ * callback
+ *
+ * Client must not modify or try to interpret this value
+ */
+typedef struct glink_link_notif_data_type * glink_link_handle_type;
+
+/** Data structure to provide link information for the link to monitor */
+typedef struct glink_link_id_t {
+ unsigned int version; /* This fields identifies the verion of
+ the structure. Initialized by
+ GLINK_LINK_ID_STRUCT_INIT macro */
+
+ const char* xport; /* NULL = any transport */
+ const char* remote_ss; /* NULL = any subsystem */
+ glink_link_state_notif_cb link_notifier; /* Notification callback */
+ glink_link_handle_type handle; /* Set by glink_register_link_state_cb */
+}glink_link_id_type;
+
+/**
+ * Opaque handle returned by glink_open. Client uses this handle to call into
+ * GLink API for any further activity related to the channel,
+ *
+ * Client must to modify or try to interpret this value
+ */
+typedef struct glink_channel_ctx* glink_handle_type;
+
+/** GLink logical link state notifications */
+typedef enum {
+ /** Channel is fully opened. Both local and remote end have
+ opened channel from their respective ends, and data communication
+ can now take place */
+ GLINK_CONNECTED = 0,
+
+ /** Local side has called glink_close() and remote side has acknowledged
+ this end's close. Client may call glink_open() after this point */
+ GLINK_LOCAL_DISCONNECTED,
+
+ /** Remote side has called glink_close() to close the channel */
+ GLINK_REMOTE_DISCONNECTED
+}glink_channel_event_type;
+
+/** Vector buffer provider type*/
+typedef void* (*glink_buffer_provider_fn)
+(
+ void* iovec, /* vector buffer */
+ size_t offset, /* offset from the beginning of the vector */
+ size_t *size /* size of the returned contiguous buffer */
+);
+
+/** Data receive notification callback type*/
+typedef void (*glink_rx_notification_cb)
+(
+ glink_handle_type handle, /* handle for the glink channel */
+ const void *priv, /* priv client data passed in glink_open */
+ const void *pkt_priv, /* private client data assiciated with the
+ rx intent that client queued earlier */
+ const void *ptr, /* pointer to the received buffer */
+ size_t size, /* size of the packet */
+ size_t intent_used /* size of the intent used for this packet */
+);
+
+/** Vector receive notification callback type*/
+typedef void (*glink_rxv_notification_cb)
+(
+ glink_handle_type handle, /* handle for the glink channel */
+ const void *priv, /* priv client data passed in glink_open */
+ const void *pkt_priv, /* private client data assiciated with the
+ rx intent that client queued earlier */
+ void *iovec, /* pointer to the received vector */
+ size_t size, /* size of the packet */
+ size_t intent_used, /* size of the intent used for this packet */
+ glink_buffer_provider_fn vprovider, /* Buffer provider for virtual space */
+ glink_buffer_provider_fn pprovider /* Buffer provider for physical space */
+);
+
+/** Data transmit notification callback type*/
+typedef void (*glink_tx_notification_cb)
+(
+ glink_handle_type handle, /* handle for the glink channel */
+ const void *priv, /* priv client data passed in glink_open */
+ const void *pkt_priv, /* private client data assiciated with the
+ tx pkt that client queued earlier */
+ const void *ptr, /* pointer to the transmitted buffer */
+ size_t size /* size of the packet */
+);
+
+/** GLink channel state change notification callback type*/
+typedef void (*glink_state_notification_cb)
+(
+ glink_handle_type handle, /* handle for the glink channel */
+ const void *priv, /* priv client data passed in glink_open */
+ glink_channel_event_type event /* Notification event */
+);
+
+/** Request for a receive intent of size req_size is queued. The request
+ * originates from the remote side GLink client. Return true if intent will
+ * be queued or false if intent request will be denied. */
+typedef bool (*glink_notify_rx_intent_req_cb)
+(
+ glink_handle_type handle, /* handle for the glink channel */
+ const void *priv, /* priv client data passed in glink_open */
+ size_t req_size /* Requested size */
+);
+
+/** New intent arrival notification callback type*/
+typedef void (*glink_notify_rx_intent_cb)
+(
+ glink_handle_type handle, /* handle for the glink channel */
+ const void *priv, /* priv client data passed in glink_open */
+ size_t size /* Intent size */
+);
+
+/** Control signal change notification - Invoked when remote side
+ * alters its control signals */
+typedef void (*glink_notify_rx_sigs_cb)
+(
+ glink_handle_type handle, /* handle for the glink channel */
+ const void *priv, /* priv client data passed in glink_open */
+ uint32_t prev, /* Previous remote state */
+ uint32_t curr /* Current remote state */
+);
+
+/** rx_intent abort notification. This callback would be invoked for
+ * every rx_intent that is queued with GLink core at the time the
+ * remote side or local side decides to close the port */
+typedef void(*glink_notify_rx_abort_cb)
+(
+glink_handle_type handle, /* handle for the glink channel */
+const void *priv, /* priv client data passed in glink_open */
+const void *pkt_priv /* pkt specific private data */
+);
+
+/** tx abort notification. This callback would be invoked if client
+ * had queued a tx buffer with glink and it had not been transmitted i.e.
+ * tx_done callback has not been called for this buffer and remote side
+ * or local side closed the port*/
+typedef void(*glink_notify_tx_abort_cb)
+(
+glink_handle_type handle, /* handle for the glink channel */
+const void *priv, /* priv client data passed in glink_open */
+const void *pkt_priv /* pkt specific private data */
+);
+
+/**
+ * Data Structure for GLink logical channel open configuration
+ *
+ * This structure is used by the clients to open a GLink logical channel
+ * when calling glink_open()
+ */
+typedef struct {
+ /** string name for the transport to use (Optional)*/
+ const char *transport;
+
+ /** string name for the remote subsystem to which the user wants to
+ connect */
+ const char *remote_ss;
+
+ /** string name for the channel */
+ const char *name;
+
+ /** bitfield for specifying various options */
+ unsigned options;
+
+ /** Private data for client to maintain context. This data is passed back
+ to client in the notification callbacks */
+ const void *priv;
+
+ /** Data receive notification callback. Optional if notify_rxv is provided */
+ glink_rx_notification_cb notify_rx;
+
+ /** Vector receive notification callback. Optional if notify_rx is provided */
+ glink_rxv_notification_cb notify_rxv;
+
+ /** Data transmit notification callback */
+ glink_tx_notification_cb notify_tx_done;
+
+ /** GLink channel state notification callback */
+ glink_state_notification_cb notify_state;
+
+ /** Intent request from the remote side. Optional */
+ glink_notify_rx_intent_req_cb notify_rx_intent_req;
+
+ /** New intent arrival from the remote side */
+ glink_notify_rx_intent_cb notify_rx_intent;
+
+ /** Control signal change notification - Invoked when remote side
+ * alters its control signals. Optional */
+ glink_notify_rx_sigs_cb notify_rx_sigs;
+
+ /** rx_intent abort notification. This callback would be invoked for
+ * every rx_intent that is queued with GLink core at the time the
+ * remote side or local side decides to close the port. Optional */
+ glink_notify_rx_abort_cb notify_rx_abort;
+
+ /** tx abort notification. This callback would be invoked if client
+ * had queued a tx buffer with glink and it had not been transmitted i.e.
+ * tx_done callback has not been called for this buffer and remote side
+ * or local side closed the port. Optional */
+ glink_notify_tx_abort_cb notify_tx_abort;
+
+}glink_open_config_type;
+
+/*===========================================================================
+ GLINK PUBLIC API
+===========================================================================*/
+/**
+ * Regsiters a client specified callback to be invoked when the specified
+ * transport (link) is up/down.
+ *
+ * @param[in] link_id Pointer to the configuration structure for the
+ * xport(link) to be monitored. See glink.h
+ * @param[in] priv Callback data returned to client when callback
+ * is invoked.
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects Puts the callback in a queue which gets scanned when a
+ * transport(link) comes up OR an SSR happnes.
+ */
+glink_err_type glink_register_link_state_cb
+(
+ glink_link_id_type *link_id,
+ void* priv
+);
+
+/**
+ * Degsiter the link UP/DOWN notification callback associated with the
+ * provided handle.
+ *
+ * @param[in] handle Callback handler returned by
+ * glink_register_link_state_cb
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects Removes the callback in a queue which gets scanned when a
+ * transport(link) comes up OR an SSR happnes.
+ */
+glink_err_type glink_deregister_link_state_cb
+(
+ glink_link_handle_type handle
+);
+
+/**
+ * Opens a logical GLink based on the specified config params
+ *
+ * @param[in] cfg_ptr Pointer to the configuration structure for the
+ * GLink. See glink.h
+ * @param[out] handle GLink handle associated with the logical channel
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects Allocates channel resources and informs remote host about
+ * channel open.
+ */
+glink_err_type glink_open
+(
+ glink_open_config_type *cfg_ptr,
+ glink_handle_type *handle
+);
+
+/**
+ * Closes the GLink logical channel specified by the handle.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects Closes local end of the channel and informs remote host
+ */
+glink_err_type glink_close
+(
+ glink_handle_type handle
+);
+
+/**
+ * Transmit the provided buffer over GLink.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[in] *pkt_priv Per packet private data
+ *
+ * @param[in] *data Pointer to the data buffer to be transmitted
+ *
+ * @param[in] size Size of buffer
+ *
+ * @param[in] options Flags specifying how transmission for this buffer
+ * would be handled. See GLINK_TX_* flag definitions.
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects Causes remote host to wake-up and process rx pkt
+ */
+glink_err_type glink_tx
+(
+ glink_handle_type handle,
+ const void *pkt_priv,
+ const void *data,
+ size_t size,
+ uint32_t options
+);
+
+/**
+ * Transmit the provided vector buffer over GLink.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[in] *pkt_priv Per packet private data
+ *
+ * @param[in] *iovec Pointer to the vector buffer to be transmitted
+ *
+ * @param[in] size Size of buffer
+ *
+ * @param[in] vprovider Buffer provider for virtual space
+ *
+ * @param[in] pprovider Buffer provider for physical space
+ *
+ * @param[in] options Flags specifying how transmission for this buffer
+ * would be handled. See GLINK_TX_* flag definitions.
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects Causes remote host to wake-up and process rx pkt
+ */
+glink_err_type glink_txv
+(
+ glink_handle_type handle,
+ const void *pkt_priv,
+ void *iovec,
+ size_t size,
+ glink_buffer_provider_fn vprovider,
+ glink_buffer_provider_fn pprovider,
+ uint32_t options
+);
+
+/**
+ * Queue one or more Rx intent for the logical GPIC Link channel.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[in] *pkt_priv Per packet private data
+ *
+ * @param[in] size Size of buffer
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects GLink XAL allocates rx buffers for receiving packets
+ */
+glink_err_type glink_queue_rx_intent
+(
+ glink_handle_type handle,
+ const void *pkt_priv,
+ size_t size
+);
+
+/**
+ * Client uses this to signal to GLink layer that it is done with the received
+ * data buffer. This API should be called to free up the receive buffer, which,
+ * in zero-copy mode is actually remote-side's transmit buffer.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[in] *ptr Pointer to the received buffer
+ *
+ * @param[in] reuse Reuse intent
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects GLink XAL frees the Rx buffer
+ */
+glink_err_type glink_rx_done
+(
+ glink_handle_type handle,
+ const void *ptr,
+ bool reuse
+);
+
+/**
+ * Set the 32 bit control signal field. Depending on the transport, it may
+ * take appropriate actions on the set bit-mask, or transmit the entire
+ * 32-bit value to the remote host.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[in] sig_value 32 bit signal word
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects None
+ */
+glink_err_type glink_sigs_set
+(
+ glink_handle_type handle,
+ uint32_t sig_value
+);
+
+/**
+ * Get the local 32 bit control signal bit-field.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[out] *sig_value Pointer to a 32 bit signal word to get sig value
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects None
+ */
+glink_err_type glink_sigs_local_get
+(
+ glink_handle_type handle,
+ uint32_t *sig_value
+);
+
+/**
+ * Get the remote 32 bit control signal bit-field.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[out] *sig_value Pointer to a 32 bit signal word to get sig value
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects None
+ */
+glink_err_type glink_sigs_remote_get
+(
+ glink_handle_type handle,
+ uint32_t *sig_value
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //GLINK_H
diff --git a/platform/msm_shared/include/glink_channel_migration.h b/platform/msm_shared/include/glink_channel_migration.h
new file mode 100644
index 0000000..3693660
--- /dev/null
+++ b/platform/msm_shared/include/glink_channel_migration.h
@@ -0,0 +1,141 @@
+/* Copyright (c) 2015, 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 GLINK_CH_MGR__H
+#define GLINK_CH_MGR__H
+
+/*===========================================================================
+
+ GLink channel migration Header File
+
+===========================================================================*/
+
+
+/*===========================================================================
+
+ INCLUDE FILES
+
+===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*===========================================================================
+ FEATURE DEFINITIONS
+===========================================================================*/
+
+/**
+ * This function returns glink_transport_if pointer based on
+ * XPORT priority
+ *
+ * @param[in] prio glink xport prio
+ * @param[in] remote_ss remote subsytem name
+ *
+ * @return pointer to glink_transport_if_type struct
+ *
+ * @sideeffects NONE
+ */
+glink_transport_if_type *glinki_get_xport_from_prio
+(
+ glink_xport_priority prio,
+ const char *remote_ss
+);
+
+/**
+ * This function negotiated xport priorities and gives best
+ * available priority
+ *
+ * @param[in] requested_best_prio priority requested by remote subsytem
+ * @param[in] current_best_prio priority requested by channel on local
+ side
+ *
+ * @return Negotiated xport priority
+ *
+ * @sideeffects NONE
+ */
+glink_xport_priority glinki_negotiate_ch_migration
+(
+ glink_xport_priority requested_prio,
+ glink_xport_priority current_prio
+);
+
+/**
+ * This function searches channel with given name on all available
+ * xports and returns channel context and xport on which channel is
+ * present. These return values are used to negotiate xport priorities
+ * and to decide if channel needs to be migrated from given xport
+ * to negotiated xport
+ *
+ * @param[in] if_ptr transport on which channel is opened
+ * @param[in] name name of the channel
+ * @param[in] is_local_channel flag to notify this function if channel to
+ * be searched will have state REMOTE_OPEN
+ * or LOCAL_OPEN
+ * @param[out] present_ch_ctx channel context to be returned
+ * @param[out] present_if_ptr xport pointer on which channel is open
+ *
+ * @return TRUE - if channel found
+ * FALSE - if channel is not found
+ *
+ * @sideeffects NONE
+ */
+boolean glinki_local_channel_exists
+(
+ glink_transport_if_type *if_ptr,
+ glink_transport_if_type **present_if_ptr,
+ const char *name,
+ glink_channel_ctx_type **present_ch_ctx,
+ boolean is_local_channel
+);
+
+/**
+ * This function sets flag for channel context to represent
+ * that channel is tagged for deletion. This is to cover corner
+ * case where local side might close the channel but channel
+ * context still sticks around and might be found again for
+ * xport negotiation.
+ *
+ * @param[in] if_ptr transport on which channel is opened
+ * @param[in] name name of the channel
+ * @param[in] prio priority of negotiated xport. all channels on
+ * xports other than xport with this prio will be
+ * tagged for deletion
+ *
+ * @return NONE
+ *
+ * @sideeffects NONE
+ */
+void glinki_tag_ch_for_deletion
+(
+ glink_transport_if_type *if_ptr,
+ const char *name,
+ glink_xport_priority prio
+);
+
+#endif /* GLINK_CHANNEL_MIGRATION_H */
diff --git a/platform/msm_shared/include/glink_core_if.h b/platform/msm_shared/include/glink_core_if.h
new file mode 100644
index 0000000..040bf31
--- /dev/null
+++ b/platform/msm_shared/include/glink_core_if.h
@@ -0,0 +1,512 @@
+/* Copyright (c) 2015, 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 GLINK_CORE_IF_H
+#define GLINK_CORE_IF_H
+
+/**
+ * @file glink_core_if.h
+ *
+ * Public API for the transport abstraction layer to call into GLINK Core
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*===========================================================================
+ INCLUDE FILES
+===========================================================================*/
+
+#include "smem_list.h"
+#include "glink.h"
+#include "glink_transport_if.h"
+#include "glink_os_utils.h"
+
+/*===========================================================================
+ MACRO DECLARATIONS
+===========================================================================*/
+
+/*===========================================================================
+ TYPE DECLARATIONS
+===========================================================================*/
+typedef struct glink_core_version glink_core_version_type;
+
+struct glink_channel_ctx;
+typedef struct glink_channel_ctx glink_channel_ctx_type;
+
+/**
+ * Transport status
+ */
+typedef enum {
+ GLINK_XPORT_REGISTERED = 0,
+ GLINK_XPORT_NEGOTIATING,
+ GLINK_XPORT_LINK_UP,
+
+}glink_transport_status_type;
+
+struct glink_rx_intent {
+ /* Link needed for use with list APIs. Must be at the head of the struct */
+ smem_list_link_type link;
+
+ void *data; /* Pointer to the data buffer to be transmitted */
+ const void *pkt_priv; /* Per packet private data */
+ size_t size; /* Size of data buffer */
+ size_t used; /* Actual valid data in *data field */
+ size_t pkt_sz; /* Size of the packet */
+ uint32 iid; /* Intent ID */
+ void *iovec; /* Pointer to the data buffer to be transmitted */
+ glink_buffer_provider_fn vprovider; /* Buffer provider for virtual space */
+ glink_buffer_provider_fn pprovider; /* Buffer provider for physical space */
+};
+/** GLink channel states*/
+typedef enum {
+ /** GLink channel state during initialization. No resources have been
+ * allocated for this channel as neither GLink end has actually opened
+ * the channel */
+ GLINK_CH_STATE_CLOSED,
+
+ /** GLink channel state when the local side has opened the channel. GLink
+ * core is waiting for the other end of the channel to open */
+ GLINK_CH_STATE_LOCAL_OPEN,
+
+ /** GLink channel state when it is fully open. This implies that both ends
+ * of the GLink channel are now open. Data transfer can now take place */
+ GLINK_CH_STATE_OPEN,
+
+ /** GLink channel state when remote side has initiated a OPEN operation. */
+ GLINK_CH_STATE_REMOTE_OPEN,
+
+ /** GLink channel state when remote side has initiated a CLOSE operation.
+ * Data cannot be transmitted/received any further on this channel */
+ GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE,
+
+ /** GLink channel state when the local side has initiated a CLOSE. This
+ * would be followed by a GLINK_STATE_CLOSE state transition after
+ * the remote side has acknowledged the CLOSE request */
+ GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE,
+
+ /** GLink channel state would transition to SLEEP if the underlying
+ * transport supports low power mode and decides to go into sleep
+ * due to inactivity for some time or any other reason. */
+ GLINK_CH_STATE_SLEEP,
+
+ /** GLink channel state would transition to AWAKE state when underlying
+ * transport layer has powered up the hardware */
+ GLINK_CH_STATE_AWAKE
+}glink_ch_state_type;
+
+/** Indicates that transport is now ready to start negotiation using the
+ * v0 configuration. */
+typedef void (*link_up_fn)
+(
+ glink_transport_if_type *if_ptr /* Pointer to the interface instance */
+);
+
+/** Receive transport version for remote-initiated version negotiation */
+typedef void (*rx_cmd_version_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 version, /* Version */
+ uint32 features /* Features */
+);
+
+/** Receive ACK to previous glink_transport_if_type::tx_cmd_version command */
+typedef void (*rx_cmd_version_ack_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 version, /* Version */
+ uint32 features /* Features */
+);
+
+/** Sets the core version used by the transport; called after completing
+ * negotiation.*/
+typedef void (*set_core_version_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 version /* Version */
+);
+
+/** Receive remote channel open request; expected response is
+ * glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
+typedef void (*rx_cmd_ch_remote_open_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid, /* Remote channel ID */
+ const char *name, /* String name for the logical channel */
+ glink_xport_priority prio /* priority of xport */
+);
+
+/** This function is invoked by the transport in response to
+ * glink_transport_if_type:: tx_cmd_ch_open */
+typedef void (*rx_cmd_ch_open_ack_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid, /* Local channel ID */
+ glink_xport_priority prio
+);
+
+/** This function is invoked by the transport in response to
+ * glink_transport_if_type:: tx_cmd_ch_close */
+typedef void (*rx_cmd_ch_close_ack_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid /* Local channel ID */
+);
+
+/** Remote channel close request; will result in sending
+ * glink_transport_if_type:: tx_cmd_ch_remote_close_ack */
+typedef void (*rx_cmd_ch_remote_close_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid /* Remote channel ID */
+);
+
+/** Process local state transition */
+typedef void (*ch_state_local_trans_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid, /* Local channel ID */
+ glink_ch_state_type new_state /* New local channel state */
+);
+
+/** Transport invokes this call on receiving remote RX intent */
+typedef void (*rx_cmd_remote_rx_intent_put_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid, /* Remote channel ID */
+ uint32 riid, /* Remote intent ID */
+ size_t size /* Size of receive intent */
+);
+
+/** Get receive packet context (if successful, should be followed by call to
+ rx_put_pkt_ctx) */
+typedef glink_rx_intent_type* (*rx_get_pkt_ctx_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid, /* Remote channel ID */
+ uint32 liid /* Local intent ID */
+);
+
+/** Receive a packet fragment (must have previously received an rx_cmd_rx_data
+ packet). */
+typedef void (*rx_put_pkt_ctx_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid, /* Remote channel ID */
+ glink_rx_intent_type *intent_ptr, /* Fragment ptr */
+ boolean complete /* True if pkt is complete */
+);
+
+/** Transport invokes this call to inform GLink that remote side is
+ * done with previous transmitted packet. */
+typedef void (*rx_cmd_tx_done_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid, /* Remote channel ID */
+ uint32 riid, /* Remote intent ID */
+ boolean reuse /* Reuse intent */
+);
+
+/** Remote side is requesting an RX intent */
+typedef void (*rx_cmd_remote_rx_intent_req_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid, /* Remote channel ID */
+ size_t size /* Size of the requested intent */
+);
+
+/** ACK to RX Intent Request */
+typedef void (*rx_cmd_rx_intent_req_ack_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid, /* Remote channel ID */
+ boolean granted /* True if RX Intent will be queued, FALSE
+ if request will not be granted. */
+);
+
+/** If transport was full and could not continue a transmit operation,
+ * then it will call this function to notify the core that it is ready to
+ * resume transmission. */
+typedef void (*tx_resume_fn)
+(
+ glink_transport_if_type *if_ptr /* Pointer to the interface instance */
+);
+
+/** Received 32-bit signals value from remote side. It is passed on to
+ * the client */
+typedef void (*rx_cmd_remote_sigs_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid, /* Remote channel ID */
+ uint32 remote_sigs /* Remote control signals */
+);
+
+/** Channel open config verification */
+typedef boolean(*verify_open_cfg_fn)
+(
+ glink_channel_ctx_type *ch_ctx /* Pointer to the channel context */
+);
+
+/** Channel initialization */
+typedef glink_err_type (*channel_init_fn)
+(
+ glink_channel_ctx_type *open_ch_ctx /* Pointer to the channel context */
+);
+
+/** Channel cleanup */
+typedef void (*channel_cleanup_fn)
+(
+ glink_channel_ctx_type *open_ch_ctx /* Pointer to the channel context */
+);
+
+/** Channel receive pkt */
+typedef void(*channel_receive_pkt_fn)
+(
+ glink_channel_ctx_type *open_ch_ctx, /* Pointer to the channel context */
+ glink_rx_intent_type *intent_ptr /* Pointer to the intent context */
+);
+
+/** Use remote intent */
+typedef glink_err_type(*use_rm_intent_fn)
+(
+ glink_channel_ctx_type *open_ch_ctx, /* Pointer to the channel context */
+ glink_core_tx_pkt_type *pctx, /* Pointer to the packet context */
+ boolean req_intent /* Request intent flag */
+);
+
+
+/** Transport specific data pointer that transport may choose fill in
+ * with some data */
+struct glink_core_xport_ctx
+{
+ /* Transport name */
+ char xport[32];
+
+ /* Remote subsystem name */
+ char remote_ss[32];
+
+ /** Keep track of version array index in use */
+ const glink_core_version_type *version_array;
+
+ /** Keep track of version array index in use */
+ uint32 version_indx;
+
+ /* Keeps track of the current status of the transport */
+ glink_transport_status_type status;
+
+ /* Transport's capabilities */
+ uint32 xport_capabilities;
+
+ /* Free lcid */
+ uint32 free_lcid;
+
+ /* Keeps track of the open channels for this transport/edge combination */
+ smem_list_type open_list;
+
+ /* Critical section to protect access to open_list */
+ os_cs_type channel_q_cs;
+
+ /* Local channel intents queued so far. This also helps determining liid
+ * when client queues new rx intents locally */
+ uint32 liid;
+
+ /* Critical section to protect access to liid allocation */
+ os_cs_type liid_cs;
+
+ /* channel open config verification */
+ verify_open_cfg_fn verify_open_cfg;
+
+ /* channel init function */
+ channel_init_fn channel_init;
+
+ /* channel cleanup function */
+ channel_cleanup_fn channel_cleanup;
+
+ /* channel receive pkt */
+ channel_receive_pkt_fn channel_receive_pkt;
+
+ /** Use remote intent */
+ use_rm_intent_fn use_rm_intent;
+};
+
+/**
+ * Data Structure for Transport abstraction layer to call into GLink Core
+ * for logical channel control state update and data Tx/Rx notifications.
+ */
+struct glink_core_if
+{
+ /** Indicates that transport is now ready to start negotiation using the
+ * v0 configuration. */
+ link_up_fn link_up;
+
+
+ /** Receive transport version for remote-initiated version negotiation */
+ rx_cmd_version_fn rx_cmd_version;
+
+
+ /** Receive ACK to previous glink_transport_if_type::tx_cmd_version command */
+ rx_cmd_version_ack_fn rx_cmd_version_ack;
+
+ /** Sets the core version used by the transport; called after completing
+ * negotiation.*/
+ set_core_version_fn set_core_version;
+
+ /** Receive remote channel open request; expected response is
+ * glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
+ rx_cmd_ch_remote_open_fn rx_cmd_ch_remote_open;
+
+
+ /** This function is invoked by the transport in response to
+ * glink_transport_if_type:: tx_cmd_ch_open */
+ rx_cmd_ch_open_ack_fn rx_cmd_ch_open_ack;
+
+
+ /** This function is invoked by the transport in response to
+ * glink_transport_if_type:: tx_cmd_ch_close */
+ rx_cmd_ch_close_ack_fn rx_cmd_ch_close_ack;
+
+
+ /** Remote channel close request; will result in sending
+ * glink_transport_if_type:: tx_cmd_ch_remote_close_ack */
+ rx_cmd_ch_remote_close_fn rx_cmd_ch_remote_close;
+
+
+ /** Process local state transition */
+ ch_state_local_trans_fn ch_state_local_trans;
+
+
+ /** Transport invokes this call on receiving remote RX intent */
+ rx_cmd_remote_rx_intent_put_fn rx_cmd_remote_rx_intent_put;
+
+ /** Get receive packet context (if successful, should be followed by call to
+ rx_put_pkt_ctx) */
+ rx_get_pkt_ctx_fn rx_get_pkt_ctx;
+
+ /** Receive a packet fragment (must have previously received an rx_cmd_rx_data
+ packet). */
+ rx_put_pkt_ctx_fn rx_put_pkt_ctx;
+
+ /** Transport invokes this call to inform GLink that remote side is
+ * done with previous transmitted packet. */
+ rx_cmd_tx_done_fn rx_cmd_tx_done;
+
+ /** Remote side is requesting an RX intent */
+ rx_cmd_remote_rx_intent_req_fn rx_cmd_remote_rx_intent_req;
+
+ /** ACK to RX Intent Request */
+ rx_cmd_rx_intent_req_ack_fn rx_cmd_rx_intent_req_ack;
+
+ /** Received 32-bit signals value from remote side. It is passed on to
+ * the client */
+ rx_cmd_remote_sigs_fn rx_cmd_remote_sigs;
+
+ /** If transport was full and could not continue a transmit operation,
+ * then it will call this function to notify the core that it is ready to
+ * resume transmission. */
+ tx_resume_fn tx_resume;
+};
+
+/** Feature negotiation function. The version negotiation starts out using
+ * the full feature set from the features element and then calls this
+ * function with a subset passed into the features argument. This
+ * function should filter passed in features with the supported feature
+ * set. For simple cases, a bitwise AND can be used, but for more
+ * complicated cases (such as when features are mutually exclusive),
+ * this function enables a more complex negotiation sequence.
+ */
+typedef uint32 (*negotiate_features_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface
+ instance */
+ const glink_core_version_type *version_ptr, /* Version structure */
+ uint32 features /* Subset of features based on
+ negotiation */
+);
+
+/**
+ * Version structure
+ */
+struct glink_core_version {
+ uint32 version; /* Version number */
+ uint32 features; /* Set of features supported in
+ this version */
+
+ /** Feature negotiation function. The version negotiation starts out using
+ * the full feature set from the features element and then calls this
+ * function with a subset passed into the features argument. This
+ * function should filter passed in features with the supported feature
+ * set. For simple cases, a bitwise AND can be used, but for more
+ * complicated cases (such as when features are mutually exclusive),
+ * this function enables a more complex negotiation sequence.
+ */
+ negotiate_features_fn negotiate_features;
+};
+
+/**
+ * Data Structure for Transport abstraction layer to call into GLink Core
+ * while registering with GLink
+ */
+typedef struct {
+ const char *name; /* Name of the transport */
+ const char *remote_ss; /* Remote host name */
+ const glink_core_version_type *version; /* Array of supported versions */
+ size_t version_count; /* Number of elements in version[] */
+ uint32 max_cid; /* Max channel ID supported by
+ transport */
+ uint32 max_iid; /* Max Rx intent ID supported by
+ transport */
+}glink_core_transport_cfg_type;
+
+/*===========================================================================
+ PUBLIC FUNCTION DECLARATIONS
+===========================================================================*/
+/*===========================================================================
+FUNCTION glink_core_register_transport
+
+DESCRIPTION Transport calls this API to register its interface with GLINK
+ Core
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ *cfg Pointer to transport configuration structure.
+
+RETURN VALUE Standard GLINK error codes.
+
+SIDE EFFECTS None
+===========================================================================*/
+
+glink_err_type glink_core_register_transport
+(
+ glink_transport_if_type *if_ptr,
+ glink_core_transport_cfg_type *cfg
+);
+
+#endif //GLINK_CORE_IF_H
+
diff --git a/platform/msm_shared/include/glink_internal.h b/platform/msm_shared/include/glink_internal.h
new file mode 100644
index 0000000..96b0a59
--- /dev/null
+++ b/platform/msm_shared/include/glink_internal.h
@@ -0,0 +1,845 @@
+/* Copyright (c) 2015, 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 GLINK_INTERNAL_H
+#define GLINK_INTERNAL_H
+
+/*===========================================================================
+
+ GLink Core Internal Header File
+
+===========================================================================*/
+
+/*===========================================================================
+
+ INCLUDE FILES
+
+===========================================================================*/
+#include "smem_list.h"
+#include "glink.h"
+#include "glink_os_utils.h"
+#include "glink_core_if.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*===========================================================================
+ FEATURE DEFINITIONS
+===========================================================================*/
+#define GLINK_VERSION 0
+#define GLINK_FEATURE_FLAGS 0
+#define GLINK_NUM_HOSTS 7
+
+/*===========================================================================
+ MACRO DEFINITIONS
+===========================================================================*/
+#define GLINK_LOG_EVENT(type, ch_name, xport, remote_ss, param) \
+ glink_mem_log(__FUNCTION__, __LINE__, type, ch_name, xport, remote_ss, param);
+
+#define GLINK_MEM_LOG_SIZE 128
+
+/*===========================================================================
+ TYPE DEFINITIONS
+===========================================================================*/
+typedef enum {
+ GLINK_EVENT_INIT,
+ GLINK_EVENT_REGISTER_XPORT,
+ GLINK_EVENT_CH_OPEN,
+ GLINK_EVENT_CH_CLOSE,
+ GLINK_EVENT_CH_TX,
+ GLINK_EVENT_CH_Q_RX_INTENT,
+ GLINK_EVENT_CH_RX_DONE,
+ GLINK_EVENT_LINK_UP,
+ GLINK_EVENT_RX_CMD_VER,
+ GLINK_EVENT_RM_CH_OPEN,
+ GLINK_EVENT_CH_OPEN_ACK,
+ GLINK_EVENT_CH_CLOSE_ACK,
+ GLINK_EVENT_CH_REMOTE_CLOSE,
+ GLINK_EVENT_CH_STATE_TRANS,
+ GLINK_EVENT_CH_INTENT_PUT,
+ GLINK_EVENT_CH_RX_DATA,
+ GLINK_EVENT_CH_RX_DATA_FRAG,
+ GLINK_EVENT_CH_GET_PKT_CTX,
+ GLINK_EVENT_CH_PUT_PKT_CTX,
+ GLINK_EVENT_CH_TX_DONE,
+ GLINK_EVENT_CH_SIG_SET,
+ GLINK_EVENT_CH_SIG_L_GET,
+ GLINK_EVENT_CH_SIG_R_GET,
+ GLINK_EVENT_XPORT_INTERNAL,
+}glink_log_event_type;
+
+typedef struct _glink_channel_intents_type {
+ /* Critical section to protest access to intent queues */
+ os_cs_type intent_q_cs;
+
+ /* Event that glink_tx waits on and blocks until remote rx_intents
+ * are available */
+ os_event_type rm_intent_avail_evt;
+
+ /* Size of requested intent that this channel wait on */
+ size_t rm_intent_req_size;
+
+ /* Linked list of remote Rx intents. Data can be transmitted only when
+ * remote intents are available */
+ smem_list_type remote_intent_q;
+
+ /* Linked list of remote Rx intents which local GLink core has used to
+ * transmit data, and are pending Tx complete */
+ smem_list_type remote_intent_pending_tx_q;
+
+ /* Linked list of local Rx intents. Data can be received only when
+ * local intents are available */
+ smem_list_type local_intent_q;
+
+ /* Linked list of remote Rx intents held by the clients */
+ smem_list_type local_intent_client_q;
+
+ /* Read intent being gathered */
+ glink_rx_intent_type *cur_read_intent;
+
+} glink_channel_intents_type;
+
+struct glink_channel_ctx {
+ /* Link needed for use with list APIs. Must be at the head of the struct */
+ smem_list_link_type link;
+
+ /* Channel name */
+ char name[GLINK_CH_NAME_LEN];
+
+ /* Local channel ID */
+ uint32 lcid;
+
+ /* Remote Channel ID */
+ uint32 rcid;
+
+ /* Channel state */
+ glink_ch_state_type state;
+
+ /* Channel local control signal state */
+ uint32 local_sigs;
+
+ /* Channel remote control signal state */
+ uint32 remote_sigs;
+
+ /* Critical section to protect tx operations */
+ os_cs_type tx_cs;
+
+ /* channel intent collection */
+ glink_channel_intents_type *pintents;
+
+ /* Interface pointer with with this channel is registered */
+ glink_transport_if_type *if_ptr;
+
+ /** Private data for client to maintain context. This data is passed back
+ * to client in the notification callbacks */
+ const void *priv;
+
+ /** Data receive notification callback */
+ glink_rx_notification_cb notify_rx;
+
+ /** Vector receive notification callback */
+ glink_rxv_notification_cb notify_rxv;
+
+ /** Data transmit notification callback */
+ glink_tx_notification_cb notify_tx_done;
+
+ /** GLink channel state notification callback */
+ glink_state_notification_cb notify_state;
+
+ /** Intent request from the remote side */
+ glink_notify_rx_intent_req_cb notify_rx_intent_req;
+
+ /** New intent arrival from the remote side */
+ glink_notify_rx_intent_cb notify_rx_intent;
+
+ /** Control signal change notification - Invoked when remote side
+ * alters its control signals */
+ glink_notify_rx_sigs_cb notify_rx_sigs;
+
+ /** rx_intent abort notification. This callback would be invoked for
+ * every rx_intent that is queued with GLink core at the time the
+ * remote side or local side decides to close the port. Optional */
+ glink_notify_rx_abort_cb notify_rx_abort;
+
+ /** tx abort notification. This callback would be invoked if client
+ * had queued a tx buffer with glink and it had not been transmitted i.e.
+ * tx_done callback has not been called for this buffer and remote side
+ * or local side closed the port. Optional */
+ glink_notify_tx_abort_cb notify_tx_abort;
+
+ /* glink transport if pointer for preferred channel */
+ glink_transport_if_type *req_if_ptr;
+
+ /* reference count for no of times channel open/close has been called */
+ uint32 ref_count;
+
+ /* flag to check if channel is marked for deletion
+ * This is workaround to prevent channel migration algorithm from finding channel
+ * which should be closed but has not been closed yet. This case occurs when glink_close
+ * is called for closing channel on initial xport and it is being opened on other xport.
+ * This may lead to remote side opening channel on neogitated xport from which local side
+ * will get remote open again. In this case channel to be closed will be found for negotiation
+ * on initial xport again and channel migration algorithm will be triggered(again) */
+ boolean tag_ch_for_close;
+
+ /* save glink open config options */
+ uint32 ch_open_options;
+};
+
+
+typedef struct _glink_mem_log_entry_type {
+ const char *func;
+ uint32 line;
+ glink_log_event_type type;
+ const char *msg;
+ const char *xport;
+ const char *remote_ss;
+ uint32 param;
+} glink_mem_log_entry_type;
+
+/* Structure to store link notification callbacks */
+typedef struct {
+ /* Link needed for use with list APIs. Must be at the head of the struct */
+ smem_list_link_type link;
+
+ const char* xport; /* NULL = any transport */
+ const char* remote_ss; /* NULL = any subsystem */
+ glink_link_state_notif_cb link_notifier; /* Notification callback */
+ void *priv; /* Notification priv ptr */
+} glink_link_notif_data_type;
+
+
+/*===========================================================================
+ GLOBAL DATA DECLARATIONS
+===========================================================================*/
+extern os_cs_type *glink_transport_q_cs;
+extern const char *glink_hosts_supported[GLINK_NUM_HOSTS];
+extern smem_list_type glink_registered_transports[];
+
+/*===========================================================================
+ LOCAL FUNCTION DEFINITIONS
+===========================================================================*/
+
+/*===========================================================================
+ EXTERNAL FUNCTION DEFINITIONS
+===========================================================================*/
+/*===========================================================================
+FUNCTION glink_link_up
+
+DESCRIPTION Indicates that transport is now ready to start negotiation
+ using the v0 configuration
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_link_up
+(
+ glink_transport_if_type *if_ptr
+);
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_version
+
+DESCRIPTION Receive transport version for remote-initiated version
+ negotiation
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ version Remote Version
+
+ features Remote Features
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_version
+(
+ glink_transport_if_type *if_ptr,
+ uint32 version,
+ uint32 features
+);
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_version_ack
+
+DESCRIPTION Receive ACK to previous glink_transport_if::tx_cmd_version
+ command
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ version Remote Version
+
+ features Remote Features
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_version_ack
+(
+ glink_transport_if_type *if_ptr,
+ uint32 version,
+ uint32 features
+);
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_ch_remote_open
+
+DESCRIPTION Receive remote channel open request; Calls
+ glink_transport_if:: tx_cmd_ch_remote_open_ack as a result
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ rcid Remote Channel ID
+
+ *name String name for logical channel
+
+ prio requested xport priority from remote side
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_ch_remote_open
+(
+ glink_transport_if_type *if_ptr,
+ uint32 rcid,
+ const char *name,
+ glink_xport_priority prio
+);
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_ch_open_ack
+
+DESCRIPTION This function is invoked by the transport in response to
+ glink_transport_if:: tx_cmd_ch_open
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ lcid Local Channel ID
+
+ prio Negotiated xport priority obtained from remote side
+ after negotiation happened on remote side
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_ch_open_ack
+(
+ glink_transport_if_type *if_ptr,
+ uint32 lcid,
+ glink_xport_priority prio
+);
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_ch_close_ack
+
+DESCRIPTION This function is invoked by the transport in response to
+ glink_transport_if_type:: tx_cmd_ch_close
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ lcid Local Channel ID
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_ch_close_ack
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid /* Local channel ID */
+);
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_ch_remote_close
+
+DESCRIPTION Remote channel close request; will result in sending
+ glink_transport_if_type:: tx_cmd_ch_remote_close_ack
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ rcid Remote Channel ID
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_ch_remote_close
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid /* Remote channel ID */
+);
+
+/*===========================================================================
+FUNCTION glink_ch_state_local_trans
+
+DESCRIPTION Process local state transition
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ rcid Remote Channel ID
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_ch_state_local_trans
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid, /* Local channel ID */
+ glink_ch_state_type new_state /* New local channel state */
+);
+
+/*===========================================================================
+FUNCTION glink_rx_put_pkt_ctx
+
+DESCRIPTION Transport invokes this call to receive a packet fragment (must
+ have previously received an rx_cmd_rx_data packet)
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ rcid Remote Channel ID
+
+ *intent_ptr Pointer to the intent fragment
+
+ complete True if pkt is complete
+
+RETURN VALUE None
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_put_pkt_ctx
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid, /* Remote channel ID */
+ glink_rx_intent_type *intent_ptr, /* Fragment ptr */
+ boolean complete /* True if pkt is complete */
+);
+
+/*===========================================================================
+FUNCTION glink_rx_cmd_remote_sigs
+
+DESCRIPTION Transport invokes this call to inform GLink of remote side
+ changing its control signals
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ rcid Remote Channel ID
+
+ remote_sigs Remote signal state.
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_rx_cmd_remote_sigs
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid, /* Remote channel ID */
+ uint32 remote_sigs /* Remote control signals */
+);
+
+/*===========================================================================
+FUNCTION glink_tx_resume
+
+DESCRIPTION If transport was full and could not continue a transmit
+ operation, then it will call this function to notify the core
+ that it is ready to resume transmission.
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_tx_resume
+(
+ glink_transport_if_type *if_ptr /* Pointer to the interface instance */
+);
+
+/*===========================================================================
+FUNCTION glink_set_core_version
+
+DESCRIPTION Sets the core version used by the transport; called after
+ completing negotiation.
+
+ARGUMENTS *if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ version Negotiated transport version
+
+RETURN VALUE None.
+
+SIDE EFFECTS None
+===========================================================================*/
+void glink_set_core_version
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 version /* Version */
+);
+
+/*===========================================================================
+ CHANNEL CONTEXT APIS
+===========================================================================*/
+
+/*===========================================================================
+FUNCTION glinki_ch_is_fully_opened
+
+DESCRIPTION Determine if both the local and remote channel state is fully
+ open
+
+ARGUMENTS *cfg_ptr - Pointer to channel context
+
+RETURN VALUE True if fully opened, FALSE otherwise.
+
+SIDE EFFECTS None
+===========================================================================*/
+boolean glinki_ch_is_fully_opened
+(
+ glink_channel_ctx_type *ctx
+);
+
+
+/*===========================================================================
+FUNCTION glinki_ch_push_local_rx_intent
+
+DESCRIPTION Create and push a local receive intent to internal list
+
+ARGUMENTS *cfg_ptr - Pointer to channel context
+
+ *pkt_priv - Client-provided opaque data
+
+ size - Size of Receive Intent
+
+RETURN VALUE Pointer to the new intent
+
+SIDE EFFECTS None
+===========================================================================*/
+glink_rx_intent_type* glinki_ch_push_local_rx_intent
+(
+ glink_channel_ctx_type *ctx,
+ const void *pkt_priv,
+ size_t size
+);
+
+/*===========================================================================
+FUNCTION glinki_ch_get_local_rx_intent
+
+DESCRIPTION Lookup a local receive intent
+
+ARGUMENTS *cfg_ptr - Pointer to channel context
+
+ liid - Local Receive Intent ID
+
+RETURN VALUE Pointer to the intent or NULL if not match is found.
+
+SIDE EFFECTS None
+===========================================================================*/
+glink_rx_intent_type* glinki_ch_get_local_rx_intent
+(
+ glink_channel_ctx_type *ctx,
+ uint32 liid
+);
+
+/*===========================================================================
+FUNCTION glinki_ch_remove_local_rx_intent
+
+DESCRIPTION Removes Local Receive Intent ID
+
+ARGUMENTS *cfg_ptr - Pointer to channel context
+
+ liid - Local Receive Intent ID
+
+RETURN VALUE None
+
+SIDE EFFECTS None
+===========================================================================*/
+void glinki_ch_remove_local_rx_intent
+(
+ glink_channel_ctx_type *ctx,
+ uint32 liid
+);
+
+/*===========================================================================
+FUNCTION glinki_ch_set_local_rx_intent_notified
+
+DESCRIPTION Sets the state of the intent as client-notified
+
+ARGUMENTS *cfg_ptr - Pointer to channel context
+
+ *intent_ptr - Pointer to the receive intent
+
+RETURN VALUE None
+
+SIDE EFFECTS None
+===========================================================================*/
+void glinki_ch_set_local_rx_intent_notified
+(
+ glink_channel_ctx_type *ctx,
+ glink_rx_intent_type *intent_ptr
+);
+
+/*===========================================================================
+FUNCTION glinki_ch_get_local_rx_intent_notified
+
+DESCRIPTION Lookup a Local Receive Intent ID that is in the client-notified
+ state
+
+ARGUMENTS *cfg_ptr - Pointer to channel context
+
+ *ptr - Data pointer of receive buffer from client
+ (passed in through glink_rx_done)
+
+RETURN VALUE Pointer to the intent or NULL if not match is found.
+
+SIDE EFFECTS None
+===========================================================================*/
+glink_rx_intent_type* glinki_ch_get_local_rx_intent_notified
+(
+ glink_channel_ctx_type *ctx,
+ void *ptr
+);
+
+/*===========================================================================
+FUNCTION glinki_ch_remove_local_rx_intent_notified
+
+DESCRIPTION Removes the Local Receive Intent
+
+ARGUMENTS *cfg_ptr - Pointer to channel context
+
+ *intent_ptr - Pointer to the receive intent
+
+RETURN VALUE New channel context or NULL
+
+SIDE EFFECTS None
+===========================================================================*/
+glink_channel_ctx_type* glinki_ch_remove_local_rx_intent_notified
+(
+ glink_channel_ctx_type *ctx,
+ glink_rx_intent_type *intent_ptr
+);
+
+/*===========================================================================
+FUNCTION glinki_ch_push_remote_rx_intent
+
+DESCRIPTION Adds a new Remote Receive Intent
+
+ARGUMENTS *cfg_ptr - Pointer to channel context
+
+ size - Size of the Remote Receive Intent
+
+RETURN VALUE None
+
+SIDE EFFECTS None
+===========================================================================*/
+void glinki_ch_push_remote_rx_intent
+(
+ glink_channel_ctx_type *ctx,
+ size_t size
+);
+
+/*===========================================================================
+FUNCTION glinki_ch_pop_remote_rx_intent
+
+DESCRIPTION Removes a Remote Receive Intent
+
+ARGUMENTS *cfg_ptr - Pointer to channel context
+
+ size - Size of the Remote Receive Intent
+
+ *riid_ptr - Pointer to the Remote Receive Intent
+
+RETURN VALUE Standard GLink Err code.
+
+SIDE EFFECTS None
+===========================================================================*/
+glink_err_type glinki_ch_pop_remote_rx_intent
+(
+ glink_channel_ctx_type *ctx,
+ size_t size,
+ uint32 *riid_ptr
+);
+
+/*===========================================================================
+FUNCTION glinki_ch_get_tx_pending_remote_done
+
+DESCRIPTION Lookup packet transmit context for a packet that is waiting for
+ the remote-done notification.
+
+ARGUMENTS *cfg_ptr - Pointer to channel context
+
+ riid - Remote Receive Intent ID
+
+RETURN VALUE Pointer to the transmit packet context or NULL if not match is
+ found.
+
+SIDE EFFECTS None
+===========================================================================*/
+glink_core_tx_pkt_type* glinki_ch_get_tx_pending_remote_done
+(
+ glink_channel_ctx_type *ctx,
+ uint32 riid
+);
+
+/*===========================================================================
+FUNCTION glinki_ch_remove_tx_pending_remote_done
+
+DESCRIPTION Removes a packet transmit context for a packet that is waiting
+ for the remote-done notification.
+
+ARGUMENTS *cfg_ptr - Pointer to channel context
+
+ *tx_pkt - Pointer to the packet context to remove
+
+RETURN VALUE None
+
+SIDE EFFECTS None
+===========================================================================*/
+void glinki_ch_remove_tx_pending_remote_done
+(
+ glink_channel_ctx_type *ctx,
+ glink_core_tx_pkt_type *tx_pkt
+);
+
+/*===========================================================================
+FUNCTION glinki_add_ch_to_xport
+
+DESCRIPTION Add remote/local channel context to xport open channel queue
+
+ARGUMENTS *if_ptr - Pointer to xport if on which channel is to
+ be opened
+ *req_if_ptr - Pointer to xport if on which channel
+ actually wants to open
+ *ch_ctx - channel context
+ **allocated_ch_ctx - Pointer to channel context pointer
+ local_open - flag to determine if channel is opened
+ locally or remotely
+ migration state - flag to identify whether channel migration
+ negotiation is done
+ TRUE - negotiation is not complete
+ FALSE - negotiation is complete.
+ channel is being opened on same xport as negotiated
+ prio - negotiated xport priority
+ (used to send priority via remote_open_ack to
+ remote side)
+ *tx_pkt - Pointer to the packet context to remove
+
+RETURN VALUE None
+
+SIDE EFFECTS None
+===========================================================================*/
+glink_err_type glinki_add_ch_to_xport
+(
+ glink_transport_if_type *if_ptr,
+ glink_transport_if_type *req_if_ptr,
+ glink_channel_ctx_type *ch_ctx,
+ glink_channel_ctx_type **allocated_ch_ctx,
+ unsigned int local_open,
+ boolean migration_state,
+ glink_xport_priority prio
+);
+
+void glink_mem_log
+(
+ const char *func,
+ uint32 line,
+ glink_log_event_type type,
+ const char *msg,
+ const char *xport,
+ const char *remote_ss,
+ uint32 param
+);
+
+/*===========================================================================
+FUNCTION glink_core_setup
+===========================================================================*/
+/**
+
+ Initializes internal core functions based on the transport capabilities.
+
+ @param[in] if_ptr The Pointer to the interface instance.
+
+ @return None.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void glink_core_setup(glink_transport_if_type *if_ptr);
+
+/*===========================================================================
+FUNCTION glink_core_setup_full_xport
+===========================================================================*/
+/**
+
+ Initializes internal core functions for the full-featured transport.
+
+ @param[in] if_ptr The Pointer to the interface instance.
+
+ @return None.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void glink_core_setup_full_xport(glink_transport_if_type *if_ptr);
+
+/*===========================================================================
+FUNCTION glink_core_setup_intentless_xport
+===========================================================================*/
+/**
+
+ Initializes internal core functions for the intentless transport.
+
+ @param[in] if_ptr The Pointer to the interface instance.
+
+ @return None.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void glink_core_setup_intentless_xport(glink_transport_if_type *if_ptr);
+
+#endif /* GLINK_INTERNAL_H */
diff --git a/platform/msm_shared/include/glink_os_type.h b/platform/msm_shared/include/glink_os_type.h
new file mode 100644
index 0000000..091ad05
--- /dev/null
+++ b/platform/msm_shared/include/glink_os_type.h
@@ -0,0 +1,97 @@
+/* Copyright (c) 2015, 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 OS_TYPE_H
+#define OS_TYPE_H
+
+/*===========================================================================
+
+ G-Link OS Specific types/functions
+
+===========================================================================*/
+
+/*===========================================================================
+
+ INCLUDE FILES
+
+===========================================================================*/
+#include <string.h>
+#include <assert.h>
+
+/*===========================================================================
+ MACRO DEFINITIONS
+===========================================================================*/
+
+#define OS_LOG_INIT( ) glink_os_log_init()
+
+/*===========================================================================
+ TYPE DEFINITIONS
+===========================================================================*/
+#define DALSYS_SYNC_OBJ_SIZE_BYTES 40
+#define DALSYS_EVENT_OBJ_SIZE_BYTES 80
+
+typedef bool boolean;
+typedef uint64_t uint64;
+typedef uint32_t uint32;
+typedef long int32;
+#define TRUE 1
+#define FALSE 0
+
+typedef struct DALSYSEventObj DALSYSEventObj;
+
+struct DALSYSEventObj
+{
+ unsigned long long _bSpace[DALSYS_EVENT_OBJ_SIZE_BYTES/sizeof(unsigned long long)];
+};
+
+
+typedef struct DALSYSSyncObj DALSYSSyncObj;
+struct DALSYSSyncObj
+{
+ unsigned long long _bSpace[DALSYS_SYNC_OBJ_SIZE_BYTES/sizeof(unsigned long long)];
+};
+
+typedef DALSYSSyncObj os_cs_type;
+
+typedef void ( *os_timer_cb_fn )( void *cb_data );
+
+typedef struct
+{
+ void * dal_event;
+ DALSYSEventObj dal_obj_memory;
+}os_event_type;
+
+typedef void ( *os_isr_cb_fn )( void *cb_data );
+
+typedef struct os_ipc_intr_struct
+{
+ uint32_t processor;
+ uint32_t irq_out;
+} os_ipc_intr_type;
+
+#endif /* OS_TYPE_H */
diff --git a/platform/msm_shared/include/glink_os_utils.h b/platform/msm_shared/include/glink_os_utils.h
new file mode 100644
index 0000000..e0a1613
--- /dev/null
+++ b/platform/msm_shared/include/glink_os_utils.h
@@ -0,0 +1,258 @@
+/* Copyright (c) 2015, 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 OS_UTILS_H
+#define OS_UTILS_H
+
+/*===========================================================================
+
+ G-Link OS Specific types/functions
+
+===========================================================================*/
+
+/*===========================================================================
+
+ INCLUDE FILES
+
+===========================================================================*/
+#include <glink_os_type.h>
+
+/*===========================================================================
+ MACRO DEFINITIONS
+===========================================================================*/
+
+/*===========================================================================
+ TYPE DEFINITIONS
+===========================================================================*/
+
+/*===========================================================================
+ EXTERNAL FUNCTION DEFINITIONS
+===========================================================================*/
+
+/*===========================================================================
+FUNCTION glink_os_cs_init
+===========================================================================*/
+/**
+ Initializes a Critical Section
+
+ @param[in] cs pointer to critical section object allocated by caller.
+
+ @return
+ TRUE if critical section was initialized, FALSE otherwise
+*/
+/*=========================================================================*/
+bool glink_os_cs_init( os_cs_type *cs );
+
+/*===========================================================================
+ FUNCTION glink_os_cs_acquire
+===========================================================================*/
+/**
+ Lock a critical section
+
+ @param[in] cs Pointer the the critical section
+
+ @return None.
+*/
+/*=========================================================================*/
+void glink_os_cs_acquire( os_cs_type *cs );
+
+/*===========================================================================
+ FUNCTION glink_os_cs_release
+===========================================================================*/
+/**
+ Unlock a critical section
+
+ @param[in] cs Pointer the the critical section
+
+ @return None.
+*/
+/*=========================================================================*/
+void glink_os_cs_release( os_cs_type *cs );
+
+/*===========================================================================
+ FUNCTION glink_os_cs_create
+===========================================================================*/
+/**
+ Create and initializesa Critical Section
+
+ @return The critical section.
+*/
+/*=========================================================================*/
+os_cs_type *glink_os_cs_create( void );
+
+/*===========================================================================
+ FUNCTION glink_os_malloc
+===========================================================================*/
+/**
+ Dynamically allocate a region of memory from the heap. The region should be
+ freed using \c glink_os_free when no longer used.
+
+ @param[in] size The number of bytes to be allocated.
+
+ @return The pointer to the region of memory that was allocated.
+ NULL if the allocation failed.
+*/
+/*=========================================================================*/
+void *glink_os_malloc( size_t size );
+
+/*===========================================================================
+ FUNCTION glink_os_calloc
+===========================================================================*/
+/**
+ Dynamically allocate a region of memory from the heap and initialize with
+ the zeroes. The region should be freed using \c glink_os_free
+ when no longer used.
+
+ @param[in] size The number of bytes to be allocated.
+
+ @return The pointer to the region of memory that was allocated.
+ NULL if the allocation failed.
+*/
+/*=========================================================================*/
+void *glink_os_calloc( size_t size );
+
+/*===========================================================================
+ FUNCTION glink_os_free
+===========================================================================*/
+/**
+ Free a region of memory that was allocated by \c glink_os_malloc.
+
+ @param[in] pMem The reference to the region of memory to be freed.
+
+ @return NA
+*/
+/*=========================================================================*/
+void glink_os_free( void *pMem );
+
+/*===========================================================================
+ FUNCTION glink_os_string_copy
+===========================================================================*/
+/**
+ Copies the source string into the destination buffer until
+ size is reached, or until a '\0' is encountered. If valid,
+ the destination string will always be NULL deliminated.
+
+ @param[in] dst The destination string, contents will be updated.
+ @param[in] src The source string
+ @param[in] size The maximum copy size (size of dst)
+
+ @return
+ The destination string pointer, dst.
+*/
+/*==========================================================================*/
+char *glink_os_string_copy(char *dst, const char *src, uint32_t size);
+
+/*===========================================================================
+ FUNCTION glink_os_string_compare
+===========================================================================*/
+/**
+ Compares two strings delimited by size or NULL character.
+
+ @param[in] s1 String 1
+ @param[in] s2 String 2
+ @param[in] size The maximum number of characters to compare
+
+ @return
+ 0 if strings are identical (up to size characters), non-zero otherwise
+*/
+/*==========================================================================*/
+long glink_os_string_compare( const char *s1, const char *s2, uint32_t size );
+
+/*===========================================================================
+ FUNCTION glink_os_copy_mem
+===========================================================================*/
+/**
+ Copies the source buffer into the destination buffer.
+
+ @param[in] dst The destination, contents will be updated.
+ @param[in] src The source
+ @param[in] size The maximum copy size (size of dst)
+
+ @return
+ The destination string pointer, dst.
+*/
+/*==========================================================================*/
+void glink_os_copy_mem(void *dst, const void *src, uint32_t size);
+
+/*===========================================================================
+ FUNCTION glink_os_register_isr
+===========================================================================*/
+/**
+ Registers ISR with the interrupt controller
+
+ @param[in] irq_in Interrupt to register for
+ @param[in] isr Callback to be invoked when interrupt fires
+ @param[in] cb_data Data to be provided to the callback
+
+ @return true if registration was successful, false otherwise.
+*/
+/*=========================================================================*/
+bool glink_os_register_isr( uint32_t irq_in, os_isr_cb_fn isr, void *cb_data );
+
+/*===========================================================================
+ FUNCTION glink_os_deregister_isr
+===========================================================================*/
+/**
+ De-registers ISR with the interrupt controller
+
+ @param[in] irq_in Interrupt to deregister for
+
+ @return TRUE if de-registration was successful, FALSE otherwise.
+*/
+/*=========================================================================*/
+bool glink_os_deregister_isr( uint32_t irq_in );
+
+/*===========================================================================
+ FUNCTION glink_os_enable_interrupt
+===========================================================================*/
+/**
+ Enables the interrupt in the interrupt controller
+
+ @param[in] irq_in Interrupt to enable
+
+ @return TRUE if operation was successful, FALSE otherwise.
+*/
+/*=========================================================================*/
+bool glink_os_enable_interrupt( uint32_t irq_in );
+
+/*===========================================================================
+ FUNCTION glink_os_disable_interrupt
+===========================================================================*/
+/**
+ Disables the interrupt in the interrupt controller
+
+ @param[in] irq_in Interrupt to disable
+
+ @return TRUE if operation was successful, FALSE otherwise.
+*/
+/*=========================================================================*/
+bool glink_os_disable_interrupt( uint32_t irq_in );
+
+bool glink_os_log_init( void );
+
+#endif /* OS_UTILS_H */
diff --git a/platform/msm_shared/include/glink_rpm.h b/platform/msm_shared/include/glink_rpm.h
new file mode 100644
index 0000000..c7cfdeb
--- /dev/null
+++ b/platform/msm_shared/include/glink_rpm.h
@@ -0,0 +1,108 @@
+/* Copyright (c) 2015, 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 GLINK_RPM_H
+#define GLINK_RPM_H
+
+/**
+ * @file glink_rpm.h
+ *
+ * Public API for the GLink-RPM
+ */
+
+/** \defgroup glink GLink
+ * \ingroup SMD
+ *
+ * GLink reliable, in-order, datagram-based interprocessor communication
+ * over a set of supported transport (Shared Memory, UART, BAM, HSIC)
+ *
+ * All ports preserve message boundaries across the interprocessor channel; one
+ * write into the port exactly matches one read from the port.
+ */
+/*@{*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "glink_os_utils.h"
+
+/*===========================================================================
+ INCLUDE FILES
+===========================================================================*/
+
+/*================= RESTRICTED API ==========================*/
+/** Note that these API are only supported for RPM client. No other
+ * client may use these as a generic API as the underlying implementation
+ * works only for RPM ports */
+
+
+/**
+ * This API allows the RPM client to poll the transport for any new data
+ * that might have come in. It would *usually* be used when incoming interrupts
+ * are disabled.
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects None
+ */
+glink_err_type glink_rpm_rx_poll
+(
+ glink_handle_type handle
+);
+
+/**
+ * This API allows the RPM client to mask/unmask rx interrupts
+ *
+ * @param[in] handle GLink handle associated with the logical channel
+ *
+ * @param[in] mask Whether to mask or un-mask the incoming interrupt
+ *
+ * @param[in] platform_struct Any platform specific into that transport may
+ require
+ *
+ * @return Standard GLink error codes
+ *
+ * @sideeffects None
+ */
+glink_err_type glink_rpm_mask_rx_interrupt
+(
+ glink_handle_type handle,
+ boolean mask,
+ void *platform_struct
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //GLINK_RPM_H
+
diff --git a/platform/msm_shared/include/glink_transport_if.h b/platform/msm_shared/include/glink_transport_if.h
new file mode 100644
index 0000000..da9e2bd
--- /dev/null
+++ b/platform/msm_shared/include/glink_transport_if.h
@@ -0,0 +1,353 @@
+/* Copyright (c) 2015, 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 GLINK_TRANSPORT_IF_H
+#define GLINK_TRANSPORT_IF_H
+
+/**
+ * @file glink_transport_if.h
+ *
+ * Public API for the GLink Core to transport interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*===========================================================================
+ INCLUDE FILES
+===========================================================================*/
+#include <smem_list.h>
+#include <glink_os_utils.h>
+
+/*===========================================================================
+ MACRO DECLARATIONS
+===========================================================================*/
+/* GLink transport capability bit definitions */
+/* Whether transport supports signalling */
+#define GLINK_CAPABILITY_SIG_SUPPORT 0x00000001
+/* Intentless mode of operation */
+#define GLINK_CAPABILITY_INTENTLESS 0x00000002
+
+/*===========================================================================
+ TYPE DECLARATIONS
+===========================================================================*/
+/* forward declaration */
+struct glink_transport_if;
+typedef struct glink_transport_if glink_transport_if_type;
+
+struct glink_core_xport_ctx;
+typedef struct glink_core_xport_ctx glink_core_xport_ctx_type;
+
+struct glink_core_if;
+typedef struct glink_core_if glink_core_if_type;
+
+struct glink_rx_intent;
+typedef struct glink_rx_intent glink_rx_intent_type;
+
+/* Priority of transports registered with glink */
+typedef enum {
+ GLINK_XPORT_SMEM = 100,
+ GLINK_XPORT_RPM = 100,
+ GLINK_XPORT_SMD = 200,
+ GLINK_XPORT_CP_ENGINE = 300,
+ GLINK_MIN_PRIORITY = GLINK_XPORT_CP_ENGINE,
+ GLINK_INVALID_PRIORITY
+} glink_xport_priority;
+
+/** Glink core -> Xport pkt type definition */
+typedef struct {
+ void *data; /* Pointer to the data buffer to be transmitted */
+ const void *pkt_priv; /* Per packet private data */
+ uint32 iid; /* Remote intent ID being used to transmit data */
+ size_t size; /* Size of data buffer */
+ size_t size_remaining; /* Size left to transmit */
+ void *iovec; /* Pointer to the data buffer to be transmitted */
+ glink_buffer_provider_fn vprovider; /* Buffer provider for virtual space */
+ glink_buffer_provider_fn pprovider; /* Buffer provider for physical space */
+}glink_core_tx_pkt_type;
+
+/** Transmit a version command for local negotiation. The transport would call
+ * glink_transport_if_type::rx_cmd_version_ack callback as a result */
+typedef void (*tx_cmd_version_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 version, /* Version */
+ uint32 features /* Features */
+);
+
+/** Transmit a version ack for remote nogotiation */
+typedef void (*tx_cmd_version_ack_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 version, /* Version */
+ uint32 features /* Features */
+);
+
+/** Signals the negotiation is complete and transport can now do version
+ * specific initialization. Return uint32 transport capabilities bit field */
+typedef uint32 (*set_version_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 version, /* Version */
+ uint32 features /* Features */
+);
+
+/** Sends OPEN command to transport for transport to do whatever it deems
+ * necessary to open a GLink logical channel.
+ * GLink Core expects glink_transport_if_type::rx_cmd_ch_open_ack to be called
+ * as a result of channel opening. */
+typedef glink_err_type (*tx_cmd_ch_open_fn)
+(
+ glink_transport_if_type *if_ptr,/* Pointer to the interface instance */
+ uint32 lcid, /* Local channel ID */
+ const char *name, /* String name for the logical channel */
+ glink_xport_priority prio
+);
+
+/** Sends CLOSE command to transport for transport to do whatever it deems
+ * necessary to close the specified GLink logical channel.
+ * GLink Core expects glink_transport_if_type::rx_cmd_ch_close_ack to be
+ * called as a result of channel closing. */
+typedef glink_err_type (*tx_cmd_ch_close_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid /* Local channel ID */
+);
+
+/** Sends the remote open ACK command in response to receiving
+ * glink_core_if_type::rx_cmd_ch_remote_open */
+typedef void (*tx_cmd_ch_remote_open_ack_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid, /* Remote channel ID */
+ glink_xport_priority prio
+);
+
+/** Sends the remote close ACK command in response to receiving
+ * glink_core_if_type::rx_cmd_ch_remote_close */
+typedef void (*tx_cmd_ch_remote_close_ack_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 rcid /* Remote channel ID */
+);
+
+/** Allocates a receive buffer for the local rx intent */
+typedef glink_err_type (*allocate_rx_intent_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ size_t size, /* Size of Rx intent */
+ glink_rx_intent_type *intent_ptr /* Intent ptr */
+);
+
+/** Deallocates a receive buffer for the local rx intent */
+typedef glink_err_type (*deallocate_rx_intent_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ glink_rx_intent_type *intent_ptr /* Intent ptr */
+);
+
+/** Send receive intent ID for a given channel */
+typedef glink_err_type (*tx_cmd_local_rx_intent_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid, /* Local channel ID */
+ size_t size, /* Size of Rx intent */
+ uint32 liid /* Local indent ID */
+);
+
+/** Send receive done command for an intent for the specified channel */
+typedef void(*tx_cmd_local_rx_done_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid, /* Local channel ID */
+ uint32 liid, /* Local indent ID */
+ boolean reuse /* Reuse indent */
+);
+
+/** Send a data packet to the transport to be transmitted over the specified
+ * channel */
+typedef glink_err_type (*tx_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid, /* Local channel ID */
+ glink_core_tx_pkt_type *pctx /* Packet to be transmitted */
+);
+
+/** Send a intent request to the remote side to have it queue more rx intents
+ * to unblock this end's tx operation */
+typedef glink_err_type (*tx_cmd_rx_intent_req_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid, /* Local channel ID */
+ size_t size /* Size of the requested intent */
+);
+
+/** Send the ACK back for the rx intent request send by the other side,
+ * specifynig whether the request was granted ot not */
+typedef glink_err_type (*tx_cmd_remote_rx_intent_req_ack_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid, /* Local channel ID */
+ boolean granted /* Whether of not the intent request was
+ granted */
+);
+
+/** Sets the local channel signals as per the specified 32-bit mask.
+ * Transport may also send the 32-bit value as-is to the remote side. */
+typedef glink_err_type (*tx_cmd_set_sigs_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 lcid, /* Local channel ID */
+ uint32 sigs /* Whether of not the intent request was
+ granted */
+);
+
+/** Lets the XAL know of SSR on that edge. */
+typedef glink_err_type (*ssr_fn)
+(
+ glink_transport_if_type *if_ptr /* Pointer to the interface instance */
+);
+
+/** Trigger a poll for any rx data / signals on transport. */
+typedef glink_err_type (*poll_fn)
+(
+ glink_transport_if_type *if_ptr /* Pointer to the interface instance */
+);
+
+/** Mask/Unmask rx interrupt associated with transport. */
+typedef glink_err_type (*mask_rx_irq_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ boolean mask /* TRUE-mask, FALSE=unmask */
+);
+
+/** Wait for the link to go down. */
+typedef boolean (*wait_link_down_fn)
+(
+ glink_transport_if_type *if_ptr /* Pointer to the interface instance */
+);
+
+
+/**
+ * Data Structure for GLink Core to call into transport API
+ *
+ * This structure is used by the GLink core to operate transport
+ * This set of function pointers to to be filled in by the transport
+ * abstraction layer.
+ */
+struct glink_transport_if {
+ /* Link needed for use with list APIs. Must be at the head of the struct */
+ smem_list_link_type link;
+
+ /** Transmit a version command for local negotiation. The transport would
+ * call glink_transport_if_type::rx_cmd_version_ack callback as a result */
+ tx_cmd_version_fn tx_cmd_version;
+
+ /** Transmit a version ack for remote nogotiation */
+ tx_cmd_version_ack_fn tx_cmd_version_ack;
+
+ /** Signals the negotiation is complete and transport can now do version
+ * specific initialization */
+ set_version_fn set_version;
+
+
+ /** Sends OPEN command to transport for transport to do whatever it deems
+ * necessary to open a GLink logical channel.
+ * GLink Core expects glink_transport_if_type::rx_cmd_ch_open_ack to be
+ * called as a result of channel opening. */
+ tx_cmd_ch_open_fn tx_cmd_ch_open;
+
+
+ /** Sends CLOSE command to transport for transport to do whatever it deems
+ * necessary to close the specified GLink logical channel.
+ * GLink Core expects glink_transport_if_type::rx_cmd_ch_close_ack to be
+ * called as a result of channel closing. */
+ tx_cmd_ch_close_fn tx_cmd_ch_close;
+
+
+ /** Sends the remote open ACK command in response to receiving
+ * glink_core_if_type::rx_cmd_ch_remote_open */
+ tx_cmd_ch_remote_open_ack_fn tx_cmd_ch_remote_open_ack;
+
+ /** Sends the remote close ACK command in response to receiving
+ * glink_core_if_type::rx_cmd_ch_remote_close */
+ tx_cmd_ch_remote_close_ack_fn tx_cmd_ch_remote_close_ack;
+
+ /** Allocates a receive vector buffer for the local rx intent */
+ allocate_rx_intent_fn allocate_rx_intent;
+
+ /** Deallocates a receive vector buffer for the local rx intent */
+ deallocate_rx_intent_fn deallocate_rx_intent;
+
+ /** Send receive intent ID for a given channel */
+ tx_cmd_local_rx_intent_fn tx_cmd_local_rx_intent;
+
+
+ /** Send receive done command for an intent for the specified channel */
+ tx_cmd_local_rx_done_fn tx_cmd_local_rx_done;
+
+
+ /** Send a data packet to the transport to be transmitted over the specified
+ * channel */
+ tx_fn tx;
+
+ /** Send request to the remote to queue more rx intents */
+ tx_cmd_rx_intent_req_fn tx_cmd_rx_intent_req;
+
+ /** Send ACK to the remote side's request to queue more rx intents */
+ tx_cmd_remote_rx_intent_req_ack_fn tx_cmd_remote_rx_intent_req_ack;
+
+ /** Sets the local channel signals as per the specified 32-bit mask.
+ * Transport may also send the 32-bit value as-is to the remote side. */
+ tx_cmd_set_sigs_fn tx_cmd_set_sigs;
+
+ /** Lets the XAL know of SSR on that edge. */
+ ssr_fn ssr;
+
+ /** Trigger a poll for any rx data / signals on transport. */
+ poll_fn poll;
+
+ /** Mask/Unmask rx interrupt associated with transport */
+ mask_rx_irq_fn mask_rx_irq;
+
+ /** Wait for the link to go down. */
+ wait_link_down_fn wait_link_down;
+
+ /** Transport specific data pointer that transport may choose fill in
+ * with some data */
+ glink_core_xport_ctx_type *glink_core_priv;
+
+ /** GLINK core interface pointer associated with this transport interface */
+ glink_core_if_type *glink_core_if_ptr;
+
+ /* glink transport priority */
+ glink_xport_priority glink_priority;
+};
+
+#endif //GLINK_TRANSPORT_IF_H
diff --git a/platform/msm_shared/include/glink_vector.h b/platform/msm_shared/include/glink_vector.h
new file mode 100644
index 0000000..863c19a
--- /dev/null
+++ b/platform/msm_shared/include/glink_vector.h
@@ -0,0 +1,155 @@
+/* Copyright (c) 2015, 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 GLINK_VECTOR_H
+#define GLINK_VECTOR_H
+
+/*===========================================================================
+
+ GLink Vector Header File
+
+===========================================================================*/
+
+
+/*===========================================================================
+
+ INCLUDE FILES
+
+===========================================================================*/
+#include "glink.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*===========================================================================
+ FEATURE DEFINITIONS
+===========================================================================*/
+
+/*===========================================================================
+ MACRO DEFINITIONS
+===========================================================================*/
+
+/*===========================================================================
+ TYPE DEFINITIONS
+===========================================================================*/
+typedef struct _glink_iovector_element_type {
+ struct _glink_iovector_element_type *next;
+ void* data;
+ size_t start_offset;
+ size_t size;
+} glink_iovector_element_type;
+
+typedef struct _glink_iovector_type {
+ glink_iovector_element_type *vlist; /* virtual buffers list */
+ glink_iovector_element_type *vlast; /* last accessed element in vlist */
+ glink_iovector_element_type *plist; /* physical buffers list */
+ glink_iovector_element_type *plast; /* last accessed element in plist */
+} glink_iovector_type;
+
+/*===========================================================================
+ GLOBAL DATA DECLARATIONS
+===========================================================================*/
+
+/*===========================================================================
+ LOCAL FUNCTION DEFINITIONS
+===========================================================================*/
+
+/*===========================================================================
+ EXTERNAL FUNCTION DEFINITIONS
+===========================================================================*/
+/*===========================================================================
+FUNCTION glink_dummy_tx_vprovider
+===========================================================================*/
+/**
+
+ Buffer provider for virtual space that operates on a non-vectored buffer.
+
+ @param[in] iovec Pointer to the dummy vector.
+ @param[in] offset Offset within the dummy vector.
+ @param[out] size Size of the provied buffer.
+
+ @return virtual address of the buffer.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void* glink_dummy_tx_vprovider
+(
+ void* iovec,
+ size_t offset,
+ size_t *size
+);
+
+/*===========================================================================
+FUNCTION glink_dummy_rx_vprovider
+===========================================================================*/
+/**
+
+ Buffer provider for virtual space that operates on a Glink iovec.
+
+ @param[in] iovec Pointer to the dummy vector.
+ @param[in] offset Offset within the dummy vector.
+ @param[out] size Size of the provied buffer.
+
+ @return virtual address of the buffer.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void* glink_iovec_vprovider
+(
+ void* iovec,
+ size_t offset,
+ size_t *size
+);
+
+/*===========================================================================
+FUNCTION glink_dummy_rx_pprovider
+===========================================================================*/
+/**
+
+ Buffer provider for physical space that operates on a Glink iovec.
+
+ @param[in] iovec Pointer to the dummy vector.
+ @param[in] offset Offset within the dummy vector.
+ @param[out] size Size of the provied buffer.
+
+ @return physical address of the buffer.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void* glink_iovec_pprovider
+(
+ void* iovec,
+ size_t offset,
+ size_t *size
+);
+
+#endif /* GLINK_VECTOR_H */
diff --git a/platform/msm_shared/include/mmc_sdhci.h b/platform/msm_shared/include/mmc_sdhci.h
index 1612e61..95d636e 100644
--- a/platform/msm_shared/include/mmc_sdhci.h
+++ b/platform/msm_shared/include/mmc_sdhci.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 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
@@ -101,6 +101,7 @@
#define MMC_USR_WP 171
#define MMC_ERASE_TIMEOUT_MULT 223
#define MMC_HC_ERASE_GRP_SIZE 224
+#define MMC_PARTITION_CONFIG 179
/* Values for ext csd fields */
#define MMC_HS_TIMING 0x1
@@ -117,6 +118,13 @@
#define MMC_HC_ERASE_MULT (512 * 1024)
#define RST_N_FUNC_ENABLE BIT(0)
+/* RPMB Related */
+#define RPMB_PART_MIN_SIZE (128 * 2014)
+#define RPMB_SIZE_MULT 168
+#define REL_WR_SEC_C 222
+#define PARTITION_ACCESS_MASK 0x7
+#define MAX_RPMB_CMDS 0x3
+
/* Command related */
#define MMC_MAX_COMMAND_RETRY 1000
#define MMC_MAX_CARD_STAT_RETRY 10000
@@ -226,6 +234,12 @@
#define MMC_CARD_MMC(card) ((card->type == MMC_TYPE_STD_MMC) || \
(card->type == MMC_TYPE_MMCHC))
+enum part_access_type
+{
+ PART_ACCESS_DEFAULT = 0x0,
+ PART_ACCESS_RPMB = 0x3,
+};
+
/* CSD Register.
* Note: not all the fields have been defined here
*/
@@ -292,6 +306,8 @@
uint8_t *ext_csd; /* Ext CSD for the card info */
uint32_t raw_csd[4]; /* Raw CSD for the card */
uint32_t raw_scr[2]; /* SCR for SD card */
+ uint32_t rpmb_size; /* Size of rpmb partition */
+ uint32_t rel_wr_count; /* Reliable write count */
struct mmc_cid cid; /* CID structure */
struct mmc_csd csd; /* CSD structure */
struct mmc_sd_scr scr; /* SCR structure */
@@ -337,4 +353,6 @@
void mmc_put_card_to_sleep(struct mmc_device *dev);
/* API: Change the driver type of the card */
bool mmc_set_drv_type(struct sdhci_host *host, struct mmc_card *card, uint8_t drv_type);
+/* API: Send the read & write command sequence to rpmb */
+uint32_t mmc_sdhci_rpmb_send(struct mmc_device *dev, struct mmc_command *cmd);
#endif
diff --git a/platform/msm_shared/include/qseecom_lk.h b/platform/msm_shared/include/qseecom_lk.h
new file mode 100644
index 0000000..dd130ed
--- /dev/null
+++ b/platform/msm_shared/include/qseecom_lk.h
@@ -0,0 +1,164 @@
+/* Copyright (c) 2015, 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 _QSEECOM_LK_H_
+#define _QSEECOM_LK_H_
+
+#define MAX_APP_NAME_SIZE 32
+#define QSEECOM_HASH_SIZE 32
+
+/* TZ Diagnostic Area legacy version number */
+#define TZBSP_DIAG_MAJOR_VERSION_LEGACY 2
+
+/*
+ * Log ring buffer position
+ */
+struct tzdbg_log_pos_t {
+ uint16_t wrap;
+ uint16_t offset;
+};
+
+ /*
+ * Log ring buffer
+ */
+struct tzdbg_log_t {
+ struct tzdbg_log_pos_t log_pos;
+ /* open ended array to the end of the 4K IMEM buffer */
+ uint8_t log_buf[];
+};
+struct scm_desc {
+ uint32_t arginfo;
+ uint32_t args[10];
+ uint32_t ret[3];
+ /* private */
+ void *extra_arg_buf;
+ uint64_t x5;
+};
+/*
+ * struct qseecom_register_listener_req -
+ * for register listener ioctl request
+ * @listener_id - service id (shared between userspace and QSE)
+ * @ifd_data_fd - ion handle
+ * @virt_sb_base - shared buffer base in user space
+ * @sb_size - shared buffer size
+ */
+struct qseecom_register_listener_req {
+ uint32_t listener_id; /* in */
+ void *virt_sb_base; /* in */
+ uint32_t sb_size; /* in */
+};
+
+/*
+ * struct qseecom_send_cmd_req - for send command ioctl request
+ * @cmd_req_len - command buffer length
+ * @cmd_req_buf - command buffer
+ * @resp_len - response buffer length
+ * @resp_buf - response buffer
+ */
+struct qseecom_send_cmd_req {
+ void *cmd_req_buf; /* in */
+ unsigned int cmd_req_len; /* in */
+ void *resp_buf; /* in/out */
+ unsigned int resp_len; /* in/out */
+};
+
+/*
+ * struct qseecom_ion_fd_info - ion fd handle data information
+ * @fd - ion handle to some memory allocated in user space
+ * @cmd_buf_offset - command buffer offset
+ */
+struct qseecom_ion_fd_info {
+ int32_t fd;
+ uint32_t cmd_buf_offset;
+};
+
+/*
+ * struct qseecom_listener_send_resp_req - signal to continue the send_cmd req.
+ * Used as a trigger from HLOS service to notify QSEECOM that it's done with its
+ * operation and provide the response for QSEECOM can continue the incomplete
+ * command execution
+ * @resp_len - Length of the response
+ * @resp_buf - Response buffer where the response of the cmd should go.
+ */
+struct qseecom_send_resp_req {
+ void *resp_buf; /* in */
+ unsigned int resp_len; /* in */
+};
+
+/*
+ * struct qseecom_load_img_data - for sending image length information and
+ * ion file descriptor to the qseecom driver. ion file descriptor is used
+ * for retrieving the ion file handle and in turn the physical address of
+ * the image location.
+ * @mdt_len - Length of the .mdt file in bytes.
+ * @img_len - Length of the .mdt + .b00 +..+.bxx images files in bytes
+ * @ion_fd - Ion file descriptor used when allocating memory.
+ * @img_name - Name of the image.
+*/
+struct qseecom_load_img_req {
+ uint32_t mdt_len; /* in */
+ uint32_t img_len; /* in */
+ int32_t ifd_data_fd; /* in */
+ char img_name[MAX_APP_NAME_SIZE]; /* in */
+ int app_id; /* out*/
+};
+
+struct qseecom_set_sb_mem_param_req {
+ int32_t ifd_data_fd; /* in */
+ void *virt_sb_base; /* in */
+ uint32_t sb_len; /* in */
+};
+
+/*
+ * struct qseecom_qseos_version_req - get qseos version
+ * @qseos_version - version number
+ */
+struct qseecom_qseos_version_req {
+ unsigned int qseos_version; /* in */
+};
+
+/*
+ * struct qseecom_qseos_app_load_query - verify if app is loaded in qsee
+ * @app_name[MAX_APP_NAME_SIZE]- name of the app.
+ * @app_id - app id.
+ */
+struct qseecom_qseos_app_load_query {
+ char app_name[MAX_APP_NAME_SIZE]; /* in */
+ int app_id; /* out */
+};
+
+struct qseecom_send_svc_cmd_req {
+ uint32_t cmd_id;
+ void *cmd_req_buf; /* in */
+ unsigned int cmd_req_len; /* in */
+ void *resp_buf; /* in/out */
+ unsigned int resp_len; /* in/out */
+};
+
+
+#endif /* _QSEECOM_LK_H_ */
diff --git a/platform/msm_shared/include/qseecom_lk_api.h b/platform/msm_shared/include/qseecom_lk_api.h
new file mode 100644
index 0000000..c26da9b
--- /dev/null
+++ b/platform/msm_shared/include/qseecom_lk_api.h
@@ -0,0 +1,189 @@
+/* Copyright (c) 2015, 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 __QSEECOM_LK_API_H_
+#define __QSEECOM_LK_API_H_
+
+#define MAX_APP_NAME_LEN 32
+
+#include <stdint.h>
+/**
+* Qseecom Init
+* To be called before any calls to qsee secure apps.
+*
+* @return int
+* Success: Init succeeded.
+* Failure: Error code (negative only).
+*/
+int qseecom_init();
+
+/**
+* Qseecom Tz Init
+* To be called before any calls to qsee secure apps.
+*
+* @return int
+* Success: Tz init succeeded.
+* Failure: Error code (negative only).
+*/
+int qseecom_tz_init();
+
+/**
+* Qseecom Exit
+* To be called before exit of lk.
+* Once this is called no calls to
+* Qsee Apps.
+*
+* @return int
+* Success: Exit succeeded.
+* Failure: Error code (negative only).
+*/
+int qseecom_exit();
+
+/**
+* Start a Secure App
+*
+* @param char* app_name
+* App name of the Secure App to be started
+* The app_name provided should be the same
+* name as the partition/ file and should
+* be the same name mentioned in TZ_APP_NAME
+* in the secure app.
+*
+* @return int
+* Success: handle to be used for all calls to
+* Secure app. Always greater than zero.
+* Failure: Error code (negative only).
+*/
+int qseecom_start_app(char *app_name);
+
+/**
+* Shutdown a Secure App
+*
+* @param int handle
+* Handle of the Secure App to be shutdown
+*
+* @return int
+* Status:
+* 0 - Success
+* Negative value indicates failure.
+*/
+int qseecom_shutdown_app(int handle);
+
+/**
+* Shutdown a Secure App
+*
+* @param int handle
+* Handle of the Secure App to send the cmd
+*
+* @param void *send_buf
+* Pointer to the App request buffer
+*
+* @param uint32_t sbuf_len
+* Size of the request buffer
+*
+* @param void *resp_buf
+* Pointer to the App response buffer
+*
+* @param uint32_t rbuf_len
+* Size of the response buffer
+*
+* @return int
+* Status:
+* 0 - Success
+* Negative value indicates failure.
+*/
+int qseecom_send_command(int handle, void *send_buf,
+ uint32_t sbuf_len, void *resp_buf, uint32_t rbuf_len);
+
+typedef int (*ListenerCallback)(void*, uint32_t);
+
+/**
+ * @param char* service_name
+ * The name of the listener service.
+ * @param uint32_t id
+ * The id used to register a listener with
+ * QSEE in the secure side. This id should
+ * be unique.
+ * @param ListenerCallback service_cmd_handler
+ * This is the service cmd handler, this cb
+ * is called for a specific service request.
+ * The input params are,
+ * @param void *buf
+ * The shared buffer which contains the
+ * request from the secure side. The service
+ * also updates this buffer with the response.
+ * @param uint32_t size
+ * The size of the shared buffer.
+ * @return int
+ * Success: Exit succeeded.
+ * Failure: Error code (negative only).
+ */
+struct qseecom_listener_services {
+ char *service_name;
+ uint32_t id;
+ uint32_t sb_size;
+ ListenerCallback service_cmd_handler;
+};
+
+/**
+* Registers a Listener Service with QSEE
+* This api should be called after all
+* service specific initialization is
+* completed, once this is called the
+* service_cmd_handler for the service can
+* be called.
+*
+* @param struct qseecom_listener_services listnr
+* Listener structure that contains all the info
+* to register a listener service.
+*
+* @return int
+* Status:
+* 0 - Success
+* Negative value indicates failure.
+*/
+int qseecom_register_listener(struct qseecom_listener_services *listnr);
+
+/**
+* De-Registers a Listener Service with QSEE
+* This api should be called before exiting lk and
+* all service de-init should be done before calling
+* the api. service_cmd_handler will not be called
+* after this api is called.
+*
+* @param uint32_t listnr_id
+* Pre-defined Listener ID to be de-registered
+*
+* @return int
+* Status:
+* 0 - Success
+* Negative value indicates failure.
+*/
+int qseecom_deregister_listener(uint32_t listnr_id);
+
+#endif /* __QSEECOM_API_LK_H_ */
diff --git a/platform/msm_shared/include/qseecomi_lk.h b/platform/msm_shared/include/qseecomi_lk.h
new file mode 100644
index 0000000..ee442be
--- /dev/null
+++ b/platform/msm_shared/include/qseecomi_lk.h
@@ -0,0 +1,518 @@
+/* Copyright (c) 2013-2014, 2015, 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 __QSEECOMI_LK_H_
+#define __QSEECOMI_LK_H_
+
+#include <qseecom_lk.h>
+
+#define QSEECOM_KEY_ID_SIZE 32
+
+#define QSEOS_RESULT_FAIL_UNSUPPORTED_CE_PIPE -63
+#define QSEOS_RESULT_FAIL_KS_OP -64
+#define QSEOS_RESULT_FAIL_KEY_ID_EXISTS -65
+#define QSEOS_RESULT_FAIL_MAX_KEYS -66
+#define QSEOS_RESULT_FAIL_SAVE_KS -67
+#define QSEOS_RESULT_FAIL_LOAD_KS -68
+#define QSEOS_RESULT_FAIL_KS_ALREADY_DONE -69
+#define QSEOS_RESULT_FAIL_KEY_ID_DNE -70
+#define QSEOS_RESULT_FAIL_INCORRECT_PSWD -71
+#define QSEOS_RESULT_FAIL_MAX_ATTEMPT -72
+
+enum qseecom_command_scm_resp_type {
+ QSEOS_APP_ID = 0xEE01,
+ QSEOS_LISTENER_ID
+};
+
+typedef enum
+{
+ QSEE_APP_START_COMMAND = 0x01,
+ QSEE_APP_SHUTDOWN_COMMAND,
+ QSEE_APP_LOOKUP_COMMAND,
+ QSEE_REGISTER_LISTENER,
+ QSEE_DEREGISTER_LISTENER,
+ QSEE_CLIENT_SEND_DATA_COMMAND,
+ QSEE_LISTENER_DATA_RSP_COMMAND,
+ QSEE_LOAD_EXTERNAL_ELF_COMMAND,
+ QSEE_UNLOAD_EXTERNAL_ELF_COMMAND,
+ QSEE_GET_APP_STATE_COMMAND,
+ QSEE_LOAD_SERV_IMAGE_COMMAND,
+ QSEE_UNLOAD_SERV_IMAGE_COMMAND,
+ QSEE_APP_REGION_NOTIFICATION,
+ QSEE_REGISTER_LOG_BUF_COMMAND,
+ QSEE_RPMB_PROVISION_KEY_COMMAND,
+ QSEE_RPMB_ERASE_COMMAND,
+ QSEE_KS_GEN_KEY_COMMAND,
+ QSEE_KS_DEL_KEY_COMMAND,
+ QSEE_KS_GET_MAX_KEYS_COMMAND,
+ QSEE_KS_SET_PIPE_KEY_COMMAND,
+ QSEE_KS_UPDATE_KEY_COMMAND,
+ QSEE_GP_OPEN_SESSION,
+ QSEE_GP_INVOKE_COMMAND,
+ QSEE_GP_CLOSE_SESSION,
+}qsee_smc_command_type;
+
+enum qseecom_qceos_cmd_status {
+ QSEOS_RESULT_SUCCESS = 0,
+ QSEOS_RESULT_INCOMPLETE,
+ QSEOS_RESULT_FAILURE = 0xFFFFFFFF
+};
+
+enum qseecom_pipe_type {
+ QSEOS_PIPE_ENC = 0x1,
+ QSEOS_PIPE_ENC_XTS = 0x2,
+ QSEOS_PIPE_AUTH = 0x4,
+ QSEOS_PIPE_ENUM_FILL = 0x7FFFFFFF
+};
+
+struct __attribute__ ((packed)) qsee_apps_region_info_ireq {
+ uint32_t qsee_cmd_id;
+ uint32_t addr;
+ uint32_t size;
+};
+
+struct __attribute__ ((packed)) qseecom_check_app_ireq {
+ uint32_t qsee_cmd_id;
+ char app_name[MAX_APP_NAME_SIZE];
+};
+
+struct __attribute__ ((packed)) qseecom_load_app_ireq {
+ uint32_t qsee_cmd_id;
+ uint32_t mdt_len; /* Length of the mdt file */
+ uint32_t img_len; /* Length of .bxx and .mdt files */
+ uint32_t phy_addr; /* phy addr of the start of image */
+ char app_name[MAX_APP_NAME_SIZE]; /* application name*/
+};
+
+struct __attribute__ ((packed)) qseecom_unload_app_ireq {
+ uint32_t qsee_cmd_id;
+ uint32_t app_id;
+};
+
+struct __attribute__ ((packed)) qseecom_load_lib_image_ireq {
+ uint32_t qsee_cmd_id;
+ uint32_t mdt_len;
+ uint32_t img_len;
+ uint32_t phy_addr;
+};
+
+struct __attribute__ ((packed)) qseecom_unload_lib_image_ireq {
+ uint32_t qsee_cmd_id;
+};
+
+struct __attribute__ ((packed)) qseecom_register_listener_ireq {
+ uint32_t qsee_cmd_id;
+ uint32_t listener_id;
+ uint32_t sb_ptr;
+ uint32_t sb_len;
+};
+
+struct __attribute__ ((packed)) qseecom_unregister_listener_ireq {
+ uint32_t qsee_cmd_id;
+ uint32_t listener_id;
+};
+
+struct __attribute__ ((packed)) qseecom_client_send_data_ireq {
+ uint32_t qsee_cmd_id;
+ uint32_t app_id;
+ uint32_t req_ptr;
+ uint32_t req_len;
+ uint32_t rsp_ptr;/* First 4 bytes should be the return status */
+ uint32_t rsp_len;
+};
+
+struct __attribute__ ((packed)) qseecom_reg_log_buf_ireq {
+ uint32_t qsee_cmd_id;
+ uint32_t phy_addr;
+ uint32_t len;
+};
+
+/* send_data resp */
+struct __attribute__ ((packed)) qseecom_client_listener_data_irsp {
+ uint32_t qsee_cmd_id;
+ uint32_t listener_id;
+ uint32_t status;
+};
+
+/*
+ * struct qseecom_command_scm_resp - qseecom response buffer
+ * @cmd_status: value from enum tz_sched_cmd_status
+ * @sb_in_rsp_addr: points to physical location of response
+ * buffer
+ * @sb_in_rsp_len: length of command response
+ */
+struct __attribute__ ((packed)) qseecom_command_scm_resp {
+ uint32_t result;
+ enum qseecom_command_scm_resp_type resp_type;
+ unsigned int data;
+};
+
+struct qseecom_rpmb_provision_key {
+ uint32_t key_type;
+};
+
+struct __attribute__ ((packed)) qseecom_client_send_service_ireq {
+ uint32_t qsee_cmd_id;
+ uint32_t key_type; /* in */
+ unsigned int req_len; /* in */
+ uint32_t rsp_ptr; /* in/out */
+ unsigned int rsp_len; /* in/out */
+};
+
+struct __attribute__ ((packed)) qseecom_key_generate_ireq {
+ uint32_t qsee_command_id;
+ uint32_t flags;
+ uint8_t key_id[QSEECOM_KEY_ID_SIZE];
+ uint8_t hash32[QSEECOM_HASH_SIZE];
+};
+
+struct __attribute__ ((packed)) qseecom_key_select_ireq {
+ uint32_t qsee_command_id;
+ uint32_t ce;
+ uint32_t pipe;
+ uint32_t pipe_type;
+ uint32_t flags;
+ uint8_t key_id[QSEECOM_KEY_ID_SIZE];
+ uint8_t hash32[QSEECOM_HASH_SIZE];
+};
+
+struct __attribute__ ((packed)) qseecom_key_delete_ireq {
+ uint32_t qsee_command_id;
+ uint32_t flags;
+ uint8_t key_id[QSEECOM_KEY_ID_SIZE];
+ uint8_t hash32[QSEECOM_HASH_SIZE];
+
+};
+
+struct __attribute__ ((packed)) qseecom_key_userinfo_update_ireq {
+ uint32_t qsee_command_id;
+ uint32_t flags;
+ uint8_t key_id[QSEECOM_KEY_ID_SIZE];
+ uint8_t current_hash32[QSEECOM_HASH_SIZE];
+ uint8_t new_hash32[QSEECOM_HASH_SIZE];
+};
+
+struct __attribute__ ((packed)) qseecom_key_max_count_query_ireq {
+ uint32_t flags;
+};
+
+struct __attribute__ ((packed)) qseecom_key_max_count_query_irsp {
+ uint32_t max_key_count;
+};
+
+struct __attribute__ ((packed)) qseecom_qteec_ireq {
+ uint32_t qsee_cmd_id;
+ uint32_t app_id;
+ uint32_t req_ptr;
+ uint32_t req_len;
+ uint32_t resp_ptr;
+ uint32_t resp_len;
+};
+
+struct __attribute__ ((packed)) qseecom_client_send_fsm_key_req {
+ uint32_t qsee_cmd_id;
+ uint32_t req_ptr;
+ uint32_t req_len;
+ uint32_t rsp_ptr;
+ uint32_t rsp_len;
+};
+
+
+/********** ARMV8 SMC INTERFACE TZ MACRO *******************/
+
+#define TZ_SVC_APP_MGR 1 /* Application management */
+#define TZ_SVC_LISTENER 2 /* Listener service management */
+#define TZ_SVC_EXTERNAL 3 /* External image loading */
+#define TZ_SVC_RPMB 4 /* RPMB */
+#define TZ_SVC_KEYSTORE 5 /* Keystore management */
+#define TZ_SVC_ES 16 /* Enterprise Security */
+
+/*----------------------------------------------------------------------------
+ * Owning Entity IDs (defined by ARM SMC doc)
+ * -------------------------------------------------------------------------*/
+#define TZ_OWNER_ARM 0 /** ARM Architecture call ID */
+#define TZ_OWNER_CPU 1 /** CPU service call ID */
+#define TZ_OWNER_SIP 2 /** SIP service call ID */
+#define TZ_OWNER_OEM 3 /** OEM service call ID */
+#define TZ_OWNER_STD 4 /** Standard service call ID */
+
+/** Values 5-47 are reserved for future use */
+
+/** Trusted Application call IDs */
+#define TZ_OWNER_TZ_APPS 48
+#define TZ_OWNER_TZ_APPS_RESERVED 49
+/** Trusted OS Call IDs */
+#define TZ_OWNER_QSEE_OS 50
+#define TZ_OWNER_MOBI_OS 51
+#define TZ_OWNER_OS_RESERVED_3 52
+#define TZ_OWNER_OS_RESERVED_4 53
+#define TZ_OWNER_OS_RESERVED_5 54
+#define TZ_OWNER_OS_RESERVED_6 55
+#define TZ_OWNER_OS_RESERVED_7 56
+#define TZ_OWNER_OS_RESERVED_8 57
+#define TZ_OWNER_OS_RESERVED_9 58
+#define TZ_OWNER_OS_RESERVED_10 59
+#define TZ_OWNER_OS_RESERVED_11 60
+#define TZ_OWNER_OS_RESERVED_12 61
+#define TZ_OWNER_OS_RESERVED_13 62
+#define TZ_OWNER_OS_RESERVED_14 63
+
+#define TZ_SVC_INFO 6 /* Misc. information services */
+
+/** Trusted Application call groups */
+#define TZ_SVC_APP_ID_PLACEHOLDER 0 /* SVC bits will contain App ID */
+
+/** General helper macro to create a bitmask from bits low to high. */
+#define TZ_MASK_BITS(h, l) ((0xffffffff >> (32 - ((h - l) + 1))) << l)
+
+/**
+ Macro used to define an SMC ID based on the owner ID,
+ service ID, and function number.
+*/
+#define TZ_SYSCALL_CREATE_SMC_ID(o, s, f) \
+ ((uint32_t)((((o & 0x3f) << 24) | (s & 0xff) << 8) | (f & 0xff)))
+
+#define TZ_SYSCALL_PARAM_NARGS_MASK TZ_MASK_BITS(3, 0)
+#define TZ_SYSCALL_PARAM_TYPE_MASK TZ_MASK_BITS(1, 0)
+
+#define TZ_SYSCALL_CREATE_PARAM_ID(nargs, p1, p2, p3, \
+ p4, p5, p6, p7, p8, p9, p10) \
+ ((nargs&TZ_SYSCALL_PARAM_NARGS_MASK)+ \
+ ((p1&TZ_SYSCALL_PARAM_TYPE_MASK)<<4)+ \
+ ((p2&TZ_SYSCALL_PARAM_TYPE_MASK)<<6)+ \
+ ((p3&TZ_SYSCALL_PARAM_TYPE_MASK)<<8)+ \
+ ((p4&TZ_SYSCALL_PARAM_TYPE_MASK)<<10)+ \
+ ((p5&TZ_SYSCALL_PARAM_TYPE_MASK)<<12)+ \
+ ((p6&TZ_SYSCALL_PARAM_TYPE_MASK)<<14)+ \
+ ((p7&TZ_SYSCALL_PARAM_TYPE_MASK)<<16)+ \
+ ((p8&TZ_SYSCALL_PARAM_TYPE_MASK)<<18)+ \
+ ((p9&TZ_SYSCALL_PARAM_TYPE_MASK)<<20)+ \
+ ((p10&TZ_SYSCALL_PARAM_TYPE_MASK)<<22))
+
+/**
+ Macros used to create the Parameter ID associated with the syscall
+ */
+#define TZ_SYSCALL_CREATE_PARAM_ID_0 0
+#define TZ_SYSCALL_CREATE_PARAM_ID_1(p1) \
+ TZ_SYSCALL_CREATE_PARAM_ID(1, p1, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_2(p1, p2) \
+ TZ_SYSCALL_CREATE_PARAM_ID(2, p1, p2, 0, 0, 0, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_3(p1, p2, p3) \
+ TZ_SYSCALL_CREATE_PARAM_ID(3, p1, p2, p3, 0, 0, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_4(p1, p2, p3, p4) \
+ TZ_SYSCALL_CREATE_PARAM_ID(4, p1, p2, p3, p4, 0, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_5(p1, p2, p3, p4, p5) \
+ TZ_SYSCALL_CREATE_PARAM_ID(5, p1, p2, p3, p4, p5, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_6(p1, p2, p3, p4, p5, p6) \
+ TZ_SYSCALL_CREATE_PARAM_ID(6, p1, p2, p3, p4, p5, p6, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_7(p1, p2, p3, p4, p5, p6, p7) \
+ TZ_SYSCALL_CREATE_PARAM_ID(7, p1, p2, p3, p4, p5, p6, p7, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_8(p1, p2, p3, p4, p5, p6, p7, p8) \
+ TZ_SYSCALL_CREATE_PARAM_ID(8, p1, p2, p3, p4, p5, p6, p7, p8, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_9(p1, p2, p3, p4, p5, p6, p7, p8, p9) \
+ TZ_SYSCALL_CREATE_PARAM_ID(9, p1, p2, p3, p4, p5, p6, p7, p8, p9, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_10(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) \
+ TZ_SYSCALL_CREATE_PARAM_ID(10, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
+
+/**
+ Macro used to obtain the Parameter ID associated with the syscall
+ */
+#define TZ_SYSCALL_GET_PARAM_ID(CMD_ID) CMD_ID ## _PARAM_ID
+
+#define TZ_SYSCALL_PARAM_TYPE_VAL 0x0 /** type of value */
+#define TZ_SYSCALL_PARAM_TYPE_BUF_RO 0x1 /** type of buffer read-only */
+#define TZ_SYSCALL_PARAM_TYPE_BUF_RW 0x2 /** type of buffer read-write */
+
+#define TZ_OS_APP_START_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x01)
+
+#define TZ_OS_APP_START_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_3( \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
+ TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_APP_SHUTDOWN_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x02)
+
+#define TZ_OS_APP_SHUTDOWN_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_APP_LOOKUP_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x03)
+
+#define TZ_OS_APP_LOOKUP_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_2( \
+ TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_APP_GET_STATE_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x04)
+
+#define TZ_OS_APP_GET_STATE_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_APP_REGION_NOTIFICATION_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x05)
+
+#define TZ_OS_APP_REGION_NOTIFICATION_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_2( \
+ TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_REGISTER_LOG_BUFFER_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x06)
+
+#define TZ_OS_REGISTER_LOG_BUFFER_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_2( \
+ TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_LOAD_SERVICES_IMAGE_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x07)
+
+#define TZ_OS_LOAD_SERVICES_IMAGE_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_3( \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
+ TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_UNLOAD_SERVICES_IMAGE_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x08)
+
+#define TZ_OS_UNLOAD_SERVICES_IMAGE_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_0
+
+#define TZ_OS_REGISTER_LISTENER_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x01)
+
+#define TZ_OS_REGISTER_LISTENER_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_3( \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+ TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_DEREGISTER_LISTENER_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x02)
+
+#define TZ_OS_DEREGISTER_LISTENER_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_LISTENER_RESPONSE_HANDLER_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x03)
+
+#define TZ_OS_LISTENER_RESPONSE_HANDLER_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_2( \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_LOAD_EXTERNAL_IMAGE_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_EXTERNAL, 0x01)
+
+#define TZ_OS_LOAD_EXTERNAL_IMAGE_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_3( \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
+ TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_APP_QSAPP_SEND_DATA_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS, \
+ TZ_SVC_APP_ID_PLACEHOLDER, 0x01)
+
+
+#define TZ_APP_QSAPP_SEND_DATA_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_5( \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+ TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_UNLOAD_EXTERNAL_IMAGE_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_EXTERNAL, 0x02)
+
+#define TZ_OS_UNLOAD_EXTERNAL_IMAGE_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_0
+
+#define TZ_INFO_IS_SVC_AVAILABLE_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_INFO, 0x01)
+
+#define TZ_INFO_IS_SVC_AVAILABLE_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_INFO_GET_FEATURE_VERSION_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_INFO, 0x03)
+
+#define TZ_INFO_GET_FEATURE_VERSION_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_RPMB_PROVISION_KEY_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_RPMB, 0x01)
+
+#define TZ_OS_RPMB_PROVISION_KEY_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_RPMB_ERASE_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_RPMB, 0x02)
+
+#define TZ_OS_RPMB_ERASE_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_0
+
+#define TZ_OS_KS_GEN_KEY_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x01)
+
+#define TZ_OS_KS_GEN_KEY_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_2( \
+ TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_KS_DEL_KEY_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x02)
+
+#define TZ_OS_KS_DEL_KEY_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_2( \
+ TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_KS_GET_MAX_KEYS_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x03)
+
+#define TZ_OS_KS_GET_MAX_KEYS_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_KS_SET_PIPE_KEY_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x04)
+
+#define TZ_OS_KS_SET_PIPE_KEY_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_2( \
+ TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_KS_UPDATE_KEY_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x05)
+
+#define TZ_OS_KS_UPDATE_KEY_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_2( \
+ TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_ES_SAVE_PARTITION_HASH_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_ES, 0x01)
+
+#define TZ_ES_SAVE_PARTITION_HASH_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_3( \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+ TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#endif /* __QSEECOMI_LK_H_ */
diff --git a/platform/msm_shared/include/rpm-glink.h b/platform/msm_shared/include/rpm-glink.h
new file mode 100644
index 0000000..1d8060a
--- /dev/null
+++ b/platform/msm_shared/include/rpm-glink.h
@@ -0,0 +1,60 @@
+/* Copyright (c) 2015, 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 Fundation, Inc. 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 __RPM_GLINK_H
+#define __RPM_GLINK_H
+
+#include <arch/defines.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <rpm-ipc.h>
+#include <glink.h>
+
+typedef struct
+{
+ uint32_t version;
+ uint32_t cmd;
+ uint32_t seqnumber;
+ uint32_t namelength;
+ char name[32];
+} rpm_ssr_req;
+
+typedef rpm_cmd rpm_ack_msg;
+glink_err_type rpm_glink_send_data(uint32_t *data, uint32_t len, msg_type type);
+uint32_t rpm_glink_recv_data(char *rx_buffer, uint32_t *len);
+void rpm_glink_clk_enable(uint32_t *data, uint32_t len);
+void rpm_glink_clk_disable(uint32_t *data, uint32_t len);
+void rpm_glink_init();
+void rpm_glink_uninit();
+void rpm_scalar_glink_isr(glink_handle_type port, void *unused_open_data, void *unused_pkt_priv, void *buffer, size_t size, size_t intent_used);
+void rpm_vector_glink_isr(glink_handle_type port, void *unused_open_data, void *unused_pkt_priv, void *buffer, size_t size, size_t intent_used, glink_buffer_provider_fn vprovider, glink_buffer_provider_fn pprovider);
+void rpm_glink_tx_done_isr(void);
+
+void rpm_glink_notify_state_isr(glink_handle_type handle, void *data, glink_channel_event_type event);
+#endif
diff --git a/platform/msm_shared/include/rpm-ipc.h b/platform/msm_shared/include/rpm-ipc.h
new file mode 100644
index 0000000..f02e8b0
--- /dev/null
+++ b/platform/msm_shared/include/rpm-ipc.h
@@ -0,0 +1,102 @@
+/* Copyright (c) 2015, 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 Fundation, Inc. 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 __RPM_IPC_H
+#define __RPM_IPC_H
+
+#include <arch/defines.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#define RPM_REQ_MAGIC 0x00716572
+#define RPM_CMD_MAGIC 0x00646d63
+#define REQ_MSG_LENGTH 0x14
+#define CMD_MSG_LENGTH 0x08
+#define ACK_MSG_LENGTH 0x0C
+
+typedef enum
+{
+ RPM_REQUEST_TYPE,
+ RPM_CMD_TYPE,
+ RPM_SUCCESS_REQ_ACK,
+ RPM_SUCCESS_CMD_ACK,
+ RPM_ERROR_ACK,
+}msg_type;
+
+enum
+{
+ RESOURCETYPE,
+ RESOURCEID,
+ KVP_KEY,
+ KVP_LENGTH,
+ KVP_VALUE,
+};
+
+typedef struct
+{
+ uint32_t type;
+ uint32_t len;
+} rpm_gen_hdr;
+
+typedef struct
+{
+ uint32_t key;
+ uint32_t len;
+ uint32_t val;
+} kvp_data;
+
+typedef struct
+{
+ uint32_t id;
+ uint32_t set;
+ uint32_t resourceType;
+ uint32_t resourceId;
+ uint32_t dataLength;
+}rpm_req_hdr;
+
+typedef struct
+{
+ rpm_gen_hdr hdr;
+ rpm_req_hdr req_hdr;
+ kvp_data *data;
+} rpm_req;
+
+typedef struct
+{
+ rpm_gen_hdr hdr;
+ kvp_data *data;
+} rpm_cmd;
+
+typedef rpm_cmd rpm_ack_msg;
+int rpm_send_data(uint32_t *data, uint32_t len, msg_type type);
+void rpm_clk_enable(uint32_t *data, uint32_t len);
+
+void fill_kvp_object(kvp_data **kdata, uint32_t *data, uint32_t len);
+void free_kvp_object(kvp_data **kdata);
+#endif
diff --git a/platform/msm_shared/include/rpm-smd.h b/platform/msm_shared/include/rpm-smd.h
index 5ac8a1b..a1eb4a2 100644
--- a/platform/msm_shared/include/rpm-smd.h
+++ b/platform/msm_shared/include/rpm-smd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 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
@@ -33,65 +33,10 @@
#include <arch/defines.h>
#include <stdint.h>
#include <sys/types.h>
+#include <rpm-ipc.h>
-typedef enum
-{
- RPM_REQUEST_TYPE,
- RPM_CMD_TYPE,
- RPM_SUCCESS_REQ_ACK,
- RPM_SUCCESS_CMD_ACK,
- RPM_ERROR_ACK,
-}msg_type;
-
-enum
-{
- RESOURCETYPE,
- RESOURCEID,
- KVP_KEY,
- KVP_LENGTH,
- KVP_VALUE,
-};
-
-typedef struct
-{
- uint32_t type;
- uint32_t len;
-} rpm_gen_hdr;
-
-typedef struct
-{
- uint32_t key;
- uint32_t len;
- uint32_t val;
-} kvp_data;
-
-typedef struct
-{
- uint32_t id;
- uint32_t set;
- uint32_t resourceType;
- uint32_t resourceId;
- uint32_t dataLength;
-}rpm_req_hdr;
-
-typedef struct
-{
- rpm_gen_hdr hdr;
- rpm_req_hdr req_hdr;
- kvp_data *data;
-} rpm_req;
-
-typedef struct
-{
- rpm_gen_hdr hdr;
- kvp_data *data;
-} rpm_cmd;
-
-typedef rpm_cmd rpm_ack_msg;
-int rpm_send_data(uint32_t *data, uint32_t len, msg_type type);
-uint32_t rpm_recv_data(uint32_t *len);
-void rpm_clk_enable(uint32_t *data, uint32_t len);
-void rpm_clk_disable(uint32_t *data, uint32_t len);
+int rpm_smd_send_data(uint32_t *data, uint32_t len, msg_type type);
+uint32_t rpm_smd_recv_data(uint32_t *len);
void rpm_smd_init();
void rpm_smd_uninit();
#endif
diff --git a/platform/msm_shared/include/rpmb.h b/platform/msm_shared/include/rpmb.h
index 8bbd985..6cd7ecd 100644
--- a/platform/msm_shared/include/rpmb.h
+++ b/platform/msm_shared/include/rpmb.h
@@ -26,6 +26,49 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef _RPMB_H_
+#define _RPMB_H_
+
+#include <qseecom_lk_api.h>
+#include <mmc_sdhci.h>
+#include <ufs.h>
+#include <debug.h>
+
+#define RPMB_SECTOR_SIZE 256
+#define RPMB_LSTNR_ID 0x2000
+#define RPMB_BLK_SIZE 512
+#define RPMB_FRAME_SIZE 512
+#define RPMB_MIN_BLK_CNT 1
+#define RPMB_MIN_BLK_SZ 512
+
+enum app_commands
+{
+ CLIENT_CMD_READ_LK_DEVICE_STATE = 0,
+ CLIENT_CMD_LK_END_MILESTONE,
+ CLIENT_CMD_GET_VERSION,
+ CLIENT_CMD_WRITE_LK_DEVICE_STATE,
+};
+
+struct send_cmd_req
+{
+ uint32_t cmd_id;
+ uint32_t data;
+ uint32_t len;
+}__PACKED;
+
+struct send_cmd_rsp
+{
+ uint32_t cmd_id;
+ uint32_t data;
+ int32_t status;
+}__PACKED;
+
+enum device_type
+{
+ EMMC_RPMB = 3,
+ UFS_RPMB = 9,
+};
+
/* RPMB request and response types */
enum rpmb_rr_type {
KEY_PROVISION = 0x1,
@@ -62,9 +105,61 @@
uint8_t keyMAC[32];
uint8_t data[256];
uint8_t nonce[16];
- uint32_t writecounter;
- uint16_t address;
- uint16_t blockcount;
+ uint8_t writecounter[4];
+ uint8_t address[2];
+ uint8_t blockcount[2];
uint8_t result[2];
- uint16_t requestresponse;
+ uint8_t requestresponse[2];
};
+
+struct rpmb_init_info
+{
+ uint32_t size;
+ uint32_t rel_wr_count;
+ uint32_t dev_type;
+};
+
+/* dump a given RPMB frame */
+static inline void dump_rpmb_frame(uint8_t *frame, const char *frame_type)
+{
+ int i;
+ char buf[512] = {0};
+ char *p = buf;
+
+ printf("Printing %s frame (in hex)\n", frame_type);
+ printf("________0__1__2__3__4__5__6__7__8__9__A__B__C__D__E__F__0__1__2__3__4__5__6__7__8__9__A__B__C__D__E__F\n");
+ for (i = 0; i < 512; i++) {
+ if (!(i % 32)) {
+ snprintf(p, 8, "| %2d | ", (i + 1) / 32);
+ p += 7;
+ }
+ snprintf(p, 4, "%.2x ", frame[i]);
+ p += 3;
+ if (((i + 1) % 32) == 0) {
+ printf("%s\n", buf);
+ p = buf;
+ }
+ }
+ printf("________F__E__D__C__B__A__9__8__7__6__5__4__3__2__1__0__F__E__D__C__B__A__9__8__7__6__5__4__3__2__1__0\n");
+}
+
+int read_device_info_rpmb(void *info, uint32_t sz);
+int write_device_info_rpmb(void *info, uint32_t sz);
+
+/* Function Prototypes */
+int rpmb_write_emmc(struct mmc_device *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
+int rpmb_read_emmc(struct mmc_device *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
+int rpmb_write_ufs(struct ufs_dev *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
+int rpmb_read_ufs(struct ufs_dev *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
+
+/* APIs exposed to applications */
+int rpmb_init();
+int rpmb_uninit();
+int rpmb_write(uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
+int rpmb_read(uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
+struct rpmb_init_info *rpmb_get_init_info();
+int rpmb_get_app_handle();
+bool is_sec_app_loaded();
+int load_sec_app();
+int unload_sec_app();
+#endif
diff --git a/platform/msm_shared/include/rpmb_listener.h b/platform/msm_shared/include/rpmb_listener.h
new file mode 100644
index 0000000..a3bb3e5
--- /dev/null
+++ b/platform/msm_shared/include/rpmb_listener.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 2015, 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 <qseecom_lk_api.h>
+#include <mmc_sdhci.h>
+#include <ufs.h>
+
+#define RPMB_LSTNR_ID 0x2000
+
+int rpmb_listener_start();
+int rpmb_listener_stop();
diff --git a/platform/msm_shared/include/scm.h b/platform/msm_shared/include/scm.h
index 283f1cc..2cdca66 100644
--- a/platform/msm_shared/include/scm.h
+++ b/platform/msm_shared/include/scm.h
@@ -256,6 +256,7 @@
#define PRNG_CMD_ID 0x01
#define IS_CALL_AVAIL_CMD 0x01
+#define IS_SECURE_BOOT_ENABLED 0x04
/* Download Mode specific arguments to be passed to TZ */
#define SCM_EDLOAD_MODE 0x01
@@ -317,6 +318,10 @@
int scm_svc_get_secure_state(uint32_t *state_low, uint32_t *state_high);
int scm_protect_keystore(uint32_t * img_ptr, uint32_t img_len);
+int
+scm_call(uint32_t svc_id, uint32_t cmd_id, const void *cmd_buf,
+ size_t cmd_len, void *resp_buf, size_t resp_len);
+
#define SCM_SVC_FUSE 0x08
#define SCM_BLOW_SW_FUSE_ID 0x01
@@ -337,9 +342,11 @@
#define SCM_SVC_PWR 0x9
#define SCM_IO_DISABLE_PMIC_ARBITER 0x1
+#define SCM_IO_DISABLE_PMIC_ARBITER1 0x2
#define SCM_SVC_MILESTONE_32_64_ID 0x1
#define SCM_SVC_MILESTONE_CMD_ID 0xf
+#define SCM_SVC_TZSCHEDULER 0xFC
enum ap_ce_channel_type {
AP_CE_REGISTER_USE = 0,
@@ -349,6 +356,11 @@
/* Apps CE resource. */
#define TZ_RESOURCE_CE_AP 2
+/* Secure IO Service IDs */
+#define SCM_IO_READ 0x1
+#define SCM_IO_WRITE 0x2
+#define SCM_SVC_IO 0x5
+
uint8_t switch_ce_chn_cmd(enum ap_ce_channel_type channel);
/**
@@ -443,4 +455,10 @@
* Used for checking if armv8 SCM support present
*/
void scm_init();
+bool is_secure_boot_enable();
+
+/* Is armv8 supported */
+bool is_scm_armv8_support();
+
+int scm_dload_mode(int mode);
#endif
diff --git a/platform/msm_shared/include/sdhci.h b/platform/msm_shared/include/sdhci.h
index 604ac81..c0b484d 100644
--- a/platform/msm_shared/include/sdhci.h
+++ b/platform/msm_shared/include/sdhci.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 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
@@ -100,6 +100,7 @@
uint32_t cmd_retry; /* Retry the command, if card is busy */
uint32_t cmd23_support; /* If card supports cmd23 */
uint64_t cmd_timeout; /* Command timeout in us */
+ bool write_flag; /* Write flag, for reliable write cases */
struct mmc_data data; /* Data pointer */
};
diff --git a/platform/msm_shared/include/smem_list.h b/platform/msm_shared/include/smem_list.h
new file mode 100644
index 0000000..22148cb
--- /dev/null
+++ b/platform/msm_shared/include/smem_list.h
@@ -0,0 +1,214 @@
+/* Copyright (c) 2015, 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 SMEM_LIST_H
+#define SMEM_LIST_H
+
+/**
+ * @file smem_list.h
+ *
+ * Public data types and functions to implement a generic
+ * list.
+ */
+
+/*===========================================================================
+
+ INCLUDE FILES
+
+===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup smem
+@{ */
+
+
+/*===========================================================================
+
+ TYPE DEFINITIONS
+
+===========================================================================*/
+
+/** Defines the structure to link to the SMEM list */
+typedef struct smem_list_link
+{
+ struct smem_list_link *next;
+} smem_list_link_type;
+
+
+/** Defines the generic SMEM list type */
+typedef struct smem_list
+{
+ smem_list_link_type *next;
+ long count;
+} smem_list_type;
+
+/*===========================================================================
+
+ PUBLIC FUNCTION DECLARATIONS
+
+===========================================================================*/
+
+/*===========================================================================
+FUNCTION smem_list_init
+===========================================================================*/
+/**
+ Creates a generic list.
+
+ @param[in/out] list Pointer to the user list.
+
+ @return
+ N/A.
+
+ @dependencies
+ List must be protected by critical sections for multi-threaded use.
+
+ @sideeffects
+ None.
+*/
+/*=========================================================================*/
+void smem_list_init( smem_list_type *list );
+
+/*===========================================================================
+FUNCTION smem_list_append
+===========================================================================*/
+/**
+ Appends an element to the end of a generic list.
+
+ The element must contain a smem_list_link_type at its base address.
+ The element should not be already present in any list.
+
+ @param[in/out] list Pointer to the user list.
+ @param[in] item Element to be inserted.
+
+ @return
+ N/A.
+
+ @dependencies
+ The element must contain a smem_list_link_type at its base address.
+ List must be protected by critical sections for multi-threaded use.
+
+ @sideeffects
+ None.
+*/
+/*=========================================================================*/
+void smem_list_append( smem_list_type *list, void *item );
+
+/*===========================================================================
+FUNCTION smem_list_delete
+===========================================================================*/
+/**
+ Removes the specified element from a generic list.
+
+ The element may be present at any point in the list.
+
+ @param[in] list Pointer to the user list.
+ @param[in] item Element to be removed.
+
+ @return
+ 0 if the element is deleted, or a negative error code if the element
+ is not found.
+
+ @dependencies
+ List must be protected by critical sections for multi-threaded use.
+
+ @sideeffects
+ None.
+*/
+/*=========================================================================*/
+long smem_list_delete( smem_list_type *list, void *item );
+
+/*===========================================================================
+FUNCTION smem_list_first
+===========================================================================*/
+/**
+ Retrieves the first element in the list without removing it.
+
+ @param[in] list Pointer to the user list.
+
+ @return
+ Pointer to the first element in the list.
+
+ @dependencies
+ List must be protected by critical sections for multi-threaded use.
+
+ @sideeffects
+ None.
+*/
+/*=========================================================================*/
+void *smem_list_first( smem_list_type *list );
+
+/*===========================================================================
+FUNCTION smem_list_next
+===========================================================================*/
+/**
+ Retrieves the next element in the list.
+
+ @param[in] list Pointer to the user list.
+
+ @return
+ Pointer to the next element in the list.
+
+ @dependencies
+ List must be protected by critical sections for multi-threaded use.
+
+ @sideeffects
+ None.
+*/
+/*=========================================================================*/
+void *smem_list_next( void * item );
+
+/*===========================================================================
+FUNCTION smem_list_count
+===========================================================================*/
+/**
+ Gets the number of elements in the list.
+
+ @param[in] list Pointer to the user list.
+
+ @return
+ Count of elements in the list.
+
+ @dependencies
+ List must be protected by critical sections for multi-threaded use.
+
+ @sideeffects
+ None.
+*/
+/*=========================================================================*/
+long smem_list_count( smem_list_type *list );
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */ /* end_addtogroup smem */
+
+#endif /* SMEM_LIST_H */
diff --git a/platform/msm_shared/include/smem_type.h b/platform/msm_shared/include/smem_type.h
new file mode 100644
index 0000000..17a2bb0
--- /dev/null
+++ b/platform/msm_shared/include/smem_type.h
@@ -0,0 +1,237 @@
+/* Copyright (c) 2015, 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 SMEM_TYPE_H
+#define SMEM_TYPE_H
+
+/**
+ * @file smem_type.h
+ *
+ * Public data types used by SMEM
+ */
+
+/** @addtogroup smem
+@{ */
+
+/*===========================================================================
+ TYPE DEFINITIONS
+===========================================================================*/
+/******************************************************************************
+ The most significant two bytes of this number are the smem major version and
+ the least significant two bytes are the smem minor version. The major version
+ number should be updated whenever a change which causes an incompatibility is
+ introduced.
+ The minor version number can track API changes and deprecations that will
+ not affect remote processors. This may include changes to the smem_mem_type
+ enum, if dependencies have already been satisfied on the relevant processors.
+ Inconsistencies in minor version, between processors, will not prevent smem
+ from booting, but major version inconsistencies will.
+ 0x2XXX in the minor version indicates that it is the SMEM minor version, and
+ unrelated to proc comm, which no longer exists.
+******************************************************************************/
+#define SMEM_VERSION_ID 0x000B2002
+
+#define SMEM_MAJOR_VERSION_MASK 0xFFFF0000
+#define SMEM_MINOR_VERSION_MASK 0x0000FFFF
+#define SMEM_FULL_VERSION_MASK 0xFFFFFFFF
+
+#define SMEM_NUM_SMD_CHANNELS 64
+#define SMEM_NUM_SMP2P_EDGES 8
+
+/** Types of memory that can be requested via smem_alloc.
+
+ All of these types of memory have corresponding buffers allocated in
+ smem_data_decl. If a buffer is added to smem_data_decl, add a corresponding
+ entry to this list.
+
+ SMEM_VERSION_FIRST and SMEM_VERSION_LAST are the first and last
+ boundaries for external version checking via the smem_version_set routine.
+ To set up versioning for a shared item, add an entry between
+ SMEM_VERSION_FIRST and SMEM_VERSION_LAST and update the SMEM version in
+ smem_version.h.
+
+ SMEM_VERSION_LAST need not be the last item in the enum.
+*/
+typedef enum
+{
+ SMEM_MEM_FIRST,
+ SMEM_RESERVED_PROC_COMM = SMEM_MEM_FIRST,
+ SMEM_FIRST_FIXED_BUFFER = SMEM_RESERVED_PROC_COMM,
+ SMEM_HEAP_INFO,
+ SMEM_ALLOCATION_TABLE,
+ SMEM_VERSION_INFO,
+ SMEM_HW_RESET_DETECT,
+ SMEM_RESERVED_AARM_WARM_BOOT,
+ SMEM_DIAG_ERR_MESSAGE,
+ SMEM_SPINLOCK_ARRAY,
+ SMEM_MEMORY_BARRIER_LOCATION,
+ SMEM_LAST_FIXED_BUFFER = SMEM_MEMORY_BARRIER_LOCATION,
+ SMEM_AARM_PARTITION_TABLE,
+ SMEM_AARM_BAD_BLOCK_TABLE,
+ SMEM_RESERVE_BAD_BLOCKS,
+ SMEM_RESERVED_WM_UUID,
+ SMEM_CHANNEL_ALLOC_TBL,
+ SMEM_SMD_BASE_ID,
+ SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_CHANNELS,
+ SMEM_SMEM_LOG_EVENTS,
+ SMEM_RESERVED_SMEM_STATIC_LOG_IDX,
+ SMEM_RESERVED_SMEM_STATIC_LOG_EVENTS,
+ SMEM_RESERVED_SMEM_SLOW_CLOCK_SYNC,
+ SMEM_RESERVED_SMEM_SLOW_CLOCK_VALUE,
+ SMEM_RESERVED_BIO_LED_BUF,
+ SMEM_SMSM_SHARED_STATE,
+ SMEM_RESERVED_SMSM_INT_INFO,
+ SMEM_RESERVED_SMSM_SLEEP_DELAY,
+ SMEM_RESERVED_SMSM_LIMIT_SLEEP,
+ SMEM_RESERVED_SLEEP_POWER_COLLAPSE_DISABLED,
+ SMEM_APPS_POWER_STATUS = SMEM_RESERVED_SLEEP_POWER_COLLAPSE_DISABLED, /*APSS power status*/
+ SMEM_RESERVED_KEYPAD_KEYS_PRESSED,
+ SMEM_RESERVED_KEYPAD_STATE_UPDATED,
+ SMEM_RESERVED_KEYPAD_STATE_IDX,
+ SMEM_RESERVED_GPIO_INT,
+ SMEM_RESERVED_MDDI_LCD_IDX,
+ SMEM_RESERVED_MDDI_HOST_DRIVER_STATE,
+ SMEM_RESERVED_MDDI_LCD_DISP_STATE,
+ SMEM_RESERVED_LCD_CUR_PANEL,
+ SMEM_RESERVED_MARM_BOOT_SEGMENT_INFO,
+ SMEM_RESERVED_AARM_BOOT_SEGMENT_INFO,
+ SMEM_RESERVED_SLEEP_STATIC,
+ SMEM_RESERVED_SCORPION_FREQUENCY,
+ SMEM_RESERVED_SMD_PROFILES,
+ SMEM_RESERVED_TSSC_BUSY,
+ SMEM_RESERVED_HS_SUSPEND_FILTER_INFO,
+ SMEM_RESERVED_BATT_INFO,
+ SMEM_RESERVED_APPS_BOOT_MODE,
+ SMEM_VERSION_FIRST,
+ SMEM_VERSION_SMD = SMEM_VERSION_FIRST,
+ SMEM_VERSION_SMD_BRIDGE,
+ SMEM_VERSION_SMSM,
+ SMEM_VERSION_SMD_NWAY_LOOP,
+ SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24,
+ SMEM_RESERVED_OSS_RRCASN1_BUF1,
+ SMEM_RESERVED_OSS_RRCASN1_BUF2,
+ SMEM_ID_VENDOR0,
+ SMEM_ID_VENDOR1,
+ SMEM_ID_VENDOR2,
+ SMEM_HW_SW_BUILD_ID,
+ SMEM_RESERVED_SMD_BLOCK_PORT_BASE_ID,
+ SMEM_RESERVED_SMD_BLOCK_PORT_PROC0_HEAP =
+ SMEM_RESERVED_SMD_BLOCK_PORT_BASE_ID +
+ SMEM_NUM_SMD_CHANNELS,
+ SMEM_RESERVED_SMD_BLOCK_PORT_PROC1_HEAP =
+ SMEM_RESERVED_SMD_BLOCK_PORT_PROC0_HEAP +
+ SMEM_NUM_SMD_CHANNELS,
+ SMEM_I2C_MUTEX = SMEM_RESERVED_SMD_BLOCK_PORT_PROC1_HEAP +
+ SMEM_NUM_SMD_CHANNELS,
+ SMEM_SCLK_CONVERSION,
+ SMEM_RESERVED_SMD_SMSM_INTR_MUX,
+ SMEM_SMSM_CPU_INTR_MASK,
+ SMEM_RESERVED_APPS_DEM_SLAVE_DATA,
+ SMEM_RESERVED_QDSP6_DEM_SLAVE_DATA,
+ SMEM_RESERVED_CLKREGIM_BSP,
+ SMEM_RESERVED_CLKREGIM_SOURCES,
+ SMEM_SMD_FIFO_BASE_ID,
+ SMEM_USABLE_RAM_PARTITION_TABLE = SMEM_SMD_FIFO_BASE_ID +
+ SMEM_NUM_SMD_CHANNELS,
+ SMEM_POWER_ON_STATUS_INFO,
+ SMEM_DAL_AREA,
+ SMEM_SMEM_LOG_POWER_IDX,
+ SMEM_SMEM_LOG_POWER_WRAP,
+ SMEM_SMEM_LOG_POWER_EVENTS,
+ SMEM_ERR_CRASH_LOG,
+ SMEM_ERR_F3_TRACE_LOG,
+ SMEM_SMD_BRIDGE_ALLOC_TABLE,
+ SMEM_SMD_FEATURE_SET,
+ SMEM_RESERVED_SD_IMG_UPGRADE_STATUS,
+ SMEM_SEFS_INFO,
+ SMEM_RESERVED_RESET_LOG,
+ SMEM_RESERVED_RESET_LOG_SYMBOLS,
+ SMEM_MODEM_SW_BUILD_ID,
+ SMEM_SMEM_LOG_MPROC_WRAP,
+ SMEM_RESERVED_BOOT_INFO_FOR_APPS,
+ SMEM_SMSM_SIZE_INFO,
+ SMEM_SMD_LOOPBACK_REGISTER,
+ SMEM_SSR_REASON_MSS0,
+ SMEM_SSR_REASON_WCNSS0,
+ SMEM_SSR_REASON_LPASS0,
+ SMEM_SSR_REASON_DSPS0,
+ SMEM_SSR_REASON_VCODEC0,
+ SMEM_VOICE,
+ SMEM_ID_SMP2P_BASE_APPS, /* = 427 */
+ SMEM_ID_SMP2P_BASE_MODEM = SMEM_ID_SMP2P_BASE_APPS +
+ SMEM_NUM_SMP2P_EDGES, /* = 435 */
+ SMEM_ID_SMP2P_BASE_ADSP = SMEM_ID_SMP2P_BASE_MODEM +
+ SMEM_NUM_SMP2P_EDGES, /* = 443 */
+ SMEM_ID_SMP2P_BASE_WCN = SMEM_ID_SMP2P_BASE_ADSP +
+ SMEM_NUM_SMP2P_EDGES, /* = 451 */
+ SMEM_ID_SMP2P_BASE_RPM = SMEM_ID_SMP2P_BASE_WCN +
+ SMEM_NUM_SMP2P_EDGES, /* = 459 */
+ SMEM_FLASH_DEVICE_INFO = SMEM_ID_SMP2P_BASE_RPM +
+ SMEM_NUM_SMP2P_EDGES, /* = 467 */
+ SMEM_BAM_PIPE_MEMORY, /* = 468 */
+ SMEM_IMAGE_VERSION_TABLE, /* = 469 */
+ SMEM_LC_DEBUGGER, /* = 470 */
+ SMEM_FLASH_NAND_DEV_INFO, /* =471 */
+ SMEM_A2_BAM_DESCRIPTOR_FIFO, /* = 472 */
+ SMEM_CPR_CONFIG, /* = 473 */
+ SMEM_CLOCK_INFO, /* = 474 */
+ SMEM_IPC_INFO, /* = 475 */
+ SMEM_RF_EEPROM_DATA, /* = 476 */
+ SMEM_COEX_MDM_WCN, /* = 477 */
+ SMEM_GLINK_NATIVE_XPORT_DESCRIPTOR, /* = 478 */
+ SMEM_GLINK_NATIVE_XPORT_FIFO_0, /* = 479 */
+ SMEM_GLINK_NATIVE_XPORT_FIFO_1, /* = 480 */
+
+ SMEM_MEM_LAST = SMEM_GLINK_NATIVE_XPORT_FIFO_1,
+ SMEM_INVALID
+} smem_mem_type;
+
+/**
+ * A list of hosts supported in SMEM
+*/
+typedef enum
+{
+ SMEM_APPS = 0, /**< Apps Processor */
+ SMEM_MODEM = 1, /**< Modem processor */
+ SMEM_ADSP = 2, /**< ADSP processor */
+ SMEM_RSVD3 = 3, /**< Reserved */
+ SMEM_WCN = 4, /**< WCN processor */
+ SMEM_RSVD5 = 5, /**< Reserved */
+ SMEM_RPM = 6, /**< RPM processor */
+ SMEM_NUM_HOSTS = 7, /**< Max number of host in target */
+ SMEM_INVALID_HOST, /**< Invalid processor */
+
+ SMEM_Q6 = SMEM_ADSP, /**< Kept for legacy purposes.
+ ** New code should use SMEM_ADSP */
+ SMEM_RIVA = SMEM_WCN, /**< Kept for legacy purposes.
+ ** New code should use SMEM_WCN */
+}smem_host_type;
+
+/** @} */ /* end_addtogroup smem */
+
+#endif /* SMEM_TYPE_H */
diff --git a/platform/msm_shared/include/spmi.h b/platform/msm_shared/include/spmi.h
index 5e6deb4..85cd66a 100644
--- a/platform/msm_shared/include/spmi.h
+++ b/platform/msm_shared/include/spmi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012,2014 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012,2014-2015 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
@@ -101,8 +101,6 @@
#define SPMI_CMD_DEV_DESC_BLK_MASTER_READ 0x10
#define SPMI_CMD_DEV_DESC_BLK_SLAVE_READ 0x11
-/* Max number of Peripherals supported by SPMI */
-#define MAX_PERIPH 128
#define PMIC_ARB_SPMI_HW_VERSION (SPMI_BASE + 0xF000)
enum spmi_geni_cmd_return_value{
diff --git a/platform/msm_shared/include/ucs.h b/platform/msm_shared/include/ucs.h
index 48c50db..a512955 100644
--- a/platform/msm_shared/include/ucs.h
+++ b/platform/msm_shared/include/ucs.h
@@ -29,6 +29,8 @@
#ifndef _UCS_H
#define _UCS_H
+#include <upiu.h>
+
#define SCSI_MAX_DATA_TRANS_BLK_LEN 0xFFFF
#define UFS_DEFAULT_SECTORE_SIZE 4096
@@ -43,10 +45,6 @@
#define SCSI_SEC_PROT 0xEC
#define SCSI_SEC_UFS_PROT_ID 0x0001
-#define RPMB_BLK_SIZE 512
-#define RPMB_FRAME_SIZE 512
-#define RPMB_MIN_BLK_CNT 1
-
/* FLAGS for indication of read or write */
enum scsi_upiu_flags
{
@@ -163,6 +161,7 @@
}__PACKED;
int ucs_scsi_send_inquiry(struct ufs_dev *dev);
+int ucs_do_scsi_cmd(struct ufs_dev *dev, struct scsi_req_build_type *req);
int ucs_do_scsi_read(struct ufs_dev *dev, struct scsi_rdwr_req *req);
int ucs_do_scsi_write(struct ufs_dev *dev, struct scsi_rdwr_req *req);
int ucs_do_scsi_unmap(struct ufs_dev *dev, struct scsi_unmap_req *req);
@@ -177,4 +176,5 @@
/* This function parses the first byte of the sense data and returns the sense key */
int parse_sense_key(uint32_t sense_data);
+int ucs_do_request_sense(struct ufs_dev *dev, uint8_t lun);
#endif
diff --git a/platform/msm_shared/include/ufs.h b/platform/msm_shared/include/ufs.h
index c28c949..0af2dc5 100644
--- a/platform/msm_shared/include/ufs.h
+++ b/platform/msm_shared/include/ufs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 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
@@ -124,4 +124,5 @@
uint32_t ufs_get_erase_blk_size(struct ufs_dev* dev);
void ufs_dump_is_register(struct ufs_dev* dev);
void ufs_dump_hc_registers(struct ufs_dev* dev);
+void ufs_rpmb_init(struct ufs_dev *dev);
#endif
diff --git a/platform/msm_shared/include/xport_rpm.h b/platform/msm_shared/include/xport_rpm.h
new file mode 100644
index 0000000..2566172
--- /dev/null
+++ b/platform/msm_shared/include/xport_rpm.h
@@ -0,0 +1,85 @@
+/* Copyright (c) 2015, 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 XPORT_RPM_H
+#define XPORT_RPM_H
+
+/**
+ * @file xport_rpm.h
+ *
+ * Internal definitions for RPM Glink transport
+ */
+
+/*===========================================================================
+ INCLUDE FILES
+===========================================================================*/
+#include "glink_transport_if.h"
+#include <glink.h>
+/*===========================================================================
+ MACRO DECLARATIONS
+===========================================================================*/
+
+/* Version request command */
+#define XPORT_RPM_CMD_VERSION_REQ 0x0
+/* Version ACK command */
+#define XPORT_RPM_CMD_VERSION_ACK 0x1
+/* Open channel command */
+#define XPORT_RPM_CMD_OPEN_CHANNEL 0x2
+/* Close channel command */
+#define XPORT_RPM_CMD_CLOSE_CHANNEL 0x3
+/* Open channel ACK command */
+#define XPORT_RPM_CMD_OPEN_CHANNEL_ACK 0x4
+/* Tx data command */
+#define XPORT_RPM_CMD_TX_DATA 0x9
+/* Close channel ACK command */
+#define XPORT_RPM_CMD_CLOSE_CHANNEL_ACK 0xB
+/* Tx signals command */
+#define XPORT_RPM_CMD_TX_SIGNALS 0xF
+
+
+#define XPORT_RPM_GET_CMD_ID(c) ((c) & 0xFFFF)
+#define XPORT_RPM_SET_CMD_ID(cmd_id) ((cmd_id) & 0xFFFF)
+
+#define XPORT_RPM_GET_CHANNEL_ID(c) (((c) >> 16) & 0xFFFF)
+#define XPORT_RPM_SET_CHANNEL_ID(cid) (((cid) << 16) & 0xFFFF0000)
+#define XPORT_RPM_GET_STR_LEN(c) (((c) >> 16) & 0xFFFF)
+#define XPORT_RPM_SET_STR_LEN(c) (((c) << 16) & 0xFFFF0000)
+#define XPORT_RPM_GET_PRIO(c) ((c) & 0xFFFF)
+#define XPORT_RPM_SET_PRIO(c) ((c) & 0xFFFF)
+
+#define XPORT_RPM_GET_VERSION(c) (((c) >> 16) & 0xFFFF)
+#define XPORT_RPM_SET_VERSION(v) (((v) << 16) & 0xFFFF0000)
+
+
+/*===========================================================================
+ TYPE DECLARATIONS
+===========================================================================*/
+
+glink_err_type xport_rpm_init(void *arg);
+#endif //XPORT_RPM_H
+
diff --git a/platform/msm_shared/include/xport_rpm_config.h b/platform/msm_shared/include/xport_rpm_config.h
new file mode 100644
index 0000000..e0e24dd
--- /dev/null
+++ b/platform/msm_shared/include/xport_rpm_config.h
@@ -0,0 +1,97 @@
+/* Copyright (c) 2015, 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 XPORT_RPM_CONFIG_H
+#define XPORT_RPM_CONFIG_H
+
+/**
+ * @file xport_rpm_config.h
+ *
+ * Internal definitions for RPM Glink transport configurations
+ */
+
+/*===========================================================================
+ INCLUDE FILES
+===========================================================================*/
+#include "glink.h"
+#include "glink_os_utils.h"
+#include "smem_type.h"
+
+/*===========================================================================
+ MACRO DECLARATIONS
+===========================================================================*/
+#define XPORT_RPM_TOC_MAGIC 0x67727430
+
+#define XPORT_RPM_AP2R_ID 0x61703272
+#define XPORT_RPM_R2AP_ID 0x72326170
+#define XPORT_RPM_MP2R_ID 0x6D703272
+#define XPORT_RPM_R2MP_ID 0x72326D70
+#define XPORT_RPM_AD2R_ID 0x61643272
+#define XPORT_RPM_R2AD_ID 0x72326164
+#define XPORT_RPM_SC2R_ID 0x73633272
+#define XPORT_RPM_R2SC_ID 0x72327363
+#define XPORT_RPM_WC2R_ID 0x77633272
+#define XPORT_RPM_R2WC_ID 0x72327763
+#define XPORT_RPM_TZ2R_ID 0x747A3272
+#define XPORT_RPM_R2TZ_ID 0x7232747A
+
+#define XPORT_RPM_TOC_MAGIC_IDX 0
+#define XPORT_RPM_TOC_LENGTH_IDX 1
+#define XPORT_RPM_TOC_ENTRIES_IDX 2
+
+#define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
+
+/*===========================================================================
+ TYPE DECLARATIONS
+===========================================================================*/
+typedef struct _xport_rpm_toc_entry_type
+{
+ uint32 fifo_id; /* FIFO ID */
+ uint32 fifo_offset; /* FIFO offset in MSG RAM */
+ uint32 fifo_size; /* FIFO size */
+} xport_rpm_toc_entry_type;
+
+typedef struct _xport_rpm_toc_config_type
+{
+ uint32 fifo_id; /* FIFO ID */
+ smem_host_type host; /* Host ID for MSG RAM allocation */
+ uint32 fifo_size; /* FIFO size */
+} xport_rpm_toc_config_type;
+
+
+typedef struct _xport_rpm_config_type
+{
+ const char* remote_ss; /* Remote host name */
+ uint32 tx_fifo_id; /* Tx FIFO ID in RPM ToC */
+ uint32 rx_fifo_id; /* Rx FIFO ID in RPM ToC */
+ os_ipc_intr_type irq_out; /* Outgoing interrupt */
+ uint32 irq_in; /* Incoming interrupt */
+} xport_rpm_config_type;
+
+#endif //XPORT_RPM_CONFIG_H
+
diff --git a/platform/msm_shared/mdp5.c b/platform/msm_shared/mdp5.c
index ddda7ee..b48efb7 100755
--- a/platform/msm_shared/mdp5.c
+++ b/platform/msm_shared/mdp5.c
@@ -40,8 +40,7 @@
#include <clock.h>
#include <scm.h>
-#define MDP_MIN_FETCH 9
-#define MDSS_MDP_MAX_FETCH 12
+#define MDSS_MDP_MAX_PREFILL_FETCH 25
int restore_secure_cfg(uint32_t id);
@@ -538,7 +537,8 @@
uint32_t intf_base)
{
uint32_t mdp_hw_rev = readl(MDP_HW_REV);
- uint32_t v_total, h_total, fetch_start, vfp_start, fetch_lines;
+ uint32_t v_total, h_total, fetch_start, vfp_start;
+ uint32_t prefetch_avail, prefetch_needed;
uint32_t adjust_xres = 0;
uint32_t fetch_enable = BIT(31);
@@ -554,16 +554,20 @@
/*
* MDP programmable fetch is for MDP with rev >= 1.05.
* Programmable fetch is not needed if vertical back porch
- * is >= 9.
+ * plus vertical puls width is >= 25.
*/
if (mdp_hw_rev < MDSS_MDP_HW_REV_105 ||
- lcdc->v_back_porch >= MDP_MIN_FETCH)
+ (lcdc->v_back_porch + lcdc->v_pulse_width) >=
+ MDSS_MDP_MAX_PREFILL_FETCH)
return;
adjust_xres = pinfo->xres;
if (pinfo->lcdc.split_display)
adjust_xres /= 2;
+ if (pinfo->fbc.enabled && pinfo->fbc.comp_ratio)
+ adjust_xres /= pinfo->fbc.comp_ratio;
+
/*
* Fetch should always be outside the active lines. If the fetching
* is programmed within active region, hardware behavior is unknown.
@@ -574,16 +578,19 @@
lcdc->h_front_porch;
vfp_start = lcdc->v_pulse_width + lcdc->v_back_porch + pinfo->yres;
- fetch_lines = v_total - vfp_start;
+ prefetch_avail = v_total - vfp_start;
+ prefetch_needed = MDSS_MDP_MAX_PREFILL_FETCH -
+ lcdc->v_back_porch -
+ lcdc->v_pulse_width;
/*
* In some cases, vertical front porch is too high. In such cases limit
- * the mdp fetch lines as the last 12 lines of vertical front porch.
+ * the mdp fetch lines as the last (25 - vbp - vpw) lines of vertical front porch.
*/
- if (fetch_lines > MDSS_MDP_MAX_FETCH)
- fetch_lines = MDSS_MDP_MAX_FETCH;
+ if (prefetch_avail > prefetch_needed)
+ prefetch_avail = prefetch_needed;
- fetch_start = (v_total - fetch_lines) * h_total + 1;
+ fetch_start = (v_total - prefetch_avail) * h_total + 1;
if (pinfo->dfps.panel_dfps.enabled)
fetch_enable |= BIT(23);
diff --git a/platform/msm_shared/mipi_dsi.c b/platform/msm_shared/mipi_dsi.c
index b18a508..66f95c6 100644
--- a/platform/msm_shared/mipi_dsi.c
+++ b/platform/msm_shared/mipi_dsi.c
@@ -41,6 +41,7 @@
#include <platform/timer.h>
#include <err.h>
#include <msm_panel.h>
+#include <arch/ops.h>
extern void mdp_disable(void);
extern int mipi_dsi_cmd_config(struct fbcon_config mipi_fb_cfg,
@@ -218,6 +219,7 @@
size = 4 - size;
size += cm->size;
memcpy((uint8_t *)off, (cm->payload), size);
+ arch_clean_invalidate_cache_range((addr_t)(off), size);
writel(off, ctl_base + DMA_CMD_OFFSET);
writel(size, ctl_base + DMA_CMD_LENGTH);
if (dual_dsi) {
@@ -412,6 +414,10 @@
tmp |= BIT(28);
writel(tmp, mipi->ctl_base + LANE_CTL);
}
+
+ if ((mipi->mode == DSI_VIDEO_MODE) && mipi->tx_eot_append)
+ writel(0x1, mipi->ctl_base + EOT_PACKET_CTRL);
+
#endif
return 0;
@@ -824,6 +830,7 @@
goto mipi_cmds_error;
memcpy((void *)off, (cm->payload), cm->size);
+ arch_clean_invalidate_cache_range((addr_t)(off), size);
writel(off, DSI_DMA_CMD_OFFSET);
writel(cm->size, DSI_DMA_CMD_LENGTH); // reg 0x48 for this build
dsb();
diff --git a/platform/msm_shared/mmc_sdhci.c b/platform/msm_shared/mmc_sdhci.c
index 2632961..3bc7110 100644
--- a/platform/msm_shared/mmc_sdhci.c
+++ b/platform/msm_shared/mmc_sdhci.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 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
@@ -240,6 +240,9 @@
card->wp_grp_size = (card->csd.wp_grp_size + 1) * (card->csd.erase_grp_size + 1) \
* (card->csd.erase_grp_mult + 1);
+ card->rpmb_size = RPMB_PART_MIN_SIZE * card->ext_csd[RPMB_SIZE_MULT];
+ card->rel_wr_count = card->ext_csd[REL_WR_SEC_C];
+
dprintf(SPEW, "Decoded CSD fields:\n");
dprintf(SPEW, "cmmc_structure: %u\n", mmc_csd.cmmc_structure);
dprintf(SPEW, "card_cmd_class: %x\n", mmc_csd.card_cmd_class);
@@ -2366,3 +2369,107 @@
if(sdhci_send_command(&dev->host, &cmd))
dprintf(CRITICAL, "card sleep error: %s\n", __func__);
}
+
+/*
+ * Switch the partition access type to rpmb or default
+ */
+static uint32_t mmc_sdhci_switch_part(struct mmc_device *dev, uint32_t type)
+{
+ uint32_t part_access;
+ uint32_t ret;
+
+ /* Clear the partition access */
+ part_access = dev->card.ext_csd[MMC_PARTITION_CONFIG] & ~PARTITION_ACCESS_MASK;
+ part_access |= type;
+
+ ret = mmc_switch_cmd(&dev->host, &dev->card, MMC_ACCESS_WRITE, MMC_PARTITION_CONFIG, part_access);
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to switch partition to type: %u\n", type);
+ return 1;
+ }
+
+ dev->card.ext_csd[MMC_PARTITION_CONFIG] = part_access;
+ return 0;
+}
+
+static uint32_t mmc_sdhci_set_blk_cnt(struct mmc_device *dev, uint32_t blk_cnt, uint32_t rel_write)
+{
+ struct mmc_command cmd = {0};
+
+ cmd.cmd_index = CMD23_SET_BLOCK_COUNT;
+ cmd.argument = blk_cnt & 0x0000ffff;
+ cmd.argument |= rel_write;
+ cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
+ cmd.resp_type = SDHCI_CMD_RESP_R1;
+
+ if (sdhci_send_command(&dev->host, &cmd))
+ {
+ dprintf(CRITICAL, "Set block count failed: %s\n", __func__);
+ return 1;
+ }
+
+ return 0;
+}
+
+uint32_t mmc_sdhci_rpmb_send(struct mmc_device *dev, struct mmc_command *cmd)
+{
+ int i;
+ uint32_t retry = 5;
+ uint32_t status;
+ uint32_t rel_write = 0;
+ uint32_t ret = 1;
+
+ ASSERT(cmd);
+
+ /* 1. Set the partition type to rpmb */
+ if (mmc_sdhci_switch_part(dev, PART_ACCESS_RPMB))
+ return 1;
+
+ for (i = 0; i < MAX_RPMB_CMDS; i++)
+ {
+ if (!cmd[i].cmd_index)
+ break;
+
+ if (cmd[i].write_flag == true)
+ rel_write = BIT(31);
+ else
+ rel_write = 0;
+
+ /* 2. Set the block count using cmd23 */
+ if (mmc_sdhci_set_blk_cnt(dev, cmd[i].data.num_blocks, rel_write))
+ goto err;
+
+ /* 3. Send the command */
+ if (sdhci_send_command(&dev->host, &cmd[i]))
+ goto err;
+ do
+ {
+ /* 4. Poll for card status to ensure rpmb operation completeness */
+ if (mmc_get_card_status(&dev->host, &dev->card, &status))
+ {
+ dprintf(CRITICAL, "Failed to get card status after rpmb operations\n");
+ goto err;
+ }
+
+ retry--;
+ udelay(500);
+ if (!retry)
+ {
+ dprintf(CRITICAL, "Card status check timed out after rpmb operations\n");
+ goto err;
+ }
+ } while(!(status & MMC_READY_FOR_DATA) || (MMC_CARD_STATUS(status) == MMC_PROG_STATE));
+ }
+
+ /* If we reach here, that means success */
+ ret = 0;
+
+err:
+ /* 5. Switch the partition back to default type */
+ if (mmc_sdhci_switch_part(dev, PART_ACCESS_DEFAULT))
+ ret = 1;
+
+ return ret;
+}
diff --git a/platform/msm_shared/mmc_wrapper.c b/platform/msm_shared/mmc_wrapper.c
index bcec0ad..10e9955 100755
--- a/platform/msm_shared/mmc_wrapper.c
+++ b/platform/msm_shared/mmc_wrapper.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 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
@@ -124,6 +124,12 @@
if (data_len % block_size)
data_len = ROUNDUP(data_len, block_size);
+ /*
+ * Flush the cache before handing over the data to
+ * storage driver
+ */
+ arch_clean_invalidate_cache_range((addr_t)in, data_len);
+
if (platform_boot_dev_isemmc())
{
/* TODO: This function is aware of max data that can be
@@ -151,8 +157,6 @@
}
else
{
- arch_clean_invalidate_cache_range((addr_t)in, data_len);
-
ret = ufs_write((struct ufs_dev *)dev, data_addr, (addr_t)in, (data_len / block_size));
if (ret)
@@ -185,6 +189,13 @@
ASSERT(!(data_addr % block_size));
ASSERT(!(data_len % block_size));
+ /*
+ * dma onto write back memory is unsafe/nonportable,
+ * but callers to this routine normally provide
+ * write back buffers. Invalidate cache
+ * before read data from mmc.
+ */
+ arch_clean_invalidate_cache_range((addr_t)(out), data_len);
if (platform_boot_dev_isemmc())
{
@@ -296,6 +307,9 @@
memset((void *)out, 0, erase_size);
+ /* Flush the data to memory before writing to storage */
+ arch_clean_invalidate_cache_range((addr_t) out , erase_size);
+
if (mmc_sdhci_write(dev, out, blk_addr, num_blks))
{
dprintf(CRITICAL, "failed to erase the partition: %x\n", blk_addr);
@@ -597,7 +611,9 @@
unsigned long long ptn = 0;
uint64_t size;
int index = -1;
+#ifdef UFS_SUPPORT
int ret = 0;
+#endif
dev = target_mmc_device();
block_size = mmc_get_device_blocksize();
@@ -614,7 +630,8 @@
return 1;
}
- size = partition_get_size(index);
+ /* Convert the size to blocks */
+ size = partition_get_size(index) / block_size;
/*
* For read only partitions the minimum size allocated on the disk is
@@ -623,13 +640,20 @@
*/
if (partition_read_only(index) && size < card->wp_grp_size)
{
+ /* Write protect api takes the size in bytes, convert size to bytes */
size = card->wp_grp_size * block_size;
}
+ else
+ {
+ size *= block_size;
+ }
+
/* Set the power on WP bit */
return mmc_set_clr_power_on_wp_user((struct mmc_device *)dev, (ptn / block_size), size, set_clr);
}
else
{
+#ifdef UFS_SUPPORT
/* Enable the power on WP fo all LUNs which have WP bit is enabled */
ret = dme_set_fpoweronwpen((struct ufs_dev*) dev);
if (ret < 0)
@@ -637,6 +661,7 @@
dprintf(CRITICAL, "Failure to WP UFS partition\n");
return 1;
}
+#endif
}
return 0;
diff --git a/platform/msm_shared/partition_parser.c b/platform/msm_shared/partition_parser.c
index 38b2a80..970d7ce 100644
--- a/platform/msm_shared/partition_parser.c
+++ b/platform/msm_shared/partition_parser.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2015, 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
@@ -872,10 +872,8 @@
return INVALID_PTN;
}
for (n = 0; n < partition_count; n++) {
- if (!memcmp
- (name, &partition_entries[n].name, input_string_length)
- && input_string_length ==
- strlen((const char *)&partition_entries[n].name)) {
+ if ((input_string_length == strlen((const char *)&partition_entries[n].name))
+ && !memcmp(name, &partition_entries[n].name, input_string_length)) {
return n;
}
}
@@ -978,7 +976,7 @@
{
unsigned int type_offset = TABLE_ENTRY_0 + OFFSET_TYPE;
- if (size < type_offset) {
+ if (size < (type_offset + sizeof (*partition_type))) {
goto end;
}
diff --git a/platform/msm_shared/qseecom_lk.c b/platform/msm_shared/qseecom_lk.c
new file mode 100644
index 0000000..4374601
--- /dev/null
+++ b/platform/msm_shared/qseecom_lk.c
@@ -0,0 +1,1400 @@
+/* Copyright (c) 2012-2015, 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 pr_fmt(fmt) "QSEECOM: %s: " fmt, __func__
+
+#include <partition_parser.h>
+#include <qseecom_lk.h>
+#include <scm.h>
+#include <qseecomi_lk.h>
+#include "qseecom_lk_api.h"
+#include <debug.h>
+#include <kernel/mutex.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <arch/defines.h>
+#include <string.h>
+#include <platform/iomap.h>
+#include <platform.h>
+
+#define QSEOS_VERSION_14 0x14
+#define QSEEE_VERSION_00 0x400000
+#define QSEE_VERSION_20 0x800000
+
+
+#define QSEOS_CHECK_VERSION_CMD 0x00001803
+
+#define MAX_SCM_ARGS 10
+#define N_EXT_SCM_ARGS 7
+#define FIRST_EXT_ARG_IDX 3
+
+#define N_REGISTER_ARGS (MAX_SCM_ARGS - N_EXT_SCM_ARGS + 1)
+
+#define QSEE_LOG_BUF_SIZE (4096)
+#define GENERIC_ERROR -1
+#define LISTENER_ALREADY_PRESENT_ERROR -2
+
+#define TZ_CALL 6
+enum qseecom_client_handle_type {
+ QSEECOM_CLIENT_APP = 1,
+ QSEECOM_LISTENER_SERVICE,
+ QSEECOM_SECURE_SERVICE,
+ QSEECOM_GENERIC,
+ QSEECOM_UNAVAILABLE_CLIENT_APP,
+};
+
+struct qseecom_registered_listener_list {
+ struct list_node node;
+ struct qseecom_register_listener_req svc;
+ ListenerCallback CallbackFn;
+};
+
+struct qseecom_registered_app_list {
+ struct list_node node;
+ uint32_t app_id;
+ uint32_t ref_cnt;
+ char app_name[MAX_APP_NAME_SIZE];
+ int handle;
+};
+
+struct qseecom_control {
+ struct list_node registered_listener_list_head;
+ mutex_t registered_listener_list_lock;
+
+ struct list_node registered_app_list_head;
+ mutex_t registered_app_list_lock;
+
+ uint32_t qseos_version;
+ uint32_t qsee_version;
+ int handle;
+ bool commonlib_loaded;
+ mutex_t global_data_lock;
+ uint32_t cmnlib_loaded;
+ uint32_t qseecom_init_done;
+ uint32_t qseecom_tz_init_done;
+};
+
+struct qseecom_listener_handle {
+ uint32_t id;
+};
+
+static struct qseecom_reg_log_buf_ireq logbuf_req;
+static struct qseecom_control qseecom;
+static int __qseecom_process_incomplete_cmd(struct qseecom_command_scm_resp *resp,
+ struct qseecom_client_listener_data_irsp *send_data_rsp);
+
+/*
+ * Appsbl runs in Aarch32 when this is ported for Aarch64,
+ * change return type for uint64_t.
+ */
+static uint32_t __qseecom_uvirt_to_kphys(uint64_t virt)
+{
+ dprintf(SPEW, "%s called\n", __func__);
+ return (uint32_t)platform_get_virt_to_phys_mapping((addr_t)virt);
+}
+
+static int _disp_log_stats(struct tzdbg_log_t *log, uint32_t log_len,
+ uint32_t startOffset, uint32_t endOffset)
+{
+ uint32_t MaxBufSize = 0;
+ uint32_t LogBufSize = 0;
+ uint32_t LogBufFirstHalf = 0;
+ uint32_t len = 0;
+ char *pCurPos, *pPrintPos = NULL;
+ void *pLogBuf = NULL;
+ int ret = GENERIC_ERROR;
+
+ MaxBufSize = QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t);
+
+ dprintf(SPEW, "%s called\n", __func__);
+ if (startOffset < endOffset)
+ {
+ LogBufSize = endOffset - startOffset;
+ pLogBuf = malloc(LogBufSize);
+ if (NULL == pLogBuf)
+ {
+ ret = GENERIC_ERROR;
+ dprintf(CRITICAL, "Failed to alloc buffer to print TZ Log:%u\n", LogBufSize);
+ goto err;
+ }
+ memset(pLogBuf, 0, LogBufSize);
+ memscpy(pLogBuf, LogBufSize, (char *)((uint32_t)log->log_buf + startOffset), LogBufSize);
+ }
+ else if ( endOffset < startOffset)
+ {
+ LogBufSize = MaxBufSize - (startOffset - endOffset);
+ LogBufFirstHalf = MaxBufSize - startOffset;
+ pLogBuf = malloc(LogBufSize);
+ if (NULL == pLogBuf)
+ {
+ ret = GENERIC_ERROR;
+ dprintf(CRITICAL, "Failed to alloc buffer to print TZ Log:%u\n", LogBufSize);
+ goto err;
+ }
+ memset(pLogBuf, 0, LogBufSize);
+ memscpy(pLogBuf, LogBufSize, (char *)((uint32_t)log->log_buf + startOffset), LogBufFirstHalf);
+ memscpy((char *)((uint32_t)pLogBuf+ LogBufFirstHalf), (LogBufSize - LogBufFirstHalf), log->log_buf, endOffset);
+ }
+ else //endOffset == startOffset
+ {
+ ret = 0;
+ goto err;
+ }
+
+ /*
+ * Read from ring buff while there is data and space in return buff
+ */
+ pCurPos = pLogBuf;
+ pPrintPos = pCurPos;
+ while (len < LogBufSize)
+ {
+ //QSEE separate each line by "\r \n"
+ if ((*pCurPos == '\r')&&(*(pCurPos+1) == '\n'))
+ {
+ //update the line to dump
+ *pCurPos = '\0';
+ len++;
+ pCurPos++;
+ *pCurPos = '\0';
+ len++;
+ pCurPos++;
+ dprintf(ALWAYS, "%s\n", pPrintPos);
+ pPrintPos = pCurPos;
+ continue;
+ }
+ len++;
+ pCurPos++;
+ }
+ ret = 0;
+ free(pLogBuf);
+err:
+ return ret;
+}
+
+static int allocate_extra_arg_buffer(uint32_t fn_id, struct scm_desc *desc)
+{
+ int i;
+ int ret = GENERIC_ERROR;
+ scmcall_arg arg = {0};
+ scmcall_ret ret_arg = {0};
+ int arglen = 0;
+
+ if (!desc) {
+ dprintf(CRITICAL, "%s: Invalid input\n", __func__);
+ return GENERIC_ERROR;
+ }
+
+ dprintf(SPEW, "%s called\n", __func__);
+ arglen = desc->arginfo & 0xf;
+
+ dprintf(SPEW, "%s:fn_id:%u, desc->arginfo:%u desc->args[0]:%u desc->args[1]:%u desc->args[2]:%u desc->args[3]:%u desc->args[4]:%u\n",
+ __func__, fn_id, desc->arginfo, desc->args[0], desc->args[1], desc->args[2], desc->args[3], desc->args[4]);
+
+ arg.x0 = fn_id;
+ arg.x1 = desc->arginfo;
+ arg.x2 = desc->args[0];
+ arg.x3 = desc->args[1];
+ arg.x4 = desc->args[2];
+
+ if (arglen > FIRST_EXT_ARG_IDX) {
+ for (i = 0; i < (arglen - FIRST_EXT_ARG_IDX); i++) {
+ arg.x5[i] = desc->args[i + FIRST_EXT_ARG_IDX];
+ }
+ }
+ ret = scm_call2(&arg, &ret_arg);
+ desc->ret[0] = ret_arg.x1;
+ desc->ret[1] = ret_arg.x2;
+ desc->ret[2] = ret_arg.x3;
+
+ dprintf(SPEW, "%s:ret:%d, desc->ret[0]]:%u desc->ret[1]:%u desc->ret[2]:%u\n",
+ __func__, ret, desc->ret[0], desc->ret[1], desc->ret[2]);
+ return ret;
+}
+
+static int qseecom_scm_call2(uint32_t svc_id, uint32_t tz_cmd_id,
+ const void *req_buf, void *resp_buf)
+{
+ int ret = 0;
+ uint32_t smc_id = 0;
+ uint32_t qseos_cmd_id = 0;
+ struct scm_desc desc = {0};
+ struct qseecom_command_scm_resp *scm_resp = NULL;
+
+ if (!req_buf || !resp_buf) {
+ dprintf(CRITICAL, "Invalid buffer pointer\n");
+ return GENERIC_ERROR;
+ }
+ dprintf(SPEW, "%s called\n", __func__);
+
+ qseos_cmd_id = *(uint32_t *)req_buf;
+ scm_resp = (struct qseecom_command_scm_resp *)resp_buf;
+
+ switch (svc_id) {
+ case TZ_CALL: {
+ if (tz_cmd_id == 1) {
+ smc_id = TZ_INFO_IS_SVC_AVAILABLE_ID;
+ desc.arginfo = TZ_INFO_IS_SVC_AVAILABLE_ID_PARAM_ID;
+ desc.args[0] = TZ_INFO_GET_FEATURE_VERSION_ID;
+ } else if (tz_cmd_id == 3) {
+ smc_id = TZ_INFO_GET_FEATURE_VERSION_ID;
+ desc.arginfo = TZ_INFO_GET_FEATURE_VERSION_ID_PARAM_ID;
+ desc.args[0] = *(uint32_t *)req_buf;
+ }
+ ret = allocate_extra_arg_buffer(smc_id, &desc);
+ break;
+ }
+
+ case SCM_SVC_TZSCHEDULER: {
+ switch (qseos_cmd_id) {
+ case QSEE_APP_START_COMMAND: {
+ struct qseecom_load_app_ireq *req;
+ req = (struct qseecom_load_app_ireq *)req_buf;
+ smc_id = TZ_OS_APP_START_ID;
+ desc.arginfo = TZ_OS_APP_START_ID_PARAM_ID;
+ desc.args[0] = req->mdt_len;
+ desc.args[1] = req->img_len;
+ desc.args[2] = req->phy_addr;
+ dprintf(SPEW, "args[0]:%u args[1]:%u args[2]:%u\n",
+ desc.args[0], desc.args[1], desc.args[2]);
+ dprintf(SPEW, "mdt_len:%u img_len:%u phy_addr:%u\n",
+ req->mdt_len, req->img_len, req->phy_addr);
+ ret = allocate_extra_arg_buffer(smc_id, &desc);
+
+ break;
+ }
+ case QSEE_APP_SHUTDOWN_COMMAND: {
+ struct qseecom_unload_app_ireq *req;
+ req = (struct qseecom_unload_app_ireq *)req_buf;
+ smc_id = TZ_OS_APP_SHUTDOWN_ID;
+ desc.arginfo = TZ_OS_APP_SHUTDOWN_ID_PARAM_ID;
+ desc.args[0] = req->app_id;
+ ret = allocate_extra_arg_buffer(smc_id, &desc);
+ break;
+ }
+ case QSEE_APP_REGION_NOTIFICATION: {
+ struct qsee_apps_region_info_ireq *req;
+ req = (struct qsee_apps_region_info_ireq *)req_buf;
+ smc_id = TZ_OS_APP_REGION_NOTIFICATION_ID;
+ desc.arginfo =
+ TZ_OS_APP_REGION_NOTIFICATION_ID_PARAM_ID;
+ desc.args[0] = req->addr;
+ desc.args[1] = req->size;
+ ret = allocate_extra_arg_buffer(smc_id, &desc);
+ break;
+ }
+ case QSEE_LOAD_SERV_IMAGE_COMMAND: {
+ struct qseecom_load_app_ireq *req;
+ req = (struct qseecom_load_app_ireq *)req_buf;
+ smc_id = TZ_OS_LOAD_SERVICES_IMAGE_ID;
+ desc.arginfo = TZ_OS_LOAD_SERVICES_IMAGE_ID_PARAM_ID;
+ desc.args[0] = req->mdt_len;
+ desc.args[1] = req->img_len;
+ desc.args[2] = req->phy_addr;
+ dprintf(SPEW, "QSEE_LOAD_SERV_IMAGE_COMMAND mdt_len:%u img_len:%u phy_addr:%u\n",
+ req->mdt_len, req->img_len, req->phy_addr);
+ ret = allocate_extra_arg_buffer(smc_id, &desc);
+ break;
+ }
+ case QSEE_UNLOAD_SERV_IMAGE_COMMAND: {
+ smc_id = TZ_OS_UNLOAD_SERVICES_IMAGE_ID;
+ desc.arginfo = TZ_OS_UNLOAD_SERVICES_IMAGE_ID_PARAM_ID;
+ ret = allocate_extra_arg_buffer(smc_id, &desc);
+ break;
+ }
+ case QSEE_REGISTER_LISTENER: {
+ struct qseecom_register_listener_ireq *req;
+ req = (struct qseecom_register_listener_ireq *)req_buf;
+ smc_id = TZ_OS_REGISTER_LISTENER_ID;
+ desc.arginfo =
+ TZ_OS_REGISTER_LISTENER_ID_PARAM_ID;
+ desc.args[0] = req->listener_id;
+ desc.args[1] = req->sb_ptr;
+ desc.args[2] = req->sb_len;
+ ret = allocate_extra_arg_buffer(smc_id, &desc);
+ break;
+ }
+ case QSEE_DEREGISTER_LISTENER: {
+ struct qseecom_unregister_listener_ireq *req;
+ req = (struct qseecom_unregister_listener_ireq *)
+ req_buf;
+ smc_id = TZ_OS_DEREGISTER_LISTENER_ID;
+ desc.arginfo = TZ_OS_DEREGISTER_LISTENER_ID_PARAM_ID;
+ desc.args[0] = req->listener_id;
+ ret = allocate_extra_arg_buffer(smc_id, &desc);
+ break;
+ }
+ case QSEE_LISTENER_DATA_RSP_COMMAND: {
+ struct qseecom_client_listener_data_irsp *req;
+ req = (struct qseecom_client_listener_data_irsp *)
+ req_buf;
+ smc_id = TZ_OS_LISTENER_RESPONSE_HANDLER_ID;
+ desc.arginfo =
+ TZ_OS_LISTENER_RESPONSE_HANDLER_ID_PARAM_ID;
+ desc.args[0] = req->listener_id;
+ desc.args[1] = req->status;
+ ret = allocate_extra_arg_buffer(smc_id, &desc);
+ break;
+ }
+ case QSEE_CLIENT_SEND_DATA_COMMAND: {
+ struct qseecom_client_send_data_ireq *req;
+ req = (struct qseecom_client_send_data_ireq *)req_buf;
+ smc_id = TZ_APP_QSAPP_SEND_DATA_ID;
+ desc.arginfo = TZ_APP_QSAPP_SEND_DATA_ID_PARAM_ID;
+ desc.args[0] = req->app_id;
+ desc.args[1] = req->req_ptr;
+ desc.args[2] = req->req_len;
+ desc.args[3] = req->rsp_ptr;
+ desc.args[4] = req->rsp_len;
+ ret = allocate_extra_arg_buffer(smc_id, &desc);
+ break;
+ }
+ case QSEE_RPMB_PROVISION_KEY_COMMAND: {
+ struct qseecom_client_send_service_ireq *req;
+ req = (struct qseecom_client_send_service_ireq *)
+ req_buf;
+ smc_id = TZ_OS_RPMB_PROVISION_KEY_ID;
+ desc.arginfo = TZ_OS_RPMB_PROVISION_KEY_ID_PARAM_ID;
+ desc.args[0] = req->key_type;
+ ret = allocate_extra_arg_buffer(smc_id, &desc);
+ break;
+ }
+ case QSEE_RPMB_ERASE_COMMAND: {
+ smc_id = TZ_OS_RPMB_ERASE_ID;
+ desc.arginfo = TZ_OS_RPMB_ERASE_ID_PARAM_ID;
+ ret = allocate_extra_arg_buffer(smc_id, &desc);
+ break;
+ }
+
+ case QSEE_REGISTER_LOG_BUF_COMMAND: {
+ struct qseecom_reg_log_buf_ireq *req;
+ req = (struct qseecom_reg_log_buf_ireq *)req_buf;
+ smc_id = TZ_OS_REGISTER_LOG_BUFFER_ID;
+ desc.arginfo = TZ_OS_REGISTER_LOG_BUFFER_ID_PARAM_ID;
+ desc.args[0] = req->phy_addr;
+ desc.args[1] = req->len;
+ ret = allocate_extra_arg_buffer(smc_id, &desc);
+ break;
+ }
+ default: {
+ dprintf(CRITICAL, "qseos_cmd_id 0x%d is not supported by armv8 scm_call2.\n",
+ qseos_cmd_id);
+ ret = GENERIC_ERROR;
+ break;
+ }
+ } /*end of switch (qsee_cmd_id) */
+ break;
+ } /*end of case SCM_SVC_TZSCHEDULER*/
+ default: {
+ dprintf(CRITICAL, "svc_id 0x%x is not supported by armv8 scm_call2.\n",
+ svc_id);
+ ret = GENERIC_ERROR;
+ break;
+ }
+ } /*end of switch svc_id */
+ scm_resp->result = desc.ret[0];
+ scm_resp->resp_type = desc.ret[1];
+ scm_resp->data = desc.ret[2];
+ dprintf(SPEW, "svc_id = 0x%x, tz_cmd_id = 0x%x, qseos_cmd_id = 0x%x, smc_id = 0x%x, param_id = 0x%x\n",
+ svc_id, tz_cmd_id, qseos_cmd_id, smc_id, desc.arginfo);
+ dprintf(SPEW, "scm_resp->result = 0x%x, scm_resp->resp_type = 0x%x, scm_resp->data = 0x%x\n",
+ scm_resp->result, scm_resp->resp_type, scm_resp->data);
+ return ret;
+}
+
+static int qseecom_scm_call(uint32_t svc_id, uint32_t tz_cmd_id, void *cmd_buf,
+ size_t cmd_len, void *resp_buf, size_t resp_len)
+{
+ void *req = NULL;
+ struct qseecom_command_scm_resp *resp = NULL;
+ struct qseecom_client_listener_data_irsp send_data_rsp = {0};
+ int ret = GENERIC_ERROR;
+ uint32_t qseos_cmd_id = 0;
+
+ if ((!cmd_buf) || (!resp_buf))
+ return GENERIC_ERROR;
+
+ dprintf(SPEW, "%s called\n", __func__);
+ mutex_acquire(&qseecom.registered_app_list_lock);
+ req = cmd_buf;
+ qseos_cmd_id = *(uint32_t *)req;
+ resp = (struct qseecom_command_scm_resp *) resp_buf;
+
+ do {
+ if (!is_scm_armv8_support()) {
+ ret = scm_call(svc_id, tz_cmd_id, req, cmd_len,
+ resp_buf, resp_len);
+ } else {
+ ret = qseecom_scm_call2(svc_id, tz_cmd_id, req, resp);
+ }
+
+ if (ret) {
+ dprintf(CRITICAL, "ERROR: scm_call to load failed : ret %d\n", ret);
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+
+ if (svc_id == TZ_CALL) {
+ goto err;
+ }
+
+ switch (resp->result) {
+ case QSEOS_RESULT_SUCCESS:
+ if(((resp->resp_type != QSEOS_APP_ID) || (resp->data <= 0)) &&
+ ((qseos_cmd_id == QSEE_CLIENT_SEND_DATA_COMMAND) ||
+ (qseos_cmd_id == QSEE_LISTENER_DATA_RSP_COMMAND)))
+ {
+ dprintf(CRITICAL, "ERROR: Resp type %d or Resp Data %d incorrect\n",
+ resp->resp_type, resp->data);
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+ goto err;
+ case QSEOS_RESULT_FAILURE:
+ dprintf(CRITICAL, "scm call failed w/response result%d\n", resp->result);
+ ret = GENERIC_ERROR;
+ goto err;
+ case QSEOS_RESULT_INCOMPLETE:
+ if(resp->resp_type != QSEOS_LISTENER_ID)
+ {
+ ret = GENERIC_ERROR;
+ dprintf(CRITICAL, "Listener service incorrect resp->result:%d resp->resp_type:%d\n",
+ resp->result, resp->resp_type);
+ goto err;
+ }
+ __qseecom_process_incomplete_cmd(resp, &send_data_rsp);
+ req = (void *)&send_data_rsp;
+ qseos_cmd_id = QSEE_LISTENER_DATA_RSP_COMMAND;
+ break;
+ default:
+ dprintf(CRITICAL, "scm call return unknown response %d\n", resp->result);
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+ } while(true);
+
+err:
+ mutex_release(&qseecom.registered_app_list_lock);
+ return ret;
+
+}
+
+static int __qseecom_process_incomplete_cmd(struct qseecom_command_scm_resp *resp,
+ struct qseecom_client_listener_data_irsp *send_data_rsp)
+{
+ int ret = 0;
+ struct qseecom_registered_listener_list *entry;
+
+ if ((!resp) || (!send_data_rsp))
+ {
+ return GENERIC_ERROR;
+ }
+
+ dprintf(SPEW, "%s called\n", __func__);
+ mutex_acquire(&qseecom.global_data_lock);
+
+ list_for_every_entry(&qseecom.registered_listener_list_head,
+ entry, struct qseecom_registered_listener_list, node) {
+ if (resp->data == entry->svc.listener_id) {
+ arch_invalidate_cache_range((addr_t) entry->svc.virt_sb_base, entry->svc.sb_size);
+ entry->CallbackFn(entry->svc.virt_sb_base, entry->svc.sb_size);
+ arch_clean_invalidate_cache_range((addr_t) entry->svc.virt_sb_base, entry->svc.sb_size);
+ break;
+ }
+ }
+ send_data_rsp->qsee_cmd_id = QSEE_LISTENER_DATA_RSP_COMMAND;
+ send_data_rsp->listener_id = entry->svc.listener_id;
+ send_data_rsp->status = 0;
+ mutex_release(&qseecom.global_data_lock);
+ return ret;
+}
+
+static int __qseecom_load_app(const char *app_name, unsigned int *app_id)
+{
+ int index = INVALID_PTN;
+ unsigned long long ptn = 0;
+ unsigned long long size = 0;
+ void *buf = NULL;
+ void *req = NULL;
+ struct qseecom_load_app_ireq load_req = {0};
+ struct qseecom_command_scm_resp resp;
+ struct tzdbg_log_t *log = NULL;
+ uint32_t QseeLogStart = 0;
+ uint32_t QseeLogNewStart = 0;
+
+ int ret = GENERIC_ERROR;
+ uint8_t lun = 0;
+
+ if (!app_name)
+ return GENERIC_ERROR;
+
+ dprintf(SPEW, "%s called\n", __func__);
+ index = partition_get_index(app_name);
+ lun = partition_get_lun(index);
+ mmc_set_lun(lun);
+
+ size = partition_get_size(index);
+
+ buf = memalign(PAGE_SIZE, ROUNDUP(size, PAGE_SIZE));
+ if (!buf) {
+ dprintf(CRITICAL, "%s: Aloc failed for %s image\n",
+ __func__, app_name);
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+
+ ptn = partition_get_offset(index);
+ if(ptn == 0) {
+ dprintf(CRITICAL, "ERROR: No %s found\n", app_name);
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+ if (mmc_read(ptn, (unsigned int *) buf, size)) {
+ dprintf(CRITICAL, "ERROR: Cannot read %s image\n", app_name);
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+
+ /* Currently on 8994 only 32-bit phy addr is supported
+ * Hence downcasting is okay
+ */
+ load_req.phy_addr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+ load_req.qsee_cmd_id = QSEE_APP_START_COMMAND;
+ load_req.img_len = size;
+ load_req.mdt_len = 0;
+ dprintf(SPEW, "phy_addr:%u img_len:%u\n", load_req.phy_addr, load_req.img_len);
+
+ memscpy(&load_req.app_name, MAX_APP_NAME_SIZE, app_name, MAX_APP_NAME_SIZE);
+ req = (void *)&load_req;
+
+ log = (struct tzdbg_log_t *)logbuf_req.phy_addr;
+ arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+ QseeLogStart = (uint32_t) log->log_pos.offset;
+
+ arch_clean_invalidate_cache_range((addr_t) load_req.phy_addr, load_req.img_len);
+ ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, req,
+ sizeof(struct qseecom_load_lib_image_ireq),
+ &resp, sizeof(resp));
+ if(ret == 0)
+ *app_id = resp.data;
+ else
+ *app_id = 0;
+ arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+ QseeLogNewStart = (uint32_t) log->log_pos.offset;
+
+ _disp_log_stats((struct tzdbg_log_t *) logbuf_req.phy_addr, QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
+ QseeLogStart, QseeLogNewStart);
+err:
+ if (buf)
+ free(buf);
+ return ret;
+}
+
+static int qseecom_load_commonlib_image(char * app_name)
+{
+ int index = INVALID_PTN;
+ unsigned long long ptn = 0;
+ unsigned long long size = 0;
+ void *buf = NULL;
+ void *req = NULL;
+ struct qseecom_load_app_ireq load_req = {0};
+ struct qseecom_command_scm_resp resp = {0};
+ int ret = GENERIC_ERROR;
+ uint8_t lun = 0;
+
+ dprintf(SPEW, "%s called\n", __func__);
+ index = partition_get_index(app_name);
+ lun = partition_get_lun(index);
+ mmc_set_lun(lun);
+
+ size = partition_get_size(index);
+
+ buf = memalign(PAGE_SIZE, ROUNDUP(size, PAGE_SIZE));
+ if (!buf) {
+ dprintf(CRITICAL, "%s: Aloc failed for %s image\n",
+ __func__, app_name);
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+
+ ptn = partition_get_offset(index);
+ if(ptn == 0) {
+ dprintf(CRITICAL, "ERROR: No %s found\n", app_name);
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+ if (mmc_read(ptn, (unsigned int *) buf, size)) {
+ dprintf(CRITICAL, "ERROR: Cannot read %s image\n", app_name);
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+
+ /* Currently on 8994 only 32-bit phy addr is supported
+ * Hence downcasting is okay
+ */
+ load_req.phy_addr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+ load_req.qsee_cmd_id = QSEE_LOAD_SERV_IMAGE_COMMAND;
+ load_req.img_len = size;
+ load_req.mdt_len = 0;
+
+ memscpy(load_req.app_name, MAX_APP_NAME_SIZE, app_name, MAX_APP_NAME_SIZE);
+ req = (void *)&load_req;
+
+ arch_clean_invalidate_cache_range((addr_t) load_req.phy_addr, load_req.img_len);
+ ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, req,
+ sizeof(struct qseecom_load_lib_image_ireq),
+ &resp, sizeof(resp));
+ if(ret == 0)
+ ret = resp.data;
+
+err:
+ if (buf)
+ free(buf);
+ return ret;
+}
+
+static int qseecom_unload_commonlib_image(void)
+{
+ int ret = GENERIC_ERROR;
+ struct qseecom_unload_lib_image_ireq unload_req = {0};
+ struct qseecom_command_scm_resp resp;
+
+ dprintf(SPEW, "%s called\n", __func__);
+ /* Populate the remaining parameters */
+ unload_req.qsee_cmd_id = QSEE_UNLOAD_SERV_IMAGE_COMMAND;
+ /* SCM_CALL to load the image */
+ ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &unload_req,
+ sizeof(struct qseecom_unload_lib_image_ireq),
+ &resp, sizeof(resp));
+ return ret;
+}
+
+/*
+ * This function is called with the global
+ * data mutex acquired.
+ */
+static struct qseecom_registered_app_list *
+ __qseecom_add_app_entry(char *app_name, uint32_t app_id)
+{
+ struct qseecom_registered_app_list *entry = NULL;
+ int32_t ret = GENERIC_ERROR;
+
+ if ((!app_name) || (app_id == 0)) {
+ dprintf(CRITICAL, "%s: Invalid Input\n", __func__);
+ return NULL;
+ }
+ dprintf(SPEW, "%s called\n", __func__);
+
+ entry = malloc(sizeof(*entry));
+ if (!entry) {
+ dprintf(CRITICAL, "malloc for app entry failed\n");
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+ entry->app_id = app_id;
+ entry->ref_cnt = 1;
+ strlcpy(entry->app_name, app_name, MAX_APP_NAME_SIZE);
+
+ dprintf(SPEW, "%s: Adding app:%s app_id:%u to list\n", __func__, entry->app_name, entry->app_id);
+ list_add_tail(&qseecom.registered_app_list_head, &entry->node);
+ ret = 0;
+err:
+ if (entry && (ret < 0)) {
+ free(entry);
+ return NULL;
+ }
+ return entry;
+}
+
+/*
+ * This function is called with the global
+ * data mutex acquired.
+ */
+static int
+ __qseecom_remove_app_entry(struct qseecom_registered_app_list *entry)
+{
+ if (!entry) {
+ dprintf(CRITICAL, "%s: Invalid Input\n", __func__);
+ return GENERIC_ERROR;
+ }
+ dprintf(SPEW, "%s called\n", __func__);
+ list_delete(&entry->node);
+ free(entry);
+
+ return 0;
+}
+
+/*
+ * This function is called with the global
+ * data mutex acquired.
+ */
+struct qseecom_registered_listener_list *
+ __qseecom_check_listener_exists(uint32_t listener_id)
+{
+ struct qseecom_registered_listener_list *entry = NULL;
+ bool listener_present = false;
+
+ if (!listener_id) {
+ dprintf(CRITICAL, "%s: Invalid Input\n", __func__);
+ return NULL;
+ }
+ dprintf(SPEW, "%s called\n", __func__);
+
+ list_for_every_entry(&qseecom.registered_listener_list_head,
+ entry, struct qseecom_registered_listener_list, node) {
+ if (entry->svc.listener_id == listener_id) {
+ listener_present = true;
+ break;
+ }
+ }
+ if (listener_present)
+ return entry;
+ else
+ return NULL;
+}
+
+/*
+ * This function is called with the global
+ * data mutex acquired.
+ */
+static struct qseecom_registered_app_list
+ *__qseecom_check_handle_exists(int handle)
+{
+ struct qseecom_registered_app_list *entry;
+ bool app_present = false;
+
+ if (handle <= 0) {
+ dprintf(CRITICAL, "%s: Invalid Input\n", __func__);
+ return NULL;
+ }
+ dprintf(SPEW, "%s called\n", __func__);
+ list_for_every_entry(&qseecom.registered_app_list_head,
+ entry, struct qseecom_registered_app_list, node) {
+ if (entry->handle == handle) {
+ app_present = true;
+ break;
+ }
+ }
+
+ if (app_present == true)
+ return entry;
+ else
+ return NULL;
+
+}
+
+
+static struct qseecom_registered_app_list *
+ __qseecom_check_app_exists(char *app_name)
+{
+ struct qseecom_registered_app_list *entry = NULL;
+
+ dprintf(SPEW, "%s called\n", __func__);
+ list_for_every_entry(&qseecom.registered_app_list_head,
+ entry, struct qseecom_registered_app_list, node) {
+ if (!strncmp(app_name, entry->app_name, 32)) {
+ dprintf(SPEW, "%s: app_name:%s\n", __func__, app_name);
+ return entry;
+ }
+ }
+ return NULL;
+}
+
+static int qseecom_unload_app(uint32_t app_id)
+{
+ int ret = 0;
+ struct qseecom_command_scm_resp resp;
+ struct qseecom_unload_app_ireq req;
+
+ dprintf(SPEW, "%s called\n", __func__);
+ /* Populate the structure for sending scm call to load image */
+ req.qsee_cmd_id = QSEE_APP_SHUTDOWN_COMMAND;
+ req.app_id = app_id;
+
+ /* SCM_CALL to unload the app */
+ ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
+ sizeof(struct qseecom_unload_app_ireq),
+ &resp, sizeof(resp));
+
+ return ret;
+}
+
+
+static int __qseecom_send_cmd(uint32_t app_id, struct qseecom_send_cmd_req *req)
+{
+ int ret = 0;
+ struct qseecom_client_send_data_ireq send_data_req;
+ struct qseecom_command_scm_resp resp;
+ void *buf = NULL;
+ uint32_t size = 0;
+
+ if (req->cmd_req_buf == NULL || req->resp_buf == NULL) {
+ dprintf(CRITICAL, "%s: cmd buffer or response buffer is null\n",
+ __func__);
+ return GENERIC_ERROR;
+ }
+ dprintf(SPEW, "%s called\n", __func__);
+
+ /* Allocate for req or rsp len whichever is higher, both req and rsp point
+ * to the same buffer
+ */
+ size = (req->cmd_req_len > req->resp_len) ? req->cmd_req_len : req->resp_len;
+
+ /* The req rsp buffer will be xPU protected by TZ during a TZ APP call
+ * This will still be protected during a listener call and there is a
+ * possibility of prefetching happening, which will cause xPU violation.
+ * Hence using (device memory with xN set) to prevent I or D prefetching.
+ * This is a contiguous region of 1MB used only for this, hence will not
+ * free this.
+ */
+ buf = (void *)RPMB_SND_RCV_BUF;
+ if (!buf) {
+ dprintf(CRITICAL, "%s: Aloc failed for app_id:%d of size:%d\n",
+ __func__, app_id, size);
+ return GENERIC_ERROR;
+ }
+
+ memscpy(buf, ROUNDUP(size, PAGE_SIZE), req->cmd_req_buf, req->cmd_req_len);
+
+ send_data_req.qsee_cmd_id = QSEE_CLIENT_SEND_DATA_COMMAND;
+ send_data_req.app_id = app_id;
+
+ /* Currently on 8994 only 32-bit phy addr is supported
+ * Hence downcasting is okay
+ */
+ send_data_req.req_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+ send_data_req.req_len = req->cmd_req_len;
+ send_data_req.rsp_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+ send_data_req.rsp_len = req->resp_len;
+
+ ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
+ (void *)&send_data_req,
+ sizeof(send_data_req), (void *)&resp, sizeof(resp));
+
+ memscpy(req->resp_buf, req->resp_len, (void *)send_data_req.rsp_ptr, send_data_req.rsp_len);
+ return ret;
+}
+
+/**
+* Start a Secure App
+*
+* @param char* app_name
+* App name of the Secure App to be started
+*
+* @return int
+* Success: handle to be used for all calls to
+* Secure app. Always greater than zero.
+* Failure: Error code (negative only).
+*/
+int qseecom_start_app(char *app_name)
+{
+ int32_t ret = GENERIC_ERROR;
+ int handle = 0;
+ struct qseecom_registered_app_list *entry = NULL;
+ unsigned int app_id = 0;
+
+ if (!app_name) {
+ dprintf(CRITICAL, "%s: Input error\n", __func__);
+ goto err;
+ }
+ dprintf(SPEW, "%s called\n", __func__);
+
+
+ mutex_acquire(&qseecom.global_data_lock);
+ if ((!qseecom.qseecom_init_done)
+ || (!qseecom.qseecom_tz_init_done)){
+ dprintf(CRITICAL, "%s qseecom_init not done\n",
+ __func__);
+ mutex_release(&qseecom.global_data_lock);
+ return ret;
+ }
+ /* Load commonlib image*/
+ if (!qseecom.cmnlib_loaded) {
+ ret = qseecom_load_commonlib_image("cmnlib");
+ if (ret) {
+ mutex_release(&qseecom.global_data_lock);
+ dprintf(CRITICAL, "%s qseecom_load_commonlib_image failed with status:%d\n",
+ __func__, ret);
+ goto err;
+ }
+ qseecom.cmnlib_loaded = 1;
+ }
+ /* Check if App already exits, if exits increase ref_cnt
+ * and return handle, else load the app from partition,
+ * call into TZ to load it, add to list and then return
+ * handle.
+ */
+
+ entry = __qseecom_check_app_exists(app_name);
+ if (!entry) {
+ mutex_release(&qseecom.global_data_lock);
+ /* load the app and get the app_id */
+ dprintf(INFO, "%s: Loading app %s for the first time'\n",
+ __func__, app_name);
+
+ ret = __qseecom_load_app(app_name, &app_id);
+ if ((ret < 0) || (app_id ==0)) {
+ dprintf(CRITICAL, "%s: __qseecom_load_app failed with err:%d for app:%s\n",
+ __func__, ret, app_name);
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+ mutex_acquire(&qseecom.global_data_lock);
+ entry = __qseecom_add_app_entry(app_name, app_id);
+ if (!entry)
+ {
+ dprintf(CRITICAL, "%s: __qseecom_add_app_entry failed\n", __func__);
+ ret = GENERIC_ERROR;
+ mutex_release(&qseecom.global_data_lock);
+ goto err;
+ }
+ qseecom.handle++;
+ entry->handle = qseecom.handle;
+ handle = entry->handle;
+ mutex_release(&qseecom.global_data_lock);
+ }
+ else {
+ entry->ref_cnt++;
+ handle = entry->handle;
+ mutex_release(&qseecom.global_data_lock);
+ }
+ return handle;
+err:
+ return ret;
+}
+
+/**
+* Shutdown a Secure App
+*
+* @param int handle
+* Handle of the Secure App to be shutdown
+*
+* @return int
+* Status:
+* 0 - Success
+* Negative value indicates failure.
+*/
+int qseecom_shutdown_app(int handle)
+{
+ int ret = GENERIC_ERROR;
+ int ref_cnt = 0;
+ struct qseecom_registered_app_list *entry = NULL;
+ struct tzdbg_log_t *log = NULL;
+ uint32_t QseeLogStart = 0;
+ uint32_t QseeLogNewStart = 0;
+
+ if (handle <= 0) {
+ dprintf(CRITICAL, "%s: Invalid Handle %d\n", __func__, handle);
+ goto err;
+ }
+ dprintf(SPEW, "%s called\n", __func__);
+ mutex_acquire(&qseecom.global_data_lock);
+ if ((!qseecom.qseecom_init_done)
+ || (!qseecom.qseecom_tz_init_done)) {
+ dprintf(CRITICAL, "%s qseecom_init not done\n",
+ __func__);
+ mutex_release(&qseecom.global_data_lock);
+ return ret;
+ }
+ entry = __qseecom_check_handle_exists(handle);
+ if (!entry) {
+ dprintf(CRITICAL, "%s: Shutdown on an app that was never loaded handle:%d\n",
+ __func__, handle);
+ ret = GENERIC_ERROR;
+ mutex_release(&qseecom.global_data_lock);
+ goto err;
+ }
+
+ /* Decrement ref_cnt by 1, if ref_cnt is 0 after
+ * decrementing unload the app by calling into
+ * TZ else just return.
+ */
+
+ if(entry->ref_cnt != 0)
+ entry->ref_cnt--;
+ ref_cnt = entry->ref_cnt;
+ mutex_release(&qseecom.global_data_lock);
+ if (ref_cnt == 0) {
+ log = (struct tzdbg_log_t *)logbuf_req.phy_addr;
+ arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+ QseeLogStart = (uint32_t) log->log_pos.offset;
+
+ ret = qseecom_unload_app(entry->app_id);
+ arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+ QseeLogNewStart = (uint32_t) log->log_pos.offset;
+
+ _disp_log_stats((struct tzdbg_log_t *) logbuf_req.phy_addr, QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
+ QseeLogStart, QseeLogNewStart);
+ if(ret) {
+ dprintf(CRITICAL, "%s: qseecom_unload_app failed with err:%d for handle:%d\n",
+ __func__, ret, handle);
+ goto err;
+ }
+ mutex_acquire(&qseecom.global_data_lock);
+ ret = __qseecom_remove_app_entry(entry);
+ mutex_release(&qseecom.global_data_lock);
+ if(ret) {
+ dprintf(CRITICAL, "%s: __qseecom_remove_app_entry failed with err:%d for handle:%d\n",
+ __func__, ret, handle);
+ goto err;
+ }
+ }
+ ret = 0;
+err:
+ return ret;
+}
+
+/**
+* Send cmd to a Secure App
+*
+* @param int handle
+* Handle of the Secure App to send the cmd
+*
+* @param void *send_buf
+* Pointer to the App request buffer
+*
+* @param uint32_t sbuf_len
+* Size of the request buffer
+*
+* @param void *resp_buf
+* Pointer to the App response buffer
+*
+* @param uint32_t rbuf_len
+* Size of the response buffer
+*
+* @return int
+* Status:
+* 0 - Success
+* Negative value indicates failure.
+*/
+int qseecom_send_command(int handle, void *send_buf,
+ uint32_t sbuf_len, void *resp_buf, uint32_t rbuf_len)
+{
+ int ret = GENERIC_ERROR;
+ uint32_t app_id = 0;
+ struct qseecom_registered_app_list *entry = NULL;
+ struct qseecom_send_cmd_req req = {0, 0, 0, 0};
+ struct tzdbg_log_t *log = NULL;
+ uint32_t QseeLogStart = 0;
+ uint32_t QseeLogNewStart = 0;
+
+ if (handle <= 0) {
+ dprintf(CRITICAL, "%s Handle is Invalid\n", __func__);
+ return GENERIC_ERROR;
+ }
+
+ if((!send_buf) || (!resp_buf)) {
+ dprintf(CRITICAL, "%s: Input Buffers invalid\n", __func__);
+ return GENERIC_ERROR;
+ }
+ dprintf(SPEW, "%s called\n", __func__);
+ mutex_acquire(&qseecom.global_data_lock);
+ if ((!qseecom.qseecom_init_done)
+ || (!qseecom.qseecom_tz_init_done)) {
+ dprintf(CRITICAL, "%s qseecom_init not done\n",
+ __func__);
+ mutex_release(&qseecom.global_data_lock);
+ return ret;
+ }
+ entry = __qseecom_check_handle_exists(handle);
+ if (!entry) {
+ dprintf(CRITICAL, "%s: Send cmd on an app that was never loaded handle:%d\n",
+ __func__, handle);
+ ret = GENERIC_ERROR;
+ mutex_release(&qseecom.global_data_lock);
+ goto err;
+ }
+
+ app_id = entry->app_id;
+ mutex_release(&qseecom.global_data_lock);
+
+ req.cmd_req_len = sbuf_len;
+ req.resp_len = rbuf_len;
+ req.cmd_req_buf = send_buf;
+ req.resp_buf = resp_buf;
+
+ log = (struct tzdbg_log_t *)logbuf_req.phy_addr;
+ arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+ QseeLogStart = (uint32_t) log->log_pos.offset;
+
+ ret = __qseecom_send_cmd(app_id, &req);
+ if (ret) {
+ dprintf(CRITICAL, "%s __qseecom_send_cmd failed with err:%d for handle:%d\n",
+ __func__, ret, handle);
+ goto err;
+ }
+ arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+ QseeLogNewStart = (uint32_t) log->log_pos.offset;
+
+ _disp_log_stats((struct tzdbg_log_t *) logbuf_req.phy_addr, QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
+ QseeLogStart, QseeLogNewStart);
+ ret = 0;
+ dprintf(SPEW, "sending cmd_req->rsp size: %u, ptr: 0x%p\n",
+ req.resp_len, req.resp_buf);
+err:
+ return ret;
+}
+
+/**
+* Registers a Listener Service with QSEE
+*
+* @param uint32_t listnr_id
+* Pre-defined Listener ID to be registered
+*
+* @param uint32_t sb_size
+* Shared buffer size required for the listener
+* service.
+*
+* @return int
+* Status:
+* 0 - Success
+* Negative value indicates failure.
+*/
+int qseecom_register_listener(struct qseecom_listener_services *listnr)
+{
+ int ret = GENERIC_ERROR;
+ struct qseecom_registered_listener_list *new_entry = NULL;
+ struct qseecom_register_listener_ireq req;
+ struct qseecom_command_scm_resp resp;
+
+ mutex_acquire(&qseecom.global_data_lock);
+ if (!qseecom.qseecom_init_done) {
+ dprintf(CRITICAL, "%s qseecom_init not done\n",
+ __func__);
+ mutex_release(&qseecom.global_data_lock);
+ return ret;
+ }
+ mutex_release(&qseecom.global_data_lock);
+
+ mutex_acquire(&qseecom.registered_listener_list_lock);
+
+ if ((!listnr)) {
+ dprintf(CRITICAL, "%s Invalid Input listnr\n", __func__);
+ return GENERIC_ERROR;
+ }
+
+ if ((!listnr->id) || (!listnr->sb_size) || (!listnr->service_cmd_handler)) {
+ dprintf(CRITICAL, "%s Invalid Input listnr_id:%d sb_size:%d\n",
+ __func__, listnr->id, listnr->sb_size);
+ return GENERIC_ERROR;
+ }
+ dprintf(SPEW, "%s called\n", __func__);
+ new_entry = __qseecom_check_listener_exists(listnr->id);
+ if (new_entry) {
+ dprintf(CRITICAL, "Service is not unique and is already registered\n");
+ ret = LISTENER_ALREADY_PRESENT_ERROR;
+ goto err;
+ }
+
+ new_entry = malloc(sizeof(*new_entry));
+ if (!new_entry) {
+ dprintf(CRITICAL, "%s new_entry malloc failed for size:%d\n", __func__, sizeof(*new_entry));
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+ memset(new_entry, 0, sizeof(*new_entry));
+ new_entry->svc.listener_id = listnr->id;
+ new_entry->svc.sb_size = listnr->sb_size;
+ new_entry->CallbackFn = listnr->service_cmd_handler;
+
+ new_entry->svc.virt_sb_base = memalign(PAGE_SIZE, ROUNDUP(listnr->sb_size, PAGE_SIZE));
+ if (!new_entry->svc.virt_sb_base) {
+ dprintf(CRITICAL, "%s virt_sb_base malloc failed for size:%d\n", __func__, listnr->sb_size);
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+ memset(new_entry->svc.virt_sb_base, 0, ROUNDUP(listnr->sb_size, PAGE_SIZE));
+ arch_clean_invalidate_cache_range((addr_t) new_entry->svc.virt_sb_base, ROUNDUP(listnr->sb_size, PAGE_SIZE));
+
+ req.qsee_cmd_id = QSEE_REGISTER_LISTENER;
+ req.listener_id = new_entry->svc.listener_id;
+ req.sb_len = new_entry->svc.sb_size;
+ /* convert to 32bit addr for tz */
+ req.sb_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) new_entry->svc.virt_sb_base);
+
+ resp.result = QSEOS_RESULT_INCOMPLETE;
+
+ ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
+ sizeof(req), &resp, sizeof(resp));
+ if (ret) {
+ dprintf(CRITICAL, "qseecom_scm_call failed with err: %d\n", ret);
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+ /* Add entry to Listener list */
+ list_add_tail(&qseecom.registered_listener_list_head, &new_entry->node);
+err:
+ if ((ret) &&
+ (ret != LISTENER_ALREADY_PRESENT_ERROR)) {
+ if ((new_entry) &&
+ (new_entry->svc.virt_sb_base))
+ free(new_entry->svc.virt_sb_base);
+ if (new_entry)
+ free(new_entry);
+ }
+ mutex_release(&qseecom.registered_listener_list_lock);
+ return ret;
+}
+
+/**
+* De-Registers a Listener Service with QSEE
+*
+* @param uint32_t listnr_id
+* Pre-defined Listener ID to be de-registered
+*
+* @return int
+* Status:
+* 0 - Success
+* Negative value indicates failure.
+*/
+int qseecom_deregister_listener(uint32_t listnr_id)
+{
+ int ret = GENERIC_ERROR;
+ struct qseecom_registered_listener_list *new_entry = NULL;
+ struct qseecom_unregister_listener_ireq req;
+ struct qseecom_command_scm_resp resp;
+
+ mutex_acquire(&qseecom.global_data_lock);
+ if (!qseecom.qseecom_init_done) {
+ dprintf(CRITICAL, "%s qseecom_init not done\n",
+ __func__);
+ mutex_release(&qseecom.global_data_lock);
+ return ret;
+ }
+ mutex_release(&qseecom.global_data_lock);
+
+ mutex_acquire(&qseecom.registered_listener_list_lock);
+ dprintf(SPEW, "%s called\n", __func__);
+ new_entry = __qseecom_check_listener_exists(listnr_id);
+ if (!new_entry) {
+ dprintf(CRITICAL, "Service not present\n");
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+
+ req.qsee_cmd_id = QSEE_DEREGISTER_LISTENER;
+ req.listener_id = listnr_id;
+ resp.result = QSEOS_RESULT_INCOMPLETE;
+
+ ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
+ sizeof(req), &resp, sizeof(resp));
+ if (ret) {
+ dprintf(CRITICAL, "scm_call() failed with err: %d (lstnr id=%d)\n",
+ ret, req.listener_id);
+ ret = GENERIC_ERROR;
+ goto err;
+ }
+
+ list_delete(&new_entry->node);
+
+err:
+ if (ret == 0) {
+ if (new_entry)
+ free(new_entry);
+ }
+ mutex_release(&qseecom.registered_listener_list_lock);
+ return ret;
+}
+
+int qseecom_tz_init()
+{
+ struct qsee_apps_region_info_ireq req;
+ struct qseecom_command_scm_resp resp;
+ int rc = GENERIC_ERROR;
+ /* register log buffer scm request */
+ void *buf = NULL;
+ /* Register app region with TZ */
+ req.qsee_cmd_id = QSEE_APP_REGION_NOTIFICATION;
+ req.addr = APP_REGION_ADDR;
+ req.size = APP_REGION_SIZE;
+ dprintf(ALWAYS, "secure app region addr=0x%x size=0x%x",
+ req.addr, req.size);
+ rc = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
+ &req, sizeof(req),
+ &resp, sizeof(resp));
+ dprintf(ALWAYS, "TZ App region notif returned with status:%d addr:%x size:%d\n",
+ rc, req.addr, req.size);
+ if (rc)
+ goto err;
+ buf = memalign(PAGE_SIZE, ROUNDUP(QSEE_LOG_BUF_SIZE, PAGE_SIZE));
+ if (!buf) {
+ rc = GENERIC_ERROR;
+ goto err;
+ }
+ memset(buf, 0, ROUNDUP(QSEE_LOG_BUF_SIZE, PAGE_SIZE));
+ logbuf_req.qsee_cmd_id = QSEE_REGISTER_LOG_BUF_COMMAND;
+ logbuf_req.phy_addr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+ logbuf_req.len = QSEE_LOG_BUF_SIZE;
+
+ rc = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
+ &logbuf_req, sizeof(logbuf_req),
+ &resp, sizeof(resp));
+ dprintf(ALWAYS, "TZ App log region register returned with status:%d addr:%x size:%d\n",
+ rc, logbuf_req.phy_addr, logbuf_req.len);
+ if (rc)
+ goto err;
+err:
+ if (!rc) {
+ qseecom.qseecom_tz_init_done = 1;
+ dprintf(ALWAYS, "Qseecom TZ Init Done in Appsbl\n");
+ }
+ return rc;
+}
+
+int qseecom_init()
+{
+ int rc = GENERIC_ERROR;
+
+ memset (&qseecom, 0, sizeof(struct qseecom_control));
+ dprintf(SPEW, "%s called\n", __func__);
+ mutex_init(&(qseecom.global_data_lock));
+ mutex_init(&(qseecom.registered_app_list_lock));
+ mutex_init(&(qseecom.registered_listener_list_lock));
+
+ list_initialize(&(qseecom.registered_app_list_head));
+ list_initialize(&(qseecom.registered_listener_list_head));
+
+ qseecom.qseos_version = QSEOS_VERSION_14;
+ rc = 0;
+
+ if (!rc) {
+ qseecom.qseecom_init_done = 1;
+ dprintf(ALWAYS, "Qseecom Init Done in Appsbl\n");
+ }
+ return rc;
+}
+
+int qseecom_exit()
+{
+ dprintf(SPEW, "%s called\n", __func__);
+
+ if (logbuf_req.phy_addr)
+ free((void *)logbuf_req.phy_addr);
+ qseecom.qseecom_init_done = 0;
+ dprintf(ALWAYS, "Qseecom De-Init Done in Appsbl\n");
+ return 0;
+}
diff --git a/platform/msm_shared/reboot.c b/platform/msm_shared/reboot.c
new file mode 100644
index 0000000..fb29ab5
--- /dev/null
+++ b/platform/msm_shared/reboot.c
@@ -0,0 +1,143 @@
+/* Copyright (c) 2015, 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 <debug.h>
+#include <platform/iomap.h>
+#include <reg.h>
+#include <target.h>
+#include <platform.h>
+#include <uart_dm.h>
+#include <mmc.h>
+#include <dev/keys.h>
+#include <spmi_v2.h>
+#include <pm8x41.h>
+#include <board.h>
+#include <baseband.h>
+#include <hsusb.h>
+#include <scm.h>
+#include <platform/gpio.h>
+#include <platform/irqs.h>
+#include <platform/clock.h>
+#include <crypto5_wrapper.h>
+#include <partition_parser.h>
+#include <stdlib.h>
+#include <reboot.h>
+
+#if USER_FORCE_RESET_SUPPORT
+/* Return 1 if it is a force resin triggered by user. */
+uint32_t is_user_force_reset(void)
+{
+ uint8_t poff_reason1 = pm8x41_get_pon_poff_reason1();
+ uint8_t poff_reason2 = pm8x41_get_pon_poff_reason2();
+
+ dprintf(SPEW, "poff_reason1: %d\n", poff_reason1);
+ dprintf(SPEW, "poff_reason2: %d\n", poff_reason2);
+ if (pm8x41_get_is_cold_boot() && (poff_reason1 == KPDPWR_AND_RESIN ||
+ poff_reason2 == STAGE3))
+ return 1;
+ else
+ return 0;
+}
+#endif
+
+unsigned check_reboot_mode(void)
+{
+ uint32_t restart_reason = 0;
+
+ /* Read reboot reason and scrub it */
+ restart_reason = readl(RESTART_REASON_ADDR);
+ writel(0x00, RESTART_REASON_ADDR);
+
+ return restart_reason;
+}
+
+unsigned check_hard_reboot_mode(void)
+{
+ uint8_t hard_restart_reason = 0;
+ uint8_t value = 0;
+
+ /* Read reboot reason and scrub it
+ * Bit-5, bit-6 and bit-7 of SOFT_RB_SPARE for hard reset reason
+ */
+ value = pm8x41_reg_read(PON_SOFT_RB_SPARE);
+ hard_restart_reason = value >> 5;
+ pm8x41_reg_write(PON_SOFT_RB_SPARE, value & 0x1f);
+
+ return hard_restart_reason;
+}
+
+/* Return true if it is triggered by alarm. */
+uint32_t check_alarm_boot(void)
+{
+ /* Check reboot reason and power on reason */
+ if (pm8x41_get_is_cold_boot()) {
+ if (pm8x41_get_pon_reason() == RTC_TRG)
+ return 1;
+ } else {
+ if (readl(RESTART_REASON_ADDR) == ALARM_BOOT)
+ return 1;
+ }
+
+ return 0;
+}
+
+void reboot_device(unsigned reboot_reason)
+{
+ uint8_t reset_type = 0;
+ uint32_t ret = 0;
+
+ /* Need to clear the SW_RESET_ENTRY register and
+ * write to the BOOT_MISC_REG for known reset cases
+ */
+ if(reboot_reason != DLOAD)
+ scm_dload_mode(NORMAL_MODE);
+
+ writel(reboot_reason, RESTART_REASON_ADDR);
+
+ /* For Reboot-bootloader and Dload cases do a warm reset
+ * For Reboot cases do a hard reset
+ */
+ if((reboot_reason == FASTBOOT_MODE) || (reboot_reason == DLOAD) || (reboot_reason == RECOVERY_MODE))
+ reset_type = PON_PSHOLD_WARM_RESET;
+ else
+ reset_type = PON_PSHOLD_HARD_RESET;
+
+ pm8x41_reset_configure(reset_type);
+
+ ret = scm_halt_pmic_arbiter();
+ if (ret)
+ dprintf(CRITICAL , "Failed to halt pmic arbiter: %d\n", ret);
+
+ /* Drop PS_HOLD for MSM */
+ writel(0x00, MPM2_MPM_PS_HOLD);
+
+ mdelay(5000);
+
+ dprintf(CRITICAL, "Rebooting failed\n");
+}
+
diff --git a/platform/msm_shared/reboot.h b/platform/msm_shared/reboot.h
new file mode 100644
index 0000000..7156c01
--- /dev/null
+++ b/platform/msm_shared/reboot.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, 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 FASTBOOT_MODE 0x77665500
+#define RECOVERY_MODE 0x77665502
+#define ALARM_BOOT 0x77665503
+#define RTC_TRG 4
+#define PON_SOFT_RB_SPARE 0x88F
+
+#if USER_FORCE_RESET_SUPPORT
+/* Return 1 if it is a force resin triggered by user. */
+uint32_t is_user_force_reset(void);
+#endif
+
+unsigned check_reboot_mode(void);
+
+unsigned check_hard_reboot_mode(void);
+
+uint32_t check_alarm_boot(void);
+
+void reboot_device(unsigned reboot_reason);
diff --git a/platform/msm_shared/rpm-glink.c b/platform/msm_shared/rpm-glink.c
new file mode 100644
index 0000000..01cae61
--- /dev/null
+++ b/platform/msm_shared/rpm-glink.c
@@ -0,0 +1,379 @@
+/* Copyright (c) 2015, 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 Fundation, Inc. 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 <rpm-glink.h>
+#include <smd.h>
+#include <glink.h>
+#include <glink_rpm.h>
+#include <xport_rpm.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <arch/defines.h>
+#include <debug.h>
+#include <stdlib.h>
+#include <platform/timer.h>
+#include <platform/interrupts.h>
+#include <platform/clock.h>
+#include <platform/iomap.h>
+#include <platform/irqs.h>
+#include <pm8x41.h>
+#include <kernel/event.h>
+
+#define RPM_REQ_MAGIC 0x00716572
+#define RPM_CMD_MAGIC 0x00646d63
+#define REQ_MSG_LENGTH 0x14
+#define CMD_MSG_LENGTH 0x08
+#define ACK_MSG_LENGTH 0x0C
+
+glink_handle_type rpm_glink_port, ssr_glink_port;
+static uint32_t msg_id;
+static event_t wait_for_data;
+
+extern glink_err_type glink_wait_link_down(glink_handle_type handle);
+
+glink_err_type rpm_glink_send_data(uint32_t *data, uint32_t len, msg_type type)
+{
+ rpm_req req;
+ rpm_cmd cmd;
+ glink_err_type send_err = 0;
+ uint32_t len_to_rpm = 0;
+ void *rpm_data = NULL;
+ event_init(&wait_for_data, false, EVENT_FLAG_AUTOUNSIGNAL);
+
+ switch(type)
+ {
+ case RPM_REQUEST_TYPE:
+ req.hdr.type = RPM_REQ_MAGIC;
+ req.hdr.len = len + REQ_MSG_LENGTH;//20
+ req.req_hdr.id = ++msg_id;
+ req.req_hdr.set = 0;
+ req.req_hdr.resourceType = data[RESOURCETYPE];
+ req.req_hdr.resourceId = data[RESOURCEID];
+ req.req_hdr.dataLength = len;
+
+ fill_kvp_object(&req.data, data, len);
+ len_to_rpm = req.req_hdr.dataLength + 0x28;
+
+ rpm_data = (void*) malloc(len_to_rpm);
+ ASSERT(rpm_data);
+ memset(rpm_data, 0, len_to_rpm);
+ memcpy(rpm_data, &req.hdr, sizeof(rpm_gen_hdr));
+ memcpy(rpm_data + sizeof(rpm_gen_hdr), &req.req_hdr, sizeof(rpm_req_hdr));
+ memcpy(rpm_data + sizeof(rpm_gen_hdr)+ sizeof(rpm_req_hdr), req.data, len);
+
+ // Send Data Request to RPM
+ send_err = glink_tx(rpm_glink_port, NULL, (const void *)rpm_data, len_to_rpm, 0);
+ if (send_err)
+ {
+ dprintf(CRITICAL, "%s:%d, Glink tx error\n", __func__, __LINE__);
+ free(rpm_data);
+ free_kvp_object(&req.data);
+ break;
+ }
+#ifdef DEBUG_GLINK
+ dprintf(INFO, "%s:%d, Wait till we receive response from RPM\n", __func__, __LINE__);
+#endif
+ event_wait(&wait_for_data);
+ free(rpm_data);
+ free_kvp_object(&req.data);
+ break;
+ case RPM_CMD_TYPE:
+ cmd.hdr.type = RPM_CMD_MAGIC;
+ cmd.hdr.len = CMD_MSG_LENGTH;//0x8;
+ len_to_rpm = sizeof(rpm_cmd);
+
+ fill_kvp_object(&cmd.data, data, len);
+ send_err = glink_tx(rpm_glink_port, NULL, (const void *)&cmd, len_to_rpm, 0);
+ if (send_err)
+ dprintf(CRITICAL, "%s:%d, Glink tx error\n", __func__, __LINE__);
+ free_kvp_object(&cmd.data);
+ break;
+ default:
+ dprintf(CRITICAL, "Invalid RPM Request\n");
+ break;
+ }
+
+ return send_err;
+}
+
+uint32_t rpm_glink_recv_data(char *rx_buffer, uint32_t* len)
+{
+ rpm_ack_msg *resp;
+ msg_type type = 0;
+ uint32_t ret = 0;
+ /* As per the current design rpm response does not exceed 20 bytes */
+ if (rx_buffer == NULL)
+ {
+ dprintf(CRITICAL, "Invalid pointer to data received from RPM\n");
+ return 99;
+ }
+ resp = (rpm_ack_msg *)rx_buffer;
+
+ arch_invalidate_cache_range((addr_t)resp, sizeof(rpm_gen_hdr));
+
+ if(resp->hdr.type == RPM_CMD_MAGIC)
+ {
+ type = RPM_CMD_TYPE;
+ }
+ else if(resp->hdr.type == RPM_REQ_MAGIC)
+ {
+ type = RPM_REQUEST_TYPE;
+ }
+
+ if (type == RPM_CMD_TYPE && resp->hdr.len == ACK_MSG_LENGTH)
+ {
+ dprintf(SPEW, "Received SUCCESS CMD ACK\n");
+ }
+ else if (type == RPM_REQUEST_TYPE && resp->hdr.len == ACK_MSG_LENGTH)
+ {
+ dprintf(SPEW, "Received SUCCESS REQ ACK \n");
+ }
+ else
+ {
+ ret = 1;
+ dprintf(CRITICAL, "Received ERROR ACK \n");
+ }
+
+ if(!ret)
+ {
+ ret = sizeof(rpm_gen_hdr) + sizeof(kvp_data);
+ }
+#ifdef DEBUG_GLINK
+ dprintf(INFO, "%s:%d Return value %u\n", __func__, __LINE__, ret);
+#endif
+ return ret;
+}
+
+void rpm_vector_glink_ssr_isr(glink_handle_type port, void *unused_open_data, void *unused_pkt_priv,
+ void *buffer, size_t size, size_t intent_used,
+ glink_buffer_provider_fn vprovider, glink_buffer_provider_fn pprovider)
+{
+ char rx_buffer[12];
+ char *return_buffer = NULL;
+ uint32_t ret = 0;
+ uint32_t offset = 0;
+ size_t return_size = 0;
+
+#ifdef DEBUG_GLINK
+ dprintf(INFO, "RPM Vector GLINK SSR ISR\n");
+#endif
+ if (size == 0)
+ {
+ dprintf(CRITICAL, "Invalid size of RPM response\n");
+ ASSERT(0);
+ }
+ if (size > sizeof(rx_buffer))
+ {
+ dprintf(CRITICAL, "Need larger RPM rx buffer. Size of Local Buffer: %u\tSize of RX Buffer: %u\n", size, sizeof(rx_buffer));
+ ASSERT(0);
+ }
+ do
+ {
+ return_buffer = vprovider(buffer, offset, &return_size);
+ if(return_buffer)
+ {
+ memcpy(rx_buffer+offset,return_buffer, return_size);
+ offset += return_size;
+ }
+ } while(return_buffer);
+ ret = rpm_glink_recv_data(rx_buffer,(uint32_t *)&size);
+ if(ret)
+ {
+ dprintf(CRITICAL, "Return value from recv_data: %x\n", ret);
+ }
+ // Release the mutex
+#ifdef DEBUG_GLINK
+ dprintf(INFO, "Received Data from RPM\n");
+#endif
+ event_signal(&wait_for_data, false);
+}
+
+void rpm_vector_glink_isr(glink_handle_type port, void *unused_open_data, void *unused_pkt_priv,
+ void *buffer, size_t size, size_t intent_used,
+ glink_buffer_provider_fn vprovider, glink_buffer_provider_fn pprovider)
+{
+ char rx_buffer[64];
+ char *return_buffer = NULL;
+ uint32_t ret = 0;
+ uint32_t offset = 0;
+ size_t return_size = 0;
+#ifdef DEBUG_GLINK
+ dprintf(INFO, "RPM Vector GLINK ISR\n");
+#endif
+ if (size == 0)
+ {
+ dprintf(CRITICAL, "Invalid size of RPM response\n");
+ ASSERT(0);
+ }
+ if (size > sizeof(rx_buffer))
+ {
+ dprintf(CRITICAL, "Need larger RPM rx buffer. Size of Local Buffer: %u\tSize of RX Buffer: %u\n", size, sizeof(rx_buffer));
+ ASSERT(0);
+ }
+ do
+ {
+ return_buffer = vprovider(buffer, offset, &return_size);
+ if(return_buffer)
+ {
+ memcpy(rx_buffer+offset,return_buffer, return_size);
+ offset += return_size;
+ }
+ } while(return_buffer);
+ ret = rpm_glink_recv_data(rx_buffer, (uint32_t *)&size);
+ if(ret)
+ {
+ dprintf(CRITICAL, "Return value from recv_data: %x\n", ret);
+ }
+ // Release the mutex
+#ifdef DEBUG_GLINK
+ dprintf(INFO, "Received Data from RPM\n");
+#endif
+ event_signal(&wait_for_data, false);
+}
+
+void rpm_glink_notify_state_isr(glink_handle_type handle, void *data, glink_channel_event_type event)
+{
+ if(event == GLINK_CONNECTED)
+ {
+ dprintf(INFO, "Glink Connection between APPS and RPM established\n");
+ return;
+ }
+}
+
+void rpm_glink_tx_done_isr(void)
+{
+ //empty function for tx_done cb. Nothing required here for now since we are always in
+ //"single-threaded" operation of sending GLink requests
+ return;
+}
+
+void rpm_glink_open(glink_link_info_type *link_info, void* priv)
+{
+ glink_err_type ret;
+ glink_open_config_type glink_open_cfg = {0}, glink_ssr_open_cfg = {0};
+
+ // Open channel for tx
+ glink_open_cfg.name = "rpm_requests";
+ glink_open_cfg.remote_ss = link_info->remote_ss;
+ glink_open_cfg.notify_rx = NULL;
+ glink_open_cfg.notify_rxv = (glink_rxv_notification_cb)rpm_vector_glink_isr;
+ glink_open_cfg.notify_tx_done = (glink_tx_notification_cb)rpm_glink_tx_done_isr;
+ glink_open_cfg.notify_state = (glink_state_notification_cb)rpm_glink_notify_state_isr;
+ glink_open_cfg.priv = NULL;
+ ret = glink_open(&glink_open_cfg, &rpm_glink_port);
+ if (ret == GLINK_STATUS_SUCCESS)
+ dprintf(INFO, "Opening RPM Glink Port success\n");
+ else
+ {
+ dprintf(CRITICAL, "Opening RPM Glink Port failure %d\n", ret);
+ ASSERT(0);
+ }
+
+ // Open Channel for tear down
+ glink_ssr_open_cfg.name = "glink_ssr";
+ glink_ssr_open_cfg.remote_ss = link_info->remote_ss;
+ glink_ssr_open_cfg.notify_rx = NULL;
+ glink_ssr_open_cfg.notify_rxv = (glink_rxv_notification_cb)rpm_vector_glink_ssr_isr;
+ glink_ssr_open_cfg.notify_tx_done = (glink_tx_notification_cb)rpm_glink_tx_done_isr;
+ glink_ssr_open_cfg.notify_state = (glink_state_notification_cb)rpm_glink_notify_state_isr;
+ glink_ssr_open_cfg.priv = NULL;
+
+ ret = glink_open(&glink_ssr_open_cfg, &ssr_glink_port);
+ if (ret == GLINK_STATUS_SUCCESS)
+ dprintf(INFO, "Opening SSR Glink Port success\n");
+ else
+ {
+ dprintf(CRITICAL, "Opening SSR Glink Port failure %d\n", ret);
+ ASSERT(0);
+ }
+
+}
+
+void rpm_glink_init()
+{
+ glink_err_type ret;
+ glink_link_id_type link_id;
+
+ dprintf(INFO, "RPM GLink Init\n");
+ // Initialize RPM transport
+ ret = xport_rpm_init(NULL);
+ if (ret == GLINK_STATUS_SUCCESS)
+ {
+ unmask_interrupt(GLINK_IPC_IRQ);
+ GLINK_LINK_ID_STRUCT_INIT(link_id);
+ link_id.remote_ss = "rpm";
+ link_id.link_notifier = (glink_link_state_notif_cb)rpm_glink_open;
+ glink_register_link_state_cb(&link_id, NULL);
+ }
+ else
+ {
+ dprintf(CRITICAL, "RPM Glink Init Failure\n");
+ ASSERT(0);
+ }
+}
+
+void rpm_glink_uninit()
+{
+ rpm_ssr_req req;
+ glink_err_type ret;
+ uint32_t len_to_rpm, loop = 100000;
+
+ // update ssr request
+ req.version = 0;
+ req.cmd = 0;
+ req.seqnumber = 0;
+ memset(req.name, 0, sizeof(req.name));
+ strncpy(req.name, "apss", 4);
+ req.namelength = strlen(req.name);
+ len_to_rpm = sizeof(rpm_ssr_req);
+ dprintf(INFO, "RPM GLINK UnInit\n");
+ ret = glink_tx(ssr_glink_port, NULL, (const void *)&req, len_to_rpm, 0);
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Glink SSR Channel: Tx for link tear down request failure\n");
+ ASSERT(0);
+ }
+
+#ifdef DEBUG_GLINK
+ dprintf(INFO, "%s:%d, Wait till we receive response from RPM\n", __func__, __LINE__);
+#endif
+ // loop till the FIFO indices are cleared
+ while((ret = glink_wait_link_down(ssr_glink_port)) && loop)
+ {
+ loop--;
+ mdelay(1);
+ continue;
+ }
+ if (!loop)
+ {
+ dprintf(INFO, "%s:%d, Tearing down Glink SSR Channel Timed out\n", __func__, __LINE__);
+ ASSERT(0);
+ }
+}
diff --git a/platform/msm_shared/rpm-ipc.c b/platform/msm_shared/rpm-ipc.c
new file mode 100644
index 0000000..2bd3c51
--- /dev/null
+++ b/platform/msm_shared/rpm-ipc.c
@@ -0,0 +1,70 @@
+/* Copyright (c) 2015, 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 Fundation, Inc. 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 <arch/defines.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <rpm-ipc.h>
+#include <rpm-glink.h>
+#include <rpm-smd.h>
+#include <string.h>
+
+void fill_kvp_object(kvp_data **kdata, uint32_t *data, uint32_t len)
+{
+ *kdata = (kvp_data *) memalign(CACHE_LINE, ROUNDUP(len, CACHE_LINE));
+ ASSERT(*kdata);
+
+ memcpy(*kdata, data+2, len);
+}
+
+void free_kvp_object(kvp_data **kdata)
+{
+ if(*kdata)
+ free(*kdata);
+}
+
+int rpm_send_data(uint32_t *data, uint32_t len, msg_type type)
+{
+ int ret = 0;
+#ifdef GLINK_SUPPORT
+ ret = rpm_glink_send_data(data, len, type);
+#else
+ ret = rpm_smd_send_data(data, len, type);
+#endif
+ return ret;
+}
+
+void rpm_clk_enable(uint32_t *data, uint32_t len)
+{
+ if(rpm_send_data(data, len, RPM_REQUEST_TYPE))
+ {
+ dprintf(CRITICAL, "Clock enable failure\n");
+ ASSERT(0);
+ }
+}
diff --git a/platform/msm_shared/rpm-smd.c b/platform/msm_shared/rpm-smd.c
index 693d369..d6869ee 100644
--- a/platform/msm_shared/rpm-smd.c
+++ b/platform/msm_shared/rpm-smd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 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
@@ -36,12 +36,6 @@
#include <stdlib.h>
#include <platform/timer.h>
-#define RPM_REQ_MAGIC 0x00716572
-#define RPM_CMD_MAGIC 0x00646d63
-#define REQ_MSG_LENGTH 0x14
-#define CMD_MSG_LENGTH 0x08
-#define ACK_MSG_LENGTH 0x0C
-
static uint32_t msg_id;
smd_channel_info_t ch;
@@ -55,21 +49,7 @@
smd_uninit(&ch);
}
-static void fill_kvp_object(kvp_data **kdata, uint32_t *data, uint32_t len)
-{
- *kdata = (kvp_data *) memalign(CACHE_LINE, ROUNDUP(len, CACHE_LINE));
- ASSERT(*kdata);
-
- memcpy(*kdata, data+2, len);
-}
-
-static void free_kvp_object(kvp_data **kdata)
-{
- if(*kdata)
- free(*kdata);
-}
-
-int rpm_send_data(uint32_t *data, uint32_t len, msg_type type)
+int rpm_smd_send_data(uint32_t *data, uint32_t len, msg_type type)
{
rpm_req req;
rpm_cmd cmd;
@@ -103,7 +83,7 @@
ret = smd_write(&ch, smd_data, len_to_smd, SMD_APPS_RPM);
/* Read the response */
- ack_msg_len = rpm_recv_data(&rlen);
+ ack_msg_len = rpm_smd_recv_data(&rlen);
smd_signal_read_complete(&ch, ack_msg_len);
@@ -127,7 +107,7 @@
return ret;
}
-uint32_t rpm_recv_data(uint32_t* len)
+uint32_t rpm_smd_recv_data(uint32_t* len)
{
rpm_ack_msg *resp;
msg_type type;
@@ -171,15 +151,3 @@
return ret;
}
-
-void rpm_clk_enable(uint32_t *data, uint32_t len)
-{
- /* Send the request to SMD */
- rpm_send_data(data, len, RPM_REQUEST_TYPE);
-}
-
-void rpm_clk_disable(uint32_t *data, uint32_t len)
-{
- dprintf(CRITICAL,"Clock disable\n");
-}
-
diff --git a/platform/msm_shared/rpmb/rpmb.c b/platform/msm_shared/rpmb/rpmb.c
new file mode 100644
index 0000000..de67c46
--- /dev/null
+++ b/platform/msm_shared/rpmb/rpmb.c
@@ -0,0 +1,251 @@
+/* Copyright (c) 2013-2015, 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 <platform.h>
+#include <rpmb.h>
+#include <rpmb_listener.h>
+#include <mmc_sdhci.h>
+#include <boot_device.h>
+#include <debug.h>
+#include <target.h>
+
+static bool lksec_app_loaded;
+
+static void *dev;
+static int app_handle;
+struct rpmb_init_info info;
+
+int rpmb_init()
+{
+ int ret = 0;
+
+ dev = target_mmc_device();
+
+ /* 1. Initialize storage specific data */
+ if (platform_boot_dev_isemmc())
+ {
+ struct mmc_device *mmc_dev = (struct mmc_device *) dev;
+ info.size = mmc_dev->card.rpmb_size / RPMB_MIN_BLK_SZ;
+ info.rel_wr_count = mmc_dev->card.rel_wr_count;
+ info.dev_type = EMMC_RPMB;
+ }
+ else
+ {
+ struct ufs_dev *ufs_dev = (struct ufs_dev *) dev;
+ ufs_rpmb_init(ufs_dev);
+ info.size = ufs_dev->rpmb_num_blocks;
+ info.rel_wr_count = ufs_dev->rpmb_rw_size;
+ info.dev_type = UFS_RPMB;
+ }
+
+ /* Initialize Qseecom */
+ ret = qseecom_init();
+
+ if (ret < 0)
+ {
+ dprintf(CRITICAL, "Failed to initialize qseecom, error: %d\n", ret);
+ goto err;
+ }
+
+ /* Register & start the listener */
+ ret = rpmb_listener_start();
+ if (ret < 0)
+ {
+ dprintf(CRITICAL, "Error registering the handler\n");
+ goto err;
+ }
+
+ /* Start Qseecom */
+ ret = qseecom_tz_init();
+
+ if (ret < 0)
+ {
+ dprintf(CRITICAL, "Failed to start qseecom, error: %d\n", ret);
+ goto err;
+ }
+
+err:
+ return ret;
+}
+
+struct rpmb_init_info *rpmb_get_init_info()
+{
+ return &info;
+}
+
+int rpmb_read(uint32_t *req, uint32_t req_len, uint32_t *resp, uint32_t *resp_len)
+{
+ if (platform_boot_dev_isemmc())
+ return rpmb_read_emmc(dev, req, req_len, resp, resp_len);
+ else
+ return rpmb_read_ufs(dev, req, req_len, resp, resp_len);
+}
+
+int rpmb_write(uint32_t *req, uint32_t req_len, uint32_t *resp, uint32_t *resp_len)
+{
+ if (platform_boot_dev_isemmc())
+ return rpmb_write_emmc(dev, req, req_len, resp, resp_len);
+ else
+ return rpmb_write_ufs(dev, req, req_len, resp, resp_len);
+}
+
+/* This API calls into TZ app to read device_info */
+int read_device_info_rpmb(void *info, uint32_t sz)
+{
+ int ret = 0;
+ struct send_cmd_req read_req = {0};
+ struct send_cmd_rsp read_rsp = {0};
+
+ /*
+ * Load the sec app for first time
+ */
+ if (!lksec_app_loaded)
+ {
+ if (load_sec_app() < 0)
+ {
+ dprintf(CRITICAL, "Failed to load App for rpmb\n");
+ ASSERT(0);
+ }
+ lksec_app_loaded = true;
+ }
+
+ read_req.cmd_id = CLIENT_CMD_READ_LK_DEVICE_STATE;
+ read_req.data = (uint32_t) info;
+ read_req.len = sz;
+
+ read_rsp.cmd_id = CLIENT_CMD_READ_LK_DEVICE_STATE;
+
+ /* Read the device info */
+ ret = qseecom_send_command(app_handle, (void*) &read_req, sizeof(read_req), (void*) &read_rsp, sizeof(read_rsp));
+
+ if (ret < 0 || read_rsp.status < 0)
+ {
+ dprintf(CRITICAL, "Reading device info failed: Error: %d\n", read_rsp.status);
+ return read_rsp.status;
+ }
+
+ return 0;
+}
+
+int write_device_info_rpmb(void *info, uint32_t sz)
+{
+ int ret = 0;
+
+ struct send_cmd_req write_req = {0};
+ struct send_cmd_rsp write_rsp = {0};
+
+ write_req.cmd_id = CLIENT_CMD_WRITE_LK_DEVICE_STATE;
+ write_req.data = (uint32_t) info;
+ write_req.len = sz;
+
+ write_rsp.cmd_id = CLIENT_CMD_WRITE_LK_DEVICE_STATE;
+
+ /* Write the device info */
+ ret = qseecom_send_command(app_handle, (void *)&write_req, sizeof(write_req), (void *)&write_rsp, sizeof(write_rsp));
+
+ if (ret < 0 || write_rsp.status < 0)
+ {
+ dprintf(CRITICAL, "Writing device info failed: Error: %d\n", write_rsp.status);
+ return ret;
+ }
+
+ return 0;
+}
+
+int rpmb_get_app_handle()
+{
+ return app_handle;
+}
+
+int rpmb_uninit()
+{
+ int ret = 0;
+
+ ret = rpmb_listener_stop(RPMB_LSTNR_ID);
+ if (ret < 0)
+ {
+ dprintf(CRITICAL, "Failed to stop Qseecom Listener\n");
+ return ret;
+ }
+ ret = qseecom_exit();
+
+ if (ret < 0)
+ {
+ dprintf(CRITICAL, "Failed to exit qseecom \n");
+ return ret;
+ }
+
+ return ret;
+}
+
+int load_sec_app()
+{
+ /* start TZ app */
+ app_handle = qseecom_start_app("lksecapp");
+
+ if (app_handle < 0)
+ {
+ dprintf(CRITICAL, "Failure to load TZ app: lksecapp, error: %d\n", app_handle);
+ return app_handle;
+ }
+
+ return 0;
+}
+
+int unload_sec_app()
+{
+ int ret = 0;
+
+ struct send_cmd_req req = {0};
+ struct send_cmd_rsp rsp = {0};
+
+ req.cmd_id = CLIENT_CMD_LK_END_MILESTONE;
+ rsp.cmd_id = CLIENT_CMD_LK_END_MILESTONE;
+
+ /* Milestone end command */
+ ret = qseecom_send_command(app_handle, (void *)&req, sizeof(req), (void *)&rsp, sizeof(rsp));
+
+ if (ret < 0 || rsp.status < 0)
+ {
+ dprintf(CRITICAL, "Failed to send milestone end command: Error: %x\n", rsp.status);
+ return ret;
+ }
+
+ if (qseecom_shutdown_app(app_handle) < 0)
+ {
+ dprintf(CRITICAL, "Failed to Shutdown sec app\n");
+ ASSERT(0);
+ }
+
+
+ return 0;
+}
+
+bool is_sec_app_loaded()
+{
+ return lksec_app_loaded;
+}
diff --git a/platform/msm_shared/rpmb/rpmb_emmc.c b/platform/msm_shared/rpmb/rpmb_emmc.c
new file mode 100644
index 0000000..2bfa545
--- /dev/null
+++ b/platform/msm_shared/rpmb/rpmb_emmc.c
@@ -0,0 +1,179 @@
+/* Copyright (c) 2015, 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 <rpmb.h>
+#include <mmc_sdhci.h>
+#include <debug.h>
+
+static const char *str_err[] =
+{
+ "Operation Ok",
+ "General failure",
+ "Authentication error (MAC comparison not matching, MAC calculation failure)",
+ "Counter failure (counters not matching in comparison, counter incrementing failure)",
+ "Address failure (address out of range, wrong address alignment)",
+ "Write failure (data/counter/result write failure)",
+ "Read failure (data/counter/result read failure)",
+ "Authentication Key not yet programmed",
+};
+
+static struct rpmb_frame read_result_reg =
+{
+ .requestresponse[1] = READ_RESULT_FLAG,
+};
+
+int rpmb_write_emmc(struct mmc_device *dev,uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len)
+{
+ uint32_t i;
+ int ret = 0;
+ struct mmc_command cmd[3] = {{0},{0},{0}};
+ struct rpmb_frame *result = (struct rpmb_frame *)resp_buf;
+
+ for (i = 0; i < blk_cnt; i++)
+ {
+#if DEBUG_RPMB
+ dump_rpmb_frame((uint8_t *)req_buf, "request");
+#endif
+
+ /* CMD25 program data packet */
+ cmd[0].write_flag = true;
+ cmd[0].cmd_index = CMD25_WRITE_MULTIPLE_BLOCK;
+ cmd[0].argument = 0;
+ cmd[0].cmd_type = SDHCI_CMD_TYPE_NORMAL;
+ cmd[0].resp_type = SDHCI_CMD_RESP_R1;
+ cmd[0].trans_mode = SDHCI_MMC_WRITE;
+ cmd[0].data_present = 0x1;
+ cmd[0].data.data_ptr = (void *)req_buf;
+ cmd[0].data.num_blocks = RPMB_MIN_BLK_CNT;
+
+ /* CMD25 Result Register Read Request Packet */
+ cmd[1].write_flag = false;
+ cmd[1].cmd_index = CMD25_WRITE_MULTIPLE_BLOCK;
+ cmd[1].argument = 0;
+ cmd[1].cmd_type = SDHCI_CMD_TYPE_NORMAL;
+ cmd[1].resp_type = SDHCI_CMD_RESP_R1;
+ cmd[1].trans_mode = SDHCI_MMC_WRITE;
+ cmd[1].data_present = 0x1;
+ cmd[1].data.data_ptr = (void *)&read_result_reg;
+ cmd[1].data.num_blocks = RPMB_MIN_BLK_CNT;
+
+ /* Read actual result with read request */
+ cmd[2].write_flag = false;
+ cmd[2].cmd_index = CMD18_READ_MULTIPLE_BLOCK;
+ cmd[2].argument = 0;
+ cmd[2].cmd_type = SDHCI_CMD_TYPE_NORMAL;
+ cmd[2].resp_type = SDHCI_CMD_RESP_R1;
+ cmd[2].trans_mode = SDHCI_MMC_READ;
+ cmd[2].data_present = 0x1;
+ cmd[2].data.data_ptr = (void *)resp_buf;
+ cmd[2].data.num_blocks = RPMB_MIN_BLK_CNT;
+
+ ret = mmc_sdhci_rpmb_send(dev, cmd);
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to Send the RPMB write sequnce of commands\n");
+ break;
+ }
+
+ if (result->result[0] == 0x80)
+ {
+ dprintf(CRITICAL, "Max write counter reached: \n");
+ break;
+ }
+
+ if (result->result[1])
+ {
+ dprintf(CRITICAL, "%s\n", str_err[result->result[1]]);
+ break;
+ }
+
+ req_buf = (uint32_t*) ((uint8_t*)req_buf + RPMB_BLK_SIZE);
+
+#if DEBUG_RPMB
+ dump_rpmb_frame((uint8_t *)resp_buf, "response");
+#endif
+ }
+ *resp_len = RPMB_MIN_BLK_CNT * RPMB_BLK_SIZE;
+
+ return 0;
+}
+
+int rpmb_read_emmc(struct mmc_device *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len)
+{
+ struct mmc_command cmd[3] = {{0}, {0}, {0}};
+ int ret = 0;
+ struct rpmb_frame *result = (struct rpmb_frame *)resp_buf;
+
+#if DEBUG_RPMB
+ dump_rpmb_frame((uint8_t *)req_buf, "request");
+#endif
+
+ /* CMD25 program data packet */
+ cmd[0].write_flag = false;
+ cmd[0].cmd_index = CMD25_WRITE_MULTIPLE_BLOCK;
+ cmd[0].argument = 0;
+ cmd[0].cmd_type = SDHCI_CMD_TYPE_NORMAL;
+ cmd[0].resp_type = SDHCI_CMD_RESP_R1;
+ cmd[0].trans_mode = SDHCI_MMC_WRITE;
+ cmd[0].data_present = 0x1;
+ cmd[0].data.data_ptr = (void *)req_buf;
+ cmd[0].data.num_blocks = RPMB_MIN_BLK_CNT;
+
+ /* Read actual result with read request */
+ cmd[1].write_flag = false;
+ cmd[1].cmd_index = CMD18_READ_MULTIPLE_BLOCK;
+ cmd[1].argument = 0;
+ cmd[1].cmd_type = SDHCI_CMD_TYPE_NORMAL;
+ cmd[1].resp_type = SDHCI_CMD_RESP_R1;
+ cmd[1].trans_mode = SDHCI_MMC_READ;
+ cmd[1].data_present = 0x1;
+ cmd[1].data.data_ptr = (void *)resp_buf;
+ cmd[1].data.num_blocks = blk_cnt;
+ cmd[1].cmd23_support = 0x1;
+
+ ret = mmc_sdhci_rpmb_send(dev, cmd);
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to Send the RPMB read sequence of commands\n");
+ return -1;
+ }
+
+ if (result->result[1])
+ {
+ dprintf(CRITICAL, "%s\n", str_err[result->result[1]]);
+ }
+
+#if DEBUG_RPMB
+ dump_rpmb_frame((uint8_t *)resp_buf, "response");
+#endif
+ *resp_len = blk_cnt * RPMB_BLK_SIZE;
+
+ return 0;
+}
diff --git a/platform/msm_shared/rpmb/rpmb_listener.c b/platform/msm_shared/rpmb/rpmb_listener.c
new file mode 100644
index 0000000..7cf0b79
--- /dev/null
+++ b/platform/msm_shared/rpmb/rpmb_listener.c
@@ -0,0 +1,199 @@
+/* Copyright (c) 2013-2015, 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 <debug.h>
+#include <rpmb.h>
+#include <rpmb_listener.h>
+#include <qseecom_lk_api.h>
+
+#define RPMB_LSTNR_VERSION_2 0x2
+
+typedef enum
+{
+ TZ_CM_CMD_RPMB_INIT = 0x101, //257
+ TZ_CM_CMD_RPMB_READ, //258
+ TZ_CM_CMD_RPMB_WRITE, //259
+ TZ_CM_CMD_RPMB_PARTITION, //260
+} tz_rpmb_cmd_type;
+
+struct tz_device_init_req
+{
+ uint32_t cmd_id;
+ uint32_t version;
+}__PACKED;
+
+/* RPMB Init response message */
+struct tz_device_init_resp
+{
+ uint32_t cmd_id; /* Command ID */
+ uint32_t version; /* Messaging version from RPMB listener */
+ uint32_t status; /* RPMB init status */
+ uint32_t num_sectors; /* Size of RPMB (in sectors) */
+ uint32_t rel_wr_count; /* Reliable write count for the RPMB */
+ uint32_t dev_type; /* Storage device type (like eMMC or UFS) */
+ uint32_t reserved1; /* Reserved 1 */
+ uint32_t reserved2; /* Reserved 2 */
+ uint32_t reserved3; /* Reserved 3 */
+ uint32_t reserved4; /* Reserved 4 */
+}__PACKED;
+
+struct tz_rpmb_rw_req
+{
+ uint32_t cmd_id;
+ uint32_t num_sectors;
+ uint32_t req_buff_len;
+ uint32_t req_buff_offset;
+}__PACKED;
+
+struct tz_rpmb_rw_resp
+{
+ uint32_t cmd_id;
+ int32_t status;
+ uint32_t res_buff_len;
+ uint32_t res_buff_offset;
+}__PACKED;
+
+typedef int (*ListenerCallback)(void*, uint32_t);
+
+static void handle_init_request(void *buf, uint32_t sz)
+{
+ struct tz_device_init_req *init_req_p = NULL;
+ struct tz_device_init_resp *init_resp = (struct tz_device_init_resp*) buf;
+ struct rpmb_init_info *rpmb_info = NULL;
+
+ init_req_p = (struct tz_device_init_req *) buf;
+
+ rpmb_info = rpmb_get_init_info();
+
+ if (rpmb_info)
+ init_resp->status = 0;
+
+ init_resp->cmd_id = init_req_p->cmd_id;
+ init_resp->version = RPMB_LSTNR_VERSION_2;
+ init_resp->num_sectors = rpmb_info->size / RPMB_SECTOR_SIZE;
+ init_resp->rel_wr_count = rpmb_info->rel_wr_count;
+ init_resp->dev_type = rpmb_info->dev_type;
+}
+
+static void handle_rw_request(void *buf, uint32_t sz)
+{
+ struct tz_rpmb_rw_req *req_p = (struct tz_rpmb_rw_req *)buf;
+ struct tz_rpmb_rw_resp *resp_p = NULL;
+ uint32_t *req_buf = buf + req_p->req_buff_offset;
+ uint32_t *resp_buf = buf + sizeof(struct tz_rpmb_rw_resp);
+
+ resp_p = (struct tz_rpmb_rw_resp *) buf;
+
+ switch (req_p->cmd_id)
+ {
+ case TZ_CM_CMD_RPMB_READ:
+#if DEBUG_RPMB
+ dprintf(INFO, "Read Request received\n");
+#endif
+ resp_p->status = rpmb_read(req_buf, req_p->num_sectors, resp_buf, &resp_p->res_buff_len);
+ break;
+ case TZ_CM_CMD_RPMB_WRITE:
+#if DEBUG_RPMB
+ dprintf(INFO, "Write Request received\n");
+#endif
+ resp_p->status = rpmb_write(req_buf, req_p->num_sectors, resp_buf, &resp_p->res_buff_len);
+ break;
+ default:
+ dprintf(CRITICAL, "Unsupported request command request: %u\n", req_p->cmd_id);
+ ASSERT(0);
+ };
+
+ resp_p->res_buff_offset = sizeof(struct tz_rpmb_rw_resp);
+ resp_p->cmd_id = req_p->cmd_id;
+}
+
+int rpmb_cmd_handler(void *buf, uint32_t sz)
+{
+ int ret = 0;
+ uint32_t cmd_id;
+
+ ASSERT(buf);
+
+ cmd_id = (uint32_t) *((uint32_t *)buf);
+
+ switch(cmd_id)
+ {
+ case TZ_CM_CMD_RPMB_READ:
+ case TZ_CM_CMD_RPMB_WRITE:
+ handle_rw_request(buf, sz);
+ break;
+ case TZ_CM_CMD_RPMB_INIT:
+#if DEBUG_RPMB
+ dprintf(INFO, "RPMB init received\n");
+#endif
+ handle_init_request(buf, sz);
+ break;
+ case TZ_CM_CMD_RPMB_PARTITION:
+#if DEBUG_RPMB
+ dprintf(INFO, "Partition init received\n");
+#endif
+ ret = -1;
+ break;
+ default:
+ /* Does qseecom need a response here? */
+ dprintf(CRITICAL, "Unsupported Request from qseecom: %d\n", cmd_id);
+ ASSERT(0);
+ };
+
+ return ret;
+}
+
+int rpmb_listener_start()
+{
+ int ret;
+ struct qseecom_listener_services rpmb_listener;
+
+ rpmb_listener.service_name = "RPMB system services";
+ rpmb_listener.id = RPMB_LSTNR_ID;
+ rpmb_listener.sb_size = 20 * 1024;
+ rpmb_listener.service_cmd_handler = rpmb_cmd_handler;
+
+ ret = qseecom_register_listener(&rpmb_listener);
+
+ if (ret < 0)
+ dprintf(CRITICAL, "Failed to register rpmb listener\n");
+
+ return ret;
+}
+
+int rpmb_listener_stop(int id)
+{
+ int ret;
+
+ ret = qseecom_deregister_listener(id);
+
+ if (ret < 0)
+ dprintf(CRITICAL, "Failed to unregister rpmb listener\n");
+
+ return ret;
+}
+
diff --git a/platform/msm_shared/rpmb/rpmb_ufs.c b/platform/msm_shared/rpmb/rpmb_ufs.c
new file mode 100644
index 0000000..3cc4d91
--- /dev/null
+++ b/platform/msm_shared/rpmb/rpmb_ufs.c
@@ -0,0 +1,294 @@
+/* Copyright (c) 2015, 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 <ufs.h>
+#include <ucs.h>
+#include <upiu.h>
+#include <rpmb.h>
+#include <debug.h>
+#include <stdlib.h>
+#include <string.h>
+#include <endian.h>
+#include <arch/defines.h>
+
+static struct rpmb_frame read_result_reg =
+{
+ .requestresponse[1] = READ_RESULT_FLAG,
+};
+
+int rpmb_read_ufs(struct ufs_dev *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len)
+{
+ // validate input parameters
+ ASSERT(req_buf);
+ ASSERT(resp_buf);
+ ASSERT(resp_len);
+
+ STACKBUF_DMA_ALIGN(cdb, sizeof(struct scsi_sec_protocol_cdb));
+ struct scsi_req_build_type req_upiu;
+ struct scsi_sec_protocol_cdb *cdb_out_param, *cdb_in_param;
+ uint32_t blks_remaining;
+ uint32_t blks_to_transfer;
+ uint64_t bytes_to_transfer;
+ uint64_t max_size;
+ blks_remaining = blk_cnt;
+ blks_to_transfer = blks_remaining;
+ bytes_to_transfer = blks_to_transfer * RPMB_FRAME_SIZE;
+
+#ifdef DEBUG_RPMB
+ dump_rpmb_frame((uint8_t *)req_buf, "request");
+#endif
+
+ // check if total bytes to transfer exceed max supported size
+ max_size = dev->rpmb_rw_size * RPMB_FRAME_SIZE * blk_cnt;
+ if (bytes_to_transfer > max_size)
+ {
+ dprintf(CRITICAL, "RPMB request transfer size %llu greater than max transfer size %llu\n", bytes_to_transfer, max_size);
+ return -UFS_FAILURE;
+ }
+#ifdef DEBUG_RPMB
+ dprintf(SPEW, "rpmb_read: req_buf: 0x%x blk_count: 0x%x\n", *req_buf, blk_cnt);
+ dprintf(INFO, "rpmb_read: bytes_to_transfer: 0x%x blks_to_transfer: 0x%x\n",
+ bytes_to_transfer, blks_to_transfer);
+#endif
+ // send the request
+ cdb_out_param = (struct scsi_sec_protocol_cdb*) cdb;
+ memset(cdb_out_param, 0, sizeof(struct scsi_sec_protocol_cdb));
+
+ cdb_out_param->opcode = SCSI_CMD_SECPROT_OUT;
+ cdb_out_param->cdb1 = SCSI_SEC_PROT;
+ cdb_out_param->sec_protocol_specific = BE16(SCSI_SEC_UFS_PROT_ID);
+ cdb_out_param->alloc_tlen = BE32(bytes_to_transfer);
+
+ // Flush CDB to memory
+ dsb();
+ arch_clean_invalidate_cache_range((addr_t) cdb_out_param, sizeof(struct scsi_sec_protocol_cdb));
+
+ memset(&req_upiu, 0, sizeof(struct scsi_req_build_type));
+
+ req_upiu.cdb = (addr_t) cdb_out_param;
+ req_upiu.data_buffer_addr = (addr_t) req_buf;
+ req_upiu.data_len = bytes_to_transfer;
+ req_upiu.flags = UPIU_FLAGS_WRITE;
+ req_upiu.lun = UFS_WLUN_RPMB;
+ req_upiu.dd = UTRD_TARGET_TO_SYSTEM;
+
+#ifdef DEBUG_RPMB
+ dprintf(INFO, "Sending RPMB Read request\n");
+#endif
+ if (ucs_do_scsi_cmd(dev, &req_upiu))
+ {
+ dprintf(CRITICAL, "%s:%d ucs_do_scsi_rpmb_read: failed\n", __func__, __LINE__);
+ return -UFS_FAILURE;
+ }
+#ifdef DEBUG_RPMB
+ dprintf(INFO, "Sending RPMB Read request complete\n");
+#endif
+ // read the response
+ cdb_in_param = (struct scsi_sec_protocol_cdb*) cdb;
+ memset(cdb_in_param, 0, sizeof(struct scsi_sec_protocol_cdb));
+
+ cdb_in_param->opcode = SCSI_CMD_SECPROT_IN;
+ cdb_in_param->cdb1 = SCSI_SEC_PROT;
+ cdb_in_param->sec_protocol_specific = BE16(SCSI_SEC_UFS_PROT_ID);
+ cdb_in_param->alloc_tlen = BE32(bytes_to_transfer);
+
+ // Flush CDB to memory
+ dsb();
+ arch_clean_invalidate_cache_range((addr_t) cdb_in_param, sizeof(struct scsi_sec_protocol_cdb));
+
+ memset(&req_upiu, 0, sizeof(struct scsi_req_build_type));
+
+ req_upiu.cdb = (addr_t) cdb_in_param;
+ req_upiu.data_buffer_addr = (addr_t) resp_buf;
+ req_upiu.data_len = bytes_to_transfer;
+ req_upiu.flags = UPIU_FLAGS_READ;
+ req_upiu.lun = UFS_WLUN_RPMB;
+ req_upiu.dd = UTRD_SYSTEM_TO_TARGET;
+
+#ifdef DEBUG_RPMB
+ dprintf(INFO, "Sending RPMB Read response\n");
+#endif
+ if (ucs_do_scsi_cmd(dev, &req_upiu))
+ {
+ dprintf(CRITICAL, "%s:%d ucs_do_scsi_rpmb_read: failed\n", __func__, __LINE__);
+ return -UFS_FAILURE;
+ }
+#ifdef DEBUG_RPMB
+ dprintf(SPEW, "Sending RPMB Read response complete\n");
+ dump_rpmb_frame((uint8_t *)resp_buf, "response");
+#endif
+ *resp_len = bytes_to_transfer;
+ return UFS_SUCCESS;
+}
+
+int rpmb_write_ufs(struct ufs_dev *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len)
+{
+ // validate input parameters
+ ASSERT(req_buf);
+ ASSERT(resp_buf);
+ ASSERT(resp_len);
+
+ STACKBUF_DMA_ALIGN(cdb, sizeof(struct scsi_sec_protocol_cdb));
+ struct scsi_req_build_type req_upiu;
+ struct scsi_sec_protocol_cdb *cdb_out_param, *cdb_in_param;
+ uint32_t blks_remaining;
+ uint32_t blks_to_transfer;
+ uint64_t bytes_to_transfer;
+ uint64_t max_size;
+ uint32_t result_frame_bytes = RPMB_FRAME_SIZE;
+ uint32_t i;
+
+ blks_remaining = blk_cnt;
+ blks_to_transfer = blks_remaining;
+ bytes_to_transfer = blks_to_transfer * RPMB_FRAME_SIZE;
+
+ // check if total bytes to transfer exceed max supported size
+ max_size = dev->rpmb_rw_size * RPMB_FRAME_SIZE * blk_cnt;
+ if (bytes_to_transfer > max_size)
+ {
+ dprintf(CRITICAL, "RPMB request transfer size %llu greater than max transfer size %llu\n", bytes_to_transfer, max_size);
+ return -UFS_FAILURE;
+ }
+#ifdef DEBUG_RPMB
+ dprintf(INFO, "%s: req_buf: 0x%x blk_count: 0x%x\n", __func__,*req_buf, blk_cnt);
+ dprintf(INFO, "%s: bytes_to_transfer: 0x%x blks_to_transfer: 0x%x\n", __func__
+ bytes_to_transfer, blk_cnt);
+ dump_rpmb_frame((uint8_t *)req_buf, "request");
+#endif
+
+ for (i = 0; i < blk_cnt; i++)
+ {
+ // send the request
+ cdb_out_param = (struct scsi_sec_protocol_cdb*) cdb;
+ memset(cdb_out_param, 0, sizeof(struct scsi_sec_protocol_cdb));
+
+ cdb_out_param->opcode = SCSI_CMD_SECPROT_OUT;
+ cdb_out_param->cdb1 = SCSI_SEC_PROT;
+ cdb_out_param->sec_protocol_specific = BE16(SCSI_SEC_UFS_PROT_ID);
+ cdb_out_param->alloc_tlen = BE32(RPMB_FRAME_SIZE);
+
+ // Flush CDB to memory
+ dsb();
+ arch_clean_invalidate_cache_range((addr_t) cdb_out_param, sizeof(struct scsi_sec_protocol_cdb));
+
+ memset(&req_upiu, 0, sizeof(struct scsi_req_build_type));
+
+ req_upiu.cdb = (addr_t) cdb_out_param;
+ req_upiu.data_buffer_addr = (addr_t) req_buf;
+ req_upiu.data_len = RPMB_FRAME_SIZE;
+ req_upiu.flags = UPIU_FLAGS_WRITE;
+ req_upiu.lun = UFS_WLUN_RPMB;
+ req_upiu.dd = UTRD_TARGET_TO_SYSTEM;
+
+#ifdef DEBUG_RPMB
+ dprintf(INFO, "Sending RPMB write request: Start\n");
+#endif
+ if (ucs_do_scsi_cmd(dev, &req_upiu))
+ {
+ dprintf(CRITICAL, "%s:%d ucs_do_scsi_rpmb_read: failed\n", __func__, __LINE__);
+ return -UFS_FAILURE;
+ }
+#ifdef DEBUG_RPMB
+ dprintf(INFO, "Sending RPMB write request: Done\n");
+#endif
+ // Result Read
+ cdb_in_param = (struct scsi_sec_protocol_cdb*) cdb;
+ memset(cdb_in_param, 0, sizeof(struct scsi_sec_protocol_cdb));
+
+ cdb_in_param->opcode = SCSI_CMD_SECPROT_OUT;
+ cdb_in_param->cdb1 = SCSI_SEC_PROT;
+ cdb_in_param->sec_protocol_specific = BE16(SCSI_SEC_UFS_PROT_ID);
+ cdb_in_param->alloc_tlen = BE32(RPMB_FRAME_SIZE);
+
+ // Flush CDB to memory
+ dsb();
+ arch_clean_invalidate_cache_range((addr_t) cdb_in_param, sizeof(struct scsi_sec_protocol_cdb));
+
+ memset(&req_upiu, 0, sizeof(struct scsi_req_build_type));
+
+ req_upiu.cdb = (addr_t) cdb_in_param;
+ req_upiu.data_buffer_addr = (addr_t) &read_result_reg ;
+ req_upiu.data_len = result_frame_bytes;
+ req_upiu.flags = UPIU_FLAGS_WRITE;
+ req_upiu.lun = UFS_WLUN_RPMB;
+ req_upiu.dd = UTRD_TARGET_TO_SYSTEM;
+
+#ifdef DEBUG_RPMB
+ dprintf(INFO, "Sending RPMB Result Read Register: Start \n");
+#endif
+ if (ucs_do_scsi_cmd(dev, &req_upiu))
+ {
+ dprintf(CRITICAL, "%s:%d ucs_do_scsi_rpmb_read: failed\n", __func__, __LINE__);
+ return -UFS_FAILURE;
+ }
+#ifdef DEBUG_RPMB
+ dprintf(SPEW, "Sending RPMB Result Read Register: Done\n");
+#endif
+
+ // Retrieve verification result
+ cdb_in_param = (struct scsi_sec_protocol_cdb*) cdb;
+ memset(cdb_in_param, 0, sizeof(struct scsi_sec_protocol_cdb));
+
+ cdb_in_param->opcode = SCSI_CMD_SECPROT_IN;
+ cdb_in_param->cdb1 = SCSI_SEC_PROT;
+ cdb_in_param->sec_protocol_specific = BE16(SCSI_SEC_UFS_PROT_ID);
+ cdb_in_param->alloc_tlen = BE32(RPMB_FRAME_SIZE);
+
+ // Flush CDB to memory
+ dsb();
+ arch_clean_invalidate_cache_range((addr_t) cdb_in_param, sizeof(struct scsi_sec_protocol_cdb));
+
+ memset(&req_upiu, 0, sizeof(struct scsi_req_build_type));
+
+ req_upiu.cdb = (addr_t) cdb_in_param;
+ req_upiu.data_buffer_addr = (addr_t) resp_buf;
+ req_upiu.data_len = result_frame_bytes;
+ req_upiu.flags = UPIU_FLAGS_READ;
+ req_upiu.lun = UFS_WLUN_RPMB;
+ req_upiu.dd = UTRD_SYSTEM_TO_TARGET;
+
+#ifdef DEBUG_RPMB
+ dprintf(INFO, "Sending RPMB Response for Result Read Register : Start\n");
+#endif
+ if (ucs_do_scsi_cmd(dev, &req_upiu))
+ {
+ dprintf(CRITICAL, "%s:%d ucs_do_scsi_rpmb_read: failed\n", __func__, __LINE__);
+ return -UFS_FAILURE;
+ }
+#ifdef DEBUG_RPMB
+ dprintf(SPEW, "Sending RPMB Response for Result Read Register: Done\n");
+ dump_rpmb_frame((uint8_t *)resp_buf, "response");
+#endif
+
+ req_buf = (uint32_t*) ((uint8_t*)req_buf + RPMB_BLK_SIZE);
+ }
+
+ *resp_len = RPMB_MIN_BLK_CNT * RPMB_BLK_SIZE;
+
+ return 0;
+}
diff --git a/platform/msm_shared/rpmb/rules.mk b/platform/msm_shared/rpmb/rules.mk
new file mode 100644
index 0000000..0e76433
--- /dev/null
+++ b/platform/msm_shared/rpmb/rules.mk
@@ -0,0 +1,8 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+INCLUDES += -I$(LOCAL_DIR)/include
+
+OBJS += $(LOCAL_DIR)/rpmb.o \
+ $(LOCAL_DIR)/rpmb_listener.o \
+ $(LOCAL_DIR)/rpmb_emmc.o \
+ $(LOCAL_DIR)/rpmb_ufs.o
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
old mode 100755
new mode 100644
index 793b88c..fe90e5d
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -23,6 +23,7 @@
ifeq ($(ENABLE_SMD_SUPPORT),1)
OBJS += \
+ $(LOCAL_DIR)/rpm-ipc.o \
$(LOCAL_DIR)/rpm-smd.o \
$(LOCAL_DIR)/smd.o
endif
@@ -43,6 +44,21 @@
$(LOCAL_DIR)/boot_verifier.o
endif
+ifeq ($(ENABLE_GLINK_SUPPORT),1)
+OBJS += \
+ $(LOCAL_DIR)/rpm-ipc.o \
+ $(LOCAL_DIR)/glink/glink_api.o \
+ $(LOCAL_DIR)/glink/glink_core_if.o \
+ $(LOCAL_DIR)/glink/glink_rpmcore_setup.o \
+ $(LOCAL_DIR)/glink/glink_core_intentless_xport.o \
+ $(LOCAL_DIR)/glink/glink_os_utils_dal.o \
+ $(LOCAL_DIR)/glink/glink_vector.o \
+ $(LOCAL_DIR)/glink/xport_rpm.o \
+ $(LOCAL_DIR)/glink/xport_rpm_config.o \
+ $(LOCAL_DIR)/smem_list.o \
+ $(LOCAL_DIR)/rpm-glink.o
+endif
+
ifeq ($(PLATFORM),msm8x60)
OBJS += $(LOCAL_DIR)/mipi_dsi.o \
$(LOCAL_DIR)/i2c_qup.o \
@@ -483,7 +499,7 @@
$(LOCAL_DIR)/mipi_dsi_autopll.o
endif
-ifeq ($(PLATFORM),thulium)
+ifeq ($(PLATFORM),msm8996)
OBJS += $(LOCAL_DIR)/qtimer.o \
$(LOCAL_DIR)/qtimer_mmap.o \
$(LOCAL_DIR)/interrupts.o \
@@ -498,6 +514,7 @@
$(LOCAL_DIR)/dev_tree.o \
$(LOCAL_DIR)/gpio.o \
$(LOCAL_DIR)/scm.o \
+ $(LOCAL_DIR)/qseecom_lk.o \
$(LOCAL_DIR)/qmp_usb30_phy.o \
$(LOCAL_DIR)/qusb2_phy.o \
$(LOCAL_DIR)/certificate.o \
@@ -517,6 +534,31 @@
$(LOCAL_DIR)/dme.o
endif
+ifeq ($(PLATFORM),msm8952)
+ OBJS += $(LOCAL_DIR)/qgic.o \
+ $(LOCAL_DIR)/qtimer.o \
+ $(LOCAL_DIR)/qtimer_mmap.o \
+ $(LOCAL_DIR)/interrupts.o \
+ $(LOCAL_DIR)/clock.o \
+ $(LOCAL_DIR)/clock_pll.o \
+ $(LOCAL_DIR)/clock_lib2.o \
+ $(LOCAL_DIR)/uart_dm.o \
+ $(LOCAL_DIR)/board.o \
+ $(LOCAL_DIR)/spmi.o \
+ $(LOCAL_DIR)/bam.o \
+ $(LOCAL_DIR)/qpic_nand.o \
+ $(LOCAL_DIR)/scm.o \
+ $(LOCAL_DIR)/dev_tree.o \
+ $(LOCAL_DIR)/gpio.o \
+ $(LOCAL_DIR)/dload_util.o \
+ $(LOCAL_DIR)/shutdown_detect.o \
+ $(LOCAL_DIR)/certificate.o \
+ $(LOCAL_DIR)/image_verify.o \
+ $(LOCAL_DIR)/crypto_hash.o \
+ $(LOCAL_DIR)/crypto5_eng.o \
+ $(LOCAL_DIR)/crypto5_wrapper.o
+endif
+
ifeq ($(ENABLE_BOOT_CONFIG_SUPPORT), 1)
OBJS += \
$(LOCAL_DIR)/boot_device.o
@@ -533,3 +575,11 @@
ifeq ($(ENABLE_PARTIAL_GOODS_SUPPORT), 1)
OBJS += $(LOCAL_DIR)/partial_goods.o
endif
+
+ifeq ($(ENABLE_RPMB_SUPPORT), 1)
+include platform/msm_shared/rpmb/rules.mk
+endif
+
+ifeq ($(ENABLE_REBOOT_MODULE), 1)
+ OBJS += $(LOCAL_DIR)/reboot.o
+endif
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
index b45fd3d..88e6898 100644
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -34,6 +34,8 @@
#include <arch/ops.h>
#include <rand.h>
#include <image_verify.h>
+#include <dload_util.h>
+#include <platform/iomap.h>
#include "scm.h"
#pragma GCC optimize ("O0")
@@ -54,6 +56,12 @@
/* SCM interface as per ARM spec present? */
bool scm_arm_support;
+static uint32_t scm_io_write(uint32_t address, uint32_t val);
+
+bool is_scm_armv8_support()
+{
+ return scm_arm_support;
+}
static void scm_arm_support_available(uint32_t svc_id, uint32_t cmd_id)
{
@@ -958,14 +966,29 @@
int scm_halt_pmic_arbiter()
{
int ret = 0;
+ scmcall_arg scm_arg = {0};
- if (scm_arm_support)
- {
- dprintf(INFO, "%s:SCM call is not supported\n",__func__);
- return -1;
+ if (scm_arm_support) {
+ scm_arg.x0 = MAKE_SIP_SCM_CMD(SCM_SVC_PWR, SCM_IO_DISABLE_PMIC_ARBITER);
+ scm_arg.x1 = MAKE_SCM_ARGS(0x1);
+ scm_arg.x2 = 0;
+ scm_arg.atomic = true;
+ ret = scm_call2(&scm_arg, NULL);
+ } else {
+ ret = scm_call_atomic(SCM_SVC_PWR, SCM_IO_DISABLE_PMIC_ARBITER, 0);
}
- ret = scm_call_atomic(SCM_SVC_PWR, SCM_IO_DISABLE_PMIC_ARBITER, 0);
+ /* Retry with the SCM_IO_DISABLE_PMIC_ARBITER1 func ID if the above Func ID fails*/
+ if(ret) {
+ if (scm_arm_support) {
+ scm_arg.x0 = MAKE_SIP_SCM_CMD(SCM_SVC_PWR, SCM_IO_DISABLE_PMIC_ARBITER1);
+ scm_arg.x1 = MAKE_SCM_ARGS(0x1);
+ scm_arg.x2 = 0;
+ scm_arg.atomic = true;
+ ret = scm_call2(&scm_arg, NULL);
+ } else
+ ret = scm_call_atomic(SCM_SVC_PWR, SCM_IO_DISABLE_PMIC_ARBITER1, 0);
+ }
return ret;
}
@@ -1117,20 +1140,22 @@
register uint32_t r4 __asm__("r4") = x4;
register uint32_t r5 __asm__("r5") = x5;
- __asm__ volatile(
- __asmeq("%0", "r0")
- __asmeq("%1", "r1")
- __asmeq("%2", "r2")
- __asmeq("%3", "r3")
- __asmeq("%4", "r0")
- __asmeq("%5", "r1")
- __asmeq("%6", "r2")
- __asmeq("%7", "r3")
- __asmeq("%8", "r4")
- __asmeq("%9", "r5")
- "smc #0 @ switch to secure world\n"
- : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
- : "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4), "r" (r5));
+ do {
+ __asm__ volatile(
+ __asmeq("%0", "r0")
+ __asmeq("%1", "r1")
+ __asmeq("%2", "r2")
+ __asmeq("%3", "r3")
+ __asmeq("%4", "r0")
+ __asmeq("%5", "r1")
+ __asmeq("%6", "r2")
+ __asmeq("%7", "r3")
+ __asmeq("%8", "r4")
+ __asmeq("%9", "r5")
+ "smc #0 @ switch to secure world\n"
+ : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
+ : "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4), "r" (r5));
+ } while(r0 == 1);
if (ret)
{
@@ -1178,3 +1203,133 @@
return 0;
}
+
+static bool secure_boot_enabled = true;
+static bool wdog_debug_fuse_disabled = true;
+
+void scm_check_boot_fuses()
+{
+ uint32_t ret = 0;
+ uint32_t resp;
+ scmcall_arg scm_arg = {0};
+ scmcall_ret scm_ret = {0};
+
+ if (!scm_arm_support) {
+ ret = scm_call(TZBSP_SVC_INFO, IS_SECURE_BOOT_ENABLED, NULL, 0, &resp, sizeof(resp));
+ } else {
+ scm_arg.x0 = MAKE_SIP_SCM_CMD(TZBSP_SVC_INFO, IS_SECURE_BOOT_ENABLED);
+ ret = scm_call2(&scm_arg, &scm_ret);
+ resp = scm_ret.x1;
+ }
+
+ /* Parse Bit 0 and Bit 2 of the response */
+ if(!ret) {
+ /* Bit 0 - SECBOOT_ENABLE_CHECK */
+ if(resp & 0x1)
+ secure_boot_enabled = false;
+ /* Bit 2 - DEBUG_DISABLE_CHECK */
+ if(resp & 0x4)
+ wdog_debug_fuse_disabled = false;
+ } else
+ dprintf(CRITICAL, "scm call to check secure boot fuses failed\n");
+}
+
+bool is_secure_boot_enable()
+{
+ scm_check_boot_fuses();
+ return secure_boot_enabled;
+}
+
+static uint32_t scm_io_read(addr_t address)
+{
+ uint32_t ret;
+ scmcall_arg scm_arg = {0};
+ scmcall_ret scm_ret = {0};
+
+ if (!scm_arm_support) {
+ ret = scm_call_atomic(SCM_SVC_IO, SCM_IO_READ, address);
+ } else {
+ scm_arg.x0 = MAKE_SIP_SCM_CMD(SCM_SVC_IO, SCM_IO_READ);
+ scm_arg.x1 = MAKE_SCM_ARGS(0x1);
+ scm_arg.x2 = address;
+ scm_arg.atomic = true;
+ ret = scm_call2(&scm_arg, &scm_ret);
+ }
+ return ret;
+}
+
+static uint32_t scm_io_write(uint32_t address, uint32_t val)
+{
+ uint32_t ret;
+ scmcall_arg scm_arg = {0};
+ scmcall_ret scm_ret = {0};
+
+ if (!scm_arm_support) {
+ ret = scm_call_atomic2(SCM_SVC_IO, SCM_IO_WRITE, address, val);
+ } else {
+ scm_arg.x0 = MAKE_SIP_SCM_CMD(SCM_SVC_IO, SCM_IO_WRITE);
+ scm_arg.x1 = MAKE_SCM_ARGS(0x2);
+ scm_arg.x2 = address;
+ scm_arg.x3 = val;
+ scm_arg.atomic = true;
+ ret = scm_call2(&scm_arg, &scm_ret);
+ }
+ return ret;
+}
+
+static int scm_call2_atomic(uint32_t svc, uint32_t cmd, uint32_t arg1, uint32_t arg2)
+{
+ uint32_t ret = 0;
+ scmcall_arg scm_arg = {0};
+ scmcall_ret scm_ret = {0};
+
+ if (!scm_arm_support)
+ {
+ ret = scm_call_atomic2(svc, cmd, arg1, arg2);
+ } else {
+ scm_arg.x0 = MAKE_SIP_SCM_CMD(svc, cmd);
+ scm_arg.x1 = MAKE_SCM_ARGS(0x2);
+ scm_arg.x2 = arg1;
+ scm_arg.x3 = arg2;
+ ret = scm_call2(&scm_arg, &scm_ret);
+ }
+ return ret;
+}
+
+#if PLATFORM_USE_SCM_DLOAD
+int scm_dload_mode(int mode)
+{
+ int ret = 0;
+ uint32_t dload_type;
+
+ dprintf(SPEW, "DLOAD mode: %d\n", mode);
+ if (mode == NORMAL_DLOAD)
+ dload_type = SCM_DLOAD_MODE;
+ else if(mode == EMERGENCY_DLOAD)
+ dload_type = SCM_EDLOAD_MODE;
+ else
+ dload_type = 0;
+
+ /* Write to the Boot MISC register */
+ ret = scm_call2_atomic(SCM_SVC_BOOT, SCM_DLOAD_CMD, dload_type, 0);
+
+ if (ret) {
+ ret = scm_io_write(TCSR_BOOT_MISC_DETECT,dload_type);
+ if(ret) {
+ dprintf(CRITICAL, "Failed to write to boot misc: %d\n", ret);
+ return ret;
+ }
+ }
+
+ scm_check_boot_fuses();
+
+ /* Make WDOG_DEBUG DISABLE scm call only in non-secure boot */
+ if(!(secure_boot_enabled || wdog_debug_fuse_disabled)) {
+ ret = scm_call2_atomic(SCM_SVC_BOOT, WDOG_DEBUG_DISABLE, 1, 0);
+ if(ret)
+ dprintf(CRITICAL, "Failed to disable the wdog debug \n");
+ }
+
+ return ret;
+}
+#endif
diff --git a/platform/msm_shared/sdhci_msm.c b/platform/msm_shared/sdhci_msm.c
index 4e83a55..47bdfd1 100644
--- a/platform/msm_shared/sdhci_msm.c
+++ b/platform/msm_shared/sdhci_msm.c
@@ -42,6 +42,7 @@
#define MX_DRV_SUPPORTED_HS200 3
+static bool attempt_cdr_unlock;
/* Known data stored in the card & read during tuning
* process. 64 bytes for 4bit bus width & 128 bytes
@@ -336,7 +337,7 @@
msm_set_dll_freq(host);
/* Configure the mclk freq based on the current clock rate
- * and fll cycle count as per hpg section 15.2.2
+ * and fll cycle count
*/
if (host->major == 1 && host->minor >= 0x42)
{
@@ -720,15 +721,6 @@
/* In Tuning mode */
host->tuning_in_progress = true;
- /* Calibration for CDCLP533 needed for HS400 mode */
- if (msm_host->tuning_done && !msm_host->calibration_done && host->timing == MMC_HS400_TIMING)
- {
- ret = sdhci_msm_hs400_calibration(host);
- if (!ret)
- msm_host->calibration_done = true;
- goto out;
- }
-
if (bus_width == DATA_BUS_WIDTH_8BIT)
{
tuning_block = (uint32_t *)tuning_block_128;
@@ -744,26 +736,34 @@
ASSERT(tuning_data);
+ /* Calibration for CDCLP533 needed for HS400 mode */
+ if (msm_host->tuning_done && !msm_host->calibration_done && host->timing == MMC_HS400_TIMING)
+ {
+ ret = sdhci_msm_hs400_calibration(host);
+ if (!ret)
+ msm_host->calibration_done = true;
+ goto out;
+ }
+
/* Reset & Initialize the DLL block */
if (sdhci_msm_init_dll(host))
{
ret = 1;
- goto free;
+ goto out;
}
retry_tuning:
tuned_phase_cnt = 0;
phase = 0;
+ struct mmc_command cmd = {0};
while (phase < MAX_PHASES)
{
- struct mmc_command cmd = {0};
-
/* configure dll to set phase delay */
if (sdhci_msm_config_dll(host, phase))
{
ret = 1;
- goto free;
+ goto out;
}
cmd.cmd_index = CMD21_SEND_TUNING_BLOCK;
@@ -802,6 +802,12 @@
if (drv_type_changed)
mmc_set_drv_type(host, card, 0);
+ if (tuned_phase_cnt == MAX_PHASES)
+ {
+ attempt_cdr_unlock = true;
+ dprintf(CRITICAL, "WARNING: All phase passed.The selected phase may not be optimal\n");
+ }
+
/* Find the appropriate tuned phase */
if (tuned_phase_cnt)
{
@@ -817,7 +823,7 @@
{
dprintf(CRITICAL, "Failed in selecting the tuning phase\n");
ret = 1;
- goto free;
+ goto out;
}
phase = (uint32_t) ret;
@@ -826,7 +832,7 @@
DBG("\n: %s: Tuned Phase: 0x%08x\n", __func__, phase);
if (sdhci_msm_config_dll(host, phase))
- goto free;
+ goto out;
/* Save the tuned phase */
host->msm_host->saved_phase = phase;
@@ -837,9 +843,30 @@
ret = 1;
}
-free:
- free(tuning_data);
out:
+ /* If all the tuning phases passed, send CMD21 after enabling
+ * CDR to make sure right tuning phase is selected by CDR
+ */
+ if (attempt_cdr_unlock)
+ {
+ cmd.cmd_index = CMD21_SEND_TUNING_BLOCK;
+ cmd.argument = 0x0;
+ cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
+ cmd.resp_type = SDHCI_CMD_RESP_R1;
+ cmd.trans_mode = SDHCI_MMC_READ;
+ cmd.data_present = 0x1;
+ cmd.data.data_ptr = tuning_data;
+ cmd.data.blk_sz = size;
+ cmd.data.num_blocks = 0x1;
+
+ /* send command */
+ if (!sdhci_send_command(host, &cmd))
+ {
+ DBG("\n: %s: Sending CMD21 after CDR enable with default phases fail\n", __func__);
+ }
+ }
+
+ free(tuning_data);
/* Tuning done */
host->tuning_in_progress = false;
host->msm_host->tuning_done = true;
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index db186d4..3468435 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -54,6 +54,7 @@
{
SMEM_RAM_PTABLE_VERSION_0,
SMEM_RAM_PTABLE_VERSION_1,
+ SMEM_RAM_PTABLE_VERSION_2,
};
struct smem_proc_comm {
@@ -400,14 +401,15 @@
MDM9609 = 262,
MSM8239 = 263,
APQ8009 = 265,
- MSMTELLURIUM = 264,
- MSMTERBIUM = 266,
+ MSM8952 = 264,
+ MSM8956 = 266,
MSM8929 = 268,
MSM8629 = 269,
MSM8229 = 270,
APQ8029 = 271,
MSM8609 = 275,
FSM9916 = 276,
+ MSM8976 = 278,
};
enum platform {
@@ -549,6 +551,20 @@
uint32_t reserved5; /* Reserved for future use */
} __attribute__ ((__packed__));
+struct smem_ram_ptn_v2 {
+ char name[RAM_PART_NAME_LENGTH];
+ uint64_t start;
+ uint64_t size;
+ uint32_t attr; /* RAM Partition attribute: READ_ONLY, READWRITE etc.*/
+ uint32_t category; /* RAM Partition category: EBI0, EBI1, IRAM, IMEM */
+ uint32_t domain; /* RAM Partition domain: APPS, MODEM, APPS & MODEM (SHARED) etc. */
+ uint32_t type; /* RAM Partition type: system, bootloader, appsboot, apps etc. */
+ uint32_t num_partitions;/* Number of memory partitions */
+ uint32_t hw_info; /* hw information such as type and frequency */
+ uint64_t reserved; /* Reserved for future use */
+ uint64_t available_length; /* Available partition length in RAM in bytes */
+} __attribute__ ((__packed__));
+
struct smem_ram_ptable {
unsigned magic[2];
unsigned version;
@@ -572,6 +588,12 @@
struct smem_ram_ptn_v1 parts[RAM_NUM_PART_ENTRIES];
} __attribute__ ((__packed__));
+struct smem_ram_ptable_v2 {
+ struct smem_ram_ptable_hdr hdr;
+ uint32_t reserved2; /* Added for 8 bytes alignment of header */
+ struct smem_ram_ptn_v2 parts[RAM_NUM_PART_ENTRIES];
+} __attribute__ ((__packed__));
+
/* Power on reason/status info */
#define PWR_ON_EVENT_RTC_ALARM 0x2
#define PWR_ON_EVENT_USB_CHG 0x20
@@ -600,8 +622,8 @@
struct smem_ptn parts[SMEM_PTABLE_MAX_PARTS];
} __attribute__ ((__packed__));
-typedef struct smem_ram_ptable_v1 ram_partition_table;
-typedef struct smem_ram_ptn_v1 ram_partition;
+typedef struct smem_ram_ptable_v2 ram_partition_table;
+typedef struct smem_ram_ptn_v2 ram_partition;
unsigned smem_read_alloc_entry_offset(smem_mem_type_t type, void *buf, int len, int offset);
int smem_ram_ptable_init(struct smem_ram_ptable *smem_ram_ptable);
@@ -610,4 +632,5 @@
uint32_t smem_get_ram_ptable_version(void);
uint32_t smem_get_ram_ptable_len(void);
void* smem_get_alloc_entry(smem_mem_type_t type, uint32_t* size);
+uint32_t get_ddr_start();
#endif /* __PLATFORM_MSM_SHARED_SMEM_H */
diff --git a/platform/msm_shared/smem_list.c b/platform/msm_shared/smem_list.c
new file mode 100644
index 0000000..fc89671
--- /dev/null
+++ b/platform/msm_shared/smem_list.c
@@ -0,0 +1,242 @@
+/* Copyright (c) 2015, 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.
+*/
+
+/*===========================================================================
+
+ S H A R E D M E M O R Y
+
+===========================================================================*/
+
+
+
+/*===========================================================================
+
+ INCLUDE FILES
+
+===========================================================================*/
+#include "smem_list.h"
+#include <sys/types.h>
+
+/*=============================================================================
+
+ GLOBAL DEFINITIONS AND DECLARATIONS FOR MODULE
+
+=============================================================================*/
+
+
+/*===========================================================================
+
+ PRIVATE FUNCTION DECLARATIONS
+
+===========================================================================*/
+
+/*===========================================================================
+FUNCTION smem_list_init
+===========================================================================*/
+/**
+ Creates a generic list.
+
+ @param[in/out] list Pointer to the user list.
+
+ @return
+ N/A.
+
+ @dependencies
+ List must be protected by critical sections for multi-threaded use.
+
+ @sideeffects
+ None.
+*/
+/*=========================================================================*/
+void smem_list_init( smem_list_type *list )
+{
+ list->next = NULL;
+ list->count = 0;
+}
+
+/*===========================================================================
+FUNCTION smem_list_append
+===========================================================================*/
+/**
+ Appends an element to the end of a generic list.
+
+ The element must contain a smem_list_link_type at its base address.
+ The element should not be already present in any list.
+
+ @param[in/out] list Pointer to the user list.
+ @param[in] item Element to be inserted.
+
+ @return
+ N/A.
+
+ @dependencies
+ The element must contain a smem_list_link_type at its base address.
+ List must be protected by critical sections for multi-threaded use.
+
+ @sideeffects
+ None.
+*/
+/*=========================================================================*/
+void smem_list_append( smem_list_type *list, void *item )
+{
+ smem_list_link_type *link = ( smem_list_link_type * )list;
+
+ /* get next item until link->next points to null */
+ while( link->next )
+ {
+ link = link->next;
+ }
+
+ /* link->next points to null here, but we can point it to the new item */
+ link->next = item;
+
+ /* point link to the head of the new item */
+ link = item;
+
+ /* terminate the list */
+ link->next = NULL;
+
+ list->count++;
+}
+
+/*===========================================================================
+FUNCTION smem_list_delete
+===========================================================================*/
+/**
+ Removes the specified element from a generic list.
+
+ The element may be present at any point in the list.
+
+ @param[in] list Pointer to the user list.
+ @param[in] item Element to be removed.
+
+ @return
+ 0 if the element is deleted, or a negative error code if the element
+ is not found.
+
+ @dependencies
+ List must be protected by critical sections for multi-threaded use.
+
+ @sideeffects
+ None.
+*/
+/*=========================================================================*/
+long smem_list_delete( smem_list_type *list, void *item )
+{
+ smem_list_link_type *link = ( smem_list_link_type * )list;
+
+ /* get next item until link points to item in question */
+ while( link->next != item )
+ {
+ if( NULL == link->next )
+ {
+ return -1;
+ }
+
+ link = link->next;
+ }
+
+ link->next = ( ( smem_list_link_type * )item )->next;
+
+ list->count--;
+
+ return 0;
+}
+
+/*===========================================================================
+FUNCTION smem_list_first
+===========================================================================*/
+/**
+ Retrieves the first element in the list without removing it.
+
+ @param[in] list Pointer to the user list.
+
+ @return
+ Pointer to the first element in the list.
+
+ @dependencies
+ List must be protected by critical sections for multi-threaded use.
+
+ @sideeffects
+ None.
+*/
+/*=========================================================================*/
+void *smem_list_first( smem_list_type *list )
+{
+ /* return the first item in the list */
+ return list->next;
+}
+
+/*===========================================================================
+FUNCTION smem_list_next
+===========================================================================*/
+/**
+ Retrieves the next element in the list.
+
+ @param[in] list Pointer to the user list.
+
+ @return
+ Pointer to the next element in the list.
+
+ @dependencies
+ List must be protected by critical sections for multi-threaded use.
+
+ @sideeffects
+ None.
+*/
+/*=========================================================================*/
+void *smem_list_next( void * item )
+{
+ /* just return the item that this item points to
+ * (base address contains a pointer) */
+ return ( ( smem_list_link_type * )item )->next;
+}
+
+/*===========================================================================
+FUNCTION smem_list_count
+===========================================================================*/
+/**
+ Gets the number of elements in the list.
+
+ @param[in] list Pointer to the user list.
+
+ @return
+ Count of elements in the list.
+
+ @dependencies
+ List must be protected by critical sections for multi-threaded use.
+
+ @sideeffects
+ None.
+*/
+/*=========================================================================*/
+long smem_list_count( smem_list_type *list )
+{
+ return list->count;
+}
+
diff --git a/platform/msm_shared/smem_ptable.c b/platform/msm_shared/smem_ptable.c
index fd27e10..b573cc8 100644
--- a/platform/msm_shared/smem_ptable.c
+++ b/platform/msm_shared/smem_ptable.c
@@ -2,7 +2,7 @@
* Copyright (c) 2009, Google Inc.
* All rights reserved.
*
- * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2012,2015 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
@@ -35,6 +35,7 @@
#include <platform/iomap.h>
#include <lib/ptable.h>
+#include "board.h"
#include "smem.h"
@@ -154,18 +155,34 @@
static void smem_copy_ram_ptable(void *buf)
{
- struct smem_ram_ptable *table_v0;
- struct smem_ram_ptable_v1 *table_v1;
+ struct smem_ram_ptable *table_v0 = NULL;
+ struct smem_ram_ptable_v1 *table_v1 = NULL;
+ struct smem_ram_ptable_v2 *table_v2 = NULL;
uint32_t pentry = 0;
ptable.hdr = *(struct smem_ram_ptable_hdr*)buf;
/* Perform member to member copy from smem_ram_ptable to wrapper struct ram_ptable */
- if(ptable.hdr.version == SMEM_RAM_PTABLE_VERSION_1)
+ if(ptable.hdr.version == SMEM_RAM_PTABLE_VERSION_2)
+ {
+ table_v2 = (struct smem_ram_ptable_v2*)buf;
+
+ memcpy(&ptable, table_v2, sizeof(ram_partition_table));
+ }
+ else if(ptable.hdr.version == SMEM_RAM_PTABLE_VERSION_1)
{
table_v1 = (struct smem_ram_ptable_v1*)buf;
- memcpy(&ptable, table_v1, sizeof(ram_partition_table));
+ for(pentry = 0; pentry < ((struct smem_ram_ptable_hdr*)buf)->len; pentry++)
+ {
+ ptable.parts[pentry].start = table_v1->parts[pentry].start;
+ ptable.parts[pentry].size = table_v1->parts[pentry].size;
+ ptable.parts[pentry].attr = table_v1->parts[pentry].attr;
+ ptable.parts[pentry].category = table_v1->parts[pentry].category;
+ ptable.parts[pentry].domain = table_v1->parts[pentry].domain;
+ ptable.parts[pentry].type = table_v1->parts[pentry].type;
+ ptable.parts[pentry].num_partitions = table_v1->parts[pentry].num_partitions;
+ }
}
else if(ptable.hdr.version == SMEM_RAM_PTABLE_VERSION_0)
{
@@ -214,7 +231,7 @@
}
/* RAM Partition table from SMEM */
-static uint32_t buffer[sizeof(struct smem_ram_ptable_v1)];
+static uint32_t buffer[sizeof(struct smem_ram_ptable_v2)];
int smem_ram_ptable_init_v1()
{
uint32_t i;
@@ -232,7 +249,9 @@
if(ret)
return 0;
- if(version == SMEM_RAM_PTABLE_VERSION_1)
+ if(version == SMEM_RAM_PTABLE_VERSION_2)
+ smem_ram_ptable_size = sizeof(struct smem_ram_ptable_v2);
+ else if(version == SMEM_RAM_PTABLE_VERSION_1)
smem_ram_ptable_size = sizeof(struct smem_ram_ptable_v1);
else if(version == SMEM_RAM_PTABLE_VERSION_0)
smem_ram_ptable_size = sizeof(struct smem_ram_ptable);
@@ -276,3 +295,32 @@
{
return ptable.hdr.version;
}
+
+uint32_t get_ddr_start()
+{
+ uint32_t i;
+ ram_partition ptn_entry;
+ uint32_t len = 0;
+
+ ASSERT(smem_ram_ptable_init_v1());
+
+ len = smem_get_ram_ptable_len();
+
+ /* Determine the Start addr of the DDR RAM */
+ for(i = 0; i < len; i++)
+ {
+ smem_get_ram_ptable_entry(&ptn_entry, i);
+ if(ptn_entry.type == SYS_MEMORY)
+ {
+ if((ptn_entry.category == SDRAM) ||
+ (ptn_entry.category == IMEM))
+ {
+ /* Check to ensure that start address is 1MB aligned */
+ ASSERT((ptn_entry.start & (MB-1)) == 0);
+ return ptn_entry.start;
+ }
+ }
+ }
+ ASSERT("DDR Start Mem Not found\n");
+ return 0;
+}
diff --git a/platform/msm_shared/spmi.c b/platform/msm_shared/spmi.c
index d82fbb9..7408a9d 100644
--- a/platform/msm_shared/spmi.c
+++ b/platform/msm_shared/spmi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, 2014-2015, 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
@@ -34,6 +34,7 @@
#include <platform/irqs.h>
#include <platform/interrupts.h>
#include <malloc.h>
+#include <platform.h>
#define PMIC_ARB_V2 0x20010000
#define CHNL_IDX(sid, pid) ((sid << 8) | pid)
@@ -44,10 +45,11 @@
static spmi_callback callback;
static uint32_t pmic_arb_ver;
static uint8_t *chnl_tbl;
+static uint32_t max_peripherals;
static void spmi_lookup_chnl_number()
{
- int i;
+ uint32_t i;
uint8_t slave_id = 0;
uint8_t ppid_address = 0;
/* We need a max of sid (4 bits) + pid (8bits) of uint8_t's */
@@ -57,7 +59,7 @@
chnl_tbl = (uint8_t *) malloc(chnl_tbl_sz);
ASSERT(chnl_tbl);
- for(i = 0; i < MAX_PERIPH ; i++)
+ for(i = 0; i < max_peripherals; i++)
{
#if SPMI_CORE_V2
slave_id = (readl(PMIC_ARB_REG_CHLN(i)) & 0xf0000) >> 16;
@@ -74,6 +76,7 @@
{
/* Read the version numver */
pmic_arb_ver = readl(PMIC_ARB_SPMI_HW_VERSION);
+ max_peripherals = platform_get_max_periph();
if (pmic_arb_ver < PMIC_ARB_V2)
{
diff --git a/platform/msm_shared/ucs.c b/platform/msm_shared/ucs.c
index f820734..a1ab6f3 100644
--- a/platform/msm_shared/ucs.c
+++ b/platform/msm_shared/ucs.c
@@ -31,8 +31,7 @@
#include <endian.h>
#include <string.h>
#include <utp.h>
-
-static int ucs_do_request_sense(struct ufs_dev *dev);
+#include <rpmb.h>
int ucs_do_scsi_cmd(struct ufs_dev *dev, struct scsi_req_build_type *req)
{
@@ -394,6 +393,7 @@
/* Flush cdb to memory. */
dsb();
arch_invalidate_cache_range((addr_t) cdb_param, SCSI_CDB_PARAM_LEN);
+ arch_invalidate_cache_range((addr_t) param, sizeof(struct unmap_param_list));
memset((void*)&req_upiu, 0 , sizeof(struct scsi_req_build_type));
@@ -463,7 +463,7 @@
dprintf(CRITICAL,"----end of buffer---\n");
}
-static int ucs_do_request_sense(struct ufs_dev *dev)
+int ucs_do_request_sense(struct ufs_dev *dev, uint8_t lun)
{
STACKBUF_DMA_ALIGN(cdb, sizeof(struct scsi_sense_cdb));
struct scsi_req_build_type req_upiu;
@@ -487,7 +487,7 @@
req_upiu.data_buffer_addr = (addr_t) buf;
req_upiu.data_len = SCSI_SENSE_BUF_LEN;
req_upiu.flags = UPIU_FLAGS_READ;
- req_upiu.lun = 0;
+ req_upiu.lun = lun;
req_upiu.dd = UTRD_TARGET_TO_SYSTEM;
if (ucs_do_scsi_cmd(dev, &req_upiu))
@@ -499,7 +499,9 @@
/* Flush buffer. */
arch_invalidate_cache_range((addr_t) buf, SCSI_INQUIRY_LEN);
+#if DEBUG_UFS
dump_sense_buffer(buf, SCSI_SENSE_BUF_LEN);
+#endif
return UFS_SUCCESS;
}
diff --git a/platform/msm_shared/ufs.c b/platform/msm_shared/ufs.c
index 0bb7eb5..d3b7065 100644
--- a/platform/msm_shared/ufs.c
+++ b/platform/msm_shared/ufs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -89,10 +89,17 @@
qgic_change_interrupt_cfg(UFS_IRQ, INTERRUPT_LVL_N_TO_N);
}
-static void ufs_rpmb_init(struct ufs_dev *dev)
+void ufs_rpmb_init(struct ufs_dev *dev)
{
int ret = 0;
+ /*
+ * Perform request sense on lun to clear
+ * attention pending, other wise all the read/write
+ * operations would fail with check condition error
+ */
+ ucs_do_request_sense(dev, UFS_WLUN_RPMB);
+
// calculate the size of rpmb partition in sectors
ret = dme_read_unit_desc(dev, UFS_WLUN_RPMB);
if (ret != UFS_SUCCESS)
@@ -167,13 +174,8 @@
if(ret)
{
dprintf(CRITICAL, "UFS erase failed \n");
- return ret;
}
- ret = dme_set_fpurgeenable((struct ufs_dev *)dev);
- if (ret)
- {
- dprintf(CRITICAL, "UFS purge operation failed after erase\n");
- }
+
return ret;
}
diff --git a/platform/msm_shared/usb30_dwc.c b/platform/msm_shared/usb30_dwc.c
index 6f419cd..5ae8801 100644
--- a/platform/msm_shared/usb30_dwc.c
+++ b/platform/msm_shared/usb30_dwc.c
@@ -1730,7 +1730,7 @@
ep->bytes_queued = 0;
- if (ep->type == EP_TYPE_CONTROL)
+ if (ep->type == EP_TYPE_CONTROL || ep->type == EP_TYPE_INTERRUPT)
{
memset(trb, 0, sizeof(dwc_trb_t));
diff --git a/platform/msm_shared/usb30_dwc.h b/platform/msm_shared/usb30_dwc.h
index 1a69a61..14402e7 100644
--- a/platform/msm_shared/usb30_dwc.h
+++ b/platform/msm_shared/usb30_dwc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 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
@@ -379,7 +379,7 @@
} dwc_notify_event_t;
/* maximum number of endpoints supported. */
-#define DWC_MAX_NUM_OF_EP 4
+#define DWC_MAX_NUM_OF_EP 8
/* length of setup packet */
#define DWC_SETUP_PKT_LEN 8
diff --git a/platform/msm_shared/usb30_udc.c b/platform/msm_shared/usb30_udc.c
index 0e5e1b0..d9d18a2 100644
--- a/platform/msm_shared/usb30_udc.c
+++ b/platform/msm_shared/usb30_udc.c
@@ -559,7 +559,7 @@
ep->number = ept->num;
ep->dir = ept->in;
- ep->type = EP_TYPE_BULK; /* the only one supported */
+ ep->type = ept->type;
ep->max_pkt_size = ept->maxpkt;
ep->burst_size = ept->maxburst;
ep->zlp = 0; /* TODO: zlp could be made part of ept */
@@ -848,6 +848,7 @@
static struct udc_endpoint *_udc_endpoint_alloc(uint8_t num,
uint8_t in,
+ uint8_t type,
uint16_t max_pkt)
{
struct udc_endpoint *ept;
@@ -858,6 +859,7 @@
ept->maxpkt = max_pkt;
ept->num = num;
+ ept->type = type;
ept->in = !!in;
ept->maxburst = 4; /* no performance improvement is seen beyond burst size of 4 */
ept->trb_count = 66; /* each trb can transfer (16MB - 1). 65 for 1GB transfer + 1 for roundup/zero length pkt. */
@@ -881,8 +883,16 @@
if (type == UDC_TYPE_BULK_IN) {
in = 1;
+ type = EP_TYPE_BULK;
} else if (type == UDC_TYPE_BULK_OUT) {
in = 0;
+ type = EP_TYPE_BULK;
+ } else if (type == UDC_TYPE_INTR_IN) {
+ in = 1;
+ type = EP_TYPE_INTERRUPT;
+ } else if (type == UDC_TYPE_INTR_OUT){
+ in = 0;
+ type = EP_TYPE_INTERRUPT;
} else {
return 0;
}
@@ -891,7 +901,7 @@
uint32_t bit = in ? EPT_TX(n) : EPT_RX(n);
if (udc->ept_alloc_table & bit)
continue;
- ept = _udc_endpoint_alloc(n, in, maxpkt);
+ ept = _udc_endpoint_alloc(n, in, type, maxpkt);
if (ept)
udc->ept_alloc_table |= bit;
return ept;
diff --git a/platform/msm_shared/usb30_udc.h b/platform/msm_shared/usb30_udc.h
index 02e86fa..97ef7e8 100644
--- a/platform/msm_shared/usb30_udc.h
+++ b/platform/msm_shared/usb30_udc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013, 2015 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
@@ -84,6 +84,7 @@
struct udc_endpoint {
struct udc_endpoint *next;
uint8_t num;
+ uint8_t type;
uint8_t in;
uint16_t maxpkt;
uint32_t maxburst; /* max pkts that this ep can transfer before waiting for ack. */
diff --git a/project/msm8909.mk b/project/msm8909.mk
index afc40f6..59f63f7 100644
--- a/project/msm8909.mk
+++ b/project/msm8909.mk
@@ -20,7 +20,7 @@
#DEFINES += WITH_DEBUG_DCC=1
DEFINES += WITH_DEBUG_LOG_BUF=1
-DEFINES += WITH_DEBUG_UART=0
+DEFINES += WITH_DEBUG_UART=1
#DEFINES += WITH_DEBUG_FBCON=1
DEFINES += DEVICE_TREE=1
#DEFINES += MMC_BOOT_BAM=1
@@ -65,3 +65,9 @@
ifeq ($(ENABLE_BOOT_CONFIG_SUPPORT),1)
DEFINES += BOOT_CONFIG_SUPPORT=1
endif
+
+#SCM call before entering DLOAD mode
+DEFINES += PLATFORM_USE_SCM_DLOAD=1
+
+#Enable the external reboot functions
+ENABLE_REBOOT_MODULE := 1
diff --git a/project/msm8916.mk b/project/msm8916.mk
index 5f51f80..5322f72 100644
--- a/project/msm8916.mk
+++ b/project/msm8916.mk
@@ -51,3 +51,9 @@
#enable user force reset feature
DEFINES += USER_FORCE_RESET_SUPPORT=1
+
+#SCM call before entering DLOAD mode
+DEFINES += PLATFORM_USE_SCM_DLOAD=1
+
+#Enable the external reboot functions
+ENABLE_REBOOT_MODULE := 1
\ No newline at end of file
diff --git a/project/msm8952.mk b/project/msm8952.mk
new file mode 100644
index 0000000..1a27c22
--- /dev/null
+++ b/project/msm8952.mk
@@ -0,0 +1,60 @@
+# top level project rules for the MSM8952 project
+#
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+TARGET := msm8952
+
+MODULES += app/aboot
+
+ifeq ($(TARGET_BUILD_VARIANT),user)
+DEBUG := 0
+else
+DEBUG := 1
+endif
+
+EMMC_BOOT := 1
+
+#ENABLE_SMD_SUPPORT := 1
+#ENABLE_PWM_SUPPORT := true
+
+#DEFINES += WITH_DEBUG_DCC=1
+DEFINES += WITH_DEBUG_LOG_BUF=1
+DEFINES += WITH_DEBUG_UART=1
+#DEFINES += WITH_DEBUG_FBCON=1
+DEFINES += DEVICE_TREE=1
+#DEFINES += MMC_BOOT_BAM=1
+DEFINES += CRYPTO_BAM=1
+DEFINES += SPMI_CORE_V2=1
+DEFINES += ABOOT_IGNORE_BOOT_HEADER_ADDRS=1
+
+DEFINES += BAM_V170=1
+
+#Enable the feature of long press power on
+#DEFINES += LONG_PRESS_POWER_ON=1
+
+#Disable thumb mode
+ENABLE_THUMB := false
+
+ENABLE_SDHCI_SUPPORT := 1
+
+ifeq ($(ENABLE_SDHCI_SUPPORT),1)
+DEFINES += MMC_SDHCI_SUPPORT=1
+endif
+
+#enable power on vibrator feature
+#ENABLE_PON_VIB_SUPPORT := true
+
+ifeq ($(EMMC_BOOT),1)
+DEFINES += _EMMC_BOOT=1
+endif
+
+ifeq ($(ENABLE_PON_VIB_SUPPORT),true)
+DEFINES += PON_VIB_SUPPORT=1
+endif
+
+ifeq ($(ENABLE_SMD_SUPPORT),1)
+DEFINES += SMD_SUPPORT=1
+endif
+
+#SCM call before entering DLOAD mode
+DEFINES += PLATFORM_USE_SCM_DLOAD=1
diff --git a/project/thulium.mk b/project/msm8996.mk
similarity index 83%
rename from project/thulium.mk
rename to project/msm8996.mk
index 05e764f..dfe74cf 100644
--- a/project/thulium.mk
+++ b/project/msm8996.mk
@@ -1,8 +1,8 @@
-# top level project rules for the thulium project
+# top level project rules for the msm8996 project
#
LOCAL_DIR := $(GET_LOCAL_DIR)
-TARGET := thulium
+TARGET := msm8996
MODULES += app/aboot
@@ -19,6 +19,7 @@
ENABLE_USB30_SUPPORT := 1
ENABLE_QGIC3 := 1
ENABLE_PARTIAL_GOODS_SUPPORT := 1
+ENABLE_RPMB_SUPPORT := 1
DEFINES +=VIRTIO=1
@@ -27,6 +28,7 @@
#DEFINES += WITH_DEBUG_FBCON=1
DEFINES += DEVICE_TREE=1
DEFINES += SPMI_CORE_V2=1
+DEFINES += BAM_V170=1
DEFINES += ABOOT_IGNORE_BOOT_HEADER_ADDRS=1
@@ -36,6 +38,7 @@
DEFINES += ABOOT_FORCE_KERNEL64_ADDR=0x80080000
DEFINES += USB_RESET_FROM_CLK=1
DEFINES += USE_BOOTDEV_CMDLINE=1
+DEFINES += USE_RPMB_FOR_DEVINFO=1
#Disable thumb mode
ENABLE_THUMB := false
@@ -61,3 +64,6 @@
endif
CFLAGS += -Werror
+
+#SCM call before entering DLOAD mode
+DEFINES += PLATFORM_USE_SCM_DLOAD=1
diff --git a/scripts/buildall b/scripts/buildall
index c355387..38db25e 100755
--- a/scripts/buildall
+++ b/scripts/buildall
@@ -1,6 +1,6 @@
#!/bin/sh
-PROJECTS="msm8226 msm8974 apq8084 msm8994 mdm9630 mdm9640 msm8610 msm8916 thulium"
+PROJECTS="msm8226 msm8974 apq8084 msm8994 mdm9630 mdm9640 msm8610 msm8916 msm8996"
FAILED=""
for p in $PROJECTS; do
diff --git a/target/fsm9010/init.c b/target/fsm9010/init.c
index 7e47d47..e5c50bb 100644
--- a/target/fsm9010/init.c
+++ b/target/fsm9010/init.c
@@ -288,7 +288,10 @@
};
switch (platform) {
+ case FSM9008:
case FSM9010:
+ case FSM9016:
+ case FSM9055:
board->baseband = BASEBAND_MSM;
break;
default:
diff --git a/target/fsm9010/meminfo.c b/target/fsm9010/meminfo.c
index fa0f96a..3c1fc98 100644
--- a/target/fsm9010/meminfo.c
+++ b/target/fsm9010/meminfo.c
@@ -90,6 +90,6 @@
unsigned target_get_max_flash_size(void)
{
- return (86 * 1024 * 1024);
+ return (222 * 1024 * 1024);
}
#endif /* DEVICE_TREE */
diff --git a/target/fsm9010/rules.mk b/target/fsm9010/rules.mk
index 17a1b1d..8e7fd48 100644
--- a/target/fsm9010/rules.mk
+++ b/target/fsm9010/rules.mk
@@ -12,7 +12,7 @@
TAGS_ADDR := BASE_ADDR+0x01e00000
KERNEL_ADDR := BASE_ADDR+0x00008000
RAMDISK_ADDR := BASE_ADDR+0x02000000
-SCRATCH_ADDR := 0x0e000000
+SCRATCH_ADDR := 0x32200000
MODULES += \
dev/keys \
diff --git a/target/init.c b/target/init.c
index ae1e311..9191572 100644
--- a/target/init.c
+++ b/target/init.c
@@ -221,3 +221,13 @@
{
return DDR_CONFIG_VAL;
}
+
+/* Return Build variant */
+__WEAK bool target_build_variant_user()
+{
+#if USER_BUILD_VARIANT
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/target/mdm9640/init.c b/target/mdm9640/init.c
index 442d117..09dedef 100644
--- a/target/mdm9640/init.c
+++ b/target/mdm9640/init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 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
@@ -83,7 +83,7 @@
#define LAST_NAND_PTN_LEN_PATTERN 0xFFFFFFFF
-#define EXT4_CMDLINE " rootfstype=ext4 root=/dev/mmcblk0p"
+#define EXT4_CMDLINE " rootwait rootfstype=ext4 root=/dev/mmcblk0p"
#define UBI_CMDLINE " rootfstype=ubifs rootflags=bulk_read ubi.fm_autoconvert=1"
struct qpic_nand_init_config config;
@@ -143,6 +143,9 @@
dprintf(CRITICAL, "Error reading the partition table info\n");
ASSERT(0);
}
+ /* Below setting is to enable EBI2 function selection in TLMM so
+ that GPIOs can be used for display */
+ writel((readl(TLMM_EBI2_EMMC_GPIO_CFG) | EBI2_BOOT_SELECT), TLMM_EBI2_EMMC_GPIO_CFG);
} else {
config.pipes.read_pipe = DATA_PRODUCER_PIPE;
config.pipes.write_pipe = DATA_CONSUMER_PIPE;
@@ -179,7 +182,10 @@
* This call should be based on the pmic version
* when PM8019 v2 is available.
*/
- pm8x41_v2_reset_configure(PON_PSHOLD_WARM_RESET);
+ if (reboot_reason)
+ pm8x41_v2_reset_configure(PON_PSHOLD_WARM_RESET);
+ else
+ pm8x41_v2_reset_configure(PON_PSHOLD_HARD_RESET);
/* Drop PS_HOLD for MSM */
writel(0x00, MPM2_MPM_PS_HOLD);
diff --git a/target/msm8226/meminfo.c b/target/msm8226/meminfo.c
index 5de0ef0..5882a2f 100644
--- a/target/msm8226/meminfo.c
+++ b/target/msm8226/meminfo.c
@@ -78,24 +78,10 @@
void *target_get_scratch_address(void)
{
- void *scratch_addr = 0;
-
- if(target_is_cdp_qvga())
- scratch_addr = (void *)SCRATCH_ADDR_128MAP;
- else
- scratch_addr = (void *)SCRATCH_ADDR_512MAP;
-
- return scratch_addr;
+ return (void *)SCRATCH_ADDR;
}
unsigned target_get_max_flash_size(void)
{
- uint32_t max_flash_size = 0;
-
- if(target_is_cdp_qvga())
- max_flash_size = SCRATCH_SIZE_128MAP;
- else
- max_flash_size = SCRATCH_SIZE_512MAP;
-
- return max_flash_size;
+ return SCRATCH_SIZE;
}
diff --git a/target/msm8226/oem_panel.c b/target/msm8226/oem_panel.c
index 354c08e..442fa29 100755
--- a/target/msm8226/oem_panel.c
+++ b/target/msm8226/oem_panel.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 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
@@ -50,6 +50,7 @@
#include "include/panel_ssd2080m_720p_video.h"
#include "include/panel_jdi_1080p_video.h"
#include "include/panel_nt35590_qvga_cmd.h"
+#include "include/panel_auo_qvga_cmd.h"
#define DISPLAY_MAX_PANEL_DETECTION 2
@@ -69,6 +70,7 @@
SSD2080M_720P_VIDEO_PANEL,
JDI_1080P_VIDEO_PANEL,
NT35590_QVGA_CMD_PANEL,
+AUO_QVGA_CMD_PANEL,
UNKNOWN_PANEL
};
@@ -86,6 +88,7 @@
{"ssd2080m_720p_video", SSD2080M_720P_VIDEO_PANEL},
{"jdi_1080p_video", JDI_1080P_VIDEO_PANEL},
{"nt35590_qvga_cmd", NT35590_QVGA_CMD_PANEL},
+ {"auo_qvga_cmd", AUO_QVGA_CMD_PANEL},
};
static uint32_t panel_id;
@@ -355,6 +358,29 @@
memcpy(phy_db->timing,
nt35590_qvga_cmd_timings, TIMING_SIZE);
break;
+ case AUO_QVGA_CMD_PANEL:
+ panelstruct->paneldata = &auo_qvga_cmd_panel_data;
+ panelstruct->panelres = &auo_qvga_cmd_panel_res;
+ panelstruct->color = &auo_qvga_cmd_color;
+ panelstruct->videopanel = &auo_qvga_cmd_video_panel;
+ panelstruct->commandpanel = &auo_qvga_cmd_command_panel;
+ panelstruct->state = &auo_qvga_cmd_state;
+ panelstruct->laneconfig = &auo_qvga_cmd_lane_config;
+ panelstruct->paneltiminginfo = &auo_qvga_cmd_timing_info;
+ panelstruct->panelresetseq
+ = &auo_qvga_cmd_panel_reset_seq;
+ panelstruct->backlightinfo = &auo_qvga_cmd_backlight;
+ pinfo->mipi.panel_on_cmds
+ = auo_qvga_cmd_on_command;
+ pinfo->mipi.num_of_panel_on_cmds
+ = auo_QVGA_CMD_ON_COMMAND;
+ pinfo->mipi.panel_off_cmds
+ = auo_qvga_cmd_off_command;
+ pinfo->mipi.num_of_panel_off_cmds
+ = auo_QVGA_CMD_OFF_COMMAND;
+ memcpy(phy_db->timing,
+ auo_qvga_cmd_timings, TIMING_SIZE);
+ break;
case UNKNOWN_PANEL:
memset(panelstruct, 0, sizeof(struct panel_struct));
memset(pinfo->mipi.panel_on_cmds, 0,
diff --git a/target/msm8226/rules.mk b/target/msm8226/rules.mk
index 91119ea..3be3c36 100755
--- a/target/msm8226/rules.mk
+++ b/target/msm8226/rules.mk
@@ -14,10 +14,7 @@
KERNEL_ADDR := BASE_ADDR+0x00008000
RAMDISK_ADDR := BASE_ADDR+0x01000000
SCRATCH_ADDR := 0x10000000
-SCRATCH_ADDR_128MAP := 0x04200000
-SCRATCH_ADDR_512MAP := 0x10000000
-SCRATCH_SIZE_128MAP := 0x03D00000
-SCRATCH_SIZE_512MAP := 0x20000000
+SCRATCH_SIZE := 0x20000000
DEFINES += DISPLAY_SPLASH_SCREEN=1
DEFINES += DISPLAY_TYPE_MIPI=1
@@ -39,10 +36,7 @@
KERNEL_ADDR=$(KERNEL_ADDR) \
RAMDISK_ADDR=$(RAMDISK_ADDR) \
SCRATCH_ADDR=$(SCRATCH_ADDR) \
- SCRATCH_ADDR_128MAP=$(SCRATCH_ADDR_128MAP) \
- SCRATCH_ADDR_512MAP=$(SCRATCH_ADDR_512MAP) \
- SCRATCH_SIZE_128MAP=$(SCRATCH_SIZE_128MAP) \
- SCRATCH_SIZE_512MAP=$(SCRATCH_SIZE_512MAP)
+ SCRATCH_SIZE=$(SCRATCH_SIZE)
OBJS += \
diff --git a/target/msm8226/target_display.c b/target/msm8226/target_display.c
index 4ac9b37..77ca16e 100755
--- a/target/msm8226/target_display.c
+++ b/target/msm8226/target_display.c
@@ -262,6 +262,8 @@
PWM_BL_LPG_CHAN_ID,
enable);
break;
+ case BL_DCS:
+ break;
default:
dprintf(CRITICAL, "backlight type:%d not supported\n",
bl->bl_interface_type);
diff --git a/target/msm8909/init.c b/target/msm8909/init.c
index 96232fe..ec1a568 100644
--- a/target/msm8909/init.c
+++ b/target/msm8909/init.c
@@ -66,8 +66,6 @@
#define VIBRATE_TIME 250
#endif
-#define FASTBOOT_MODE 0x77665500
-
#define CE1_INSTANCE 1
#define CE_EE 1
#define CE_FIFO_SIZE 64
@@ -151,8 +149,15 @@
void target_early_init(void)
{
#if WITH_DEBUG_UART
- uart_dm_init(1, 0, BLSP1_UART0_BASE);
+ /* Do not intilaise UART in case the h/w
+ * is RCM.
+ */
+ if( board_hardware_id()!= HW_PLATFORM_RCM )
+ uart_dm_init(1, 0, BLSP1_UART0_BASE);
+ else
+ return;
#endif
+
}
int target_is_emmc_boot(void)
@@ -367,41 +372,6 @@
return LINUX_MACHTYPE_UNKNOWN;
}
-unsigned check_reboot_mode(void)
-{
- uint32_t restart_reason = 0;
-
- /* Read reboot reason and scrub it */
- restart_reason = readl(RESTART_REASON_ADDR);
- writel(0x00, RESTART_REASON_ADDR);
-
- return restart_reason;
-}
-
-static int scm_dload_mode(int mode)
-{
- int ret = 0;
- uint32_t dload_type;
-
- dprintf(SPEW, "DLOAD mode: %d\n", mode);
- if (mode == NORMAL_DLOAD)
- dload_type = SCM_DLOAD_MODE;
- else if(mode == EMERGENCY_DLOAD)
- dload_type = SCM_EDLOAD_MODE;
- else
- dload_type = 0;
-
- ret = scm_call_atomic2(SCM_SVC_BOOT, SCM_DLOAD_CMD, dload_type, 0);
- if (ret)
- dprintf(CRITICAL, "Failed to write to boot misc: %d\n", ret);
-
- ret = scm_call_atomic2(SCM_SVC_BOOT, WDOG_DEBUG_DISABLE, 1, 0);
- if (ret)
- dprintf(CRITICAL, "Failed to disable the wdog debug \n");
-
- return ret;
-}
-
/* Configure PMIC and Drop PS_HOLD for shutdown */
void shutdown_device()
{
@@ -417,42 +387,6 @@
}
-void reboot_device(unsigned reboot_reason)
-{
- uint8_t reset_type = 0;
- uint32_t ret = 0;
-
- /* Need to clear the SW_RESET_ENTRY register and
- * write to the BOOT_MISC_REG for known reset cases
- */
- if(reboot_reason != DLOAD)
- scm_dload_mode(NORMAL_MODE);
-
- writel(reboot_reason, RESTART_REASON_ADDR);
-
- /* For Reboot-bootloader and Dload cases do a warm reset
- * For Reboot cases do a hard reset
- */
- if((reboot_reason == FASTBOOT_MODE) || (reboot_reason == DLOAD))
- reset_type = PON_PSHOLD_WARM_RESET;
- else
- reset_type = PON_PSHOLD_HARD_RESET;
-
- pm8x41_reset_configure(reset_type);
-
- ret = scm_halt_pmic_arbiter();
-
- if (ret)
- dprintf(CRITICAL , "Failed to halt pmic arbiter: %d\n", ret);
-
- /* Drop PS_HOLD for MSM */
- writel(0x00, MPM2_MPM_PS_HOLD);
-
- mdelay(5000);
-
- dprintf(CRITICAL, "Rebooting failed\n");
-}
-
/* Detect the target type */
void target_detect(struct board_data *board)
{
diff --git a/target/msm8909/oem_panel.c b/target/msm8909/oem_panel.c
index 50aad97..f7b5717 100644
--- a/target/msm8909/oem_panel.c
+++ b/target/msm8909/oem_panel.c
@@ -205,10 +205,14 @@
panelstruct->panelresetseq
= &truly_wvga_cmd_reset_seq;
panelstruct->backlightinfo = &truly_wvga_cmd_backlight;
- pinfo->mipi.panel_cmds
+ pinfo->mipi.panel_on_cmds
= truly_wvga_cmd_on_command;
- pinfo->mipi.num_of_panel_cmds
+ pinfo->mipi.num_of_panel_on_cmds
= TRULY_WVGA_CMD_ON_COMMAND;
+ pinfo->mipi.panel_off_cmds
+ = truly_wvga_cmd_off_command;
+ pinfo->mipi.num_of_panel_off_cmds
+ = TRULY_WVGA_CMD_OFF_COMMAND;
memcpy(phy_db->timing,
truly_wvga_cmd_timings, TIMING_SIZE);
break;
@@ -275,10 +279,14 @@
panelstruct->panelresetseq
= &hx8394d_qhd_video_panel_reset_seq;
panelstruct->backlightinfo = &hx8394d_qhd_video_backlight;
- pinfo->mipi.panel_cmds
+ pinfo->mipi.panel_on_cmds
= hx8394d_qhd_video_on_command;
- pinfo->mipi.num_of_panel_cmds
+ pinfo->mipi.num_of_panel_on_cmds
= HX8394D_QHD_VIDEO_ON_COMMAND;
+ pinfo->mipi.panel_off_cmds
+ = hx8394d_qhd_video_off_command;
+ pinfo->mipi.num_of_panel_off_cmds
+ = HX8394D_QHD_VIDEO_OFF_COMMAND;
memcpy(phy_db->timing,
hx8394d_qhd_video_timings, TIMING_SIZE);
pinfo->mipi.signature = HX8394D_QHD_VIDEO_SIGNATURE;
diff --git a/target/msm8909/rules.mk b/target/msm8909/rules.mk
index 5753859..b3e2059 100644
--- a/target/msm8909/rules.mk
+++ b/target/msm8909/rules.mk
@@ -14,6 +14,7 @@
DEFINES += DISPLAY_SPLASH_SCREEN=1
DEFINES += DISPLAY_TYPE_MIPI=1
DEFINES += DISPLAY_TYPE_DSI6G=1
+DEFINES += NO_ALARM_DISPLAY=0
MODULES += \
dev/keys \
diff --git a/target/msm8916/init.c b/target/msm8916/init.c
index f1aff17..f0f6bba 100644
--- a/target/msm8916/init.c
+++ b/target/msm8916/init.c
@@ -65,9 +65,6 @@
#define VIBRATE_TIME 250
#endif
-#define FASTBOOT_MODE 0x77665500
-#define PON_SOFT_RB_SPARE 0x88F
-
#define CE1_INSTANCE 1
#define CE_EE 1
#define CE_FIFO_SIZE 64
@@ -169,23 +166,6 @@
keys_post_event(KEY_VOLUMEUP, 1);
}
-#if USER_FORCE_RESET_SUPPORT
-/* Return 1 if it is a force resin triggered by user. */
-uint32_t is_user_force_reset(void)
-{
- uint8_t poff_reason1 = pm8x41_get_pon_poff_reason1();
- uint8_t poff_reason2 = pm8x41_get_pon_poff_reason2();
-
- dprintf(SPEW, "poff_reason1: %d\n", poff_reason1);
- dprintf(SPEW, "poff_reason2: %d\n", poff_reason2);
- if (pm8x41_get_is_cold_boot() && (poff_reason1 == KPDPWR_AND_RESIN ||
- poff_reason2 == STAGE3))
- return 1;
- else
- return 0;
-}
-#endif
-
void target_init(void)
{
uint32_t base_addr;
@@ -231,55 +211,6 @@
return LINUX_MACHTYPE_UNKNOWN;
}
-unsigned check_reboot_mode(void)
-{
- uint32_t restart_reason = 0;
-
- /* Read reboot reason and scrub it */
- restart_reason = readl(RESTART_REASON_ADDR);
- writel(0x00, RESTART_REASON_ADDR);
-
- return restart_reason;
-}
-
-unsigned check_hard_reboot_mode(void)
-{
- uint8_t hard_restart_reason = 0;
- uint8_t value = 0;
-
- /* Read reboot reason and scrub it
- * Bit-5, bit-6 and bit-7 of SOFT_RB_SPARE for hard reset reason
- */
- value = pm8x41_reg_read(PON_SOFT_RB_SPARE);
- hard_restart_reason = value >> 5;
- pm8x41_reg_write(PON_SOFT_RB_SPARE, value & 0x1f);
-
- return hard_restart_reason;
-}
-
-static int scm_dload_mode(int mode)
-{
- int ret = 0;
- uint32_t dload_type;
-
- dprintf(SPEW, "DLOAD mode: %d\n", mode);
- if (mode == NORMAL_DLOAD)
- dload_type = SCM_DLOAD_MODE;
- else if(mode == EMERGENCY_DLOAD)
- dload_type = SCM_EDLOAD_MODE;
- else
- dload_type = 0;
-
- ret = scm_call_atomic2(SCM_SVC_BOOT, SCM_DLOAD_CMD, dload_type, 0);
- if (ret)
- dprintf(CRITICAL, "Failed to write to boot misc: %d\n", ret);
-
- ret = scm_call_atomic2(SCM_SVC_BOOT, WDOG_DEBUG_DISABLE, 1, 0);
- if (ret)
- dprintf(CRITICAL, "Failed to disable the wdog debug \n");
-
- return ret;
-}
/* Configure PMIC and Drop PS_HOLD for shutdown */
void shutdown_device()
{
@@ -298,41 +229,6 @@
ASSERT(0);
}
-void reboot_device(unsigned reboot_reason)
-{
- uint8_t reset_type = 0;
- uint32_t ret = 0;
-
- /* Need to clear the SW_RESET_ENTRY register and
- * write to the BOOT_MISC_REG for known reset cases
- */
- if(reboot_reason != DLOAD)
- scm_dload_mode(NORMAL_MODE);
-
- writel(reboot_reason, RESTART_REASON_ADDR);
-
- /* For Reboot-bootloader and Dload cases do a warm reset
- * For Reboot cases do a hard reset
- */
- if((reboot_reason == FASTBOOT_MODE) || (reboot_reason == DLOAD))
- reset_type = PON_PSHOLD_WARM_RESET;
- else
- reset_type = PON_PSHOLD_HARD_RESET;
-
- pm8x41_reset_configure(reset_type);
-
- ret = scm_halt_pmic_arbiter();
- if (ret)
- dprintf(CRITICAL , "Failed to halt pmic arbiter: %d\n", ret);
-
- /* Drop PS_HOLD for MSM */
- writel(0x00, MPM2_MPM_PS_HOLD);
-
- mdelay(5000);
-
- dprintf(CRITICAL, "Rebooting failed\n");
-}
-
/* Detect the target type */
void target_detect(struct board_data *board)
{
@@ -391,7 +287,7 @@
{
{ SDC1_CLK_HDRV_CTL_OFF, TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK, 0},
{ SDC1_CMD_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, 0},
- { SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_6MA, TLMM_HDRV_MASK , 0},
+ { SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK , 0},
};
/* Pull configs for sdc pins */
@@ -481,7 +377,7 @@
if (is_cold_boot &&
(!(pon_reason & HARD_RST)) &&
(!(pon_reason & KPDPWR_N)) &&
- ((pon_reason & USB_CHG) || (pon_reason & DC_CHG)))
+ ((pon_reason & USB_CHG) || (pon_reason & DC_CHG) || (pon_reason & CBLPWR_N)))
return 1;
else
return 0;
diff --git a/target/msm8916/oem_panel.c b/target/msm8916/oem_panel.c
index ae2725d..4c51fcb 100644
--- a/target/msm8916/oem_panel.c
+++ b/target/msm8916/oem_panel.c
@@ -64,6 +64,8 @@
#define NT35590_720P_CMD_PANEL_ON_DELAY 40
#define SAMSUNG_WXGA_VIDEO_PANEL_ON_DELAY 100
+#define BOARD_SOC_VERSION3 0x30000
+
/*---------------------------------------------------------------------------*/
/* static panel selection variable */
/*---------------------------------------------------------------------------*/
@@ -634,6 +636,9 @@
panel_id = JDI_1080P_VIDEO_PANEL;
break;
case 1:
+ panel_id = HX8394D_720P_VIDEO_PANEL;
+ break;
+ case 2:
panel_id = NT35590_720P_VIDEO_PANEL;
break;
default:
@@ -708,7 +713,9 @@
* Update all data structures after 'panel_init' label. Only panel
* selection is supposed to happen before that.
*/
- if (platform_is_msm8939() || platform_is_msm8929() || (hw_id == HW_PLATFORM_QRD)) {
+ if ((platform_is_msm8939() && (board_soc_version() !=
+ BOARD_SOC_VERSION3)) || platform_is_msm8929() ||
+ (hw_id == HW_PLATFORM_QRD)) {
phy_db->regulator_mode = DSI_PHY_REGULATOR_LDO_MODE;
memcpy(panel_regulator_settings,
ldo_regulator_settings, REGULATOR_SIZE);
diff --git a/target/msm8916/target_display.c b/target/msm8916/target_display.c
index 0ddaec1..43a2903 100644
--- a/target/msm8916/target_display.c
+++ b/target/msm8916/target_display.c
@@ -62,33 +62,124 @@
mdelay(1);
}
-static uint32_t dsi_pll_enable_seq_8916(uint32_t pll_base)
+static void dsi_pll_toggle_lock_detect_8916(uint32_t pll_base)
{
- uint32_t pll_locked = 0;
+ writel(0x04, pll_base + 0x0064); /* LKDetect CFG2 */
+ udelay(1);
+ writel(0x05, pll_base + 0x0064); /* LKDetect CFG2 */
+ udelay(512);
+}
+static void dsi_pll_sw_reset_8916(uint32_t pll_base)
+{
writel(0x01, pll_base + 0x0068); /* PLL TEST CFG */
udelay(1);
writel(0x00, pll_base + 0x0068); /* PLL TEST CFG */
+}
+
+static uint32_t gf_1_dsi_pll_enable_sequence_8916(uint32_t pll_base)
+{
+ uint32_t rc;
+
+ dsi_pll_sw_reset_8916(pll_base);
/*
* Add hardware recommended delays between register writes for
* the updates to take effect. These delays are necessary for the
* PLL to successfully lock
*/
- writel(0x34, pll_base + 0x0070); /* CAL CFG1*/
- udelay(1);
+ writel(0x14, pll_base + 0x0070); /* CAL CFG1*/
writel(0x01, pll_base + 0x0020); /* GLB CFG */
- udelay(1);
writel(0x05, pll_base + 0x0020); /* GLB CFG */
- udelay(1);
+ udelay(3);
writel(0x0f, pll_base + 0x0020); /* GLB CFG */
- udelay(1);
+ udelay(500);
- writel(0x04, pll_base + 0x0064); /* LKDetect CFG2 */
- udelay(1);
- writel(0x05, pll_base + 0x0064); /* LKDetect CFG2 */
- udelay(512);
- pll_locked = readl(pll_base + 0x00c0) & 0x01;
+ dsi_pll_toggle_lock_detect_8916(pll_base);
+ rc = readl(pll_base + 0x00c0) & 0x01;
+
+ return rc;
+}
+
+static uint32_t gf_2_dsi_pll_enable_sequence_8916(uint32_t pll_base)
+{
+ uint32_t rc;
+
+ dsi_pll_sw_reset_8916(pll_base);
+
+ /*
+ * Add hardware recommended delays between register writes for
+ * the updates to take effect. These delays are necessary for the
+ * PLL to successfully lock
+ */
+ writel(0x04, pll_base + 0x0070); /* CAL CFG1*/
+ writel(0x01, pll_base + 0x0020); /* GLB CFG */
+ writel(0x05, pll_base + 0x0020); /* GLB CFG */
+ udelay(3);
+ writel(0x0f, pll_base + 0x0020); /* GLB CFG */
+ udelay(500);
+
+ dsi_pll_toggle_lock_detect_8916(pll_base);
+ rc = readl(pll_base + 0x00c0) & 0x01;
+
+ return rc;
+}
+
+static uint32_t tsmc_dsi_pll_enable_sequence_8916(uint32_t pll_base)
+{
+ uint32_t rc;
+
+ dsi_pll_sw_reset_8916(pll_base);
+ /*
+ * Add hardware recommended delays between register writes for
+ * the updates to take effect. These delays are necessary for the
+ * PLL to successfully lock
+ */
+
+ writel(0x34, pll_base + 0x0070); /* CAL CFG1*/
+ writel(0x01, pll_base + 0x0020); /* GLB CFG */
+ writel(0x05, pll_base + 0x0020); /* GLB CFG */
+ writel(0x0f, pll_base + 0x0020); /* GLB CFG */
+ udelay(500);
+
+ dsi_pll_toggle_lock_detect_8916(pll_base);
+ rc = readl(pll_base + 0x00c0) & 0x01;
+
+ return rc;
+}
+
+
+static uint32_t dsi_pll_enable_seq_8916(uint32_t pll_base)
+{
+ uint32_t pll_locked = 0;
+ uint32_t counter = 0;
+
+ do {
+ pll_locked = tsmc_dsi_pll_enable_sequence_8916(pll_base);
+
+ dprintf(SPEW, "TSMC pll locked status is %d\n", pll_locked);
+ ++counter;
+ } while (!pll_locked && (counter < 3));
+
+ if(!pll_locked) {
+ counter = 0;
+ do {
+ pll_locked = gf_1_dsi_pll_enable_sequence_8916(pll_base);
+
+ dprintf(SPEW, "GF P1 pll locked status is %d\n", pll_locked);
+ ++counter;
+ } while (!pll_locked && (counter < 3));
+ }
+
+ if(!pll_locked) {
+ counter = 0;
+ do {
+ pll_locked = gf_2_dsi_pll_enable_sequence_8916(pll_base);
+
+ dprintf(SPEW, "GF P2 pll locked status is %d\n", pll_locked);
+ ++counter;
+ } while (!pll_locked && (counter < 3));
+ }
return pll_locked;
}
diff --git a/target/msm8952/init.c b/target/msm8952/init.c
new file mode 100644
index 0000000..445e132
--- /dev/null
+++ b/target/msm8952/init.c
@@ -0,0 +1,505 @@
+/* Copyright (c) 2015, 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 <debug.h>
+#include <platform/iomap.h>
+#include <reg.h>
+#include <target.h>
+#include <platform.h>
+#include <uart_dm.h>
+#include <mmc.h>
+#include <platform/gpio.h>
+#include <dev/keys.h>
+#include <spmi_v2.h>
+#include <pm8x41.h>
+#include <board.h>
+#include <baseband.h>
+#include <hsusb.h>
+#include <scm.h>
+#include <platform/gpio.h>
+#include <platform/gpio.h>
+#include <platform/irqs.h>
+#include <platform/clock.h>
+#include <crypto5_wrapper.h>
+#include <partition_parser.h>
+#include <stdlib.h>
+
+#if LONG_PRESS_POWER_ON
+#include <shutdown_detect.h>
+#endif
+
+#define PMIC_ARB_CHANNEL_NUM 0
+#define PMIC_ARB_OWNER_ID 0
+#define TLMM_VOL_UP_BTN_GPIO 85
+
+#define FASTBOOT_MODE 0x77665500
+#define PON_SOFT_RB_SPARE 0x88F
+
+#define CE1_INSTANCE 1
+#define CE_EE 1
+#define CE_FIFO_SIZE 64
+#define CE_READ_PIPE 3
+#define CE_WRITE_PIPE 2
+#define CE_READ_PIPE_LOCK_GRP 0
+#define CE_WRITE_PIPE_LOCK_GRP 0
+#define CE_ARRAY_SIZE 20
+
+struct mmc_device *dev;
+
+static uint32_t mmc_pwrctl_base[] =
+ { MSM_SDC1_BASE, MSM_SDC2_BASE };
+
+static uint32_t mmc_sdhci_base[] =
+ { MSM_SDC1_SDHCI_BASE, MSM_SDC2_SDHCI_BASE };
+
+static uint32_t mmc_sdc_pwrctl_irq[] =
+ { SDCC1_PWRCTL_IRQ, SDCC2_PWRCTL_IRQ };
+
+void target_early_init(void)
+{
+#if WITH_DEBUG_UART
+ uart_dm_init(2, 0, BLSP1_UART1_BASE);
+#endif
+}
+
+static void set_sdc_power_ctrl()
+{
+ /* Drive strength configs for sdc pins */
+ struct tlmm_cfgs sdc1_hdrv_cfg[] =
+ {
+ { SDC1_CLK_HDRV_CTL_OFF, TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK, 0},
+ { SDC1_CMD_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, 0},
+ { SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK , 0},
+ };
+
+ /* Pull configs for sdc pins */
+ struct tlmm_cfgs sdc1_pull_cfg[] =
+ {
+ { SDC1_CLK_PULL_CTL_OFF, TLMM_NO_PULL, TLMM_PULL_MASK, 0},
+ { SDC1_CMD_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK, 0},
+ { SDC1_DATA_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK, 0},
+ };
+
+ /* Set the drive strength & pull control values */
+ tlmm_set_hdrive_ctrl(sdc1_hdrv_cfg, ARRAY_SIZE(sdc1_hdrv_cfg));
+ tlmm_set_pull_ctrl(sdc1_pull_cfg, ARRAY_SIZE(sdc1_pull_cfg));
+}
+
+void target_sdc_init()
+{
+ struct mmc_config_data config;
+
+ /* Set drive strength & pull ctrl values */
+ set_sdc_power_ctrl();
+
+ /* Try slot 1*/
+ config.slot = 1;
+ config.bus_width = DATA_BUS_WIDTH_8BIT;
+ config.max_clk_rate = MMC_CLK_177MHZ;
+ config.sdhc_base = mmc_sdhci_base[config.slot - 1];
+ config.pwrctl_base = mmc_pwrctl_base[config.slot - 1];
+ config.pwr_irq = mmc_sdc_pwrctl_irq[config.slot - 1];
+ config.hs400_support = 1;
+
+ if (!(dev = mmc_init(&config))) {
+ /* Try slot 2 */
+ config.slot = 2;
+ config.max_clk_rate = MMC_CLK_200MHZ;
+ config.sdhc_base = mmc_sdhci_base[config.slot - 1];
+ config.pwrctl_base = mmc_pwrctl_base[config.slot - 1];
+ config.pwr_irq = mmc_sdc_pwrctl_irq[config.slot - 1];
+ config.hs400_support = 0;
+
+ if (!(dev = mmc_init(&config))) {
+ dprintf(CRITICAL, "mmc init failed!");
+ ASSERT(0);
+ }
+ }
+}
+
+void *target_mmc_device()
+{
+ return (void *) dev;
+}
+
+/* Return 1 if vol_up pressed */
+static int target_volume_up()
+{
+ uint8_t status = 0;
+
+ gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
+
+ /* Wait for the gpio config to take effect - debounce time */
+ thread_sleep(10);
+
+ /* Get status of GPIO */
+ status = gpio_status(TLMM_VOL_UP_BTN_GPIO);
+
+ /* Active high signal. */
+ return status;
+}
+
+/* Return 1 if vol_down pressed */
+uint32_t target_volume_down()
+{
+ /* Volume down button tied in with PMIC RESIN. */
+ return pm8x41_resin_status();
+}
+
+static void target_keystatus()
+{
+ keys_init();
+
+ if(target_volume_down())
+ keys_post_event(KEY_VOLUMEDOWN, 1);
+
+ if(target_volume_up())
+ keys_post_event(KEY_VOLUMEUP, 1);
+}
+
+/* Configure PMIC and Drop PS_HOLD for shutdown */
+void shutdown_device()
+{
+ dprintf(CRITICAL, "Going down for shutdown.\n");
+
+ /* Configure PMIC for shutdown */
+ pm8x41_reset_configure(PON_PSHOLD_SHUTDOWN);
+
+ /* Drop PS_HOLD for MSM */
+ writel(0x00, MPM2_MPM_PS_HOLD);
+
+ mdelay(5000);
+
+ dprintf(CRITICAL, "shutdown failed\n");
+
+ ASSERT(0);
+}
+
+
+void target_init(void)
+{
+ uint32_t base_addr;
+ uint8_t slot;
+
+ dprintf(INFO, "target_init()\n");
+
+ spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
+
+ target_keystatus();
+
+ target_sdc_init();
+ if (partition_read_table())
+ {
+ dprintf(CRITICAL, "Error reading the partition table info\n");
+ ASSERT(0);
+ }
+
+#if LONG_PRESS_POWER_ON
+ shutdown_detect();
+#endif
+ if (target_use_signed_kernel())
+ target_crypto_init_params();
+}
+
+void target_serialno(unsigned char *buf)
+{
+ uint32_t serialno;
+ if (target_is_emmc_boot()) {
+ serialno = mmc_get_psn();
+ snprintf((char *)buf, 13, "%x", serialno);
+ }
+}
+
+unsigned board_machtype(void)
+{
+ return LINUX_MACHTYPE_UNKNOWN;
+}
+
+/* Detect the target type */
+void target_detect(struct board_data *board)
+{
+ /* This is already filled as part of board.c */
+}
+
+/* Detect the modem type */
+void target_baseband_detect(struct board_data *board)
+{
+ uint32_t platform;
+
+ platform = board->platform;
+
+ switch(platform) {
+ case MSM8952:
+ case MSM8956:
+ case MSM8976:
+ board->baseband = BASEBAND_MSM;
+ break;
+ default:
+ dprintf(CRITICAL, "Platform type: %u is not supported\n",platform);
+ ASSERT(0);
+ };
+}
+
+unsigned target_baseband()
+{
+ return board_baseband();
+}
+
+unsigned check_reboot_mode(void)
+{
+ uint32_t restart_reason = 0;
+
+ /* Read reboot reason and scrub it */
+ restart_reason = readl(RESTART_REASON_ADDR);
+ writel(0x00, RESTART_REASON_ADDR);
+
+ return restart_reason;
+}
+
+unsigned check_hard_reboot_mode(void)
+{
+ uint8_t hard_restart_reason = 0;
+ uint8_t value = 0;
+
+ /* Read reboot reason and scrub it
+ * Bit-5, bit-6 and bit-7 of SOFT_RB_SPARE for hard reset reason
+ */
+ value = pm8x41_reg_read(PON_SOFT_RB_SPARE);
+ hard_restart_reason = value >> 5;
+ pm8x41_reg_write(PON_SOFT_RB_SPARE, value & 0x1f);
+
+ return hard_restart_reason;
+}
+
+int set_download_mode(enum dload_mode mode)
+{
+ int ret = 0;
+ ret = scm_dload_mode(mode);
+
+ pm8x41_clear_pmic_watchdog();
+
+ return ret;
+}
+
+int emmc_recovery_init(void)
+{
+ return _emmc_recovery_init();
+}
+
+void reboot_device(unsigned reboot_reason)
+{
+ uint8_t reset_type = 0;
+ uint32_t ret = 0;
+
+ /* Need to clear the SW_RESET_ENTRY register and
+ * write to the BOOT_MISC_REG for known reset cases
+ */
+ if(reboot_reason != DLOAD)
+ scm_dload_mode(NORMAL_MODE);
+
+ writel(reboot_reason, RESTART_REASON_ADDR);
+
+ /* For Reboot-bootloader and Dload cases do a warm reset
+ * For Reboot cases do a hard reset
+ */
+ if((reboot_reason == FASTBOOT_MODE) || (reboot_reason == DLOAD))
+ reset_type = PON_PSHOLD_WARM_RESET;
+ else
+ reset_type = PON_PSHOLD_HARD_RESET;
+
+ pm8x41_reset_configure(reset_type);
+
+ ret = scm_halt_pmic_arbiter();
+ if (ret)
+ dprintf(CRITICAL , "Failed to halt pmic arbiter: %d\n", ret);
+
+ /* Drop PS_HOLD for MSM */
+ writel(0x00, MPM2_MPM_PS_HOLD);
+
+ mdelay(5000);
+
+ dprintf(CRITICAL, "Rebooting failed\n");
+}
+
+#if USER_FORCE_RESET_SUPPORT
+/* Return 1 if it is a force resin triggered by user. */
+uint32_t is_user_force_reset(void)
+{
+ uint8_t poff_reason1 = pm8x41_get_pon_poff_reason1();
+ uint8_t poff_reason2 = pm8x41_get_pon_poff_reason2();
+
+ dprintf(SPEW, "poff_reason1: %d\n", poff_reason1);
+ dprintf(SPEW, "poff_reason2: %d\n", poff_reason2);
+ if (pm8x41_get_is_cold_boot() && (poff_reason1 == KPDPWR_AND_RESIN ||
+ poff_reason2 == STAGE3))
+ return 1;
+ else
+ return 0;
+}
+#endif
+
+unsigned target_pause_for_battery_charge(void)
+{
+ uint8_t pon_reason = pm8x41_get_pon_reason();
+ uint8_t is_cold_boot = pm8x41_get_is_cold_boot();
+ dprintf(INFO, "%s : pon_reason is %d cold_boot:%d\n", __func__,
+ pon_reason, is_cold_boot);
+ /* In case of fastboot reboot,adb reboot or if we see the power key
+ * pressed we do not want go into charger mode.
+ * fastboot reboot is warm boot with PON hard reset bit not set
+ * adb reboot is a cold boot with PON hard reset bit set
+ */
+ if (is_cold_boot &&
+ (!(pon_reason & HARD_RST)) &&
+ (!(pon_reason & KPDPWR_N)) &&
+ ((pon_reason & USB_CHG)))
+ return 1;
+ else
+ return 0;
+}
+
+void target_uninit(void)
+{
+ mmc_put_card_to_sleep(dev);
+ sdhci_mode_disable(&dev->host);
+ if (crypto_initialized())
+ crypto_eng_cleanup();
+
+ if (target_is_ssd_enabled())
+ clock_ce_disable(CE1_INSTANCE);
+}
+
+void target_usb_init(void)
+{
+ uint32_t val;
+
+ /* Select and enable external configuration with USB PHY */
+ ulpi_write(ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT, ULPI_MISC_A_SET);
+
+ /* Enable sess_vld */
+ val = readl(USB_GENCONFIG_2) | GEN2_SESS_VLD_CTRL_EN;
+ writel(val, USB_GENCONFIG_2);
+
+ /* Enable external vbus configuration in the LINK */
+ val = readl(USB_USBCMD);
+ val |= SESS_VLD_CTRL;
+ writel(val, USB_USBCMD);
+}
+
+void target_usb_stop(void)
+{
+ /* Disable VBUS mimicing in the controller. */
+ ulpi_write(ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT, ULPI_MISC_A_CLEAR);
+}
+
+/* Do any target specific intialization needed before entering fastboot mode */
+void target_fastboot_init(void)
+{
+ if (target_is_ssd_enabled()) {
+ clock_ce_enable(CE1_INSTANCE);
+ target_load_ssd_keystore();
+ }
+}
+
+void target_load_ssd_keystore(void)
+{
+ uint64_t ptn;
+ int index;
+ uint64_t size;
+ uint32_t *buffer = NULL;
+
+ if (!target_is_ssd_enabled())
+ return;
+
+ index = partition_get_index("ssd");
+
+ ptn = partition_get_offset(index);
+ if (ptn == 0){
+ dprintf(CRITICAL, "Error: ssd partition not found\n");
+ return;
+ }
+
+ size = partition_get_size(index);
+ if (size == 0) {
+ dprintf(CRITICAL, "Error: invalid ssd partition size\n");
+ return;
+ }
+
+ buffer = memalign(CACHE_LINE, ROUNDUP(size, CACHE_LINE));
+ if (!buffer) {
+ dprintf(CRITICAL, "Error: allocating memory for ssd buffer\n");
+ return;
+ }
+
+ if (mmc_read(ptn, buffer, size)) {
+ dprintf(CRITICAL, "Error: cannot read data\n");
+ free(buffer);
+ return;
+ }
+
+ clock_ce_enable(CE1_INSTANCE);
+ scm_protect_keystore(buffer, size);
+ clock_ce_disable(CE1_INSTANCE);
+ free(buffer);
+}
+
+crypto_engine_type board_ce_type(void)
+{
+ return CRYPTO_ENGINE_TYPE_HW;
+}
+
+/* Set up params for h/w CE. */
+void target_crypto_init_params()
+{
+ struct crypto_init_params ce_params;
+
+ /* Set up base addresses and instance. */
+ ce_params.crypto_instance = CE1_INSTANCE;
+ ce_params.crypto_base = MSM_CE1_BASE;
+ ce_params.bam_base = MSM_CE1_BAM_BASE;
+
+ /* Set up BAM config. */
+ ce_params.bam_ee = CE_EE;
+ ce_params.pipes.read_pipe = CE_READ_PIPE;
+ ce_params.pipes.write_pipe = CE_WRITE_PIPE;
+ ce_params.pipes.read_pipe_grp = CE_READ_PIPE_LOCK_GRP;
+ ce_params.pipes.write_pipe_grp = CE_WRITE_PIPE_LOCK_GRP;
+
+ /* Assign buffer sizes. */
+ ce_params.num_ce = CE_ARRAY_SIZE;
+ ce_params.read_fifo_size = CE_FIFO_SIZE;
+ ce_params.write_fifo_size = CE_FIFO_SIZE;
+
+ /* BAM is initialized by TZ for this platform.
+ * Do not do it again as the initialization address space
+ * is locked.
+ */
+ ce_params.do_bam_init = 0;
+
+ crypto_init_params(&ce_params);
+}
diff --git a/target/thulium/meminfo.c b/target/msm8952/meminfo.c
similarity index 96%
rename from target/thulium/meminfo.c
rename to target/msm8952/meminfo.c
index 9aa1dd5..b2f46df 100644
--- a/target/thulium/meminfo.c
+++ b/target/msm8952/meminfo.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 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
@@ -64,14 +64,11 @@
if (ret)
{
- dprintf(CRITICAL, "Failed to add secondary banks memory addresses\n"
-);
+ dprintf(CRITICAL, "Failed to add secondary banks memory addresses\n");
goto target_dev_tree_mem_err;
}
-
}
}
-
target_dev_tree_mem_err:
return ret;
diff --git a/target/msm8952/rules.mk b/target/msm8952/rules.mk
new file mode 100644
index 0000000..31d4c36
--- /dev/null
+++ b/target/msm8952/rules.mk
@@ -0,0 +1,29 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared
+
+PLATFORM := msm8952
+
+MEMBASE := 0x8F600000 # SDRAM
+MEMSIZE := 0x00100000 # 1MB
+
+BASE_ADDR := 0x80000000
+SCRATCH_ADDR := 0x90000000
+
+MODULES += \
+ dev/keys \
+ dev/vib \
+ lib/ptable \
+ dev/pmic/pm8x41 \
+ lib/libfdt
+
+DEFINES += \
+ MEMSIZE=$(MEMSIZE) \
+ MEMBASE=$(MEMBASE) \
+ BASE_ADDR=$(BASE_ADDR) \
+ SCRATCH_ADDR=$(SCRATCH_ADDR)
+
+
+OBJS += \
+ $(LOCAL_DIR)/init.o \
+ $(LOCAL_DIR)/meminfo.o
diff --git a/target/msm8952/tools/makefile b/target/msm8952/tools/makefile
new file mode 100644
index 0000000..da48f0d
--- /dev/null
+++ b/target/msm8952/tools/makefile
@@ -0,0 +1,12 @@
+#Makefile to generate appsboot.mbn
+
+ifeq ($(BOOTLOADER_OUT),.)
+APPSBOOTOUT_DIR := $(BUILDDIR)
+else
+APPSBOOTOUT_DIR := $(BOOTLOADER_OUT)/../..
+endif
+
+APPSBOOTHEADER: emmc_appsboot.mbn
+
+emmc_appsboot.mbn: $(OUTELF_STRIP)
+ $(hide) cp -f $(OUTELF_STRIP) $(APPSBOOTOUT_DIR)/emmc_appsboot.mbn
diff --git a/target/msm8994/init.c b/target/msm8994/init.c
index 4e2e160..824bdc1 100644
--- a/target/msm8994/init.c
+++ b/target/msm8994/init.c
@@ -105,7 +105,7 @@
}
/* Return 1 if vol_up pressed */
-static int target_volume_up()
+int target_volume_up()
{
uint8_t status = 0;
struct pm8x41_gpio gpio;
@@ -446,16 +446,22 @@
void reboot_device(unsigned reboot_reason)
{
uint8_t reset_type = 0;
+ uint32_t restart_reason_addr;
+
+ if (platform_is_msm8994())
+ restart_reason_addr = RESTART_REASON_ADDR;
+ else
+ restart_reason_addr = RESTART_REASON_ADDR2;
/* Write the reboot reason */
- writel(reboot_reason, RESTART_REASON_ADDR);
+ writel(reboot_reason, restart_reason_addr);
if(reboot_reason == FASTBOOT_MODE)
reset_type = PON_PSHOLD_WARM_RESET;
else
reset_type = PON_PSHOLD_HARD_RESET;
- pm8x41_reset_configure(reset_type);
+ pm8994_reset_configure(reset_type);
/* Drop PS_HOLD for MSM */
writel(0x00, MPM2_MPM_PS_HOLD);
@@ -556,7 +562,7 @@
dprintf(CRITICAL, "Going down for shutdown.\n");
/* Configure PMIC for shutdown. */
- pm8x41_reset_configure(PON_PSHOLD_SHUTDOWN);
+ pm8994_reset_configure(PON_PSHOLD_SHUTDOWN);
/* Drop PS_HOLD for MSM */
writel(0x00, MPM2_MPM_PS_HOLD);
diff --git a/target/msm8994/oem_panel.c b/target/msm8994/oem_panel.c
index de292b5..62795ad 100644
--- a/target/msm8994/oem_panel.c
+++ b/target/msm8994/oem_panel.c
@@ -48,6 +48,7 @@
#include "include/panel_jdi_qhd_dualdsi_cmd.h"
#include "include/panel_jdi_4k_dualdsi_video.h"
#include "include/panel_jdi_1080p_video.h"
+#include "include/panel_sharp_1080p_cmd.h"
#include "include/panel_hx8379a_truly_fwvga_video.h"
#include "include/panel_nt35597_wqxga_video.h"
#include "include/panel_nt35597_wqxga_cmd.h"
@@ -61,6 +62,7 @@
JDI_QHD_DUALDSI_CMD_PANEL,
JDI_4K_DUALDSI_VIDEO_PANEL,
JDI_1080P_VIDEO_PANEL,
+SHARP_1080P_CMD_PANEL,
HX8379A_TRULY_FWVGA_VIDEO_PANEL,
NOVATEK_WQXGA_VIDEO_PANEL,
NOVATEK_WQXGA_CMD_PANEL,
@@ -77,6 +79,7 @@
{"jdi_qhd_dualdsi_cmd", JDI_QHD_DUALDSI_CMD_PANEL},
{"jdi_4k_dualdsi_video", JDI_4K_DUALDSI_VIDEO_PANEL},
{"jdi_1080p_video", JDI_1080P_VIDEO_PANEL},
+ {"sharp_1080p_cmd", SHARP_1080P_CMD_PANEL},
{"hx8379a_truly_fwvga_video", HX8379A_TRULY_FWVGA_VIDEO_PANEL},
{"nt35597_wqxga_video", NOVATEK_WQXGA_VIDEO_PANEL},
{"nt35597_wqxga_cmd", NOVATEK_WQXGA_CMD_PANEL},
@@ -158,6 +161,7 @@
memcpy(phy_db->timing,
sharp_wqxga_dualdsi_video_timings, TIMING_SIZE);
pinfo->dfps.panel_dfps = sharp_wqxga_dualdsi_video_dfps;
+ pinfo->mipi.tx_eot_append = true;
break;
case JDI_QHD_DUALDSI_VIDEO_PANEL:
pan_type = PANEL_TYPE_DSI;
@@ -278,6 +282,32 @@
memcpy(phy_db->timing,
jdi_1080p_video_timings, TIMING_SIZE);
break;
+ case SHARP_1080P_CMD_PANEL:
+ pan_type = PANEL_TYPE_DSI;
+ pinfo->lcd_reg_en = 0;
+ panelstruct->paneldata = &sharp_1080p_cmd_panel_data;
+ panelstruct->panelres = &sharp_1080p_cmd_panel_res;
+ panelstruct->color = &sharp_1080p_cmd_color;
+ panelstruct->videopanel = &sharp_1080p_cmd_video_panel;
+ panelstruct->commandpanel = &sharp_1080p_cmd_command_panel;
+ panelstruct->state = &sharp_1080p_cmd_state;
+ panelstruct->laneconfig = &sharp_1080p_cmd_lane_config;
+ panelstruct->paneltiminginfo
+ = &sharp_1080p_cmd_timing_info;
+ panelstruct->panelresetseq
+ = &sharp_1080p_cmd_panel_reset_seq;
+ panelstruct->backlightinfo = &sharp_1080p_cmd_backlight;
+ pinfo->mipi.panel_on_cmds
+ = sharp_1080p_cmd_on_command;
+ pinfo->mipi.num_of_panel_on_cmds
+ = SHARP_1080P_CMD_ON_COMMAND;
+ pinfo->mipi.panel_off_cmds
+ = sharp_1080p_cmd_off_command;
+ pinfo->mipi.num_of_panel_off_cmds
+ = SHARP_1080P_CMD_OFF_COMMAND;
+ memcpy(phy_db->timing,
+ sharp_1080p_cmd_timings, TIMING_SIZE);
+ break;
case HX8379A_TRULY_FWVGA_VIDEO_PANEL:
pan_type = PANEL_TYPE_DSI;
pinfo->lcd_reg_en = 1;
diff --git a/target/msm8994/regulator.c b/target/msm8994/regulator.c
index 8a8d1e1..51bd966 100644
--- a/target/msm8994/regulator.c
+++ b/target/msm8994/regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 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
@@ -28,22 +28,22 @@
*/
#include <regulator.h>
-#include <rpm-smd.h>
+#include <rpm-ipc.h>
static uint32_t ldo2[][11]=
{
{
LDOA_RES_TYPE, 2,
KEY_SOFTWARE_ENABLE, 4, GENERIC_DISABLE,
- KEY_LDO_SOFTWARE_MODE, 4, SW_MODE_LDO_IPEAK,
KEY_MICRO_VOLT, 4, 0,
+ KEY_CURRENT, 4, 0,
},
{
LDOA_RES_TYPE, 2,
KEY_SOFTWARE_ENABLE, 4, GENERIC_ENABLE,
- KEY_LDO_SOFTWARE_MODE, 4, SW_MODE_LDO_IPEAK,
KEY_MICRO_VOLT, 4, 1250000,
+ KEY_CURRENT, 4, 16,
},
};
@@ -52,15 +52,15 @@
{
LDOA_RES_TYPE, 12,
KEY_SOFTWARE_ENABLE, 4, GENERIC_DISABLE,
- KEY_LDO_SOFTWARE_MODE, 4, SW_MODE_LDO_IPEAK,
KEY_MICRO_VOLT, 4, 0,
+ KEY_CURRENT, 4, 0,
},
{
LDOA_RES_TYPE, 12,
KEY_SOFTWARE_ENABLE, 4, GENERIC_ENABLE,
- KEY_LDO_SOFTWARE_MODE, 4, SW_MODE_LDO_IPEAK,
KEY_MICRO_VOLT, 4, 1800000,
+ KEY_CURRENT, 4, 11,
},
};
@@ -69,32 +69,32 @@
{
LDOA_RES_TYPE, 14,
KEY_SOFTWARE_ENABLE, 4, GENERIC_DISABLE,
- KEY_LDO_SOFTWARE_MODE, 4, SW_MODE_LDO_IPEAK,
KEY_MICRO_VOLT, 4, 0,
+ KEY_CURRENT, 4, 0,
},
{
LDOA_RES_TYPE, 14,
KEY_SOFTWARE_ENABLE, 4, GENERIC_ENABLE,
- KEY_LDO_SOFTWARE_MODE, 4, SW_MODE_LDO_IPEAK,
KEY_MICRO_VOLT, 4, 1800000,
+ KEY_CURRENT, 4, 52,
},
};
-static uint32_t ldo28[][11]=
+static uint32_t ldo28[][14]=
{
{
LDOA_RES_TYPE, 28,
KEY_SOFTWARE_ENABLE, 4, GENERIC_DISABLE,
- KEY_LDO_SOFTWARE_MODE, 4, SW_MODE_LDO_IPEAK,
KEY_MICRO_VOLT, 4, 0,
+ KEY_CURRENT, 4, 0,
},
{
LDOA_RES_TYPE, 28,
KEY_SOFTWARE_ENABLE, 4, GENERIC_ENABLE,
- KEY_LDO_SOFTWARE_MODE, 4, SW_MODE_LDO_IPEAK,
KEY_MICRO_VOLT, 4, 1000000,
+ KEY_CURRENT, 4, 72,
},
};
diff --git a/target/thulium/init.c b/target/msm8996/init.c
similarity index 89%
rename from target/thulium/init.c
rename to target/msm8996/init.c
index 28c6b2c..356ef5e 100644
--- a/target/thulium/init.c
+++ b/target/msm8996/init.c
@@ -55,6 +55,7 @@
#include <qmp_phy.h>
#include <sdhci_msm.h>
#include <qusb2_phy.h>
+#include <rpmb.h>
#define CE_INSTANCE 1
#define CE_EE 1
@@ -136,6 +137,22 @@
/* Disable HC mode before jumping to kernel */
sdhci_mode_disable(&dev->host);
}
+
+ if (is_sec_app_loaded())
+ {
+ if (unload_sec_app() < 0)
+ {
+ dprintf(CRITICAL, "Failed to unload App for rpmb\n");
+ ASSERT(0);
+ }
+ }
+
+ if (rpmb_uninit() < 0)
+ {
+ dprintf(CRITICAL, "RPMB uninit failed\n");
+ ASSERT(0);
+ }
+
}
static void set_sdc_power_ctrl()
@@ -238,6 +255,12 @@
/* Storage initialization is complete, read the partition table info */
mmc_read_partition_table(0);
+
+ if (rpmb_init() < 0)
+ {
+ dprintf(CRITICAL, "RPMB init failed\n");
+ ASSERT(0);
+ }
}
unsigned board_machtype(void)
@@ -392,3 +415,31 @@
crypto_init_params(&ce_params);
}
+
+unsigned target_pause_for_battery_charge(void)
+{
+ uint8_t pon_reason = pm8x41_get_pon_reason();
+ uint8_t is_cold_boot = pm8x41_get_is_cold_boot();
+ dprintf(INFO, "%s : pon_reason is %d cold_boot:%d\n", __func__,
+ pon_reason, is_cold_boot);
+ /* In case of fastboot reboot,adb reboot or if we see the power key
+ * pressed we do not want go into charger mode.
+ * fastboot reboot is warm boot with PON hard reset bit not set
+ * adb reboot is a cold boot with PON hard reset bit set
+ */
+ if (is_cold_boot &&
+ (!(pon_reason & HARD_RST)) &&
+ (!(pon_reason & KPDPWR_N)) &&
+ ((pon_reason & PON1)))
+ return 1;
+ else
+ return 0;
+}
+
+int set_download_mode(enum dload_mode mode)
+{
+ int ret = 0;
+ ret = scm_dload_mode(mode);
+
+ return ret;
+}
diff --git a/target/thulium/meminfo.c b/target/msm8996/meminfo.c
similarity index 91%
copy from target/thulium/meminfo.c
copy to target/msm8996/meminfo.c
index 9aa1dd5..c65525f 100644
--- a/target/thulium/meminfo.c
+++ b/target/msm8996/meminfo.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 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
@@ -41,6 +41,7 @@
unsigned int index;
int ret = 0;
uint32_t len = 0;
+ uint64_t size = 0;
/* Make sure RAM partition table is initialized */
ASSERT(smem_ram_ptable_init_v1());
@@ -56,11 +57,16 @@
(ptn_entry.type == SYS_MEMORY))
{
+ if (smem_get_ram_ptable_version() == SMEM_RAM_PTABLE_VERSION_2)
+ size = ptn_entry.available_length;
+ else
+ size = ptn_entry.size;
+
/* Pass along all other usable memory regions to Linux */
ret = dev_tree_add_mem_info(fdt,
memory_node_offset,
ptn_entry.start,
- ptn_entry.size);
+ size);
if (ret)
{
diff --git a/target/thulium/rules.mk b/target/msm8996/rules.mk
similarity index 90%
rename from target/thulium/rules.mk
rename to target/msm8996/rules.mk
index 5ec0e88..28ab538 100644
--- a/target/thulium/rules.mk
+++ b/target/msm8996/rules.mk
@@ -2,14 +2,14 @@
INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared
-PLATFORM := thulium
+PLATFORM := msm8996
MEMBASE := 0x8F000000 # SDRAM
-MEMSIZE := 0x00100000 # 1MB
+MEMSIZE := 0x00200000 # 2MB
BASE_ADDR := 0x0000000
-SCRATCH_ADDR := 0x8F100000
+SCRATCH_ADDR := 0x8F300000
SCRATCH_SIZE := 512
KERNEL_ADDR := 0x80000000
KERNEL_SIZE := 62
diff --git a/target/thulium/tools/makefile b/target/msm8996/tools/makefile
similarity index 100%
rename from target/thulium/tools/makefile
rename to target/msm8996/tools/makefile