For use in the barebox EFI runtime, implement a self-contained CRC32
that will be placed into the .efi_runtime section.

The code is in the public domain.

Signed-off-by: Ahmad Fatoum <[email protected]>
---
 crypto/crc32.c | 24 ++++++++++++++++++++++++
 include/crc.h  |  2 ++
 2 files changed, 26 insertions(+)

diff --git a/crypto/crc32.c b/crypto/crc32.c
index 5013556c0bea..bcfc8e99ee39 100644
--- a/crypto/crc32.c
+++ b/crypto/crc32.c
@@ -17,9 +17,11 @@
 #include <malloc.h>
 #include <linux/ctype.h>
 #include <errno.h>
+#include <efi/attributes.h>
 #define STATIC
 #else
 #define STATIC static inline
+#define __efi_runtime
 #endif
 
 static uint32_t crc_table[sizeof(uint32_t) * 256];
@@ -107,6 +109,28 @@ STATIC uint32_t crc32(uint32_t crc, const void *buf, 
unsigned int len)
 EXPORT_SYMBOL(crc32);
 #endif
 
+/* Taken from Hacker's Delight 2nd Edition by Henry S. Warren */
+STATIC __efi_runtime  uint32_t __pi_crc32(uint32_t crc, const void *_buf, 
unsigned int len)
+{
+       const unsigned char *buf = _buf;
+       uint32_t mask;
+
+       crc = ~crc;
+       for (int i = 0; i < len; i++) {
+               crc = crc ^ buf[i];
+               for (int j = 7; j >= 0; j--) {
+                       mask = -(crc & 1);
+                       crc = (crc >> 1) ^ (0xEDB88320 & mask);
+               }
+       }
+
+       return ~crc;
+}
+
+#ifdef __BAREBOX__
+EXPORT_SYMBOL(__pi_crc32);
+#endif
+
 STATIC uint32_t crc32_be(uint32_t crc, const void *_buf, unsigned int len)
 {
        const unsigned char *buf = _buf;
diff --git a/include/crc.h b/include/crc.h
index 3eba635dbaa4..c7d52f7cd078 100644
--- a/include/crc.h
+++ b/include/crc.h
@@ -18,4 +18,6 @@ uint32_t crc32_no_comp(uint32_t, const void *, unsigned int);
 int file_crc(char *filename, unsigned long start, unsigned long size,
             unsigned long *crc, unsigned long *total);
 
+uint32_t __pi_crc32(uint32_t, const void *, unsigned int);
+
 #endif /* __INCLUDE_CRC_H */
-- 
2.47.3


Reply via email to