diff mbox series

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

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

Commit Message

Christophe Lombard March 4, 2022, 1:11 p.m. UTC
Move these helpers to the right location.
No functional change.

Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
---
 hw/lpc.c               | 74 ++++++++++++++++++++++++++++++++++++++++++
 include/lpc.h          |  6 ++++
 libflash/ipmi-hiomap.c | 60 ++--------------------------------
 3 files changed, 82 insertions(+), 58 deletions(-)

Comments

Abhishek Singh Tomar March 16, 2022, 9:35 a.m. UTC | #1
hello Christophe Lombard

This patch broke already existing IPMI testcase (test-ipmi-hiomap).
Modification is needed for backward compatibility.

 HOSTCC ]  libflash/test/test-ipmi-hiomap
/usr/bin/ld: x86_64-redhat-linux/libflash/ipmi-hiomap.o: in function `lpc_window_read':
/home/abhishekTomar/project/sourceCode/opal/opalAbhishekRepo/pldmNewChritopheSkiboot/skiboot_new/skiboot/libflash/ipmi-hiomap.c:565: undefined reference to `lpc_fw_read'
/usr/bin/ld: x86_64-redhat-linux/libflash/ipmi-hiomap.o: in function `lpc_window_write':
/home/abhishekTomar/project/sourceCode/opal/opalAbhishekRepo/pldmNewChritopheSkiboot/skiboot_new/skiboot/libflash/ipmi-hiomap.c:587: undefined reference to `lpc_fw_write'
collect2: error: ld returned 1 exit status
make: *** [/home/abhishekTomar/project/sourceCode/opal/opalAbhishekRepo/pldmNewChritopheSkiboot/skiboot_new/skiboot/libflash/test/Makefile.check:136: libflash/test/test-ipmi-hiomap] Error 1

Use "make check" to compile and run testcases.

Regards
Abhishek Singh Tomar

On Fri, Mar 04, 2022 at 02:11:34PM +0100, Christophe Lombard wrote:
> Move these helpers to the right location.
> No functional change.
> 
> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
> ---
>  hw/lpc.c               | 74 ++++++++++++++++++++++++++++++++++++++++++
>  include/lpc.h          |  6 ++++
>  libflash/ipmi-hiomap.c | 60 ++--------------------------------
>  3 files changed, 82 insertions(+), 58 deletions(-)
> 
> 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);
>  
> diff --git a/libflash/ipmi-hiomap.c b/libflash/ipmi-hiomap.c
> index 29355d66..c634eeeb 100644
> --- a/libflash/ipmi-hiomap.c
> +++ b/libflash/ipmi-hiomap.c
> @@ -555,7 +555,6 @@ static int lpc_window_read(struct ipmi_hiomap *ctx, uint32_t pos,
>  			   void *buf, uint32_t len)
>  {
>  	uint32_t off = ctx->current.lpc_addr + (pos - ctx->current.cur_pos);
> -	int rc;
>  
>  	if ((ctx->current.lpc_addr + ctx->current.size) < (off + len))
>  		return FLASH_ERR_PARM_ERROR;
> @@ -563,37 +562,7 @@ static int lpc_window_read(struct ipmi_hiomap *ctx, uint32_t pos,
>  	prlog(PR_TRACE, "Reading at 0x%08x for 0x%08x offset: 0x%08x\n",
>  	      pos, 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;
> +	return lpc_fw_read(off, buf, len);
>  }
>  
>  static int lpc_window_write(struct ipmi_hiomap *ctx, uint32_t pos,
> @@ -601,7 +570,6 @@ static int lpc_window_write(struct ipmi_hiomap *ctx, uint32_t pos,
>  {
>  	uint32_t off = ctx->current.lpc_addr + (pos - ctx->current.cur_pos);
>  	enum lpc_window_state state;
> -	int rc;
>  
>  	lock(&ctx->lock);
>  	state = ctx->window_state;
> @@ -616,31 +584,7 @@ static int lpc_window_write(struct ipmi_hiomap *ctx, uint32_t pos,
>  	prlog(PR_TRACE, "Writing at 0x%08x for 0x%08x offset: 0x%08x\n",
>  	      pos, len, off);
>  
> -	while(len) {
> -		uint32_t chunk;
> -
> -		if (len > 3 && !(off & 3)) {
> -			/* endian swap: see lpc_window_read */
> -			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;
> +	return lpc_fw_write(off, buf, len);
>  }
>  
>  /* Best-effort asynchronous event handling by blocklevel callbacks */
> -- 
> 2.35.1
> 
> _______________________________________________
> Skiboot mailing list
> Skiboot@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/skiboot
Christophe Lombard March 17, 2022, 1:51 p.m. UTC | #2
Le 16/03/2022 à 10:35, Abhishek SIngh Tomar a écrit :
> hello Christophe Lombard
>
> This patch broke already existing IPMI testcase (test-ipmi-hiomap).
> Modification is needed for backward compatibility.
>
>   HOSTCC ]  libflash/test/test-ipmi-hiomap
> /usr/bin/ld: x86_64-redhat-linux/libflash/ipmi-hiomap.o: in function `lpc_window_read':
> /home/abhishekTomar/project/sourceCode/opal/opalAbhishekRepo/pldmNewChritopheSkiboot/skiboot_new/skiboot/libflash/ipmi-hiomap.c:565: undefined reference to `lpc_fw_read'
> /usr/bin/ld: x86_64-redhat-linux/libflash/ipmi-hiomap.o: in function `lpc_window_write':
> /home/abhishekTomar/project/sourceCode/opal/opalAbhishekRepo/pldmNewChritopheSkiboot/skiboot_new/skiboot/libflash/ipmi-hiomap.c:587: undefined reference to `lpc_fw_write'
> collect2: error: ld returned 1 exit status
> make: *** [/home/abhishekTomar/project/sourceCode/opal/opalAbhishekRepo/pldmNewChritopheSkiboot/skiboot_new/skiboot/libflash/test/Makefile.check:136: libflash/test/test-ipmi-hiomap] Error 1
>
> Use "make check" to compile and run testcases.

Thanks. I am going to look at this point.

> Regards
> Abhishek Singh Tomar
>
> On Fri, Mar 04, 2022 at 02:11:34PM +0100, Christophe Lombard wrote:
>> Move these helpers to the right location.
>> No functional change.
>>
>> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
>> ---
>>   hw/lpc.c               | 74 ++++++++++++++++++++++++++++++++++++++++++
>>   include/lpc.h          |  6 ++++
>>   libflash/ipmi-hiomap.c | 60 ++--------------------------------
>>   3 files changed, 82 insertions(+), 58 deletions(-)
>>
>> 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);
>>   
>> diff --git a/libflash/ipmi-hiomap.c b/libflash/ipmi-hiomap.c
>> index 29355d66..c634eeeb 100644
>> --- a/libflash/ipmi-hiomap.c
>> +++ b/libflash/ipmi-hiomap.c
>> @@ -555,7 +555,6 @@ static int lpc_window_read(struct ipmi_hiomap *ctx, uint32_t pos,
>>   			   void *buf, uint32_t len)
>>   {
>>   	uint32_t off = ctx->current.lpc_addr + (pos - ctx->current.cur_pos);
>> -	int rc;
>>   
>>   	if ((ctx->current.lpc_addr + ctx->current.size) < (off + len))
>>   		return FLASH_ERR_PARM_ERROR;
>> @@ -563,37 +562,7 @@ static int lpc_window_read(struct ipmi_hiomap *ctx, uint32_t pos,
>>   	prlog(PR_TRACE, "Reading at 0x%08x for 0x%08x offset: 0x%08x\n",
>>   	      pos, 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;
>> +	return lpc_fw_read(off, buf, len);
>>   }
>>   
>>   static int lpc_window_write(struct ipmi_hiomap *ctx, uint32_t pos,
>> @@ -601,7 +570,6 @@ static int lpc_window_write(struct ipmi_hiomap *ctx, uint32_t pos,
>>   {
>>   	uint32_t off = ctx->current.lpc_addr + (pos - ctx->current.cur_pos);
>>   	enum lpc_window_state state;
>> -	int rc;
>>   
>>   	lock(&ctx->lock);
>>   	state = ctx->window_state;
>> @@ -616,31 +584,7 @@ static int lpc_window_write(struct ipmi_hiomap *ctx, uint32_t pos,
>>   	prlog(PR_TRACE, "Writing at 0x%08x for 0x%08x offset: 0x%08x\n",
>>   	      pos, len, off);
>>   
>> -	while(len) {
>> -		uint32_t chunk;
>> -
>> -		if (len > 3 && !(off & 3)) {
>> -			/* endian swap: see lpc_window_read */
>> -			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;
>> +	return lpc_fw_write(off, buf, len);
>>   }
>>   
>>   /* Best-effort asynchronous event handling by blocklevel callbacks */
>> -- 
>> 2.35.1
>>
>> _______________________________________________
>> Skiboot mailing list
>> Skiboot@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/skiboot
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);
 
diff --git a/libflash/ipmi-hiomap.c b/libflash/ipmi-hiomap.c
index 29355d66..c634eeeb 100644
--- a/libflash/ipmi-hiomap.c
+++ b/libflash/ipmi-hiomap.c
@@ -555,7 +555,6 @@  static int lpc_window_read(struct ipmi_hiomap *ctx, uint32_t pos,
 			   void *buf, uint32_t len)
 {
 	uint32_t off = ctx->current.lpc_addr + (pos - ctx->current.cur_pos);
-	int rc;
 
 	if ((ctx->current.lpc_addr + ctx->current.size) < (off + len))
 		return FLASH_ERR_PARM_ERROR;
@@ -563,37 +562,7 @@  static int lpc_window_read(struct ipmi_hiomap *ctx, uint32_t pos,
 	prlog(PR_TRACE, "Reading at 0x%08x for 0x%08x offset: 0x%08x\n",
 	      pos, 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;
+	return lpc_fw_read(off, buf, len);
 }
 
 static int lpc_window_write(struct ipmi_hiomap *ctx, uint32_t pos,
@@ -601,7 +570,6 @@  static int lpc_window_write(struct ipmi_hiomap *ctx, uint32_t pos,
 {
 	uint32_t off = ctx->current.lpc_addr + (pos - ctx->current.cur_pos);
 	enum lpc_window_state state;
-	int rc;
 
 	lock(&ctx->lock);
 	state = ctx->window_state;
@@ -616,31 +584,7 @@  static int lpc_window_write(struct ipmi_hiomap *ctx, uint32_t pos,
 	prlog(PR_TRACE, "Writing at 0x%08x for 0x%08x offset: 0x%08x\n",
 	      pos, len, off);
 
-	while(len) {
-		uint32_t chunk;
-
-		if (len > 3 && !(off & 3)) {
-			/* endian swap: see lpc_window_read */
-			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;
+	return lpc_fw_write(off, buf, len);
 }
 
 /* Best-effort asynchronous event handling by blocklevel callbacks */