[Pdbg] [PATCH v2 5/6] libpdbg: Add sbefifo driver for cronus backend

Alistair Popple alistair at popple.id.au
Tue Oct 29 11:54:50 AEDT 2019


On Thursday, 24 October 2019 12:53:30 PM AEDT Amitay Isaacs wrote:
> Signed-off-by: Amitay Isaacs <amitay at ozlabs.org>
> ---
>  libpdbg/cronus.c | 320 ++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 316 insertions(+), 4 deletions(-)
> 
> diff --git a/libpdbg/cronus.c b/libpdbg/cronus.c
> index 7931611..1475622 100644
> --- a/libpdbg/cronus.c
> +++ b/libpdbg/cronus.c
> @@ -14,15 +14,14 @@
>   * limitations under the License.
>   */
>  #include <stdint.h>
> +#include <inttypes.h>
>  #include <stdio.h>
>  #include <unistd.h>
>  #include <stdlib.h>
> -#include <sys/types.h>
> -#include <sys/socket.h>
> -#include <netinet/in.h>
> -#include <arpa/inet.h>
> +#include <errno.h>
>  
>  #include <libcronus/libcronus.h>
> +#include <libsbefifo/libsbefifo.h>
>  
>  #include "hwunit.h"
>  #include "debug.h"
> @@ -138,6 +137,278 @@ static int cronus_fsi_write(struct fsi *fsi, uint32_t 
addr, uint32_t value)
>  	return 0;
>  }
>  
> +static uint32_t cronus_op_ffdc_get(struct sbefifo *sbefifo, const uint8_t 
**ffdc, uint32_t *ffdc_len)
> +{
> +	return sbefifo_ffdc_get(sbefifo->sf_ctx, ffdc, ffdc_len);
> +}
> +
> +static int cronus_op_istep(struct sbefifo *sbefifo,
> +			    uint32_t major, uint32_t minor)
> +{
> +	PR_NOTICE("sbefifo: istep %u.%u\n", major, minor);
> +
> +	return sbefifo_istep_execute(sbefifo->sf_ctx, major & 0xff, minor & 0xff);
> +}
> +
> +static int cronus_op_getmem(struct mem *sbefifo_mem,
> +			     uint64_t addr, uint8_t *data, uint64_t size,
> +			     uint8_t block_size, bool ci)

We shouldn't need a separate cronus_op_getmem, it should use the same hardware 
unit as the kernel sbefifo driver. Specifically the device tree should look 
something like this for the Cronus backend:

               sbefifo at 2400 { /* Bogus address */
                       reg = <0x0 0x2400 0x7>;
                       index = <0x0>;
                       compatible = "ibm,cronus-sbefifo";
                       #address-cells = <0x2>;
                       #size-cells = <0x1>;

                       sbefifo-mem at 0 {
                               compatible = "ibm,sbefifo-mem";
                               reg = <0x0 0x0 0x0>;
                       };
	       };

The HW unit implemented by the "ibm,cronus-sbefifo" driver should provide the 
correct callbacks to completely abstract the actual transport so that the 
"ibm,sbefifo-mem" unit only has to format the chip-op and pass it on to the 
sbefifo for transport.

> +{
> +	struct sbefifo *sbefifo = target_to_sbefifo(sbefifo_mem->target.parent);
> +	uint8_t *out;
> +	uint64_t start_addr, end_addr;
> +	uint32_t align, offset, len;
> +	uint16_t flags;
> +	int rc;
> +
> +	align = 8;
> +
> +	if (block_size && block_size != 8) {
> +		PR_ERROR("sbefifo: Only 8 byte block sizes are supported\n");
> +		return -1;
> +	};
> +
> +	start_addr = addr & (~(uint64_t)(align-1));
> +	end_addr = (addr + size + (align-1)) & (~(uint64_t)(align-1));
> +
> +	if (end_addr - start_addr > UINT32_MAX) {
> +		PR_ERROR("sbefifo: size too large\n");
> +		return -EINVAL;
> +	}
> +
> +	offset = addr - start_addr;
> +	len = end_addr - start_addr;
> +
> +	PR_NOTICE("sbefifo: getmem addr=0x%016" PRIx64 ", len=%u\n",
> +		  start_addr, len);
> +
> +	flags = SBEFIFO_MEMORY_FLAG_PROC;
> +	if (ci)
> +		flags |= SBEFIFO_MEMORY_FLAG_CI;
> +
> +	rc = sbefifo_mem_get(sbefifo->sf_ctx, start_addr, len, flags, &out);
> +	if (rc)
> +		return rc;
> +
> +	pdbg_progress_tick(len, len);
> +
> +	memcpy(data, out+offset, size);
> +	free(out);
> +
> +	return 0;
> +}

<snip>

> +static int cronus_op_thread_sreset(struct sbefifo *sbefifo,
> +				    uint32_t core_id, uint32_t thread_id)
> +{
> +	return cronus_op_control(sbefifo, core_id, thread_id, 
SBEFIFO_INSN_OP_SRESET);
> +}

It looks like most of this code is just a direct copy of the implementations 
in sbefifo.c, so we should just be calling those. Hence why the sbefifo-mem 
driver should be the same regardless of backend/transport.

> +static int cronus_sbefifo_probe(struct pdbg_target *target)
> +{
> +	struct sbefifo *sf = target_to_sbefifo(target);
> +	int rc;
> +
> +	rc = sbefifo_connect_transport(cronus_transport, target, &sf->sf_ctx);

As the only bit that really needs to be different is the library/context 
initialisation.

- Alistair

> +	if (rc) {
> +		PR_ERROR("Unable to initialize sbefifo driver\n");
> +		return rc;
> +	}
> +
> +	return 0;
> +}
> +
>  static struct pib cronus_pib = {
>  	.target = {
>  		.name =	"Cronus Client based PIB",
> @@ -164,9 +435,50 @@ static struct fsi cronus_fsi = {
>  };
>  DECLARE_HW_UNIT(cronus_fsi);
>  
> +struct mem cronus_sbefifo_mem = {
> +	.target = {
> +		.name = "Cronus Client based SBE FIFO memory access",
> +		.compatible = "ibm,cronus-sbefifo-mem",
> +		.class = "mem",
> +	},
> +	.read = cronus_op_getmem,
> +	.write = cronus_op_putmem,
> +};
> +DECLARE_HW_UNIT(cronus_sbefifo_mem);
> +
> +struct pba cronus_sbefifo_pba = {
> +	.target = {
> +		.name = "Cronus Client based SBE FIFO PBA memory access",
> +		.compatible = "ibm,cronus-sbefifo-pba",
> +		.class = "pba",
> +	},
> +	.read = cronus_op_getmem_pba,
> +	.write = cronus_op_putmem_pba,
> +};
> +DECLARE_HW_UNIT(cronus_sbefifo_pba);
> +
> +struct sbefifo cronus_sbefifo = {
> +	.target = {
> +		.name =	"Cronus Client based SBE FIFO",
> +		.compatible = "ibm,cronus-sbefifo",
> +		.class = "sbefifo",
> +		.probe = cronus_sbefifo_probe,
> +	},
> +	.istep = cronus_op_istep,
> +	.thread_start = cronus_op_thread_start,
> +	.thread_stop = cronus_op_thread_stop,
> +	.thread_step = cronus_op_thread_step,
> +	.thread_sreset = cronus_op_thread_sreset,
> +	.ffdc_get = cronus_op_ffdc_get,
> +};
> +DECLARE_HW_UNIT(cronus_sbefifo);
> +
>  __attribute__((constructor))
>  static void register_cronus(void)
>  {
>  	pdbg_hwunit_register(&cronus_pib_hw_unit);
>  	pdbg_hwunit_register(&cronus_fsi_hw_unit);
> +	pdbg_hwunit_register(&cronus_sbefifo_hw_unit);
> +	pdbg_hwunit_register(&cronus_sbefifo_mem_hw_unit);
> +	pdbg_hwunit_register(&cronus_sbefifo_pba_hw_unit);
>  }
> 






More information about the Pdbg mailing list