Changeset bef6dfc5 in rtems


Ignore:
Timestamp:
Nov 19, 2018, 5:36:15 AM (2 years ago)
Author:
David Gibson <david@…>
Branches:
5, master
Children:
ab3efcc
Parents:
8bd3915
git-author:
David Gibson <david@…> (11/19/18 05:36:15)
git-committer:
Sebastian Huber <sebastian.huber@…> (03/02/20 06:52:19)
Message:

libfdt: Don't use memcpy to handle unaligned reads on ARM

6dcb8ba4 "libfdt: Add helpers for accessing unaligned words" introduced
the fdt32_ld() and fdt64_ld() helpers for loading values from the FDT blob
which might not be naturally aligned. This matters for ARM, where
attempting a plain unaligned load will often cause an exception.

However, it seems the memcpy() we used here was surprisingly expensive,
making libfdt nearly 6x slower on at least some ARM platforms.

This patch takes an alternative approach, using a bunch of 1-byte loads
and shifts to implement the helpers.

Signed-off-by: David Gibson <david@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/include/libfdt.h

    r8bd3915 rbef6dfc5  
    164164static inline uint32_t fdt32_ld(const fdt32_t *p)
    165165{
    166         fdt32_t v;
    167 
    168         memcpy(&v, p, sizeof(v));
    169         return fdt32_to_cpu(v);
     166        const uint8_t *bp = (const uint8_t *)p;
     167
     168        return ((uint32_t)bp[0] << 24)
     169                | ((uint32_t)bp[1] << 16)
     170                | ((uint32_t)bp[2] << 8)
     171                | bp[3];
    170172}
    171173
    172174static inline uint64_t fdt64_ld(const fdt64_t *p)
    173175{
    174         fdt64_t v;
    175 
    176         memcpy(&v, p, sizeof(v));
    177         return fdt64_to_cpu(v);
     176        const uint8_t *bp = (const uint8_t *)p;
     177
     178        return ((uint64_t)bp[0] << 56)
     179                | ((uint64_t)bp[1] << 48)
     180                | ((uint64_t)bp[2] << 40)
     181                | ((uint64_t)bp[3] << 32)
     182                | ((uint64_t)bp[4] << 24)
     183                | ((uint64_t)bp[5] << 16)
     184                | ((uint64_t)bp[6] << 8)
     185                | bp[7];
    178186}
    179187
Note: See TracChangeset for help on using the changeset viewer.