diff mbox series

[2/4] htm: Fix ability to use arbitray buffer sizes

Message ID 20180628020256.27494-2-mikey@neuling.org
State Accepted
Headers show
Series [1/4] pdbg: Fix htm return codes | expand

Commit Message

Michael Neuling June 28, 2018, 2:02 a.m. UTC
Add some buffer size checks, use the P8 bit definitions (we don't
support P9 currently and simplify the algorithm to calculate
HTM_MEM_SIZE.

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 libpdbg/htm.c | 57 +++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 46 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/libpdbg/htm.c b/libpdbg/htm.c
index 4a49628395..4e0c7aaa23 100644
--- a/libpdbg/htm.c
+++ b/libpdbg/htm.c
@@ -73,9 +73,10 @@ 
 #define HTM_MEMORY_CONF			1
 #define   HTM_MEM_ALLOC			PPC_BIT(0)
 #define   HTM_MEM_SCOPE			PPC_BITMASK(1,3)
-#define   HTM_MEM_PRIORITY		PPC_BIT(4)
-#define   HTM_MEM_SIZE_SMALL		PPC_BIT(5)
-#define   HTM_MEM_BASE			PPC_BITMASK(8,39)
+/* Note: the next 3 change on P9 */
+#define   HTM_MEM_PRIORITY		PPC_BITMASK(4,5)
+#define   HTM_MEM_SIZE_SMALL		PPC_BIT(13)
+#define   HTM_MEM_BASE			PPC_BITMASK(14,39)
 #define	  HTM_MEM_SIZE			PPC_BITMASK(40,48)
 #define HTM_STATUS			2
 #define   HTM_STATUS_MASK		PPC_BITMASK(2,19)
@@ -659,8 +660,8 @@  static bool is_configured(struct htm *htm)
 }
 static int configure_memory(struct htm *htm)
 {
-	uint64_t i, size, base, val;
-	uint16_t mem_size;
+	uint64_t size, base, val, small, mem_size;
+	int shift;
 
 	if (HTM_ERR(get_trace_size(htm, &size)))
 		return -1;
@@ -685,15 +686,49 @@  static int configure_memory(struct htm *htm)
 	/* Put mem alloc back in */
 	val |= HTM_MEM_ALLOC;
 
-	mem_size = 0;
-	i = size;
-	while ((!((val & HTM_MEM_SIZE_SMALL) && i>>20 == 16)) && (!(!(val & HTM_MEM_SIZE_SMALL) && i>>20 == 512))) {
-		mem_size <<= 1;
-		mem_size++;
-		i >>= 1;
+	/*
+	 * HTMSC_MEM_SIZE_SMALL:
+	 * 0 = Trace Mem Size from 512M to 256G
+	 * 1 = Trace Mem Size from 16M to 8G
+	 */
+	if (size < 16777216UL) {
+		PR_ERROR("memtrace size must be atleast 16MB. Currently:%lx\n", size);
+		return -1;
+	}
+	if (size > 274877906944UL) {
+		PR_ERROR("memtrace size must be smaller than 256GB. Currently:%lx\n", size);
+		return -1;
 	}
 
+	/*
+	 * The hardware has two sizes, small and large
+	 *   small: 16M  - 8G
+	 *   large: 512M - 256G
+	 * We use small for 16M-256, then large for 512M-256G
+	 *
+	 * Hardware buffer sizes:
+	 * Large  Small    HTMSC_MEM_SIZE encoding
+	 * 512M   16M        0b000000000
+	 * 1G     32M        0b000000001
+	 * 2G     64M        0b000000011
+	 * 4G     128M       0b000000111
+	 * 8G     256M       0b000001111
+	 * 16G    512M       0b000011111
+	 * 32G    1G         0b000111111
+	 * 64G    2G         0b001111111
+	 * 128G   4G         0b011111111
+	 * 256G   8G         0b111111111
+	 */
+	small = 0;
+	if (size < 512*1024*1024)
+		small = 1;
+	val = SETFIELD(HTM_MEM_SIZE_SMALL, val, small);
+	shift = 29; /* large */
+	if (small)
+		shift = 24;
+	mem_size = (size >> shift) - 1;
 	val = SETFIELD(HTM_MEM_SIZE, val, mem_size);
+
 	/*
 	 * Clear out the base
 	 * Don't use SETFIELD to write the base in since the value is