Message ID | 20220414134404.39888-2-clombard@linux.vnet.ibm.com |
---|---|
State | Superseded |
Headers | show |
Series | Implement MCTP and PLDM features | expand |
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
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 --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);
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(+)