Browse Source

Merge "tz_log: Update the tz_log module"

qctecmdr 3 years ago
parent
commit
6f44d8b491
1 changed files with 141 additions and 1 deletions
  1. 141 1
      tz_log/tz_log.c

+ 141 - 1
tz_log/tz_log.c

@@ -337,6 +337,14 @@ struct hypdbg_log_pos_t {
 	uint16_t offset;
 };
 
+struct rmdbg_log_hdr_t {
+	uint32_t write_idx;
+	uint32_t size;
+};
+struct rmdbg_log_pos_t {
+	uint32_t read_idx;
+	uint32_t size;
+};
 struct hypdbg_boot_info_t {
 	uint32_t warm_entry_cnt;
 	uint32_t warm_exit_cnt;
@@ -379,6 +387,7 @@ enum tzdbg_stats_type {
 	TZDBG_QSEE_LOG,
 	TZDBG_HYP_GENERAL,
 	TZDBG_HYP_LOG,
+	TZDBG_RM_LOG,
 	TZDBG_STATS_MAX
 };
 
@@ -392,12 +401,15 @@ struct tzdbg_stat {
 struct tzdbg {
 	void __iomem *virt_iobase;
 	void __iomem *hyp_virt_iobase;
+	void __iomem *rmlog_virt_iobase;
 	struct tzdbg_t *diag_buf;
 	struct hypdbg_t *hyp_diag_buf;
+	uint8_t *rm_diag_buf;
 	char *disp_buf;
 	int debug_tz[TZDBG_STATS_MAX];
 	struct tzdbg_stat stat[TZDBG_STATS_MAX];
 	uint32_t hyp_debug_rw_buf_size;
+	uint32_t rmlog_rw_buf_size;
 	bool is_hyplog_enabled;
 	uint32_t tz_version;
 	bool is_encrypted_log_enabled;
@@ -444,6 +456,7 @@ static struct tzdbg tzdbg = {
 	.stat[TZDBG_QSEE_LOG].name = "qsee_log",
 	.stat[TZDBG_HYP_GENERAL].name = "hyp_general",
 	.stat[TZDBG_HYP_LOG].name = "hyp_log",
+	.stat[TZDBG_RM_LOG].name = "rm_log",
 };
 
 static struct tzdbg_log_t *g_qsee_log;
@@ -922,6 +935,22 @@ static int __disp_hyp_log_stats(uint8_t *log,
 	tzdbg.stat[buf_idx].data = tzdbg.disp_buf;
 	return len;
 }
+static int __disp_rm_log_stats(uint8_t *log_ptr, uint32_t max_len)
+{
+	uint32_t i = 0;
+	/*
+	 *  Transfer data from rm dialog buff to display buffer in user space
+	 */
+	while ((i < max_len) && (i < display_buf_size)) {
+		tzdbg.disp_buf[i] = log_ptr[i];
+		i++;
+	}
+	if (i != max_len)
+		pr_err("Dropping RM log message, max_len:%d display_buf_size:%d\n",
+			i, display_buf_size);
+	tzdbg.stat[TZDBG_RM_LOG].data = tzdbg.disp_buf;
+	return i;
+}
 
 static int print_text(char *intro_message,
 			unsigned char *text_addr,
@@ -1045,6 +1074,55 @@ static int _disp_hyp_log_stats(size_t count)
 			log_len, count, TZDBG_HYP_LOG);
 }
 
+static int _disp_rm_log_stats(size_t count)
+{
+	static struct rmdbg_log_pos_t log_start = { 0 };
+	struct rmdbg_log_hdr_t *p_log_hdr = NULL;
+	uint8_t *log_ptr = NULL;
+	uint32_t log_len = 0;
+	static bool wrap_around = { false };
+
+	/* Return 0 to close the display file,if there is nothing else to do */
+	if ((log_start.size == 0x0) && wrap_around) {
+		wrap_around = false;
+		return 0;
+	}
+	/* Copy RM log data to tzdbg diag buffer for the first time */
+	/* Initialize the tracking data structure */
+	if (tzdbg.rmlog_rw_buf_size != 0) {
+		if (!wrap_around) {
+			memcpy_fromio((void *)tzdbg.rm_diag_buf,
+					tzdbg.rmlog_virt_iobase,
+					tzdbg.rmlog_rw_buf_size);
+			/* get RM header info first */
+			p_log_hdr = (struct rmdbg_log_hdr_t *)tzdbg.rm_diag_buf;
+			/* Update RM log buffer index tracker and its size */
+			log_start.read_idx = 0x0;
+			log_start.size = p_log_hdr->size;
+		}
+		/* Update RM log buffer starting ptr */
+		log_ptr =
+			(uint8_t *) ((unsigned char *)tzdbg.rm_diag_buf +
+				 sizeof(struct rmdbg_log_hdr_t));
+	} else {
+	/* Return 0 to close the display file,if there is nothing else to do */
+		pr_err("There is no RM log to read, size is %d!\n",
+			tzdbg.rmlog_rw_buf_size);
+		return 0;
+	}
+	log_len = log_start.size;
+	log_ptr += log_start.read_idx;
+	/* Check if we exceed the max length provided by user space */
+	log_len = (count > log_len) ? log_len : count;
+	/* Update tracking data structure */
+	log_start.size -= log_len;
+	log_start.read_idx += log_len;
+
+	if (log_start.size)
+		wrap_around =  true;
+	return __disp_rm_log_stats(log_ptr, log_len);
+}
+
 static int _disp_qsee_log_stats(size_t count)
 {
 	static struct tzdbg_log_pos_t log_start = {0};
@@ -1148,6 +1226,10 @@ static ssize_t tzdbg_fs_read_unencrypted(int tz_id, char __user *buf,
 		len = _disp_hyp_log_stats(count);
 		*offp = 0;
 		break;
+	case TZDBG_RM_LOG:
+		len = _disp_rm_log_stats(count);
+		*offp = 0;
+		break;
 	default:
 		break;
 	}
@@ -1213,7 +1295,8 @@ static ssize_t tzdbg_fs_read(struct file *file, char __user *buf,
 	}
 
 	if (!tzdbg.is_encrypted_log_enabled ||
-		(tz_id == TZDBG_HYP_GENERAL || tz_id == TZDBG_HYP_LOG))
+	    (tz_id == TZDBG_HYP_GENERAL || tz_id == TZDBG_HYP_LOG)
+	    || tz_id == TZDBG_RM_LOG)
 		return tzdbg_fs_read_unencrypted(tz_id, buf, count, offp);
 	else
 		return tzdbg_fs_read_encrypted(tz_id, buf, count, offp);
@@ -1412,6 +1495,7 @@ err:
 static void tzdbg_fs_exit(struct platform_device *pdev)
 {
 	struct proc_dir_entry *dent_dir;
+
 	dent_dir = platform_get_drvdata(pdev);
 	if (dent_dir)
 		remove_proc_entry(TZDBG_DIR_NAME, NULL);
@@ -1460,6 +1544,55 @@ static int __update_hypdbg_base(struct platform_device *pdev,
 	return 0;
 }
 
+static int __update_rmlog_base(struct platform_device *pdev,
+			       void __iomem *virt_iobase)
+{
+	uint32_t rmlog_address;
+	uint32_t rmlog_size;
+	uint32_t *ptr = NULL;
+
+	/* if we don't get the node just ignore it */
+	if (of_property_read_u32((&pdev->dev)->of_node, "rmlog-address",
+							&rmlog_address)) {
+		dev_err(&pdev->dev, "RM log address is not defined\n");
+		tzdbg.rmlog_rw_buf_size = 0;
+		return 0;
+	}
+	/* if we don't get the node just ignore it */
+	if (of_property_read_u32((&pdev->dev)->of_node, "rmlog-size",
+							&rmlog_size)) {
+		dev_err(&pdev->dev, "RM log size is not defined\n");
+		tzdbg.rmlog_rw_buf_size = 0;
+		return 0;
+	}
+
+	tzdbg.rmlog_rw_buf_size = rmlog_size;
+
+	/* Check if there is RM log to read */
+	if (!tzdbg.rmlog_rw_buf_size) {
+		tzdbg.rmlog_virt_iobase = NULL;
+		tzdbg.rm_diag_buf = NULL;
+		dev_err(&pdev->dev, "RM log size is %d\n",
+			tzdbg.rmlog_rw_buf_size);
+		return 0;
+	}
+
+	tzdbg.rmlog_virt_iobase = devm_ioremap(&pdev->dev,
+					rmlog_address,
+					rmlog_size);
+	if (!tzdbg.rmlog_virt_iobase) {
+		dev_err(&pdev->dev, "ERROR could not ioremap: start=%pr, len=%u\n",
+			rmlog_address, tzdbg.rmlog_rw_buf_size);
+		return -ENXIO;
+	}
+
+	ptr = kzalloc(tzdbg.rmlog_rw_buf_size, GFP_KERNEL);
+	if (!ptr)
+		return -ENOMEM;
+
+	tzdbg.rm_diag_buf = (uint8_t *)ptr;
+	return 0;
+}
 static int tzdbg_get_tz_version(void)
 {
 	u64 version;
@@ -1570,6 +1703,13 @@ static int tz_log_probe(struct platform_device *pdev)
 					__func__, ret);
 				return -EINVAL;
 			}
+			ret = __update_rmlog_base(pdev, virt_iobase);
+			if (ret) {
+				dev_err(&pdev->dev,
+					"%s: fail to get rmlog_base ret %d\n",
+					__func__, ret);
+				return -EINVAL;
+			}
 		} else {
 			dev_info(&pdev->dev, "Hyp log service not support\n");
 		}