summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile9
-rw-r--r--lib/bzip2/Makefile2
-rw-r--r--lib/bzip2/bzlib.c (renamed from lib/bzlib.c)0
-rw-r--r--lib/bzip2/bzlib_crctable.c (renamed from lib/bzlib_crctable.c)0
-rw-r--r--lib/bzip2/bzlib_decompress.c (renamed from lib/bzlib_decompress.c)0
-rw-r--r--lib/bzip2/bzlib_huffman.c (renamed from lib/bzlib_huffman.c)0
-rw-r--r--lib/bzip2/bzlib_private.h (renamed from lib/bzlib_private.h)0
-rw-r--r--lib/bzip2/bzlib_randtable.c (renamed from lib/bzlib_randtable.c)0
-rw-r--r--lib/errno_str.c147
-rw-r--r--lib/fdtdec.c296
-rw-r--r--lib/initcall.c6
-rw-r--r--lib/libfdt/Makefile5
-rw-r--r--lib/string.c25
-rw-r--r--lib/strmhz.c4
-rw-r--r--lib/vsprintf.c19
-rw-r--r--lib/zlib/zlib.h2
16 files changed, 465 insertions, 50 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 320197a520..07d175f45e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -11,14 +11,12 @@ obj-$(CONFIG_RSA) += rsa/
obj-$(CONFIG_LZMA) += lzma/
obj-$(CONFIG_LZO) += lzo/
obj-$(CONFIG_ZLIB) += zlib/
+obj-$(CONFIG_BZIP2) += bzip2/
obj-$(CONFIG_TIZEN) += tizen/
+obj-$(CONFIG_OF_LIBFDT) += libfdt/
+obj-$(CONFIG_FIT) += libfdt/
obj-$(CONFIG_AES) += aes.o
-obj-$(CONFIG_BZIP2) += bzlib.o
-obj-$(CONFIG_BZIP2) += bzlib_crctable.o
-obj-$(CONFIG_BZIP2) += bzlib_decompress.o
-obj-$(CONFIG_BZIP2) += bzlib_randtable.o
-obj-$(CONFIG_BZIP2) += bzlib_huffman.o
obj-$(CONFIG_USB_TTY) += circbuf.o
obj-y += crc7.o
obj-y += crc8.o
@@ -53,6 +51,7 @@ endif
obj-$(CONFIG_ADDR_MAP) += addr_map.o
obj-y += hashtable.o
obj-y += errno.o
+obj-$(CONFIG_ERRNO_STR) += errno_str.o
obj-y += display_options.o
obj-$(CONFIG_BCH) += bch.o
obj-y += crc32.o
diff --git a/lib/bzip2/Makefile b/lib/bzip2/Makefile
new file mode 100644
index 0000000000..929c24e228
--- /dev/null
+++ b/lib/bzip2/Makefile
@@ -0,0 +1,2 @@
+obj-y += bzlib.o bzlib_crctable.o bzlib_decompress.o \
+ bzlib_randtable.o bzlib_huffman.o
diff --git a/lib/bzlib.c b/lib/bzip2/bzlib.c
index 5844e187c0..5844e187c0 100644
--- a/lib/bzlib.c
+++ b/lib/bzip2/bzlib.c
diff --git a/lib/bzlib_crctable.c b/lib/bzip2/bzlib_crctable.c
index 325b96643e..325b96643e 100644
--- a/lib/bzlib_crctable.c
+++ b/lib/bzip2/bzlib_crctable.c
diff --git a/lib/bzlib_decompress.c b/lib/bzip2/bzlib_decompress.c
index 4412b8a23e..4412b8a23e 100644
--- a/lib/bzlib_decompress.c
+++ b/lib/bzip2/bzlib_decompress.c
diff --git a/lib/bzlib_huffman.c b/lib/bzip2/bzlib_huffman.c
index 801b8ec39a..801b8ec39a 100644
--- a/lib/bzlib_huffman.c
+++ b/lib/bzip2/bzlib_huffman.c
diff --git a/lib/bzlib_private.h b/lib/bzip2/bzlib_private.h
index 87d8f94525..87d8f94525 100644
--- a/lib/bzlib_private.h
+++ b/lib/bzip2/bzlib_private.h
diff --git a/lib/bzlib_randtable.c b/lib/bzip2/bzlib_randtable.c
index c3dc7e4181..c3dc7e4181 100644
--- a/lib/bzlib_randtable.c
+++ b/lib/bzip2/bzlib_randtable.c
diff --git a/lib/errno_str.c b/lib/errno_str.c
new file mode 100644
index 0000000000..0ba950e970
--- /dev/null
+++ b/lib/errno_str.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics
+ * Przemyslaw Marczak <p.marczak@samsung.com>
+ *
+ * SDPX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <errno.h>
+
+#define ERRNO_MSG(errno, msg) msg
+#define SAME_AS(x) (const char *)&errno_message[x]
+
+static const char * const errno_message[] = {
+ ERRNO_MSG(0, "Success"),
+ ERRNO_MSG(EPERM, "Operation not permitted"),
+ ERRNO_MSG(ENOEN, "No such file or directory"),
+ ERRNO_MSG(ESRCH, "No such process"),
+ ERRNO_MSG(EINTR, "Interrupted system call"),
+ ERRNO_MSG(EIO, "I/O error"),
+ ERRNO_MSG(ENXIO, "No such device or address"),
+ ERRNO_MSG(E2BIG, "Argument list too long"),
+ ERRNO_MSG(ENOEXEC, "Exec format error"),
+ ERRNO_MSG(EBADF, "Bad file number"),
+ ERRNO_MSG(ECHILD, "No child processes"),
+ ERRNO_MSG(EAGAIN, "Try again"),
+ ERRNO_MSG(ENOMEM, "Out of memory"),
+ ERRNO_MSG(EACCES, "Permission denied"),
+ ERRNO_MSG(EFAULT, "Bad address"),
+ ERRNO_MSG(ENOTBL, "Block device required"),
+ ERRNO_MSG(EBUSY, "Device or resource busy"),
+ ERRNO_MSG(EEXIST, "File exists"),
+ ERRNO_MSG(EXDEV, "Cross-device link"),
+ ERRNO_MSG(ENODEV, "No such device"),
+ ERRNO_MSG(ENOTDIR, "Not a directory"),
+ ERRNO_MSG(EISDIR, "Is a directory"),
+ ERRNO_MSG(EINVAL, "Invalid argument"),
+ ERRNO_MSG(ENFILE, "File table overflow"),
+ ERRNO_MSG(EMFILE, "Too many open files"),
+ ERRNO_MSG(ENOTTY, "Not a typewriter"),
+ ERRNO_MSG(ETXTBSY, "Text file busy"),
+ ERRNO_MSG(EFBIG, "File too large"),
+ ERRNO_MSG(ENOSPC, "No space left on device"),
+ ERRNO_MSG(ESPIPE, "Illegal seek"),
+ ERRNO_MSG(EROFS, "Read-only file system"),
+ ERRNO_MSG(EMLINK, "Too many links"),
+ ERRNO_MSG(EPIPE, "Broken pipe"),
+ ERRNO_MSG(EDOM, "Math argument out of domain of func"),
+ ERRNO_MSG(ERANGE, "Math result not representable"),
+ ERRNO_MSG(EDEADLK, "Resource deadlock would occur"),
+ ERRNO_MSG(ENAMETOOLONG, "File name too long"),
+ ERRNO_MSG(ENOLCK, "No record locks available"),
+ ERRNO_MSG(ENOSYS, "Function not implemented"),
+ ERRNO_MSG(ENOTEMPTY, "Directory not empty"),
+ ERRNO_MSG(ELOOP, "Too many symbolic links encountered"),
+ ERRNO_MSG(EWOULDBLOCK, SAME_AS(EAGAIN)),
+ ERRNO_MSG(ENOMSG, "No message of desired type"),
+ ERRNO_MSG(EIDRM, "Identifier removed"),
+ ERRNO_MSG(ECHRNG, "Channel number out of range"),
+ ERRNO_MSG(EL2NSYNC, "Level 2 not synchronized"),
+ ERRNO_MSG(EL3HLT, "Level 3 halted"),
+ ERRNO_MSG(EL3RST, "Level 3 reset"),
+ ERRNO_MSG(ELNRNG, "Link number out of range"),
+ ERRNO_MSG(EUNATCH, "Protocol driver not attached"),
+ ERRNO_MSG(ENOCSI, "No CSI structure available"),
+ ERRNO_MSG(EL2HLT, "Level 2 halted"),
+ ERRNO_MSG(EBADE, "Invalid exchange"),
+ ERRNO_MSG(EBADR, "Invalid request descriptor"),
+ ERRNO_MSG(EXFULL, "Exchange full"),
+ ERRNO_MSG(ENOANO, "No anode"),
+ ERRNO_MSG(EBADRQC, "Invalid request code"),
+ ERRNO_MSG(EBADSLT, "Invalid slot"),
+ ERRNO_MSG(EDEADLOCK, SAME_AS(EDEADLK)),
+ ERRNO_MSG(EBFONT, "Bad font file format"),
+ ERRNO_MSG(ENOSTR, "Device not a stream"),
+ ERRNO_MSG(ENODATA, "No data available"),
+ ERRNO_MSG(ETIME, "Timer expired"),
+ ERRNO_MSG(ENOSR, "Out of streams resources"),
+ ERRNO_MSG(ENONET, "Machine is not on the network"),
+ ERRNO_MSG(ENOPKG, "Package not installed"),
+ ERRNO_MSG(EREMOTE, "Object is remote"),
+ ERRNO_MSG(ENOLINK, "Link has been severed"),
+ ERRNO_MSG(EADV, "Advertise error"),
+ ERRNO_MSG(ESRMNT, "Srmount error"),
+ ERRNO_MSG(ECOMM, "Communication error on send"),
+ ERRNO_MSG(EPROTO, "Protocol error"),
+ ERRNO_MSG(EMULTIHOP, "Multihop attempted"),
+ ERRNO_MSG(EDOTDOT, "RFS specific error"),
+ ERRNO_MSG(EBADMSG, "Not a data message"),
+ ERRNO_MSG(EOVERFLOW, "Value too large for defined data type"),
+ ERRNO_MSG(ENOTUNIQ, "Name not unique on network"),
+ ERRNO_MSG(EBADFD, "File descriptor in bad state"),
+ ERRNO_MSG(EREMCHG, "Remote address changed"),
+ ERRNO_MSG(ELIBACC, "Can not access a needed shared library"),
+ ERRNO_MSG(ELIBBAD, "Accessing a corrupted shared library"),
+ ERRNO_MSG(ELIBSCN, ".lib section in a.out corrupted"),
+ ERRNO_MSG(ELIBMAX, "Attempting to link in too many shared libraries"),
+ ERRNO_MSG(ELIBEXEC, "Cannot exec a shared library directly"),
+ ERRNO_MSG(EILSEQ, "Illegal byte sequence"),
+ ERRNO_MSG(ERESTART, "Interrupted system call should be restarted"),
+ ERRNO_MSG(ESTRPIPE, "Streams pipe error"),
+ ERRNO_MSG(EUSERS, "Too many users"),
+ ERRNO_MSG(ENOTSOCK, "Socket operation on non-socket"),
+ ERRNO_MSG(EDESTADDRREQ, "Destination address required"),
+ ERRNO_MSG(EMSGSIZE, "Message too long"),
+ ERRNO_MSG(EPROTOTYPE, "Protocol wrong type for socket"),
+ ERRNO_MSG(ENOPROTOOPT, "Protocol not available"),
+ ERRNO_MSG(EPROTONOSUPPORT, "Protocol not supported"),
+ ERRNO_MSG(ESOCKTNOSUPPORT, "Socket type not supported"),
+ ERRNO_MSG(EOPNOTSUPP, "Operation not supported on transport endpoint"),
+ ERRNO_MSG(EPFNOSUPPORT, "Protocol family not supported"),
+ ERRNO_MSG(AFNOSUPPORT, "Address family not supported by protocol"),
+ ERRNO_MSG(EADDRINUSE, "Address already in use"),
+ ERRNO_MSG(EADDRNOTAVAIL, "Cannot assign requested address"),
+ ERRNO_MSG(ENETDOWN, "Network is down"),
+ ERRNO_MSG(ENETUNREACH, "Network is unreachable"),
+ ERRNO_MSG(ENETRESET, "Network dropped connection because of reset"),
+ ERRNO_MSG(ECONNABORTED, "Software caused connection abort"),
+ ERRNO_MSG(ECONNRESET, "Connection reset by peer"),
+ ERRNO_MSG(ENOBUFS, "No buffer space available"),
+ ERRNO_MSG(EISCONN, "Transport endpoint is already connected"),
+ ERRNO_MSG(ENOTCONN, "Transport endpoint is not connected"),
+ ERRNO_MSG(ESHUTDOWN, "Cannot send after transport endpoint shutdown"),
+ ERRNO_MSG(ETOOMANYREFS, "Too many references: cannot splice"),
+ ERRNO_MSG(ETIMEDOUT, "Connection timed out"),
+ ERRNO_MSG(ECONNREFUSED, "Connection refused"),
+ ERRNO_MSG(EHOSTDOWN, "Host is down"),
+ ERRNO_MSG(EHOSTUNREACH, "No route to host"),
+ ERRNO_MSG(EALREADY, "Operation already in progress"),
+ ERRNO_MSG(EINPROGRESS, "Operation now in progress"),
+ ERRNO_MSG(ESTALE, "Stale NFS file handle"),
+ ERRNO_MSG(EUCLEAN, "Structure needs cleaning"),
+ ERRNO_MSG(ENOTNAM, "Not a XENIX named type file"),
+ ERRNO_MSG(ENAVAIL, "No XENIX semaphores available"),
+ ERRNO_MSG(EISNAM, "Is a named type file"),
+ ERRNO_MSG(EREMOTEIO, "Remote I/O error"),
+ ERRNO_MSG(EDQUOT, "Quota exceeded"),
+ ERRNO_MSG(ENOMEDIUM, "No medium found"),
+ ERRNO_MSG(EMEDIUMTYPE, "Wrong medium type"),
+};
+
+const char *errno_str(int errno)
+{
+ if (errno >= 0)
+ return errno_message[0];
+
+ return errno_message[abs(errno)];
+}
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 9714620ab3..487122eebc 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -41,6 +41,10 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(NVIDIA_TEGRA20_SFLASH, "nvidia,tegra20-sflash"),
COMPAT(NVIDIA_TEGRA20_SLINK, "nvidia,tegra20-slink"),
COMPAT(NVIDIA_TEGRA114_SPI, "nvidia,tegra114-spi"),
+ COMPAT(NVIDIA_TEGRA124_PCIE, "nvidia,tegra124-pcie"),
+ COMPAT(NVIDIA_TEGRA30_PCIE, "nvidia,tegra30-pcie"),
+ COMPAT(NVIDIA_TEGRA20_PCIE, "nvidia,tegra20-pcie"),
+ COMPAT(NVIDIA_TEGRA124_XUSB_PADCTL, "nvidia,tegra124-xusb-padctl"),
COMPAT(SMSC_LAN9215, "smsc,lan9215"),
COMPAT(SAMSUNG_EXYNOS5_SROMC, "samsung,exynos-sromc"),
COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"),
@@ -73,6 +77,12 @@ 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"),
+ COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"),
+ COMPAT(INTEL_MODEL_206AX, "intel,model-206ax"),
+ COMPAT(INTEL_GMA, "intel,gma"),
+ COMPAT(AMS_AS3722, "ams,as3722"),
};
const char *fdtdec_get_compatible(enum fdt_compat_id id)
@@ -116,6 +126,163 @@ fdt_addr_t fdtdec_get_addr(const void *blob, int node,
return fdtdec_get_addr_size(blob, node, prop_name, NULL);
}
+#ifdef CONFIG_PCI
+int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
+ const char *prop_name, struct fdt_pci_addr *addr)
+{
+ const u32 *cell;
+ int len;
+ int ret = -ENOENT;
+
+ debug("%s: %s: ", __func__, prop_name);
+
+ /*
+ * If we follow the pci bus bindings strictly, we should check
+ * the value of the node's parent node's #address-cells and
+ * #size-cells. They need to be 3 and 2 accordingly. However,
+ * for simplicity we skip the check here.
+ */
+ cell = fdt_getprop(blob, node, prop_name, &len);
+ if (!cell)
+ goto fail;
+
+ if ((len % FDT_PCI_REG_SIZE) == 0) {
+ int num = len / FDT_PCI_REG_SIZE;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ debug("pci address #%d: %08lx %08lx %08lx\n", i,
+ (ulong)fdt_addr_to_cpu(cell[0]),
+ (ulong)fdt_addr_to_cpu(cell[1]),
+ (ulong)fdt_addr_to_cpu(cell[2]));
+ if ((fdt_addr_to_cpu(*cell) & type) == type) {
+ addr->phys_hi = fdt_addr_to_cpu(cell[0]);
+ addr->phys_mid = fdt_addr_to_cpu(cell[1]);
+ addr->phys_lo = fdt_addr_to_cpu(cell[2]);
+ break;
+ } else {
+ cell += (FDT_PCI_ADDR_CELLS +
+ FDT_PCI_SIZE_CELLS);
+ }
+ }
+
+ if (i == num)
+ goto fail;
+
+ return 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+fail:
+ debug("(not found)\n");
+ return ret;
+}
+
+int fdtdec_get_pci_vendev(const void *blob, int node, u16 *vendor, u16 *device)
+{
+ const char *list, *end;
+ int len;
+
+ list = fdt_getprop(blob, node, "compatible", &len);
+ if (!list)
+ return -ENOENT;
+
+ end = list + len;
+ while (list < end) {
+ char *s;
+
+ len = strlen(list);
+ if (len >= strlen("pciVVVV,DDDD")) {
+ s = strstr(list, "pci");
+
+ /*
+ * check if the string is something like pciVVVV,DDDD.RR
+ * or just pciVVVV,DDDD
+ */
+ if (s && s[7] == ',' &&
+ (s[12] == '.' || s[12] == 0)) {
+ s += 3;
+ *vendor = simple_strtol(s, NULL, 16);
+
+ s += 5;
+ *device = simple_strtol(s, NULL, 16);
+
+ return 0;
+ }
+ } else {
+ list += (len + 1);
+ }
+ }
+
+ return -ENOENT;
+}
+
+int fdtdec_get_pci_bdf(const void *blob, int node,
+ struct fdt_pci_addr *addr, pci_dev_t *bdf)
+{
+ u16 dt_vendor, dt_device, vendor, device;
+ int ret;
+
+ /* get vendor id & device id from the compatible string */
+ ret = fdtdec_get_pci_vendev(blob, node, &dt_vendor, &dt_device);
+ if (ret)
+ return ret;
+
+ /* extract the bdf from fdt_pci_addr */
+ *bdf = addr->phys_hi & 0xffff00;
+
+ /* read vendor id & device id based on bdf */
+ pci_read_config_word(*bdf, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word(*bdf, PCI_DEVICE_ID, &device);
+
+ /*
+ * Note there are two places in the device tree to fully describe
+ * a pci device: one is via compatible string with a format of
+ * "pciVVVV,DDDD" and the other one is the bdf numbers encoded in
+ * the device node's reg address property. We read the vendor id
+ * and device id based on bdf and compare the values with the
+ * "VVVV,DDDD". If they are the same, then we are good to use bdf
+ * to read device's bar. But if they are different, we have to rely
+ * on the vendor id and device id extracted from the compatible
+ * string and locate the real bdf by pci_find_device(). This is
+ * because normally we may only know device's device number and
+ * function number when writing device tree. The bus number is
+ * dynamically assigned during the pci enumeration process.
+ */
+ if ((dt_vendor != vendor) || (dt_device != device)) {
+ *bdf = pci_find_device(dt_vendor, dt_device, 0);
+ if (*bdf == -1)
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+int fdtdec_get_pci_bar32(const void *blob, int node,
+ struct fdt_pci_addr *addr, u32 *bar)
+{
+ pci_dev_t bdf;
+ int barnum;
+ int ret;
+
+ /* get pci devices's bdf */
+ ret = fdtdec_get_pci_bdf(blob, node, addr, &bdf);
+ if (ret)
+ return ret;
+
+ /* extract the bar number from fdt_pci_addr */
+ barnum = addr->phys_hi & 0xff;
+ if ((barnum < PCI_BASE_ADDRESS_0) || (barnum > PCI_CARDBUS_CIS))
+ return -EINVAL;
+
+ barnum = (barnum - PCI_BASE_ADDRESS_0) / 4;
+ *bar = pci_read_bar32(pci_bus_to_hose(PCI_BUS(bdf)), bdf, barnum);
+
+ return 0;
+}
+#endif
+
uint64_t fdtdec_get_uint64(const void *blob, int node, const char *prop_name,
uint64_t default_val)
{
@@ -355,9 +522,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;
}
@@ -368,21 +535,6 @@ int fdtdec_get_alias_seq(const void *blob, const char *base, int offset,
return -ENOENT;
}
-int fdtdec_get_alias_node(const void *blob, const char *name)
-{
- const char *prop;
- int alias_node;
- int len;
-
- if (!blob)
- return -FDT_ERR_NOTFOUND;
- alias_node = fdt_path_offset(blob, "/aliases");
- prop = fdt_getprop(blob, alias_node, name, &len);
- if (!prop)
- return -FDT_ERR_NOTFOUND;
- return fdt_path_offset(blob, prop);
-}
-
int fdtdec_get_chosen_node(const void *blob, const char *name)
{
const char *prop;
@@ -485,6 +637,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 +841,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 +875,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 +884,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;
}
@@ -767,16 +952,63 @@ int fdt_get_named_resource(const void *fdt, int node, const char *property,
return fdt_get_resource(fdt, node, property, index, res);
}
-int fdtdec_pci_get_bdf(const void *fdt, int node, int *bdf)
+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)
{
- const fdt32_t *prop;
- int len;
+ char prop_name[50];
+ const char *mem;
+ fdt_size_t size, offset_size;
+ fdt_addr_t base, offset;
+ int node;
- prop = fdt_getprop(fdt, node, "reg", &len);
- if (!prop)
- return len;
+ 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;
+ }
- *bdf = fdt32_to_cpu(*prop) & 0xffffff;
+ *basep = base + offset;
+ *sizep = offset_size;
return 0;
}
diff --git a/lib/initcall.c b/lib/initcall.c
index 39f4b3f8ad..714274415c 100644
--- a/lib/initcall.c
+++ b/lib/initcall.c
@@ -19,7 +19,11 @@ int initcall_run_list(const init_fnc_t init_sequence[])
if (gd->flags & GD_FLG_RELOC)
reloc_ofs = gd->reloc_off;
- debug("initcall: %p\n", (char *)*init_fnc_ptr - reloc_ofs);
+ debug("initcall: %p", (char *)*init_fnc_ptr - reloc_ofs);
+ if (gd->flags & GD_FLG_RELOC)
+ debug(" (relocated to %p)\n", (char *)*init_fnc_ptr);
+ else
+ debug("\n");
ret = (*init_fnc_ptr)();
if (ret) {
printf("initcall sequence %p failed at call %p (err=%d)\n",
diff --git a/lib/libfdt/Makefile b/lib/libfdt/Makefile
index 6fe79e0b06..2f5413f90d 100644
--- a/lib/libfdt/Makefile
+++ b/lib/libfdt/Makefile
@@ -5,8 +5,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
-COBJS-libfdt += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o \
+obj-y += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o \
fdt_empty_tree.o fdt_addresses.o
-
-obj-$(CONFIG_OF_LIBFDT) += $(COBJS-libfdt)
-obj-$(CONFIG_FIT) += $(COBJS-libfdt)
diff --git a/lib/string.c b/lib/string.c
index 29c2ca7ef6..87c9a408e6 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -102,6 +102,31 @@ char * strncpy(char * dest,const char *src,size_t count)
}
#endif
+#ifndef __HAVE_ARCH_STRLCPY
+/**
+ * strlcpy - Copy a C-string into a sized buffer
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ * @size: size of destination buffer
+ *
+ * Compatible with *BSD: the result is always a valid
+ * NUL-terminated string that fits in the buffer (unless,
+ * of course, the buffer size is zero). It does not pad
+ * out the result like strncpy() does.
+ */
+size_t strlcpy(char *dest, const char *src, size_t size)
+{
+ size_t ret = strlen(src);
+
+ if (size) {
+ size_t len = (ret >= size) ? size - 1 : ret;
+ memcpy(dest, src, len);
+ dest[len] = '\0';
+ }
+ return ret;
+}
+#endif
+
#ifndef __HAVE_ARCH_STRCAT
/**
* strcat - Append one %NUL-terminated string to another
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,
diff --git a/lib/zlib/zlib.h b/lib/zlib/zlib.h
index 556be32754..af3703e6d7 100644
--- a/lib/zlib/zlib.h
+++ b/lib/zlib/zlib.h
@@ -3,7 +3,7 @@
#define __GLUE_ZLIB_H__
#include <common.h>
-#include <compiler.h>
+#include <linux/compiler.h>
#include <asm/unaligned.h>
#include <watchdog.h>
#include "u-boot/zlib.h"