astlpc: Force FW2AHB to map reserved memory

Traditionally the job of handling this mapping has been the
responsibilty of another daemon, but it's less weird if we just enforce
the requirement here were it matters. Anyone using the FW2AHB has to do
so in a coordinated fashion, and the operation is idempotent.

This allows us to avoid taking an unnatural dependency on other daemons
who may also configure the bridge.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: Ic4e0ef8956e9b1d32e557e73d58058e461c372df
diff --git a/astlpc.c b/astlpc.c
index 388dc11..33eb8e0 100644
--- a/astlpc.c
+++ b/astlpc.c
@@ -1225,6 +1225,42 @@
 		return -1;
 	}
 
+	/*
+	 * 🚨🚨🚨
+	 *
+	 * Decouple ourselves from hiomapd[1] (another user of the FW2AHB) by
+	 * mapping the FW2AHB to the reserved memory here as well.
+	 *
+	 * It's not possible to use the MCTP ASTLPC binding on machines that
+	 * need the FW2AHB bridge mapped anywhere except to the reserved memory
+	 * (e.g. the host SPI NOR).
+	 *
+	 * [1] https://github.com/openbmc/hiomapd/
+	 *
+	 * 🚨🚨🚨
+	 *
+	 * The following calculation must align with what's going on in
+	 * hiomapd's lpc.c so as not to disrupt its behaviour:
+	 *
+	 * https://github.com/openbmc/hiomapd/blob/5ff50e3cbd7702aefc185264e4adfb9952040575/lpc.c#L68
+	 *
+	 * 🚨🚨🚨
+	 */
+
+	/* Map the reserved memory at the top of the 28-bit LPC firmware address space */
+	map.addr = 0x0FFFFFFF & -map.size;
+	astlpc_prinfo(astlpc,
+		      "Configuring FW2AHB to map reserved memory at 0x%08x for 0x%x in the LPC FW cycle address-space",
+		      map.addr, map.size);
+
+	rc = ioctl(fd, ASPEED_LPC_CTRL_IOCTL_MAP, &map);
+	if (rc) {
+		astlpc_prwarn(astlpc, "Failed to map FW2AHB to reserved memory");
+		close(fd);
+		return -1;
+	}
+
+	/* Map the reserved memory into our address space */
 	lpc_map_base =
 		mmap(NULL, map.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 	if (lpc_map_base == MAP_FAILED) {