summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/asm-offsets.c3
-rw-r--r--lib/fdtdec.c116
-rw-r--r--lib/strmhz.c4
-rw-r--r--lib/vsprintf.c19
4 files changed, 125 insertions, 17 deletions
diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c
index 129bc3e2af..580f763da6 100644
--- a/lib/asm-offsets.c
+++ b/lib/asm-offsets.c
@@ -31,6 +31,9 @@ int main(void)
#ifdef CONFIG_SYS_MALLOC_F_LEN
DEFINE(GD_MALLOC_BASE, offsetof(struct global_data, malloc_base));
#endif
+#ifdef CONFIG_X86
+ DEFINE(GD_BIST, offsetof(struct global_data, arch.bist));
+#endif
#if defined(CONFIG_ARM)
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 9714620ab3..7c7e673aeb 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -73,6 +73,8 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
COMPAT(PARADE_PS8625, "parade,ps8625"),
COMPAT(COMPAT_INTEL_LPC, "intel,lpc"),
+ COMPAT(INTEL_MICROCODE, "intel,microcode"),
+ COMPAT(MEMORY_SPD, "memory-spd"),
};
const char *fdtdec_get_compatible(enum fdt_compat_id id)
@@ -355,9 +357,9 @@ int fdtdec_get_alias_seq(const void *blob, const char *base, int offset,
slash = strrchr(prop, '/');
if (strcmp(slash + 1, find_name))
continue;
- for (p = name; *p; p++) {
- if (isdigit(*p)) {
- *seqp = simple_strtoul(p, NULL, 10);
+ for (p = name + strlen(name) - 1; p > name; p--) {
+ if (!isdigit(*p)) {
+ *seqp = simple_strtoul(p + 1, NULL, 10);
debug("Found seq %d\n", *seqp);
return 0;
}
@@ -485,6 +487,26 @@ int fdtdec_get_int_array(const void *blob, int node, const char *prop_name,
return err;
}
+int fdtdec_get_int_array_count(const void *blob, int node,
+ const char *prop_name, u32 *array, int count)
+{
+ const u32 *cell;
+ int len, elems;
+ int i;
+
+ debug("%s: %s\n", __func__, prop_name);
+ cell = fdt_getprop(blob, node, prop_name, &len);
+ if (!cell)
+ return -FDT_ERR_NOTFOUND;
+ elems = len / sizeof(u32);
+ if (count > elems)
+ count = elems;
+ for (i = 0; i < count; i++)
+ array[i] = fdt32_to_cpu(cell[i]);
+
+ return count;
+}
+
const u32 *fdtdec_locate_array(const void *blob, int node,
const char *prop_name, int count)
{
@@ -669,20 +691,25 @@ char *fdtdec_get_config_string(const void *blob, const char *prop_name)
return (char *)nodep;
}
-int fdtdec_decode_region(const void *blob, int node,
- const char *prop_name, void **ptrp, size_t *size)
+int fdtdec_decode_region(const void *blob, int node, const char *prop_name,
+ fdt_addr_t *basep, fdt_size_t *sizep)
{
const fdt_addr_t *cell;
int len;
- debug("%s: %s\n", __func__, prop_name);
+ debug("%s: %s: %s\n", __func__, fdt_get_name(blob, node, NULL),
+ prop_name);
cell = fdt_getprop(blob, node, prop_name, &len);
- if (!cell || (len != sizeof(fdt_addr_t) * 2))
+ if (!cell || (len < sizeof(fdt_addr_t) * 2)) {
+ debug("cell=%p, len=%d\n", cell, len);
return -1;
+ }
+
+ *basep = fdt_addr_to_cpu(*cell);
+ *sizep = fdt_size_to_cpu(cell[1]);
+ debug("%s: base=%08lx, size=%lx\n", __func__, (ulong)*basep,
+ (ulong)*sizep);
- *ptrp = map_sysmem(fdt_addr_to_cpu(*cell), *size);
- *size = fdt_size_to_cpu(cell[1]);
- debug("%s: size=%zx\n", __func__, *size);
return 0;
}
@@ -698,6 +725,7 @@ int fdtdec_decode_region(const void *blob, int node,
int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
struct fmap_entry *entry)
{
+ const char *prop;
u32 reg[2];
if (fdtdec_get_int_array(blob, node, "reg", reg, 2)) {
@@ -706,6 +734,13 @@ int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
}
entry->offset = reg[0];
entry->length = reg[1];
+ entry->used = fdtdec_get_int(blob, node, "used", entry->length);
+ prop = fdt_getprop(blob, node, "compress", NULL);
+ entry->compress_algo = prop && !strcmp(prop, "lzo") ?
+ FMAP_COMPRESS_LZO : FMAP_COMPRESS_NONE;
+ prop = fdt_getprop(blob, node, "hash", &entry->hash_size);
+ entry->hash_algo = prop ? FMAP_HASH_SHA256 : FMAP_HASH_NONE;
+ entry->hash = (uint8_t *)prop;
return 0;
}
@@ -780,4 +815,65 @@ int fdtdec_pci_get_bdf(const void *fdt, int node, int *bdf)
return 0;
}
+
+int fdtdec_decode_memory_region(const void *blob, int config_node,
+ const char *mem_type, const char *suffix,
+ fdt_addr_t *basep, fdt_size_t *sizep)
+{
+ char prop_name[50];
+ const char *mem;
+ fdt_size_t size, offset_size;
+ fdt_addr_t base, offset;
+ int node;
+
+ if (config_node == -1) {
+ config_node = fdt_path_offset(blob, "/config");
+ if (config_node < 0) {
+ debug("%s: Cannot find /config node\n", __func__);
+ return -ENOENT;
+ }
+ }
+ if (!suffix)
+ suffix = "";
+
+ snprintf(prop_name, sizeof(prop_name), "%s-memory%s", mem_type,
+ suffix);
+ mem = fdt_getprop(blob, config_node, prop_name, NULL);
+ if (!mem) {
+ debug("%s: No memory type for '%s', using /memory\n", __func__,
+ prop_name);
+ mem = "/memory";
+ }
+
+ node = fdt_path_offset(blob, mem);
+ if (node < 0) {
+ debug("%s: Failed to find node '%s': %s\n", __func__, mem,
+ fdt_strerror(node));
+ return -ENOENT;
+ }
+
+ /*
+ * Not strictly correct - the memory may have multiple banks. We just
+ * use the first
+ */
+ if (fdtdec_decode_region(blob, node, "reg", &base, &size)) {
+ debug("%s: Failed to decode memory region %s\n", __func__,
+ mem);
+ return -EINVAL;
+ }
+
+ snprintf(prop_name, sizeof(prop_name), "%s-offset%s", mem_type,
+ suffix);
+ if (fdtdec_decode_region(blob, config_node, prop_name, &offset,
+ &offset_size)) {
+ debug("%s: Failed to decode memory region '%s'\n", __func__,
+ prop_name);
+ return -EINVAL;
+ }
+
+ *basep = base + offset;
+ *sizep = offset_size;
+
+ return 0;
+}
#endif
diff --git a/lib/strmhz.c b/lib/strmhz.c
index f9a17727f5..5c16cc4fc7 100644
--- a/lib/strmhz.c
+++ b/lib/strmhz.c
@@ -11,11 +11,11 @@ char *strmhz (char *buf, unsigned long hz)
long l, n;
long m;
- n = DIV_ROUND(hz, 1000) / 1000L;
+ n = DIV_ROUND_CLOSEST(hz, 1000) / 1000L;
l = sprintf (buf, "%ld", n);
hz -= n * 1000000L;
- m = DIV_ROUND(hz, 1000L);
+ m = DIV_ROUND_CLOSEST(hz, 1000L);
if (m != 0)
sprintf (buf + l, ".%03ld", m);
return (buf);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index b585713b7c..e0f264850f 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -25,9 +25,6 @@
#include <div64.h>
#define noinline __attribute__((noinline))
-/* some reluctance to put this into a new limits.h, so it is here */
-#define INT_MAX ((int)(~0U>>1))
-
unsigned long simple_strtoul(const char *cp, char **endp,
unsigned int base)
{
@@ -518,6 +515,8 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width,
static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
int field_width, int precision, int flags)
{
+ u64 num = (uintptr_t)ptr;
+
/*
* Being a boot loader, we explicitly allow pointers to
* (physical) address null.
@@ -530,6 +529,17 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
#ifdef CONFIG_CMD_NET
switch (*fmt) {
+ case 'a':
+ flags |= SPECIAL | ZEROPAD;
+
+ switch (fmt[1]) {
+ case 'p':
+ default:
+ field_width = sizeof(phys_addr_t) * 2 + 2;
+ num = *(phys_addr_t *)ptr;
+ break;
+ }
+ break;
case 'm':
flags |= SPECIAL;
/* Fallthrough */
@@ -555,8 +565,7 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
field_width = 2*sizeof(void *);
flags |= ZEROPAD;
}
- return number(buf, end, (unsigned long)ptr, 16, field_width,
- precision, flags);
+ return number(buf, end, num, 16, field_width, precision, flags);
}
static int vsnprintf_internal(char *buf, size_t size, const char *fmt,