Hi Paul, On Wed, Dec 23, 2020 at 10:57:09AM +0000, Paul Cercueil wrote: > Hi, > > Having written the ingenic-remoteproc driver I am trying now to write > something a bit more advanced than a hello-world. Something like a > case-invert program for starters. However I'm having a hard time trying to > figure out how things work. > > My resource table is as follows: > > ---------------------------- > struct resource_table_hdr { > struct resource_table header; > > uint32_t offset[3]; > > struct { > struct fw_rsc_hdr header; > struct fw_rsc_carveout carveout; > } carveout; > > struct { > struct fw_rsc_hdr header; > struct fw_rsc_trace trace; > } trace; > > struct { > struct fw_rsc_hdr header; > struct fw_rsc_vdev vdev; > struct fw_rsc_vdev_vring vrings[2]; > uint8_t config[0xc]; > } vdev; > }; > > const struct resource_table_hdr resource_table > __attribute__((used, section (".resource_table"))) = { > .header = { > .ver = 1, > .num = ARRAY_SIZE(resource_table.offset), /* Number of resources */ > }, > > .offset[0] = offsetof(struct resource_table_hdr, carveout), > .offset[1] = offsetof(struct resource_table_hdr, trace), > .offset[2] = offsetof(struct resource_table_hdr, vdev), > > .carveout = { > .header = { > .type = RSC_CARVEOUT, > }, > .carveout = { > .da = 0xf4000000, > .len = 0x2000, > .name = "firmware", > }, > }, > > /* Trace resource to printf() into */ > .trace = { > .header = { > .type = RSC_TRACE, > }, > .trace = { > .da = (uint32_t)trace_buf, > .len = TRACE_BUFFER_SIZE, > .name = "trace", > }, > }, > > /* VirtIO device */ > .vdev = { > .header = { > .type = RSC_VDEV, > }, > .vdev = { > .id = VIRTIO_ID_RPROC_SERIAL, > .notifyid = 0, > .dfeatures = 0, > .config_len = 0xc, > .num_of_vrings = 2, > }, > .vrings = { > [0] = { > .align = 0x10, > .num = 0x4, > .notifyid = 0, > }, > [1] = { > .align = 0x10, > .num = 0x4, > .notifyid = 0, > }, > }, > }, > }; > ---------------------------- > The lack of proper tabulation above makes it really hard to read. > The firmware is properly loaded and I get debug prints in my trace buffer. > However, my vrings' .da fields don't seem to be initialized to anything > meaningful at all. Then I use the virtio/vring code from (https://github.com/MIPS/mips-rproc-example/blob/master/firmware/common/include/vring.h), > and calling vring_print() shows that my vring_desc's addresses are garbage > as well. > > Is there an example on how to write a basic I/O remoteproc program? > The easiest is probably to implement a VIRTIO_ID_RPMSG and try to test things out with the RPMSG client sample application [1]. It isn't an I/O example but it will allow you to quickly find the problem with the vring addresses. You may also want to checkout ST's development kit [2] if you want a working example. I use it as one of my reference board, the price is right and the support is completely upstream. Mathieu [1]. https://elixir.bootlin.com/linux/latest/source/samples/rpmsg/rpmsg_client_sample.c [2]. https://www.st.com/en/evaluation-tools/stm32mp157c-dk2.html > Cheers, > -Paul > >