summaryrefslogtreecommitdiffstats
path: root/utils/hwpatcher/hwpatcher.c
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2014-08-13 12:46:45 +0200
committerMarcin Bukat <marcin.bukat@gmail.com>2014-08-26 07:21:19 +0200
commit69df56504e7dfc8ba7e283901aadde6ebdada5b1 (patch)
tree2852978cbb169c810fd81f98266d1e9d971a6ca8 /utils/hwpatcher/hwpatcher.c
parentbfbec3a3a7de448902b2b3244f5b4f942ef09570 (diff)
downloadrockbox-69df56504e7dfc8ba7e283901aadde6ebdada5b1.tar.gz
rockbox-69df56504e7dfc8ba7e283901aadde6ebdada5b1.zip
hwpatcher: add framework for CRC computation
Change-Id: Ib78f0fe58db5cec86f043d3e9e1ca14e69297ba0 Reviewed-on: http://gerrit.rockbox.org/911 Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
Diffstat (limited to 'utils/hwpatcher/hwpatcher.c')
-rw-r--r--utils/hwpatcher/hwpatcher.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/utils/hwpatcher/hwpatcher.c b/utils/hwpatcher/hwpatcher.c
index 60e142bbc1..7153a220c9 100644
--- a/utils/hwpatcher/hwpatcher.c
+++ b/utils/hwpatcher/hwpatcher.c
@@ -47,6 +47,8 @@
#include "misc.h"
#include "md5.h"
+#define ARRAYLEN(arr) (sizeof(arr) / sizeof(arr[0]))
+
lua_State *g_lua;
bool g_exit = false;
@@ -59,6 +61,18 @@ enum fw_type_t
FW_UNK, FW_ELF, FW_SB1, FW_SB2, FW_BIN, FW_EDOC
};
+enum crc_type_t
+{
+ CRC_RKW
+};
+
+struct crc_type_desc_t
+{
+ enum crc_type_t type;
+ const char *lua_name;
+ unsigned (*fn)(uint8_t *buf, size_t len);
+};
+
struct bin_file_t
{
size_t size;
@@ -849,6 +863,66 @@ int my_lua_section_info(lua_State *state)
return 1;
}
+unsigned crc_rkw(uint8_t *buf, size_t len)
+{
+ /* polynomial 0x04c10db7 */
+ static const uint32_t crc32_lookup[16] =
+ { /* lookup table for 4 bits at a time is affordable */
+ 0x00000000, 0x04C10DB7, 0x09821B6E, 0x0D4316D9,
+ 0x130436DC, 0x17C53B6B, 0x1A862DB2, 0x1E472005,
+ 0x26086DB8, 0x22C9600F, 0x2F8A76D6, 0x2B4B7B61,
+ 0x350C5B64, 0x31CD56D3, 0x3C8E400A, 0x384F4DBD
+ };
+
+ uint32_t crc32 = 0;
+ unsigned char byte;
+ uint32_t t;
+
+ while (len--)
+ {
+ byte = *buf++; /* get one byte of data */
+
+ /* upper nibble of our data */
+ t = crc32 >> 28; /* extract the 4 most significant bits */
+ t ^= byte >> 4; /* XOR in 4 bits of data into the extracted bits */
+ crc32 <<= 4; /* shift the CRC register left 4 bits */
+ crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */
+
+ /* lower nibble of our data */
+ t = crc32 >> 28; /* extract the 4 most significant bits */
+ t ^= byte & 0x0F; /* XOR in 4 bits of data into the extracted bits */
+ crc32 <<= 4; /* shift the CRC register left 4 bits */
+ crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */
+ }
+
+ return crc32;
+}
+
+struct crc_type_desc_t crc_types[] =
+{
+ {CRC_RKW, "RKW", crc_rkw}
+};
+
+int my_lua_crc_buf(lua_State *state)
+{
+ int n = lua_gettop(state);
+ if(n != 2)
+ return luaL_error(state, "crc_buf takes two arguments: a crc type and a buffer");
+ unsigned type = lua_tounsigned(state, 1);
+ size_t len;
+ void *buf = my_lua_get_buffer(state, 2, &len);
+ for(int i = 0; i < ARRAYLEN(crc_types); i++)
+ if(crc_types[i].type == type)
+ {
+ lua_pushunsigned(state, crc_types[i].fn(buf, len));
+ free(buf);
+ return 1;
+ }
+ free(buf);
+ luaL_error(state, "crc_buf: unknown crc type");
+ return 0;
+}
+
/* compute MD5 sum of a buffer */
static bool compute_md5sum_buf(void *buf, size_t sz, uint8_t file_md5sum[16])
{
@@ -945,6 +1019,17 @@ static bool init_lua_hwp(void)
lua_pushcfunction(g_lua, my_lua_md5sum);
lua_setfield(g_lua, -2, "md5sum");
+ lua_newtable(g_lua);
+ for(int i = 0; i < ARRAYLEN(crc_types); i++)
+ {
+ lua_pushunsigned(g_lua, crc_types[i].type);
+ lua_setfield(g_lua, -2, crc_types[i].lua_name);
+ }
+ lua_setfield(g_lua, -2, "CRC");
+
+ lua_pushcfunction(g_lua, my_lua_crc_buf);
+ lua_setfield(g_lua, -2, "crc_buf");
+
return true;
}