Hi Peter,

good finding!

There is actually a comment in this regard in include/nuttx/net/netdev.h:
> The d_buf array must be aligned to two-byte, 16-bit address boundaries in
order to support aligned 16-bit accesses performed by the network.

W.r.t. to your proposed fix I think it would be more appropriate to make
the alignment requirement explicit by using the 'aligned_data' macro from
include/nuttx/compiler.h.

Thanks!
Michael

Am Mo., 17. Jan. 2022 um 09:01 Uhr schrieb Peter Kalbus
<p...@mailbox.org.invalid>:

> Hi all,
>
> during the bring-up of the composite-cdcecm a alignment issue result in
> hard faults (always on the used rp2040 based device).
>
> ANALYSIS:
>
> The root cause seems to be the way the pktbuf is defined in
> cdcecm_driver_s (driver/usbdev/cdcecm.c):
>
> struct cdcecm_driver_s
> {
>   /* USB CDC-ECM device */
>
>   struct usbdevclass_driver_s  usbdev;      /* USB device class vtable */
>   struct usbdev_devinfo_s      devinfo;
>   FAR struct usbdev_req_s     *ctrlreq;     /* Allocated control request */
>   FAR struct usbdev_ep_s      *epint;       /* Interrupt IN endpoint */
>   FAR struct usbdev_ep_s      *epbulkin;    /* Bulk IN endpoint */
>   FAR struct usbdev_ep_s      *epbulkout;   /* Bulk OUT endpoint */
>   uint8_t                      config;      /* Selected configuration
> number */
>
>   uint8_t                      pktbuf[CONFIG_NET_ETH_PKTSIZE +
>                                       CONFIG_NET_GUARDSIZE];
>
>
> Due to 'config‘ element ‚ pktbuf‘ in the structure is not aligned in
> anyway from the struct itself.
>
> The driver structure is allocation during driver initialization in
> cdcecm_classobject():
>
>   /* Initialize the driver structure */
>
>   self = kmm_zalloc(sizeof(struct cdcecm_driver_s));
>   if (!self)
>     {
>       nerr("Out of memory!\n");
>       return -ENOMEM;
>     }
>
>   /* Network device initialization */
>
>   self->dev.d_buf     = self->pktbuf;
>
> As ’ self’ points to an aligned address, 'pktbuf' is always aligned at an
> odd address.
>
> Once the driver is initialized and processes received data in
> cdcecm_receive() the driver creates a hard fault at:
>
> #ifdef CONFIG_NET_IPv4
>   if (BUF->type == HTONS(ETHTYPE_IP))
>     {
>
> BUF/eth_hdr_s are defined as:
>
> #define BUF ((struct eth_hdr_s *)self->dev.d_buf)
>
>
> struct eth_hdr_s
> {
>   uint8_t  dest[6]; /* Ethernet destination address (6 bytes) */
>   uint8_t  src[6];  /* Ethernet source address (6 bytes) */
>   uint16_t type;    /* Type code (2 bytes) */
> };
>
>
> Element ’ type’ is always odd aligned and access to it results in all
> cases to a hard fault on the used rp2040 based board.
>
> PROPOSAL:
>
> Assuming the analysis is correct, there could be different options to fix
> there issue.
> Proposal would be to let the compiler do the job and not introduce any
> special code or elements in the structure to fix it programmatically.
>
> Analysing cdcdcm_driver_s in more details:
>
>   FAR struct usbdev_ep_s      *epbulkout;   /* Bulk OUT endpoint */
>   uint8_t                      config;      /* Selected configuration
> number */
>
>   uint8_t                      pktbuf[CONFIG_NET_ETH_PKTSIZE +
>                                       CONFIG_NET_GUARDSIZE];
>
>
> Element 'epbulkout' is a 32bit pointer and thus always aligned to 32bit.
> Element 'config‘ following is also aligned to 32bit —> as it’s only an
> uint8_t is doesn’t need to be aligned at all.
> Element ‚pktbuf‘ is odd aligned, but needs to be at least 16bit aligned.
>
> Exchanging 'config‘ and 'pktbuf‘ in the structure solves the issue:
>
>   FAR struct usbdev_ep_s      *epbulkout;   /* Bulk OUT endpoint */
>
>   uint8_t                      pktbuf[CONFIG_NET_ETH_PKTSIZE +
>                                       CONFIG_NET_GUARDSIZE];
>
>   uint8_t                      config;      /* Selected configuration
> number */
>
>
> Element ‚pktbuf‘ is now 32bit aligned as it’s following a 32bit pointer.
>
> The change has been tested on an rp2040 based device.
>
> The fix can be reviewed at:
> https://github.com/ptka/incubator-nuttx/commit/01732850ad345b5e2a9af24f788935d8f7928781
> <
> https://github.com/ptka/incubator-nuttx/commit/01732850ad345b5e2a9af24f788935d8f7928781
> >
>
> Please comment on the analysis and proposed fix.
>
> /Piet
>
>

Reply via email to