diff options
Diffstat (limited to 'target/linux/ar71xx/files/arch/mips')
-rw-r--r-- | target/linux/ar71xx/files/arch/mips/ath79/routerboot.c | 100 | ||||
-rw-r--r-- | target/linux/ar71xx/files/arch/mips/ath79/routerboot.h | 26 |
2 files changed, 126 insertions, 0 deletions
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/routerboot.c b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.c new file mode 100644 index 000000000..3c6f9aaeb --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.c @@ -0,0 +1,100 @@ +/* + * RouterBoot helper routines + * + * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/routerboot.h> + +#include "routerboot.h" + +static u32 get_u32(void *buf) +{ + u8 *p = buf; + + return ((u32) p[3] + ((u32) p[2] << 8) + ((u32) p[1] << 16) + + ((u32) p[0] << 24)); +} + +static u16 get_u16(void *buf) +{ + u8 *p = buf; + + return (u16) p[1] + ((u16) p[0] << 8); +} + +__init int +routerboot_find_tag(u8 *buf, unsigned int buflen, u16 tag_id, + u8 **tag_data, u16 *tag_len) +{ + uint32_t magic; + int ret; + + if (buflen < 4) + return -EINVAL; + + magic = get_u32(buf); + switch (magic) { + case RB_MAGIC_HARD: + /* skip magic value */ + buf += 4; + buflen -= 4; + break; + + case RB_MAGIC_SOFT: + if (buflen < 8) + return -EINVAL; + + /* skip magic and CRC value */ + buf += 8; + buflen -= 8; + + break; + + default: + return -EINVAL; + } + + ret = -ENOENT; + while (buflen > 2) { + u16 id; + u16 len; + + len = get_u16(buf); + buf += 2; + buflen -= 2; + + if (buflen < 2) + break; + + id = get_u16(buf); + buf += 2; + buflen -= 2; + + if (id == RB_ID_TERMINATOR) + break; + + if (buflen < len) + break; + + if (id == tag_id) { + if (tag_len) + *tag_len = len; + if (tag_data) + *tag_data = buf; + ret = 0; + break; + } + + buf += len; + buflen -= len; + } + + return ret; +} diff --git a/target/linux/ar71xx/files/arch/mips/ath79/routerboot.h b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.h new file mode 100644 index 000000000..9a4dde59e --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.h @@ -0,0 +1,26 @@ +/* + * RouterBoot definitions + * + * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef _ATH79_ROUTERBOOT_H_ +#define _ATH79_ROUTERBOOT_H_ + +#ifdef CONFIG_ATH79_ROUTERBOOT +int routerboot_find_tag(u8 *buf, unsigned int buflen, u16 tag_id, + u8 **tag_data, u16 *tag_len); +#else +static inline int +routerboot_find_tag(u8 *buf, unsigned int buflen, u16 tag_id, + u8 **tag_data, u16 *tag_len) +{ + return -ENOENT; +} +#endif + +#endif /* _ATH79_ROUTERBOOT_H_ */ |