[qca-nss-drv] Dump logbuffer during the coredump

Change-Id: Icacb3056cb4baac1c18d0d3a802cadf2d94d1914
Signed-off-by: Cemil Coskun <ccoskun@codeaurora.org>
diff --git a/nss_core.c b/nss_core.c
index 244b87e..d5ed5c4 100644
--- a/nss_core.c
+++ b/nss_core.c
@@ -2891,4 +2891,3 @@
 	NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_PACKET]);
 	return status;
 }
-
diff --git a/nss_core.h b/nss_core.h
index 82897c9..3fc12b6 100644
--- a/nss_core.h
+++ b/nss_core.h
@@ -217,6 +217,13 @@
 #define NSS_TX_UNBLOCKED_PROCESSING_WEIGHT 1
 
 /*
+ * Cache line size of the NSS.
+ */
+#define NSS_CACHE_LINE_SIZE 32
+
+/*
+ * Statistics struct
+ *
  * INFO: These numbers are based on previous generation chip
  *	These may change in future
  */
@@ -270,14 +277,18 @@
 #if (NSS_DT_SUPPORT == 1)
 #define NSSTCM_FREQ		400000000	/* NSS TCM Frequency in Hz */
 
-/* NSS Clock names */
+/*
+ * NSS Clock names
+ */
 #define NSS_CORE_CLK		"nss-core-clk"
 #define NSS_TCM_SRC_CLK		"nss-tcm-src"
 #define NSS_TCM_CLK		"nss-tcm-clk"
 #define NSS_FABRIC0_CLK		"nss-fab0-clk"
 #define NSS_FABRIC1_CLK		"nss-fab1-clk"
 
-/* NSS Fabric speeds */
+/*
+ * NSS Fabric speeds
+ */
 #define NSS_FABRIC0_TURBO	533000000
 #define NSS_FABRIC1_TURBO	266500000
 #define NSS_FABRIC0_NOMINAL	400000000
diff --git a/nss_coredump.c b/nss_coredump.c
index 4692d48..ee3888b 100644
--- a/nss_coredump.c
+++ b/nss_coredump.c
@@ -1,6 +1,6 @@
 /*
  **************************************************************************
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * above copyright notice and this permission notice appear in all copies.
@@ -21,6 +21,7 @@
 
 #include "nss_core.h"
 #include "nss_hal.h"
+#include "nss_log.h"
 #include <linux/kernel.h>
 #include <linux/notifier.h>	/* for panic_notifier_list */
 #include <linux/jiffies.h>	/* for time */
@@ -131,23 +132,72 @@
 void nss_fw_coredump_notify(struct nss_ctx_instance *nss_own,
 				int intr __attribute__ ((unused)))
 {
-	int i;
+	int i, j, curr_index, useful_entries;
+	struct nss_log_descriptor *nld;
+	struct nss_log_entry *nle_init, *nle_print;
+	dma_addr_t dma_addr;
+	uint32_t offset, index;
+
 	nss_warning("\n%p: COREDUMP %x Baddr %p stat %x\n",
 			nss_own, intr, nss_own->nmap, nss_own->state);
 	nss_own->state |= NSS_CORE_STATE_FW_DEAD;
 	queue_delayed_work(coredump_workqueue, &coredump_queuewait,
 			msecs_to_jiffies(3456));
 
+	/*
+	 * If external log buffer is not set, use the nss initial log buffer.
+	 */
+	nld = (struct nss_log_descriptor *)(nss_rbe[nss_own->id].addr);
+	dma_addr = nss_rbe[nss_own->id].dma_addr;
+	if (!nld) {
+		nld = nss_own->meminfo_ctx.logbuffer;
+		dma_addr = nss_own->meminfo_ctx.logbuffer_dma;
+	}
+
+	dma_sync_single_for_cpu(NULL, dma_addr, sizeof(struct nss_log_descriptor), DMA_FROM_DEVICE);
+
+	/*
+	 * If the current entry is smaller than or equal to the number of NSS_LOG_COREDUMP_LINE_NUM,
+	 * only print whatever is in the buffer. Otherwise, dump last NSS_LOG_COREDUMP_LINE_NUM
+	 * to the dmessage.
+	 */
+	nss_info_always("\n%p: Starting NSS-FW logbuffer dump for core %u\n",
+			nss_own, nss_own->id);
+	nle_init = nld->log_ring_buffer;
+	if (nld->current_entry <= NSS_LOG_COREDUMP_LINE_NUM) {
+		curr_index = 0;
+		useful_entries = nld->current_entry;
+	} else {
+		curr_index = ((nld->current_entry - NSS_LOG_COREDUMP_LINE_NUM) % nld->log_nentries);
+		useful_entries = NSS_LOG_COREDUMP_LINE_NUM;
+	}
+
+	nle_print = nle_init + curr_index;
+	for (j = index = curr_index; j < (curr_index + useful_entries); j++, index++) {
+		if (j == nld->log_nentries) {
+			nle_print = nle_init;
+			index = 0;
+		}
+
+		offset = (index * sizeof(struct nss_log_entry))
+			+ offsetof(struct nss_log_descriptor, log_ring_buffer);
+		dma_sync_single_for_cpu(NULL, dma_addr + offset,
+				sizeof(struct nss_log_entry), DMA_FROM_DEVICE);
+		nss_info_always("%p: %s\n", nss_own, nle_print->message);
+		nle_print++;
+	}
+
 	if (nss_own->state & NSS_CORE_STATE_PANIC)
 		return;
 
 	for (i = 0; i < NSS_MAX_CORES; i++) {
-		struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[i];
+
 		/*
 		 * only for two core now; if more cores, a counter is required
 		 * to remember how many core has dumped.
 		 * Do not call panic() till all core dumped.
 		 */
+		struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[i];
 		if (nss_ctx != nss_own) {
 			if (nss_ctx->state & NSS_CORE_STATE_FW_DEAD ||
 					!nss_ctx->nmap) {
diff --git a/nss_log.c b/nss_log.c
index 4cf0795..7a0fdd5 100644
--- a/nss_log.c
+++ b/nss_log.c
@@ -46,17 +46,7 @@
 	int nss_id;		/* NSS Core id being used */
 };
 
-/*
- * Saves the ring buffer address for logging per NSS core
- */
-struct nss_ring_buffer_addr {
-	void *addr;		/* Pointer to struct nss_log_descriptor */
-	dma_addr_t dma_addr;	/* DMA Handle */
-	uint32_t nentries;	/* Number of entries in the ring buffer */
-	int refcnt;		/* Reference count */
-};
-
-static struct nss_ring_buffer_addr nss_rbe[NSS_MAX_CORES];
+struct nss_log_ring_buffer_addr nss_rbe[NSS_MAX_CORES];
 
 static DEFINE_MUTEX(nss_log_mutex);
 static wait_queue_head_t nss_log_wq;
@@ -140,7 +130,7 @@
 	 * Increment the reference count so that we don't free
 	 * the memory
 	 */
-	nss_rbe[nss_id].refcnt++;
+	nss_rbe[nss_id].ref_cnt++;
 	data->nss_id = nss_id;
 	filp->private_data = data;
 	mutex_unlock(&nss_log_mutex);
@@ -162,9 +152,9 @@
 	}
 
 	mutex_lock(&nss_log_mutex);
-	nss_rbe[data->nss_id].refcnt--;
-	BUG_ON(nss_rbe[data->nss_id].refcnt < 0);
-	if (nss_rbe[data->nss_id].refcnt == 0) {
+	nss_rbe[data->nss_id].ref_cnt--;
+	BUG_ON(nss_rbe[data->nss_id].ref_cnt < 0);
+	if (!nss_rbe[data->nss_id].ref_cnt) {
 		wake_up(&nss_log_wq);
 	}
 	mutex_unlock(&nss_log_mutex);
@@ -217,7 +207,7 @@
 	/*
 	 * Get the current index
 	 */
-	dma_sync_single_for_cpu(NULL, data->dma_addr, sizeof (struct nss_log_descriptor), DMA_FROM_DEVICE);
+	dma_sync_single_for_cpu(NULL, data->dma_addr, sizeof(struct nss_log_descriptor), DMA_FROM_DEVICE);
 	entry = nss_log_current_entry(desc);
 
 	/*
@@ -230,7 +220,7 @@
 	/*
 	 * If this is the first read (after open) on our device file.
 	 */
-	if (unlikely(*ppos == 0)) {
+	if (unlikely(!(*ppos))) {
 		/*
 		 * If log buffer has rolled over. Almost all the time
 		 * it will be true.
@@ -258,7 +248,7 @@
 	 */
 	while (entry > data->last_entry) {
 		index = offset = (data->last_entry % data->nentries);
-		offset = (offset * sizeof (struct nss_log_entry))
+		offset = (offset * sizeof(struct nss_log_entry))
 			 + offsetof(struct nss_log_descriptor, log_ring_buffer);
 
 		dma_sync_single_for_cpu(NULL, data->dma_addr + offset,
@@ -274,13 +264,12 @@
 		 * Copy to user buffer and if we fail then we return
 		 * failure.
 		 */
-	        if (copy_to_user(buf + bytes, msg, b) == 0) {
-			bytes += b;
-		} else {
-			bytes = -EFAULT;
-			break;
+		if (copy_to_user(buf + bytes, msg, b)) {
+			return -EFAULT;
 		}
 
+		bytes += b;
+
 		/*
 		 * If we ran out of space in the buffer.
 		 */
@@ -316,7 +305,7 @@
  * nss_debug_interface_event()
  *	Received an event from NSS FW
  */
-static void nss_debug_interface_event(void *app_data, struct nss_debug_interface_msg *nim)
+static void nss_debug_interface_event(void *app_data, struct nss_log_debug_interface_msg *nim)
 {
 	struct nss_cmn_msg *ncm = (struct nss_cmn_msg *)nim;
 
@@ -327,11 +316,11 @@
 
 /*
  * nss_debug_interface_handler()
- * 	handle NSS -> HLOS messages for debug interfaces
+ *	handle NSS -> HLOS messages for debug interfaces
  */
 static void nss_debug_interface_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data)
 {
-	struct nss_debug_interface_msg *ntm = (struct nss_debug_interface_msg *)ncm;
+	struct nss_log_debug_interface_msg *ntm = (struct nss_log_debug_interface_msg *)ncm;
 	nss_log_msg_callback_t cb;
 
 	BUG_ON(ncm->interface != NSS_DEBUG_INTERFACE);
@@ -344,7 +333,7 @@
 		return;
 	}
 
-	if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_debug_interface_msg)) {
+	if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_log_debug_interface_msg)) {
 		nss_warning("%p: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
 		return;
 	}
@@ -373,9 +362,9 @@
 
 /*
  * nss_debug_interface_tx()
- * 	Transmit a debug interface message to NSS FW
+ *	Transmit a debug interface message to NSS FW
  */
-static nss_tx_status_t nss_debug_interface_tx(struct nss_ctx_instance *nss_ctx, struct nss_debug_interface_msg *msg)
+static nss_tx_status_t nss_debug_interface_tx(struct nss_ctx_instance *nss_ctx, struct nss_log_debug_interface_msg *msg)
 {
 	struct nss_cmn_msg *ncm = &msg->cm;
 
@@ -401,17 +390,14 @@
  */
 bool nss_debug_log_buffer_alloc(uint8_t nss_id, uint32_t nentry)
 {
-	struct nss_ring_buffer_addr old_rbe;
-	struct nss_debug_interface_msg msg;
-	struct nss_debug_log_memory_msg *dbg;
+	struct nss_log_debug_interface_msg msg;
+	struct nss_log_debug_memory_msg *dbg;
 	struct nss_top_instance *nss_top;
 	struct nss_ctx_instance *nss_ctx;
 	dma_addr_t dma_addr;
 	uint32_t size;
 	void *addr = NULL;
 	nss_tx_status_t status;
-	bool err = false;
-	bool old_state = false;
 
 	if (nss_id >= NSS_MAX_CORES) {
 		return false;
@@ -425,9 +411,7 @@
 		return false;
 	}
 
-	memset(&msg, 0, sizeof(struct nss_debug_interface_msg));
-
-	size = sizeof (struct nss_log_descriptor) + (sizeof (struct nss_log_entry) * nentry);
+	size = sizeof(struct nss_log_descriptor) + (sizeof(struct nss_log_entry) * nentry);
 	addr = kmalloc(size, GFP_ATOMIC);
 	if (!addr) {
 		nss_warning("%p: Failed to allocate memory for logging (size:%d)\n", nss_ctx, size);
@@ -438,7 +422,8 @@
 	dma_addr = (uint32_t)dma_map_single(nss_ctx->dev, addr, size, DMA_FROM_DEVICE);
 	if (unlikely(dma_mapping_error(nss_ctx->dev, dma_addr))) {
 		nss_warning("%p: Failed to map address in DMA", nss_ctx);
-		goto fail2;
+		kfree(addr);
+		return false;
 	}
 
 	/*
@@ -448,40 +433,32 @@
 	mutex_lock(&nss_log_mutex);
 	if (nss_rbe[nss_id].addr) {
 		mutex_unlock(&nss_log_mutex);
-		if (!wait_event_timeout(nss_log_wq, nss_rbe[nss_id].refcnt == 0, 5 * HZ)) {
+
+		/*
+		 * Someone is using the current logbuffer. Wait until ref count become 0.
+		 * We have to return mutex here, because the current user requires it to
+		 * release the reference.
+		 */
+		if (!wait_event_timeout(nss_log_wq, !nss_rbe[nss_id].ref_cnt, 5 * HZ)) {
 			nss_warning("%p: Timeout waiting for refcnt to become 0\n", nss_ctx);
-			goto fail1;
+			goto fail;
 		}
 
 		mutex_lock(&nss_log_mutex);
 		if (!nss_rbe[nss_id].addr) {
 			mutex_unlock(&nss_log_mutex);
-			goto fail1;
+			goto fail;
 		}
-		if (nss_rbe[nss_id].refcnt > 0) {
+		if (nss_rbe[nss_id].ref_cnt > 0) {
 			mutex_unlock(&nss_log_mutex);
-			nss_warning("%p: Some other thread is condenting..opting out\n", nss_ctx);
-			goto fail1;
+			nss_warning("%p: Some other thread is contending..opting out\n", nss_ctx);
+			goto fail;
 		}
-
-		/*
-		 * Save the original dma buffer. In case we fail down the line, we will
-		 * restore the state. Otherwise, old_state will be freed once we get
-		 * ACK from NSS FW.
-		 */
-		old_state = true;
-		memcpy(&old_rbe, &nss_rbe[nss_id], sizeof (struct nss_ring_buffer_addr));
 	}
 
-	nss_rbe[nss_id].addr = addr;
-	nss_rbe[nss_id].nentries = nentry;
-	nss_rbe[nss_id].refcnt = 1;	/* Block other threads till we are done */
-	nss_rbe[nss_id].dma_addr = dma_addr;
-	mutex_unlock(&nss_log_mutex);
-
-	memset(&msg, 0, sizeof (struct nss_debug_interface_msg));
+	memset(&msg, 0, sizeof(struct nss_log_debug_interface_msg));
 	nss_cmn_msg_init(&msg.cm, NSS_DEBUG_INTERFACE, NSS_DEBUG_INTERFACE_TYPE_LOG_BUF_INIT,
-		sizeof(struct nss_debug_log_memory_msg), nss_debug_interface_event, NULL);
+		sizeof(struct nss_log_debug_memory_msg), nss_debug_interface_event, NULL);
 
 	dbg = &msg.msg.addr;
 	dbg->nentry = nentry;
@@ -491,80 +468,49 @@
 	msg_event = false;
 	status = nss_debug_interface_tx(nss_ctx, &msg);
 	if (status != NSS_TX_SUCCESS) {
+		mutex_unlock(&nss_log_mutex);
 		nss_warning("%p: Failed to send message to debug interface:%d\n", nss_ctx, status);
-		err = true;
-	} else {
-		int r;
+		goto fail;
+	}
 
-		/*
-		 * Wait for 5 seconds since this is a critical operation.
-		 */
-		r = wait_event_timeout(msg_wq, msg_event == true, 5 * HZ);
-		if (r == 0) {
-			nss_warning("%p: Timeout send message to debug interface\n", nss_ctx);
-			err = true;
-		} else if (msg_response != NSS_CMN_RESPONSE_ACK) {
-			nss_warning("%p: Response error for send message to debug interface:%d\n", nss_ctx, msg_response);
-			err = true;
-		}
+	/*
+	 * Wait for 5 seconds since this is a critical operation.
+	 * Mutex is not unlocked here because we do not want someone to acquire the mutex and use the logbuffer
+	 * while we are waiting message from NSS.
+	 */
+	if (!wait_event_timeout(msg_wq, msg_event, 5 * HZ)) {
+		mutex_unlock(&nss_log_mutex);
+		nss_warning("%p: Timeout send message to debug interface\n", nss_ctx);
+		goto fail;
+	}
+
+	if (msg_response != NSS_CMN_RESPONSE_ACK) {
+		mutex_unlock(&nss_log_mutex);
+		nss_warning("%p: Response error for send message to debug interface:%d\n", nss_ctx, msg_response);
+		goto fail;
 	}
 
 	/*
 	 * If we had to free the previous allocation for ring buffer.
 	 */
-	if (old_state == true) {
-		/*
-		 * If we didn't fail, then we must unmap and free previous dma buffer
-		 */
-		if (err == false) {
-			uint32_t old_size;
-
-			old_size = sizeof (struct nss_log_descriptor) +
-				(sizeof (struct nss_log_entry) * old_rbe.nentries);
-			dma_unmap_single(nss_ctx->dev, old_rbe.dma_addr, old_size, DMA_FROM_DEVICE);
-			kfree(old_rbe.addr);
-		} else {
-			/*
-			 * Restore the original dma buffer since we failed somewhere.
-			 */
-			mutex_lock(&nss_log_mutex);
-			memcpy(&nss_rbe[nss_id], &old_rbe, sizeof (struct nss_ring_buffer_addr));
-			mutex_unlock(&nss_log_mutex);
-			wake_up(&nss_log_wq);
-		}
-	} else {
-		/*
-		 * There was no logbuffer allocated from host side.
-		 */
-
-		/*
-		 * If there was error, then we need to reset back. Note that we are
-		 * still holding refcnt.
-		 */
-		if (err == true) {
-			mutex_lock(&nss_log_mutex);
-			nss_rbe[nss_id].addr = NULL;
-			nss_rbe[nss_id].nentries = 0;
-			nss_rbe[nss_id].refcnt = 0;
-			nss_rbe[nss_id].dma_addr = 0;
-			mutex_unlock(&nss_log_mutex);
-			wake_up(&nss_log_wq);
-		}
+	if (nss_rbe[nss_id].addr) {
+		uint32_t old_size;
+		old_size = sizeof(struct nss_log_descriptor) +
+			(sizeof(struct nss_log_entry) * nss_rbe[nss_id].nentries);
+		dma_unmap_single(nss_ctx->dev, nss_rbe[nss_id].dma_addr, old_size, DMA_FROM_DEVICE);
+		kfree(nss_rbe[nss_id].addr);
 	}
 
-	if (err == false) {
-		mutex_lock(&nss_log_mutex);
-		nss_rbe[nss_id].refcnt--;	/* we are done */
-		mutex_unlock(&nss_log_mutex);
-		wake_up(&nss_log_wq);
-		return true;
-	}
+	nss_rbe[nss_id].addr = addr;
+	nss_rbe[nss_id].nentries = nentry;
+	nss_rbe[nss_id].ref_cnt = 0;
+	nss_rbe[nss_id].dma_addr = dma_addr;
+	mutex_unlock(&nss_log_mutex);
+	wake_up(&nss_log_wq);
+	return true;
 
-fail1:
-	if (addr) {
-		dma_unmap_single(NULL, dma_addr, size, DMA_FROM_DEVICE);
-	}
-fail2:
+fail:
+	dma_unmap_single(NULL, dma_addr, size, DMA_FROM_DEVICE);
 	kfree(addr);
 	wake_up(&nss_log_wq);
 	return false;
@@ -590,7 +536,7 @@
 	}
 
 	if (nss_ctl_logbuf < 32) {
-		printk("Invalid NSS FW logbuffer size:%d (must be > 32)\n", nss_ctl_logbuf);
+		nss_warning("Invalid NSS FW logbuffer size:%d (must be > 32)\n", nss_ctl_logbuf);
 		nss_ctl_logbuf = 0;
 		return ret;
 	}
@@ -604,7 +550,7 @@
 			nss_warning("NSS logbuffer init failed with register handler:%d\n", core_status);
 		}
 
-		if (nss_debug_log_buffer_alloc(i, nss_ctl_logbuf) == false) {
+		if (!nss_debug_log_buffer_alloc(i, nss_ctl_logbuf)) {
 			nss_warning("%d: Failed to set debug log buffer on NSS core", i);
 		}
 	}
diff --git a/nss_log.h b/nss_log.h
index fd463c5..d5220d1 100644
--- a/nss_log.h
+++ b/nss_log.h
@@ -1,6 +1,6 @@
 /*
  **************************************************************************
- * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015, 2018 The Linux Foundation. All rights reserved.
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * above copyright notice and this permission notice appear in all copies.
@@ -38,10 +38,26 @@
 #define	NSS_LOG_OUTPUT_LINE_SIZE	151	/* 5 + 12 + 132 + '\n' + '\0' (see below) */
 #define	NSS_LOG_LINE_FORMAT		"%3d: %010u: %s\n"
 #define	NSS_LOG_LINE_WIDTH		132
-#define	NSS_CACHE_LINE_SIZE		32
 #define	NSS_LOG_COOKIE			0xFF785634
 
 /*
+ * Dump last N entry during the coredump.
+ * This number should be lower than the minimum size of the logbuf
+ * which 32 right now.
+ */
+#define NSS_LOG_COREDUMP_LINE_NUM	10
+
+/*
+ * Saves the ring buffer address for logging per NSS core
+ */
+struct nss_log_ring_buffer_addr {
+	void *addr;		/* Pointer to struct nss_log_descriptor */
+	dma_addr_t dma_addr;	/* DMA Handle */
+	uint32_t nentries;	/* Number of entries in the ring buffer */
+	int ref_cnt;		/* Reference count */
+};
+
+/*
  * nss_log_entry is shared between Host and NSS FW
  */
 struct nss_log_entry {
@@ -66,16 +82,16 @@
 	struct nss_log_entry log_ring_buffer[0];	/* The actual log entry ring buffer */
 } __attribute__((aligned(NSS_CACHE_LINE_SIZE)));
 
-struct nss_debug_log_memory_msg {
+struct nss_log_debug_memory_msg {
 	uint32_t version;
 	uint32_t nentry;
 	uint32_t phy_addr;
 };
 
-struct nss_debug_interface_msg {
+struct nss_log_debug_interface_msg {
 	struct nss_cmn_msg cm;
 	union {
-		struct nss_debug_log_memory_msg addr;
+		struct nss_log_debug_memory_msg addr;
 	} msg;
 };
 
@@ -87,11 +103,13 @@
  *
  * @return void
  */
-typedef void (*nss_log_msg_callback_t)(void *app_data, struct nss_debug_interface_msg *msg);
+typedef void (*nss_log_msg_callback_t)(void *app_data, struct nss_log_debug_interface_msg *msg);
 
 /*
  * Exported by nss_init.c and used in nss_log.c
  */
 extern int nss_ctl_logbuf;
 
+extern struct nss_log_ring_buffer_addr nss_rbe[NSS_MAX_CORES];
+
 #endif /* __NSS_LOG_H */
diff --git a/nss_meminfo.c b/nss_meminfo.c
index 2028948..719a4aa 100644
--- a/nss_meminfo.c
+++ b/nss_meminfo.c
@@ -299,6 +299,12 @@
 			mem_ctx->if_map = (struct nss_if_mem_map *)kern_addr;
 		}
 
+		if (!strcmp(r->name, "debug_boot_log_desc")) {
+			mem_ctx->logbuffer_memtype = mtype;
+			mem_ctx->logbuffer_dma = dma_addr;
+			mem_ctx->logbuffer = (struct nss_log_descriptor *)kern_addr;
+		}
+
 		/*
 		 * Flush the updated meminfo request.
 		 */
diff --git a/nss_meminfo.h b/nss_meminfo.h
index bd7a8d7..d2f5d1e 100644
--- a/nss_meminfo.h
+++ b/nss_meminfo.h
@@ -112,6 +112,9 @@
 	struct nss_if_mem_map *if_map;			/* nss_if_mem_map_inst virtual address */
 	uint32_t if_map_dma;				/* nss_if_mem_map_inst physical address */
 	enum nss_meminfo_memtype if_map_memtype;	/* Memory type for nss_if_mem_map */
+	struct nss_log_descriptor *logbuffer;		/* nss_logbuffer virtual address */
+	uint32_t logbuffer_dma;				/* nss_logbuffer physical address */
+	enum nss_meminfo_memtype logbuffer_memtype;	/* Memory type for logbuffer */
 	struct nss_meminfo_map meminfo_map;		/* Meminfo map */
 	struct nss_meminfo_block_list block_lists[NSS_MEMINFO_MEMTYPE_MAX];
 							/* Block lists for each memory type */