summaryrefslogtreecommitdiffstats
path: root/include/firmware.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/firmware.h')
-rw-r--r--include/firmware.h62
1 files changed, 55 insertions, 7 deletions
diff --git a/include/firmware.h b/include/firmware.h
index 2583342230..361ff2f8ae 100644
--- a/include/firmware.h
+++ b/include/firmware.h
@@ -6,13 +6,23 @@
#ifndef FIRMWARE_H
#define FIRMWARE_H
+#include <pbl.h>
+#include <printk.h>
#include <types.h>
#include <driver.h>
+#include <debug_ll.h>
+#include <linux/kernel.h>
+#include <asm/sections.h>
+
+struct firmware {
+ size_t size;
+ const u8 *data;
+};
struct firmware_handler {
char *id; /* unique identifier for this firmware device */
char *model; /* description for this device */
- struct device_d *dev;
+ struct device *dev;
void *priv;
struct device_node *device_node;
/* called once to prepare the firmware's programming cycle */
@@ -33,6 +43,8 @@ struct firmware_mgr *firmwaremgr_find_by_node(struct device_node *np);
int firmwaremgr_load_file(struct firmware_mgr *, const char *path);
char *firmware_get_searchpath(void);
void firmware_set_searchpath(const char *path);
+int request_firmware(const struct firmware **fw, const char *fw_name, struct device *dev);
+void release_firmware(const struct firmware *fw);
#else
static inline struct firmware_mgr *firmwaremgr_find_by_node(struct device_node *np)
{
@@ -53,16 +65,52 @@ static inline void firmware_set_searchpath(const char *path)
{
}
+static inline int request_firmware(const struct firmware **fw, const char *fw_name,
+ struct device *dev)
+{
+ return -EINVAL;
+}
+
+static inline void release_firmware(const struct firmware *fw)
+{
+}
#endif
void firmwaremgr_list_handlers(void);
-#define get_builtin_firmware(name, start, size) \
- { \
- extern char _fw_##name##_start[]; \
- extern char _fw_##name##_end[]; \
- *start = (typeof(*start)) _fw_##name##_start; \
- *size = _fw_##name##_end - _fw_##name##_start; \
+static inline void firmware_ext_verify(const void *data_start, size_t data_size,
+ const void *hash_start, size_t hash_size)
+{
+ if (pbl_barebox_verify(data_start, data_size,
+ hash_start, hash_size) != 0) {
+ putc_ll('!');
+ panic("hash mismatch, refusing to decompress");
}
+}
+
+#define __get_builtin_firmware(name, offset, start, size) \
+ do { \
+ extern char _fw_##name##_start[]; \
+ extern char _fw_##name##_end[]; \
+ extern char _fw_##name##_sha_start[]; \
+ extern char _fw_##name##_sha_end[]; \
+ *start = (typeof(*start)) _fw_##name##_start; \
+ *size = _fw_##name##_end - _fw_##name##_start; \
+ if (!(offset)) \
+ break; \
+ *start += (offset); \
+ firmware_ext_verify( \
+ *start, *size, \
+ _fw_##name##_sha_start, \
+ _fw_##name##_sha_end - _fw_##name##_sha_start \
+ ); \
+ } while (0)
+
+
+#define get_builtin_firmware(name, start, size) \
+ __get_builtin_firmware(name, 0, start, size)
+
+#define get_builtin_firmware_ext(name, base, start, size) \
+ __get_builtin_firmware(name, (long)base - (long)_text, start, size)
#endif /* FIRMWARE_H */