diff mbox series

[V4,01/21] hw: Move lpc firmware space helpers

Message ID 20220414134404.39888-2-clombard@linux.vnet.ibm.com
State Superseded
Headers show
Series Implement MCTP and PLDM features | expand

Commit Message

Christophe Lombard April 14, 2022, 1:43 p.m. UTC
Add new lpc helpers for doing a bulk io to firmware space.

Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
---
 hw/lpc.c      | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/lpc.h |  6 +++++
 2 files changed, 80 insertions(+)

Comments

Nicholas Piggin April 21, 2022, 3:32 a.m. UTC | #1
Excerpts from Christophe Lombard's message of April 14, 2022 11:43 pm:
> Add new lpc helpers for doing a bulk io to firmware space.
> 
> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
> ---
>  hw/lpc.c      | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/lpc.h |  6 +++++
>  2 files changed, 80 insertions(+)
> 
> diff --git a/hw/lpc.c b/hw/lpc.c
> index bf3ab1fa..caaacc46 100644
> --- a/hw/lpc.c
> +++ b/hw/lpc.c
> @@ -667,6 +667,80 @@ int64_t lpc_probe_read(enum OpalLPCAddressType addr_type, uint32_t addr,
>  	return __lpc_read_sanity(addr_type, addr, data, sz, true);
>  }
>  
> +int64_t lpc_fw_read(uint32_t off, void *buf, uint32_t len)
> +{
> +	int rc;
> +
> +	prlog(PR_TRACE, "Reading 0x%08x bytes at FW offset 0x%08x\n",
> +	      len, off);
> +
> +	while (len) {
> +		uint32_t chunk;
> +		uint32_t dat;
> +
> +		/* XXX: make this read until it's aligned */
> +		if (len > 3 && !(off & 3)) {
> +			rc = lpc_read(OPAL_LPC_FW, off, &dat, 4);


Looks fine but can these functions consolidate the 3 pairs of functions 
that seem to do the same thing already in the tree?

Thanks,
Nick
Christophe Lombard April 25, 2022, 8:04 a.m. UTC | #2
Le 21/04/2022 à 05:32, Nicholas Piggin a écrit :
> Excerpts from Christophe Lombard's message of April 14, 2022 11:43 pm:
>> Add new lpc helpers for doing a bulk io to firmware space.
>>
>> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
>> ---
>>   hw/lpc.c      | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>   include/lpc.h |  6 +++++
>>   2 files changed, 80 insertions(+)
>>
>> diff --git a/hw/lpc.c b/hw/lpc.c
>> index bf3ab1fa..caaacc46 100644
>> --- a/hw/lpc.c
>> +++ b/hw/lpc.c
>> @@ -667,6 +667,80 @@ int64_t lpc_probe_read(enum OpalLPCAddressType addr_type, uint32_t addr,
>>   	return __lpc_read_sanity(addr_type, addr, data, sz, true);
>>   }
>>   
>> +int64_t lpc_fw_read(uint32_t off, void *buf, uint32_t len)
>> +{
>> +	int rc;
>> +
>> +	prlog(PR_TRACE, "Reading 0x%08x bytes at FW offset 0x%08x\n",
>> +	      len, off);
>> +
>> +	while (len) {
>> +		uint32_t chunk;
>> +		uint32_t dat;
>> +
>> +		/* XXX: make this read until it's aligned */
>> +		if (len > 3 && !(off & 3)) {
>> +			rc = lpc_read(OPAL_LPC_FW, off, &dat, 4);
>
> Looks fine but can these functions consolidate the 3 pairs of functions
> that seem to do the same thing already in the tree?

Certainly, yes. Let me look at this point and try to have common
functions, if it's possible.

Thanks,
Christophe

> Thanks,
> Nick
diff mbox series

Patch

diff --git a/hw/lpc.c b/hw/lpc.c
index bf3ab1fa..caaacc46 100644
--- a/hw/lpc.c
+++ b/hw/lpc.c
@@ -667,6 +667,80 @@  int64_t lpc_probe_read(enum OpalLPCAddressType addr_type, uint32_t addr,
 	return __lpc_read_sanity(addr_type, addr, data, sz, true);
 }
 
+int64_t lpc_fw_read(uint32_t off, void *buf, uint32_t len)
+{
+	int rc;
+
+	prlog(PR_TRACE, "Reading 0x%08x bytes at FW offset 0x%08x\n",
+	      len, off);
+
+	while (len) {
+		uint32_t chunk;
+		uint32_t dat;
+
+		/* XXX: make this read until it's aligned */
+		if (len > 3 && !(off & 3)) {
+			rc = lpc_read(OPAL_LPC_FW, off, &dat, 4);
+			if (!rc) {
+				/*
+				 * lpc_read swaps to CPU endian but it's not
+				 * really a 32-bit value, so convert back.
+				 */
+				*(__be32 *)buf = cpu_to_be32(dat);
+			}
+			chunk = 4;
+		} else {
+			rc = lpc_read(OPAL_LPC_FW, off, &dat, 1);
+			if (!rc)
+				*(uint8_t *)buf = dat;
+			chunk = 1;
+		}
+		if (rc) {
+			prlog(PR_ERR, "lpc_read failure %d to FW 0x%08x\n", rc, off);
+			return rc;
+		}
+		len -= chunk;
+		off += chunk;
+		buf += chunk;
+	}
+
+	return 0;
+}
+
+int64_t lpc_fw_write(uint32_t off, const void *buf, uint32_t len)
+{
+	int rc;
+
+	prlog(PR_TRACE, "Writing 0x%08x bytes at FW offset 0x%08x\n",
+	      len, off);
+
+	while (len) {
+		uint32_t chunk;
+
+		if (len > 3 && !(off & 3)) {
+			/* endian swap: see lpc_window_write */
+			uint32_t dat = be32_to_cpu(*(__be32 *)buf);
+
+			rc = lpc_write(OPAL_LPC_FW, off, dat, 4);
+			chunk = 4;
+		} else {
+			uint8_t dat = *(uint8_t *)buf;
+
+			rc = lpc_write(OPAL_LPC_FW, off, dat, 1);
+			chunk = 1;
+		}
+		if (rc) {
+			prlog(PR_ERR, "lpc_write failure %d to FW 0x%08x\n", rc, off);
+			return rc;
+		}
+		len -= chunk;
+		off += chunk;
+		buf += chunk;
+	}
+
+	return 0;
+}
+
 /*
  * The "OPAL" variant add the emulation of 2 and 4 byte accesses using
  * byte accesses for IO and MEM space in order to be compatible with
diff --git a/include/lpc.h b/include/lpc.h
index b641aa4e..ce9c33dc 100644
--- a/include/lpc.h
+++ b/include/lpc.h
@@ -102,6 +102,12 @@  extern int64_t lpc_probe_write(enum OpalLPCAddressType addr_type, uint32_t addr,
 extern int64_t lpc_probe_read(enum OpalLPCAddressType addr_type, uint32_t addr,
 			      uint32_t *data, uint32_t sz);
 
+/*
+ * helpers for doing a bulk io to firmware space.
+ */
+extern int64_t lpc_fw_read(uint32_t addr, void *buf, uint32_t sz);
+extern int64_t lpc_fw_write(uint32_t addr, const void *buf, uint32_t sz);
+
 /* Mark LPC bus as used by console */
 extern void lpc_used_by_console(void);