Merge git://git.denx.de/u-boot-dm

master
Tom Rini 7 years ago
commit 15616a0aa5
  1. 6
      Makefile
  2. 6
      arch/arm/config.mk
  3. 7
      arch/arm/cpu/u-boot-spl.lds
  4. 40
      arch/arm/dts/tegra-u-boot.dtsi
  5. 3
      arch/arm/dts/tegra114-u-boot.dtsi
  6. 2
      arch/arm/dts/tegra124-nyan-big-u-boot.dtsi
  7. 3
      arch/arm/dts/tegra124-u-boot.dtsi
  8. 11
      arch/arm/dts/tegra20-u-boot.dtsi
  9. 3
      arch/arm/dts/tegra210-u-boot.dtsi
  10. 3
      arch/arm/dts/tegra30-u-boot.dtsi
  11. 1
      arch/arm/mach-tegra/Kconfig
  12. 6
      arch/sandbox/dts/sandbox_pmic.dtsi
  13. 16
      common/spl/spl.c
  14. 19
      common/spl/spl_ram.c
  15. 16
      doc/device-tree-bindings/regulator/regulator.txt
  16. 7
      drivers/block/blk-uclass.c
  17. 8
      drivers/power/pmic/Kconfig
  18. 1
      drivers/power/pmic/Makefile
  19. 11
      drivers/power/pmic/pmic-uclass.c
  20. 98
      drivers/power/pmic/pmic_tps65910_dm.c
  21. 8
      drivers/power/regulator/Kconfig
  22. 1
      drivers/power/regulator/Makefile
  23. 459
      drivers/power/regulator/tps65910_regulator.c
  24. 2
      drivers/sysreset/sysreset-uclass.c
  25. 93
      include/binman_sym.h
  26. 5
      include/power/sandbox_pmic.h
  27. 130
      include/power/tps65910_pmic.h
  28. 11
      include/spl.h
  29. 2
      test/dm/regulator.c
  30. 32
      tools/binman/README
  31. 11
      tools/binman/binman.py
  32. 3
      tools/binman/control.py
  33. 129
      tools/binman/elf.py
  34. 122
      tools/binman/elf_test.py
  35. 8
      tools/binman/etype/entry.py
  36. 6
      tools/binman/etype/u_boot_spl.py
  37. 7
      tools/binman/etype/u_boot_spl_bss_pad.py
  38. 17
      tools/binman/etype/u_boot_spl_dtb.py
  39. 17
      tools/binman/etype/u_boot_spl_nodtb.py
  40. 9
      tools/binman/etype/u_boot_with_ucode_ptr.py
  41. 68
      tools/binman/ftest.py
  42. 79
      tools/binman/image.py
  43. 46
      tools/binman/image_test.py
  44. 2
      tools/binman/test/21_image_pad.dts
  45. 4
      tools/binman/test/24_sorted.dts
  46. 4
      tools/binman/test/28_pack_4gb_outside.dts
  47. 6
      tools/binman/test/29_x86-rom.dts
  48. 13
      tools/binman/test/51_u_boot_spl_dtb.dts
  49. 11
      tools/binman/test/52_u_boot_spl_nodtb.dts
  50. 20
      tools/binman/test/53_symbols.dts
  51. 18
      tools/binman/test/Makefile
  52. 2
      tools/binman/test/bss_data.c
  53. BIN
      tools/binman/test/u_boot_binman_syms
  54. 14
      tools/binman/test/u_boot_binman_syms.c
  55. 30
      tools/binman/test/u_boot_binman_syms.lds
  56. BIN
      tools/binman/test/u_boot_binman_syms_bad
  57. 1
      tools/binman/test/u_boot_binman_syms_bad.c
  58. 29
      tools/binman/test/u_boot_binman_syms_bad.lds
  59. BIN
      tools/binman/test/u_boot_binman_syms_size
  60. 12
      tools/binman/test/u_boot_binman_syms_size.c
  61. 2
      tools/binman/test/u_boot_ucode_ptr.c

@ -1149,6 +1149,11 @@ u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.img u-boot.dtb FORCE
endif
ifneq ($(CONFIG_TEGRA),)
ifneq ($(CONFIG_BINMAN),)
u-boot-dtb-tegra.bin u-boot-tegra.bin u-boot-nodtb-tegra.bin: \
spl/u-boot-spl u-boot.bin FORCE
$(call if_changed,binman)
else
OBJCOPYFLAGS_u-boot-nodtb-tegra.bin = -O binary --pad-to=$(CONFIG_SYS_TEXT_BASE)
u-boot-nodtb-tegra.bin: spl/u-boot-spl u-boot-nodtb.bin FORCE
$(call if_changed,pad_cat)
@ -1159,6 +1164,7 @@ u-boot-tegra.bin: spl/u-boot-spl u-boot.bin FORCE
u-boot-dtb-tegra.bin: u-boot-tegra.bin FORCE
$(call if_changed,copy)
endif # binman
endif
OBJCOPYFLAGS_u-boot-app.efi := $(OBJCOPYFLAGS_EFI)

@ -136,10 +136,12 @@ endif
# limit ourselves to the sections we want in the .bin.
ifdef CONFIG_ARM64
OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .data \
-j .u_boot_list -j .rela.dyn -j .got -j .got.plt
-j .u_boot_list -j .rela.dyn -j .got -j .got.plt \
-j .binman_sym_table
else
OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \
-j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn
-j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn \
-j .binman_sym_table
endif
# if a dtb section exists we always have to include it

@ -37,6 +37,13 @@ SECTIONS
}
. = ALIGN(4);
.binman_sym_table : {
__binman_sym_start = .;
KEEP(*(SORT(.binman_sym*)));
__binman_sym_end = .;
}
. = ALIGN(4);
__image_copy_end = .;

@ -0,0 +1,40 @@
#include <config.h>
/ {
binman {
multiple-images;
image1 {
filename = "u-boot-tegra.bin";
pad-byte = <0xff>;
u-boot-spl {
};
u-boot {
pos = <(CONFIG_SYS_TEXT_BASE -
CONFIG_SPL_TEXT_BASE)>;
};
};
/* Same as image1 - some tools still expect the -dtb suffix */
image2 {
filename = "u-boot-dtb-tegra.bin";
pad-byte = <0xff>;
u-boot-spl {
};
u-boot {
pos = <(CONFIG_SYS_TEXT_BASE -
CONFIG_SPL_TEXT_BASE)>;
};
};
image3 {
filename = "u-boot-nodtb-tegra.bin";
pad-byte = <0xff>;
u-boot-spl {
};
u-boot-nodtb {
pos = <(CONFIG_SYS_TEXT_BASE -
CONFIG_SPL_TEXT_BASE)>;
};
};
};
};

@ -0,0 +1,3 @@
#include <config.h>
#include "tegra-u-boot.dtsi"

@ -5,6 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include "tegra-u-boot.dtsi"
/ {
host1x@50000000 {
u-boot,dm-pre-reloc;

@ -0,0 +1,3 @@
#include <config.h>
#include "tegra-u-boot.dtsi"

@ -1,8 +1,3 @@
/ {
host1x@50000000 {
u-boot,dm-pre-reloc;
dc@54200000 {
u-boot,dm-pre-reloc;
};
};
};
#include <config.h>
#include "tegra-u-boot.dtsi"

@ -0,0 +1,3 @@
#include <config.h>
#include "tegra-u-boot.dtsi"

@ -0,0 +1,3 @@
#include <config.h>
#include "tegra-u-boot.dtsi"

@ -38,6 +38,7 @@ config TEGRA_COMMON
select OF_CONTROL
select VIDCONSOLE_AS_LCD if DM_VIDEO
select BOARD_EARLY_INIT_F
select BINMAN
imply CRC32_VERIFY
config TEGRA_NO_BPMP

@ -75,4 +75,10 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
no_match_by_nodename {
regulator-name = "buck_SUPPLY_1.5V";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
};
};

@ -8,6 +8,7 @@
*/
#include <common.h>
#include <binman_sym.h>
#include <dm.h>
#include <spl.h>
#include <asm/u-boot.h>
@ -32,6 +33,9 @@ DECLARE_GLOBAL_DATA_PTR;
u32 *boot_params_ptr = NULL;
/* See spl.h for information about this */
binman_sym_declare(ulong, u_boot_any, pos);
/* Define board data structure */
static bd_t bdata __attribute__ ((section(".data")));
@ -120,9 +124,17 @@ __weak void spl_board_prepare_for_boot(void)
void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
{
ulong u_boot_pos = binman_sym(ulong, u_boot_any, pos);
spl_image->size = CONFIG_SYS_MONITOR_LEN;
spl_image->entry_point = CONFIG_SYS_UBOOT_START;
spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
if (u_boot_pos != BINMAN_SYM_MISSING) {
/* biman does not support separate entry addresses at present */
spl_image->entry_point = u_boot_pos;
spl_image->load_addr = u_boot_pos;
} else {
spl_image->entry_point = CONFIG_SYS_UBOOT_START;
spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
}
spl_image->os = IH_OS_U_BOOT;
spl_image->name = "U-Boot";
}

@ -11,6 +11,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <binman_sym.h>
#include <mapmem.h>
#include <spl.h>
#include <libfdt.h>
@ -48,15 +50,24 @@ static int spl_ram_load_image(struct spl_image_info *spl_image,
load.read = spl_ram_load_read;
spl_load_simple_fit(spl_image, &load, 0, header);
} else {
ulong u_boot_pos = binman_sym(ulong, u_boot_any, pos);
debug("Legacy image\n");
/*
* Get the header. It will point to an address defined by
* handoff which will tell where the image located inside
* the flash. For now, it will temporary fixed to address
* pointed by U-Boot.
* the flash.
*/
header = (struct image_header *)
(CONFIG_SYS_TEXT_BASE - sizeof(struct image_header));
debug("u_boot_pos = %lx\n", u_boot_pos);
if (u_boot_pos == BINMAN_SYM_MISSING) {
/*
* No binman support or no information. For now, fix it
* to the address pointed to by U-Boot.
*/
u_boot_pos = CONFIG_SYS_TEXT_BASE -
sizeof(struct image_header);
}
header = (struct image_header *)map_sysmem(u_boot_pos, 0);
spl_parse_image_header(spl_image, header);
}

@ -2,7 +2,8 @@ Voltage/Current regulator
Binding:
The regulator devices don't use the "compatible" property. The binding is done
by the prefix of regulator node's name. Usually the pmic I/O driver will provide
by the prefix of regulator node's name, or, if this fails, by the prefix of the
regulator's "regulator-name" property. Usually the pmic I/O driver will provide
the array of 'struct pmic_child_info' with the prefixes and compatible drivers.
The bind is done by calling function: pmic_bind_childs().
Example drivers:
@ -15,8 +16,19 @@ For the node name e.g.: "prefix[:alpha:]num { ... }":
Example the prefix "ldo" will pass for: "ldo1", "ldo@1", "ldoreg@1, ...
Binding by means of the node's name is preferred. However if the node names
would produce ambiguous prefixes (like "regulator@1" and "regualtor@11") and you
can't or do not want to change them then binding against the "regulator-name"
property is possible. The syntax for the prefix of the "regulator-name" property
is the same as the one for the regulator's node name.
Use case: a regulator named "regulator@1" to be bound to a driver named
"LDO_DRV" and a regulator named "regualator@11" to be bound to an other driver
named "BOOST_DRV". Using prefix "regualtor@1" for driver matching would load
the same driver for both regulators, hence the prefix is ambiguous.
Optional properties:
- regulator-name: a string, required by the regulator uclass
- regulator-name: a string, required by the regulator uclass, used for driver
binding if binding by node's name prefix fails
- regulator-min-microvolt: a minimum allowed Voltage value
- regulator-max-microvolt: a maximum allowed Voltage value
- regulator-min-microamp: a minimum allowed Current value

@ -10,6 +10,7 @@
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/uclass-internal.h>
static const char *if_typename_str[IF_TYPE_COUNT] = {
[IF_TYPE_IDE] = "ide",
@ -331,7 +332,7 @@ int blk_first_device(int if_type, struct udevice **devp)
struct blk_desc *desc;
int ret;
ret = uclass_first_device(UCLASS_BLK, devp);
ret = uclass_find_first_device(UCLASS_BLK, devp);
if (ret)
return ret;
if (!*devp)
@ -340,7 +341,7 @@ int blk_first_device(int if_type, struct udevice **devp)
desc = dev_get_uclass_platdata(*devp);
if (desc->if_type == if_type)
return 0;
ret = uclass_next_device(devp);
ret = uclass_find_next_device(devp);
if (ret)
return ret;
} while (*devp);
@ -356,7 +357,7 @@ int blk_next_device(struct udevice **devp)
desc = dev_get_uclass_platdata(*devp);
if_type = desc->if_type;
do {
ret = uclass_next_device(devp);
ret = uclass_find_next_device(devp);
if (ret)
return ret;
if (!*devp)

@ -201,3 +201,11 @@ config POWER_MC34VR500
The MC34VR500 is used in conjunction with the FSL T1 and LS1 series
SoC. It provides 4 buck DC-DC convertors and 5 LDOs, and it is accessed
via an I2C interface.
config DM_PMIC_TPS65910
bool "Enable driver for Texas Instruments TPS65910 PMIC"
depends on DM_PMIC
---help---
The TPS65910 is a PMIC containing 3 buck DC-DC converters, one boost
DC-DC converter, 8 LDOs and a RTC. This driver binds the SMPS and LDO
pmic children.

@ -19,6 +19,7 @@ obj-$(CONFIG_PMIC_RK8XX) += rk8xx.o
obj-$(CONFIG_PMIC_RN5T567) += rn5t567.o
obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o
obj-$(CONFIG_DM_PMIC_TPS65910) += pmic_tps65910_dm.o
obj-$(CONFIG_$(SPL_)PMIC_PALMAS) += palmas.o
obj-$(CONFIG_$(SPL_)PMIC_LP873X) += lp873x.o
obj-$(CONFIG_$(SPL_)PMIC_LP87565) += lp87565.o

@ -26,6 +26,7 @@ int pmic_bind_children(struct udevice *pmic, ofnode parent,
struct driver *drv;
struct udevice *child;
const char *node_name;
const char *reg_name;
int bind_count = 0;
ofnode node;
int prefix_len;
@ -44,8 +45,14 @@ int pmic_bind_children(struct udevice *pmic, ofnode parent,
debug(" - compatible prefix: '%s'\n", info->prefix);
prefix_len = strlen(info->prefix);
if (strncmp(info->prefix, node_name, prefix_len))
continue;
if (strncmp(info->prefix, node_name, prefix_len)) {
reg_name = ofnode_read_string(node,
"regulator-name");
if (!reg_name)
continue;
if (strncmp(info->prefix, reg_name, prefix_len))
continue;
}
drv = lists_driver_lookup_name(info->driver);
if (!drv) {

@ -0,0 +1,98 @@
/*
* Copyright (C) EETS GmbH, 2017, Felix Brack <f.brack@eets.ch>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <i2c.h>
#include <power/pmic.h>
#include <power/regulator.h>
#include <power/tps65910_pmic.h>
DECLARE_GLOBAL_DATA_PTR;
static const struct pmic_child_info pmic_children_info[] = {
{ .prefix = "ldo_", .driver = TPS65910_LDO_DRIVER },
{ .prefix = "buck_", .driver = TPS65910_BUCK_DRIVER },
{ .prefix = "boost_", .driver = TPS65910_BOOST_DRIVER },
{ },
};
static int pmic_tps65910_reg_count(struct udevice *dev)
{
return TPS65910_NUM_REGS;
}
static int pmic_tps65910_write(struct udevice *dev, uint reg, const u8 *buffer,
int len)
{
int ret;
ret = dm_i2c_write(dev, reg, buffer, len);
if (ret)
error("%s write error on register %02x\n", dev->name, reg);
return ret;
}
static int pmic_tps65910_read(struct udevice *dev, uint reg, u8 *buffer,
int len)
{
int ret;
ret = dm_i2c_read(dev, reg, buffer, len);
if (ret)
error("%s read error on register %02x\n", dev->name, reg);
return ret;
}
static int pmic_tps65910_bind(struct udevice *dev)
{
ofnode regulators_node;
int children;
regulators_node = dev_read_subnode(dev, "regulators");
if (!ofnode_valid(regulators_node)) {
debug("%s regulators subnode not found\n", dev->name);
return -EINVAL;
}
children = pmic_bind_children(dev, regulators_node, pmic_children_info);
if (!children)
debug("%s has no children (regulators)\n", dev->name);
return 0;
}
static int pmic_tps65910_probe(struct udevice *dev)
{
/* use I2C control interface instead of I2C smartreflex interface to
* access smartrefelex registers VDD1_OP_REG, VDD1_SR_REG, VDD2_OP_REG
* and VDD2_SR_REG
*/
return pmic_clrsetbits(dev, TPS65910_REG_DEVICE_CTRL, 0,
TPS65910_I2C_SEL_MASK);
}
static struct dm_pmic_ops pmic_tps65910_ops = {
.reg_count = pmic_tps65910_reg_count,
.read = pmic_tps65910_read,
.write = pmic_tps65910_write,
};
static const struct udevice_id pmic_tps65910_match[] = {
{ .compatible = "ti,tps65910" },
{ /* sentinel */ }
};
U_BOOT_DRIVER(pmic_tps65910) = {
.name = "pmic_tps65910",
.id = UCLASS_PMIC,
.of_match = pmic_tps65910_match,
.bind = pmic_tps65910_bind,
.probe = pmic_tps65910_probe,
.ops = &pmic_tps65910_ops,
};

@ -188,3 +188,11 @@ config DM_REGULATOR_LP87565
LP87565 series of PMICs have 4 single phase BUCKs that can also
be configured in multi phase modes. The driver implements
get/set api for value and enable.
config DM_REGULATOR_TPS65910
bool "Enable driver for TPS65910 PMIC regulators"
depends on DM_PMIC_TPS65910
---help---
The TPS65910 PMIC provides 4 SMPSs and 8 LDOs. This driver supports all
regulator types of the TPS65910 (BUCK, BOOST and LDO). It implements
the get/set api for value and enable.

@ -21,3 +21,4 @@ obj-$(CONFIG_$(SPL_)DM_REGULATOR_PALMAS) += palmas_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_PBIAS) += pbias_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP87565) += lp87565_regulator.o
obj-$(CONFIG_DM_REGULATOR_TPS65910) += tps65910_regulator.o

@ -0,0 +1,459 @@
/*
* Copyright (C) EETS GmbH, 2017, Felix Brack <f.brack@eets.ch>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <power/pmic.h>
#include <power/regulator.h>
#include <power/tps65910_pmic.h>
#define VOUT_CHOICE_COUNT 4
/*
* struct regulator_props - Properties of a LDO and VIO SMPS regulator
*
* All of these regulators allow setting one out of four output voltages.
* These output voltages are only achievable when supplying the regulator
* with a minimum input voltage.
*
* @vin_min[]: minimum supply input voltage in uV required to achieve the
* corresponding vout[] voltage
* @vout[]: regulator output voltage in uV
* @reg: I2C register used to set regulator voltage
*/
struct regulator_props {
int vin_min[VOUT_CHOICE_COUNT];
int vout[VOUT_CHOICE_COUNT];
int reg;
};
static const struct regulator_props ldo_props_vdig1 = {
.vin_min = { 1700000, 2100000, 2700000, 3200000 },
.vout = { 1200000, 1500000, 1800000, 2700000 },
.reg = TPS65910_REG_VDIG1
};
static const struct regulator_props ldo_props_vdig2 = {
.vin_min = { 1700000, 1700000, 1700000, 2700000 },
.vout = { 1000000, 1100000, 1200000, 1800000 },
.reg = TPS65910_REG_VDIG2
};
static const struct regulator_props ldo_props_vpll = {
.vin_min = { 2700000, 2700000, 2700000, 3000000 },
.vout = { 1000000, 1100000, 1800000, 2500000 },
.reg = TPS65910_REG_VPLL
};
static const struct regulator_props ldo_props_vdac = {
.vin_min = { 2700000, 3000000, 3200000, 3200000 },
.vout = { 1800000, 2600000, 2800000, 2850000 },
.reg = TPS65910_REG_VDAC
};
static const struct regulator_props ldo_props_vaux1 = {
.vin_min = { 2700000, 3200000, 3200000, 3200000 },
.vout = { 1800000, 2500000, 2800000, 2850000 },
.reg = TPS65910_REG_VAUX1
};
static const struct regulator_props ldo_props_vaux2 = {
.vin_min = { 2700000, 3200000, 3200000, 3600000 },
.vout = { 1800000, 2800000, 2900000, 3300000 },
.reg = TPS65910_REG_VAUX2
};
static const struct regulator_props ldo_props_vaux33 = {
.vin_min = { 2700000, 2700000, 3200000, 3600000 },
.vout = { 1800000, 2000000, 2800000, 3300000 },
.reg = TPS65910_REG_VAUX33
};
static const struct regulator_props ldo_props_vmmc = {
.vin_min = { 2700000, 3200000, 3200000, 3600000 },
.vout = { 1800000, 2800000, 3000000, 3300000 },
.reg = TPS65910_REG_VMMC
};
static const struct regulator_props smps_props_vio = {
.vin_min = { 3200000, 3200000, 4000000, 4400000 },
.vout = { 1500000, 1800000, 2500000, 3300000 },
.reg = TPS65910_REG_VIO
};
/* lookup table of control registers indexed by regulator unit number */
static const int ctrl_regs[] = {
TPS65910_REG_VRTC,
TPS65910_REG_VIO,
TPS65910_REG_VDD1,
TPS65910_REG_VDD2,
TPS65910_REG_VDD3,
TPS65910_REG_VDIG1,
TPS65910_REG_VDIG2,
TPS65910_REG_VPLL,
TPS65910_REG_VDAC,
TPS65910_REG_VAUX1,
TPS65910_REG_VAUX2,
TPS65910_REG_VAUX33,
TPS65910_REG_VMMC
};
/* supply names as used in DT */
static const char * const supply_names[] = {
"vccio-supply",
"vcc1-supply",
"vcc2-supply",
"vcc3-supply",
"vcc4-supply",
"vcc5-supply",
"vcc6-supply",
"vcc7-supply"
};
/* lookup table of regulator supplies indexed by regulator unit number */
static const int regulator_supplies[] = {
TPS65910_SUPPLY_VCC7,
TPS65910_SUPPLY_VCCIO,
TPS65910_SUPPLY_VCC1,
TPS65910_SUPPLY_VCC2,
TPS65910_SUPPLY_VCC7,
TPS65910_SUPPLY_VCC6,
TPS65910_SUPPLY_VCC6,
TPS65910_SUPPLY_VCC5,
TPS65910_SUPPLY_VCC5,
TPS65910_SUPPLY_VCC4,
TPS65910_SUPPLY_VCC4,
TPS65910_SUPPLY_VCC3,
TPS65910_SUPPLY_VCC3
};
static int get_ctrl_reg_from_unit_addr(const uint unit_addr)
{
if (unit_addr < ARRAY_SIZE(ctrl_regs))
return ctrl_regs[unit_addr];
return -ENXIO;
}
static int tps65910_regulator_get_value(struct udevice *dev,
const struct regulator_props *rgp)
{
int sel, val, vout;
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
int vin = pdata->supply;
val = pmic_reg_read(dev->parent, rgp->reg);
if (val < 0)
return val;
sel = (val & TPS65910_SEL_MASK) >> 2;
vout = (vin >= *(rgp->vin_min + sel)) ? *(rgp->vout + sel) : 0;
vout = ((val & TPS65910_SUPPLY_STATE_MASK) == 1) ? vout : 0;
return vout;
}
static int tps65910_ldo_get_value(struct udevice *dev)
{
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
int vin;
if (!pdata)
return 0;
vin = pdata->supply;
switch (pdata->unit) {
case TPS65910_UNIT_VRTC:
/* VRTC is fixed and can't be turned off */
return (vin >= 2500000) ? 1830000 : 0;
case TPS65910_UNIT_VDIG1:
return tps65910_regulator_get_value(dev, &ldo_props_vdig1);
case TPS65910_UNIT_VDIG2:
return tps65910_regulator_get_value(dev, &ldo_props_vdig2);
case TPS65910_UNIT_VPLL:
return tps65910_regulator_get_value(dev, &ldo_props_vpll);
case TPS65910_UNIT_VDAC:
return tps65910_regulator_get_value(dev, &ldo_props_vdac);
case TPS65910_UNIT_VAUX1:
return tps65910_regulator_get_value(dev, &ldo_props_vaux1);
case TPS65910_UNIT_VAUX2:
return tps65910_regulator_get_value(dev, &ldo_props_vaux2);
case TPS65910_UNIT_VAUX33:
return tps65910_regulator_get_value(dev, &ldo_props_vaux33);
case TPS65910_UNIT_VMMC:
return tps65910_regulator_get_value(dev, &ldo_props_vmmc);
default:
return 0;
}
}
static int tps65910_regulator_set_value(struct udevice *dev,
const struct regulator_props *ldo,
int uV)
{
int val;
int sel = 0;
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
do {
/* we only allow exact voltage matches */
if (uV == *(ldo->vout + sel))
break;
} while (++sel < VOUT_CHOICE_COUNT);
if (sel == VOUT_CHOICE_COUNT)
return -EINVAL;
if (pdata->supply < *(ldo->vin_min + sel))
return -EINVAL;
val = pmic_reg_read(dev->parent, ldo->reg);
if (val < 0)
return val;
val &= ~TPS65910_SEL_MASK;
val |= sel << 2;
return pmic_reg_write(dev->parent, ldo->reg, val);
}
static int tps65910_ldo_set_value(struct udevice *dev, int uV)
{
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
int vin = pdata->supply;
switch (pdata->unit) {
case TPS65910_UNIT_VRTC:
/* VRTC is fixed to 1.83V and can't be turned off */
if (vin < 2500000)
return -EINVAL;
return 0;
case TPS65910_UNIT_VDIG1:
return tps65910_regulator_set_value(dev, &ldo_props_vdig1, uV);
case TPS65910_UNIT_VDIG2:
return tps65910_regulator_set_value(dev, &ldo_props_vdig2, uV);
case TPS65910_UNIT_VPLL:
return tps65910_regulator_set_value(dev, &ldo_props_vpll, uV);
case TPS65910_UNIT_VDAC:
return tps65910_regulator_set_value(dev, &ldo_props_vdac, uV);
case TPS65910_UNIT_VAUX1:
return tps65910_regulator_set_value(dev, &ldo_props_vaux1, uV);
case TPS65910_UNIT_VAUX2:
return tps65910_regulator_set_value(dev, &ldo_props_vaux2, uV);
case TPS65910_UNIT_VAUX33:
return tps65910_regulator_set_value(dev, &ldo_props_vaux33, uV);
case TPS65910_UNIT_VMMC:
return tps65910_regulator_set_value(dev, &ldo_props_vmmc, uV);
default:
return 0;
}
}
static int tps65910_get_enable(struct udevice *dev)
{
int reg, val;
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
reg = get_ctrl_reg_from_unit_addr(pdata->unit);
if (reg < 0)
return reg;
val = pmic_reg_read(dev->parent, reg);
if (val < 0)
return val;
/* bits 1:0 of regulator control register define state */
return ((val & TPS65910_SUPPLY_STATE_MASK) == 1);
}
static int tps65910_set_enable(struct udevice *dev, bool enable)
{
int reg;
uint clr, set;
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
reg = get_ctrl_reg_from_unit_addr(pdata->unit);
if (reg < 0)
return reg;
if (enable) {
clr = TPS65910_SUPPLY_STATE_MASK & ~TPS65910_SUPPLY_STATE_ON;
set = TPS65910_SUPPLY_STATE_MASK & TPS65910_SUPPLY_STATE_ON;
} else {
clr = TPS65910_SUPPLY_STATE_MASK & ~TPS65910_SUPPLY_STATE_OFF;
set = TPS65910_SUPPLY_STATE_MASK & TPS65910_SUPPLY_STATE_OFF;
}
return pmic_clrsetbits(dev->parent, reg, clr, set);
}
static int buck_get_vdd1_vdd2_value(struct udevice *dev, int reg_vdd)
{
int gain;
int val = pmic_reg_read(dev, reg_vdd);
if (val < 0)
return val;
gain = (val & TPS65910_GAIN_SEL_MASK) >> 6;
gain = (gain == 0) ? 1 : gain;
val = pmic_reg_read(dev, reg_vdd + 1);
if (val < 0)
return val;
if (val & TPS65910_VDD_SR_MASK)
/* use smart reflex value instead */
val = pmic_reg_read(dev, reg_vdd + 2);
if (val < 0)
return val;
return (562500 + (val & TPS65910_VDD_SEL_MASK) * 12500) * gain;
}
static int tps65910_buck_get_value(struct udevice *dev)
{
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
switch (pdata->unit) {
case TPS65910_UNIT_VIO:
return tps65910_regulator_get_value(dev, &smps_props_vio);
case TPS65910_UNIT_VDD1:
return buck_get_vdd1_vdd2_value(dev->parent, TPS65910_REG_VDD1);
case TPS65910_UNIT_VDD2:
return buck_get_vdd1_vdd2_value(dev->parent, TPS65910_REG_VDD2);
default:
return 0;
}
}
static int buck_set_vdd1_vdd2_value(struct udevice *dev, int uV)
{
int ret, reg_vdd, gain;
int val;
struct dm_regulator_uclass_platdata *uc_pdata;
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
switch (pdata->unit) {
case TPS65910_UNIT_VDD1:
reg_vdd = TPS65910_REG_VDD1;
break;
case TPS65910_UNIT_VDD2:
reg_vdd = TPS65910_REG_VDD2;
break;
default:
return -EINVAL;
}
uc_pdata = dev_get_uclass_platdata(dev);
/* check setpoint is within limits */
if (uV < uc_pdata->min_uV) {
error("voltage %duV for %s too low\n", uV, dev->name);
return -EINVAL;
}
if (uV > uc_pdata->max_uV) {
error("voltage %duV for %s too high\n", uV, dev->name);
return -EINVAL;
}
val = pmic_reg_read(dev->parent, reg_vdd);
if (val < 0)
return val;
gain = (val & TPS65910_GAIN_SEL_MASK) >> 6;
gain = (gain == 0) ? 1 : gain;
val = ((uV / gain) - 562500) / 12500;
if (val < TPS65910_VDD_SEL_MIN || val > TPS65910_VDD_SEL_MAX)
/*
* Neither do we change the gain, nor do we allow shutdown or
* any approximate value (for now)
*/
return -EPERM;
val &= TPS65910_VDD_SEL_MASK;
ret = pmic_reg_write(dev->parent, reg_vdd + 1, val);
if (ret)
return ret;
return 0;
}
static int tps65910_buck_set_value(struct udevice *dev, int uV)
{
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
if (pdata->unit == TPS65910_UNIT_VIO)
return tps65910_regulator_set_value(dev, &smps_props_vio, uV);
return buck_set_vdd1_vdd2_value(dev, uV);
}
static int tps65910_boost_get_value(struct udevice *dev)
{
int vout;
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
vout = (pdata->supply >= 3000000) ? 5000000 : 0;
return vout;
}
static int tps65910_regulator_ofdata_to_platdata(struct udevice *dev)
{
struct udevice *supply;
int ret;
const char *supply_name;
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
pdata->unit = dev_get_driver_data(dev);
if (pdata->unit > TPS65910_UNIT_VMMC)
return -EINVAL;
supply_name = supply_names[regulator_supplies[pdata->unit]];
debug("Looking up supply power %s\n", supply_name);
ret = device_get_supply_regulator(dev->parent, supply_name, &supply);
if (ret) {
debug(" missing supply power %s\n", supply_name);
return ret;
}
pdata->supply = regulator_get_value(supply);
if (pdata->supply < 0) {
debug(" invalid supply voltage for regulator %s\n",
supply->name);
return -EINVAL;
}
return 0;
}
static const struct dm_regulator_ops tps65910_boost_ops = {
.get_value = tps65910_boost_get_value,
.get_enable = tps65910_get_enable,
.set_enable = tps65910_set_enable,
};
U_BOOT_DRIVER(tps65910_boost) = {
.name = TPS65910_BOOST_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &tps65910_boost_ops,
.platdata_auto_alloc_size = sizeof(struct tps65910_regulator_pdata),
.ofdata_to_platdata = tps65910_regulator_ofdata_to_platdata,
};
static const struct dm_regulator_ops tps65910_buck_ops = {
.get_value = tps65910_buck_get_value,
.set_value = tps65910_buck_set_value,
.get_enable = tps65910_get_enable,
.set_enable = tps65910_set_enable,
};
U_BOOT_DRIVER(tps65910_buck) = {
.name = TPS65910_BUCK_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &tps65910_buck_ops,
.platdata_auto_alloc_size = sizeof(struct tps65910_regulator_pdata),
.ofdata_to_platdata = tps65910_regulator_ofdata_to_platdata,
};
static const struct dm_regulator_ops tps65910_ldo_ops = {
.get_value = tps65910_ldo_get_value,
.set_value = tps65910_ldo_set_value,
.get_enable = tps65910_get_enable,
.set_enable = tps65910_set_enable,
};
U_BOOT_DRIVER(tps65910_ldo) = {
.name = TPS65910_LDO_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &tps65910_ldo_ops,
.platdata_auto_alloc_size = sizeof(struct tps65910_regulator_pdata),
.ofdata_to_platdata = tps65910_regulator_ofdata_to_platdata,
};

@ -70,7 +70,7 @@ void reset_cpu(ulong addr)
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
sysreset_walk_halt(SYSRESET_WARM);
sysreset_walk_halt(SYSRESET_COLD);
return 0;
}

@ -0,0 +1,93 @@
/*
* Symbol access for symbols set up by binman as part of the build.
*
* This allows C code to access the position of a particular part of the image
* assembled by binman.
*
* Copyright (c) 2017 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __BINMAN_SYM_H
#define __BINMAN_SYM_H
#define BINMAN_SYM_MISSING (-1UL)
#ifdef CONFIG_BINMAN
/**
* binman_symname() - Internal fnuction to get a binman symbol name
*
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl')
* @_prop_name: Property value to get from that entry (e.g. 'pos')
* @returns name of the symbol for that entry and property
*/
#define binman_symname(_entry_name, _prop_name) \
_binman_ ## _entry_name ## _prop_ ## _prop_name
/**
* binman_sym_declare() - Declare a symbol that will be used at run-time
*
* @_type: Type f the symbol (e.g. unsigned long)
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl')
* @_prop_name: Property value to get from that entry (e.g. 'pos')
*/
#define binman_sym_declare(_type, _entry_name, _prop_name) \
_type binman_symname(_entry_name, _prop_name) \
__attribute__((aligned(4), unused, section(".binman_sym")))
/**
* binman_sym_extern() - Declare a extern symbol that will be used at run-time
*
* @_type: Type f the symbol (e.g. unsigned long)
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl')
* @_prop_name: Property value to get from that entry (e.g. 'pos')
*/
#define binman_sym_extern(_type, _entry_name, _prop_name) \
extern _type binman_symname(_entry_name, _prop_name) \
__attribute__((aligned(4), unused, section(".binman_sym")))
/**
* binman_sym_declare_optional() - Declare an optional symbol
*
* If this symbol cannot be provided by binman, an error will not be generated.
* Instead the image will be assigned the value BINMAN_SYM_MISSING.
*
* @_type: Type f the symbol (e.g. unsigned long)
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl')
* @_prop_name: Property value to get from that entry (e.g. 'pos')
*/
#define binman_sym_declare_optional(_type, _entry_name, _prop_name) \
_type binman_symname(_entry_name, _prop_name) \
__attribute__((aligned(4), weak, unused, \
section(".binman_sym")))
/**
* binman_sym() - Access a previously declared symbol
*
* This is used to get the value of a symbol. E.g.:
*
* ulong address = binman_sym(ulong, u_boot_spl, pos);
*
* @_type: Type f the symbol (e.g. unsigned long)
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl')
* @_prop_name: Property value to get from that entry (e.g. 'pos')
* @returns value of that property (filled in by binman)
*/
#define binman_sym(_type, _entry_name, _prop_name) \
(*(_type *)&binman_symname(_entry_name, _prop_name))
#else /* !BINMAN */
#define binman_sym_declare(_type, _entry_name, _prop_name)
#define binman_sym_declare_optional(_type, _entry_name, _prop_name)
#define binman_sym_extern(_type, _entry_name, _prop_name)
#define binman_sym(_type, _entry_name, _prop_name) BINMAN_SYM_MISSING
#endif /* BINMAN */
#endif

@ -13,7 +13,7 @@
#define SANDBOX_BUCK_DRIVER "sandbox_buck"
#define SANDBOX_OF_BUCK_PREFIX "buck"
#define SANDBOX_BUCK_COUNT 2
#define SANDBOX_BUCK_COUNT 3
#define SANDBOX_LDO_COUNT 2
/*
* Sandbox PMIC registers:
@ -109,6 +109,9 @@ enum {
#define SANDBOX_BUCK1_PLATNAME "SUPPLY_1.2V"
#define SANDBOX_BUCK2_DEVNAME "buck2"
#define SANDBOX_BUCK2_PLATNAME "SUPPLY_3.3V"
/* BUCK3: for testing fallback regulator prefix matching during bind */
#define SANDBOX_BUCK3_DEVNAME "no_match_by_nodename"
#define SANDBOX_BUCK3_PLATNAME "buck_SUPPLY_1.5V"
/* LDO names */
#define SANDBOX_LDO1_DEVNAME "ldo1"
#define SANDBOX_LDO1_PLATNAME "VDD_EMMC_1.8V"

@ -0,0 +1,130 @@
/*
* Copyright (C) EETS GmbH, 2017, Felix Brack <f.brack@eets.ch>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __TPS65910_PMIC_H_
#define __TPS65910_PMIC_H_
#define TPS65910_I2C_SEL_MASK (0x1 << 4)
#define TPS65910_VDD_SR_MASK (0x1 << 7)
#define TPS65910_GAIN_SEL_MASK (0x3 << 6)
#define TPS65910_VDD_SEL_MASK 0x7f
#define TPS65910_VDD_SEL_MIN 3
#define TPS65910_VDD_SEL_MAX 75
#define TPS65910_SEL_MASK (0x3 << 2)
#define TPS65910_SUPPLY_STATE_MASK 0x3
#define TPS65910_SUPPLY_STATE_OFF 0x0
#define TPS65910_SUPPLY_STATE_ON 0x1
/* i2c registers */
enum {
TPS65910_REG_RTC_SEC = 0x00,
TPS65910_REG_RTC_MIN,
TPS65910_REG_RTC_HOUR,
TPS65910_REG_RTC_DAY,
TPS65910_REG_RTC_MONTH,
TPS65910_REG_RTC_YEAR,
TPS65910_REG_RTC_WEEK,
TPS65910_REG_RTC_ALARM_SEC = 0x08,
TPS65910_REG_RTC_ALARM_MIN,
TPS65910_REG_RTC_ALARM_HOUR,
TPS65910_REG_RTC_ALARM_DAY,
TPS65910_REG_RTC_ALARM_MONTH,
TPS65910_REG_RTC_ALARM_YEAR,
TPS65910_REG_RTC_CTRL = 0x10,
TPS65910_REG_RTC_STAT,
TPS65910_REG_RTC_INT,
TPS65910_REG_RTC_COMP_LSB,
TPS65910_REG_RTC_COMP_MSB,
TPS65910_REG_RTC_RESISTOR_PRG,
TPS65910_REG_RTC_RESET_STAT,
TPS65910_REG_BACKUP1,
TPS65910_REG_BACKUP2,
TPS65910_REG_BACKUP3,
TPS65910_REG_BACKUP4,
TPS65910_REG_BACKUP5,
TPS65910_REG_PUADEN,
TPS65910_REG_REF,
TPS65910_REG_VRTC,
TPS65910_REG_VIO = 0x20,
TPS65910_REG_VDD1,
TPS65910_REG_VDD1_VAL,
TPS65910_REG_VDD1_VAL_SR,
TPS65910_REG_VDD2,
TPS65910_REG_VDD2_VAL,
TPS65910_REG_VDD2_VAL_SR,
TPS65910_REG_VDD3,
TPS65910_REG_VDIG1 = 0x30,
TPS65910_REG_VDIG2,
TPS65910_REG_VAUX1,
TPS65910_REG_VAUX2,
TPS65910_REG_VAUX33,
TPS65910_REG_VMMC,
TPS65910_REG_VPLL,
TPS65910_REG_VDAC,
TPS65910_REG_THERM,
TPS65910_REG_BATTERY_BACKUP_CHARGE,
TPS65910_REG_DCDC_CTRL = 0x3e,
TPS65910_REG_DEVICE_CTRL,
TPS65910_REG_DEVICE_CTRL2,
TPS65910_REG_SLEEP_KEEP_LDO_ON,
TPS65910_REG_SLEEP_KEEP_RES_ON,
TPS65910_REG_SLEEP_SET_LDO_OFF,
TPS65910_REG_SLEEP_SET_RES_OFF,
TPS65910_REG_EN1_LDO_ASS,
TPS65910_REG_EM1_SMPS_ASS,
TPS65910_REG_EN2_LDO_ASS,
TPS65910_REG_EM2_SMPS_ASS,
TPS65910_REG_INT_STAT = 0x50,
TPS65910_REG_INT_MASK,
TPS65910_REG_INT_STAT2,
TPS65910_REG_INT_MASK2,
TPS65910_REG_GPIO = 0x60,
TPS65910_REG_JTAGREVNUM = 0x80,
TPS65910_NUM_REGS
};
/* chip supplies */
enum {
TPS65910_SUPPLY_VCCIO = 0x00,
TPS65910_SUPPLY_VCC1,
TPS65910_SUPPLY_VCC2,
TPS65910_SUPPLY_VCC3,
TPS65910_SUPPLY_VCC4,
TPS65910_SUPPLY_VCC5,
TPS65910_SUPPLY_VCC6,
TPS65910_SUPPLY_VCC7,
TPS65910_NUM_SUPPLIES
};
/* regulator unit numbers */
enum {
TPS65910_UNIT_VRTC = 0x00,
TPS65910_UNIT_VIO,
TPS65910_UNIT_VDD1,
TPS65910_UNIT_VDD2,
TPS65910_UNIT_VDD3,
TPS65910_UNIT_VDIG1,
TPS65910_UNIT_VDIG2,
TPS65910_UNIT_VPLL,
TPS65910_UNIT_VDAC,
TPS65910_UNIT_VAUX1,
TPS65910_UNIT_VAUX2,
TPS65910_UNIT_VAUX33,
TPS65910_UNIT_VMMC,
};
/* platform data */
struct tps65910_regulator_pdata {
u32 supply; /* regulator supply voltage in uV */
uint unit; /* unit-address according to DT */
};
/* driver names */
#define TPS65910_BUCK_DRIVER "tps65910_buck"
#define TPS65910_BOOST_DRIVER "tps65910_boost"
#define TPS65910_LDO_DRIVER "tps65910_ldo"
#endif /* __TPS65910_PMIC_H_ */

@ -7,6 +7,8 @@
#ifndef _SPL_H_
#define _SPL_H_
#include <binman_sym.h>
/* Platform-specific defines */
#include <linux/compiler.h>
#include <asm/spl.h>
@ -51,6 +53,15 @@ struct spl_load_info {
void *buf);
};
/*
* We need to know the position of U-Boot in memory so we can jump to it. We
* allow any U-Boot binary to be used (u-boot.bin, u-boot-nodtb.bin,
* u-boot.img), hence the '_any'. These is no checking here that the correct
* image is found. For * example if u-boot.img is used we don't check that
* spl_parse_image_header() can parse a valid header.
*/
binman_sym_extern(ulong, u_boot_any, pos);
/**
* spl_load_simple_fit() - Loads a fit image from a device.
* @spl_image: Image description to set up

@ -27,6 +27,7 @@ DECLARE_GLOBAL_DATA_PTR;
enum {
BUCK1,
BUCK2,
BUCK3,
LDO1,
LDO2,
OUTPUT_COUNT,
@ -42,6 +43,7 @@ static const char *regulator_names[OUTPUT_COUNT][OUTPUT_NAME_COUNT] = {
/* devname, platname */
{ SANDBOX_BUCK1_DEVNAME, SANDBOX_BUCK1_PLATNAME },
{ SANDBOX_BUCK2_DEVNAME, SANDBOX_BUCK2_PLATNAME },
{ SANDBOX_BUCK3_DEVNAME, SANDBOX_BUCK3_PLATNAME },
{ SANDBOX_LDO1_DEVNAME, SANDBOX_LDO1_PLATNAME},
{ SANDBOX_LDO2_DEVNAME, SANDBOX_LDO2_PLATNAME},
};

@ -439,6 +439,8 @@ contents of an entry in some way. For example, it would be possible to create
an entry containing a hash of the contents of some other entries. At this
stage the position and size of entries should not be adjusted.
6. WriteEntryInfo()
7. BuildImage() - builds the image and writes it to a file. This is the final
step.
@ -471,6 +473,33 @@ the 'warning' line in scripts/Makefile.lib to see what it has found:
# u_boot_dtsi_options_debug = $(u_boot_dtsi_options_raw)
Access to binman entry positions at run time
--------------------------------------------
Binman assembles images and determines where each entry is placed in the image.
This information may be useful to U-Boot at run time. For example, in SPL it
is useful to be able to find the location of U-Boot so that it can be executed
when SPL is finished.
Binman allows you to declare symbols in the SPL image which are filled in
with their correct values during the build. For example:
binman_sym_declare(ulong, u_boot_any, pos);
declares a ulong value which will be assigned to the position of any U-Boot
image (u-boot.bin, u-boot.img, u-boot-nodtb.bin) that is present in the image.
You can access this value with something like:
ulong u_boot_pos = binman_sym(ulong, u_boot_any, pos);
Thus u_boot_pos will be set to the position of U-Boot in memory, assuming that
the whole image has been loaded, or is available in flash. You can then jump to
that address to start U-Boot.
At present this feature is only supported in SPL. In principle it is possible
to fill in such symbols in U-Boot proper, as well.
Code coverage
-------------
@ -543,7 +572,8 @@ To do
Some ideas:
- Fill out the device tree to include the final position and size of each
entry (since the input file may not always specify these)
entry (since the input file may not always specify these). See also
'Access to binman entry positions at run time' above
- Use of-platdata to make the information available to code that is unable
to use device tree (such as a very small SPL image)
- Write an image map to a text file

@ -31,11 +31,13 @@ import cmdline
import command
import control
def RunTests():
def RunTests(debug):
"""Run the functional tests and any embedded doctests"""
import elf_test
import entry_test
import fdt_test
import ftest
import image_test
import test
import doctest
@ -45,12 +47,15 @@ def RunTests():
suite.run(result)
sys.argv = [sys.argv[0]]
if debug:
sys.argv.append('-D')
# Run the entry tests first ,since these need to be the first to import the
# 'entry' module.
suite = unittest.TestLoader().loadTestsFromTestCase(entry_test.TestEntry)
suite.run(result)
for module in (ftest.TestFunctional, fdt_test.TestFdt):
for module in (ftest.TestFunctional, fdt_test.TestFdt, elf_test.TestElf,
image_test.TestImage):
suite = unittest.TestLoader().loadTestsFromTestCase(module)
suite.run(result)
@ -110,7 +115,7 @@ def RunBinman(options, args):
sys.tracebacklimit = 0
if options.test:
ret_code = RunTests()
ret_code = RunTests(options.debug)
elif options.test_coverage:
RunTestCoverage()

@ -12,6 +12,7 @@ import sys
import tools
import command
import elf
import fdt
import fdt_util
from image import Image
@ -89,6 +90,7 @@ def Binman(options, args):
try:
tout.Init(options.verbosity)
elf.debug = options.debug
try:
tools.SetInputDirs(options.indir)
tools.PrepareOutputDir(options.outdir, options.preserve)
@ -109,6 +111,7 @@ def Binman(options, args):
image.CheckSize()
image.CheckEntries()
image.ProcessEntryContents()
image.WriteSymbols()
image.BuildImage()
finally:
tools.FinaliseOutputDir()

@ -0,0 +1,129 @@
# Copyright (c) 2016 Google, Inc
# Written by Simon Glass <sjg@chromium.org>
#
# SPDX-License-Identifier: GPL-2.0+
#
# Handle various things related to ELF images
#
from collections import namedtuple, OrderedDict
import command
import os
import re
import struct
import tools
# This is enabled from control.py
debug = False
Symbol = namedtuple('Symbol', ['section', 'address', 'size', 'weak'])
def GetSymbols(fname, patterns):
"""Get the symbols from an ELF file
Args:
fname: Filename of the ELF file to read
patterns: List of regex patterns to search for, each a string
Returns:
None, if the file does not exist, or Dict:
key: Name of symbol
value: Hex value of symbol
"""
stdout = command.Output('objdump', '-t', fname, raise_on_error=False)
lines = stdout.splitlines()
if patterns:
re_syms = re.compile('|'.join(patterns))
else:
re_syms = None
syms = {}
syms_started = False
for line in lines:
if not line or not syms_started:
if 'SYMBOL TABLE' in line:
syms_started = True
line = None # Otherwise code coverage complains about 'continue'
continue
if re_syms and not re_syms.search(line):
continue
space_pos = line.find(' ')
value, rest = line[:space_pos], line[space_pos + 1:]
flags = rest[:7]
parts = rest[7:].split()
section, size = parts[:2]
if len(parts) > 2:
name = parts[2]
syms[name] = Symbol(section, int(value, 16), int(size,16),
flags[1] == 'w')
return syms
def GetSymbolAddress(fname, sym_name):
"""Get a value of a symbol from an ELF file
Args:
fname: Filename of the ELF file to read
patterns: List of regex patterns to search for, each a string
Returns:
Symbol value (as an integer) or None if not found
"""
syms = GetSymbols(fname, [sym_name])
sym = syms.get(sym_name)
if not sym:
return None
return sym.address
def LookupAndWriteSymbols(elf_fname, entry, image):
"""Replace all symbols in an entry with their correct values
The entry contents is updated so that values for referenced symbols will be
visible at run time. This is done by finding out the symbols positions in
the entry (using the ELF file) and replacing them with values from binman's
data structures.
Args:
elf_fname: Filename of ELF image containing the symbol information for
entry
entry: Entry to process
image: Image which can be used to lookup symbol values
"""
fname = tools.GetInputFilename(elf_fname)
syms = GetSymbols(fname, ['image', 'binman'])
if not syms:
return
base = syms.get('__image_copy_start')
if not base:
return
for name, sym in syms.iteritems():
if name.startswith('_binman'):
msg = ("Image '%s': Symbol '%s'\n in entry '%s'" %
(image.GetPath(), name, entry.GetPath()))
offset = sym.address - base.address
if offset < 0 or offset + sym.size > entry.contents_size:
raise ValueError('%s has offset %x (size %x) but the contents '
'size is %x' % (entry.GetPath(), offset,
sym.size, entry.contents_size))
if sym.size == 4:
pack_string = '<I'
elif sym.size == 8:
pack_string = '<Q'
else:
raise ValueError('%s has size %d: only 4 and 8 are supported' %
(msg, sym.size))
# Look up the symbol in our entry tables.
value = image.LookupSymbol(name, sym.weak, msg)
if value is not None:
value += base.address
else:
value = -1
pack_string = pack_string.lower()
value_bytes = struct.pack(pack_string, value)
if debug:
print('%s:\n insert %s, offset %x, value %x, length %d' %
(msg, name, offset, value, len(value_bytes)))
entry.data = (entry.data[:offset] + value_bytes +
entry.data[offset + sym.size:])

@ -0,0 +1,122 @@
#
# Copyright (c) 2017 Google, Inc
# Written by Simon Glass <sjg@chromium.org>
#
# SPDX-License-Identifier: GPL-2.0+
#
# Test for the elf module
from contextlib import contextmanager
import os
import sys
import unittest
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
import elf
binman_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
# Use this to suppress stdout/stderr output:
# with capture_sys_output() as (stdout, stderr)
# ...do something...
@contextmanager
def capture_sys_output():
capture_out, capture_err = StringIO(), StringIO()
old_out, old_err = sys.stdout, sys.stderr
try:
sys.stdout, sys.stderr = capture_out, capture_err
yield capture_out, capture_err
finally:
sys.stdout, sys.stderr = old_out, old_err
class FakeEntry:
def __init__(self, contents_size):
self.contents_size = contents_size
self.data = 'a' * contents_size
def GetPath(self):
return 'entry_path'
class FakeImage:
def __init__(self, sym_value=1):
self.sym_value = sym_value
def GetPath(self):
return 'image_path'
def LookupSymbol(self, name, weak, msg):
return self.sym_value
class TestElf(unittest.TestCase):
def testAllSymbols(self):
fname = os.path.join(binman_dir, 'test', 'u_boot_ucode_ptr')
syms = elf.GetSymbols(fname, [])
self.assertIn('.ucode', syms)
def testRegexSymbols(self):
fname = os.path.join(binman_dir, 'test', 'u_boot_ucode_ptr')
syms = elf.GetSymbols(fname, ['ucode'])
self.assertIn('.ucode', syms)
syms = elf.GetSymbols(fname, ['missing'])
self.assertNotIn('.ucode', syms)
syms = elf.GetSymbols(fname, ['missing', 'ucode'])
self.assertIn('.ucode', syms)
def testMissingFile(self):
entry = FakeEntry(10)
image = FakeImage()
with self.assertRaises(ValueError) as e:
syms = elf.LookupAndWriteSymbols('missing-file', entry, image)
self.assertIn("Filename 'missing-file' not found in input path",
str(e.exception))
def testOutsideFile(self):
entry = FakeEntry(10)
image = FakeImage()
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms')
with self.assertRaises(ValueError) as e:
syms = elf.LookupAndWriteSymbols(elf_fname, entry, image)
self.assertIn('entry_path has offset 4 (size 8) but the contents size '
'is a', str(e.exception))
def testMissingImageStart(self):
entry = FakeEntry(10)
image = FakeImage()
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms_bad')
self.assertEqual(elf.LookupAndWriteSymbols(elf_fname, entry, image),
None)
def testBadSymbolSize(self):
entry = FakeEntry(10)
image = FakeImage()
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms_size')
with self.assertRaises(ValueError) as e:
syms = elf.LookupAndWriteSymbols(elf_fname, entry, image)
self.assertIn('has size 1: only 4 and 8 are supported',
str(e.exception))
def testNoValue(self):
entry = FakeEntry(20)
image = FakeImage(sym_value=None)
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms')
syms = elf.LookupAndWriteSymbols(elf_fname, entry, image)
self.assertEqual(chr(255) * 16 + 'a' * 4, entry.data)
def testDebug(self):
elf.debug = True
entry = FakeEntry(20)
image = FakeImage()
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms')
with capture_sys_output() as (stdout, stderr):
syms = elf.LookupAndWriteSymbols(elf_fname, entry, image)
elf.debug = False
self.assertTrue(len(stdout.getvalue()) > 0)
if __name__ == '__main__':
unittest.main()

@ -198,3 +198,11 @@ class Entry(object):
def ProcessContents(self):
pass
def WriteSymbols(self, image):
"""Write symbol values into binary files for access at run time
Args:
image: Image containing the entry
"""
pass

@ -6,12 +6,18 @@
# Entry-type module for spl/u-boot-spl.bin
#
import elf
from entry import Entry
from blob import Entry_blob
class Entry_u_boot_spl(Entry_blob):
def __init__(self, image, etype, node):
Entry_blob.__init__(self, image, etype, node)
self.elf_fname = 'spl/u-boot-spl'
def GetDefaultFilename(self):
return 'spl/u-boot-spl.bin'
def WriteSymbols(self, image):
elf.LookupAndWriteSymbols(self.elf_fname, self, image)

@ -9,6 +9,7 @@
#
import command
import elf
from entry import Entry
from blob import Entry_blob
import tools
@ -19,8 +20,8 @@ class Entry_u_boot_spl_bss_pad(Entry_blob):
def ObtainContents(self):
fname = tools.GetInputFilename('spl/u-boot-spl')
args = [['nm', fname], ['grep', '__bss_size']]
out = command.RunPipe(args, capture=True).stdout.splitlines()
bss_size = int(out[0].split()[0], 16)
bss_size = elf.GetSymbolAddress(fname, '__bss_size')
if not bss_size:
self.Raise('Expected __bss_size symbol in spl/u-boot-spl')
self.data = chr(0) * bss_size
self.contents_size = bss_size

@ -0,0 +1,17 @@
# Copyright (c) 2016 Google, Inc
# Written by Simon Glass <sjg@chromium.org>
#
# SPDX-License-Identifier: GPL-2.0+
#
# Entry-type module for U-Boot device tree
#
from entry import Entry
from blob import Entry_blob
class Entry_u_boot_spl_dtb(Entry_blob):
def __init__(self, image, etype, node):
Entry_blob.__init__(self, image, etype, node)
def GetDefaultFilename(self):
return 'spl/u-boot-spl.dtb'

@ -0,0 +1,17 @@
# Copyright (c) 2016 Google, Inc
# Written by Simon Glass <sjg@chromium.org>
#
# SPDX-License-Identifier: GPL-2.0+
#
# Entry-type module for 'u-boot-nodtb.bin'
#
from entry import Entry
from blob import Entry_blob
class Entry_u_boot_spl_nodtb(Entry_blob):
def __init__(self, image, etype, node):
Entry_blob.__init__(self, image, etype, node)
def GetDefaultFilename(self):
return 'spl/u-boot-spl-nodtb.bin'

@ -9,6 +9,7 @@
import struct
import command
import elf
from entry import Entry
from blob import Entry_blob
import fdt_util
@ -31,11 +32,9 @@ class Entry_u_boot_with_ucode_ptr(Entry_blob):
def ObtainContents(self):
# Figure out where to put the microcode pointer
fname = tools.GetInputFilename(self.elf_fname)
args = [['nm', fname], ['grep', '-w', '_dt_ucode_base_size']]
out = (command.RunPipe(args, capture=True, raise_on_error=False).
stdout.splitlines())
if len(out) == 1:
self.target_pos = int(out[0].split()[0], 16)
sym = elf.GetSymbolAddress(fname, '_dt_ucode_base_size')
if sym:
self.target_pos = sym
elif not fdt_util.GetBool(self._node, 'optional-ucode'):
self.Raise('Cannot locate _dt_ucode_base_size symbol in u-boot')

@ -20,6 +20,7 @@ import binman
import cmdline
import command
import control
import elf
import fdt
import fdt_util
import tools
@ -28,11 +29,12 @@ import tout
# Contents of test files, corresponding to different entry types
U_BOOT_DATA = '1234'
U_BOOT_IMG_DATA = 'img'
U_BOOT_SPL_DATA = '567'
U_BOOT_SPL_DATA = '56780123456789abcde'
BLOB_DATA = '89'
ME_DATA = '0abcd'
VGA_DATA = 'vga'
U_BOOT_DTB_DATA = 'udtb'
U_BOOT_SPL_DTB_DATA = 'spldtb'
X86_START16_DATA = 'start16'
X86_START16_SPL_DATA = 'start16spl'
U_BOOT_NODTB_DATA = 'nodtb with microcode pointer somewhere in here'
@ -76,6 +78,7 @@ class TestFunctional(unittest.TestCase):
TestFunctional._MakeInputFile('me.bin', ME_DATA)
TestFunctional._MakeInputFile('vga.bin', VGA_DATA)
TestFunctional._MakeInputFile('u-boot.dtb', U_BOOT_DTB_DATA)
TestFunctional._MakeInputFile('spl/u-boot-spl.dtb', U_BOOT_SPL_DTB_DATA)
TestFunctional._MakeInputFile('u-boot-x86-16bit.bin', X86_START16_DATA)
TestFunctional._MakeInputFile('spl/u-boot-x86-16bit-spl.bin',
X86_START16_SPL_DATA)
@ -134,7 +137,10 @@ class TestFunctional(unittest.TestCase):
Returns:
Return value (0 for success)
"""
(options, args) = cmdline.ParseArgs(list(args))
args = list(args)
if '-D' in sys.argv:
args = args + ['-D']
(options, args) = cmdline.ParseArgs(args)
options.pager = 'binman-invalid-pager'
options.build_dir = self._indir
@ -142,14 +148,16 @@ class TestFunctional(unittest.TestCase):
# options.verbosity = tout.DEBUG
return control.Binman(options, args)
def _DoTestFile(self, fname):
def _DoTestFile(self, fname, debug=False):
"""Run binman with a given test file
Args:
fname: Device tree source filename to use (e.g. 05_simple.dts)
"""
return self._DoBinman('-p', '-I', self._indir,
'-d', self.TestFile(fname))
args = ['-p', '-I', self._indir, '-d', self.TestFile(fname)]
if debug:
args.append('-D')
return self._DoBinman(*args)
def _SetupDtb(self, fname, outfile='u-boot.dtb'):
"""Set up a new test device-tree file
@ -302,7 +310,6 @@ class TestFunctional(unittest.TestCase):
self.assertEqual(0, len(result.stderr))
self.assertEqual(0, result.return_code)
# Not yet available.
def testBoard(self):
"""Test that we can run it with a specific board"""
self._SetupDtb('05_simple.dts', 'sandbox/u-boot.dtb')
@ -362,6 +369,10 @@ class TestFunctional(unittest.TestCase):
data = self._DoReadFile('05_simple.dts')
self.assertEqual(U_BOOT_DATA, data)
def testSimpleDebug(self):
"""Test a simple binman run with debugging enabled"""
data = self._DoTestFile('05_simple.dts', debug=True)
def testDual(self):
"""Test that we can handle creating two images
@ -563,8 +574,10 @@ class TestFunctional(unittest.TestCase):
def testImagePadByte(self):
"""Test that the image pad byte can be specified"""
with open(self.TestFile('bss_data')) as fd:
TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read())
data = self._DoReadFile('21_image_pad.dts')
self.assertEqual(U_BOOT_SPL_DATA + (chr(0xff) * 9) + U_BOOT_DATA, data)
self.assertEqual(U_BOOT_SPL_DATA + (chr(0xff) * 1) + U_BOOT_DATA, data)
def testImageName(self):
"""Test that image files can be named"""
@ -586,7 +599,7 @@ class TestFunctional(unittest.TestCase):
def testPackSorted(self):
"""Test that entries can be sorted"""
data = self._DoReadFile('24_sorted.dts')
self.assertEqual(chr(0) * 5 + U_BOOT_SPL_DATA + chr(0) * 2 +
self.assertEqual(chr(0) * 1 + U_BOOT_SPL_DATA + chr(0) * 2 +
U_BOOT_DATA, data)
def testPackZeroPosition(self):
@ -614,14 +627,14 @@ class TestFunctional(unittest.TestCase):
with self.assertRaises(ValueError) as e:
self._DoTestFile('28_pack_4gb_outside.dts')
self.assertIn("Node '/binman/u-boot': Position 0x0 (0) is outside "
"the image starting at 0xfffffff0 (4294967280)",
"the image starting at 0xffffffe0 (4294967264)",
str(e.exception))
def testPackX86Rom(self):
"""Test that a basic x86 ROM can be created"""
data = self._DoReadFile('29_x86-rom.dts')
self.assertEqual(U_BOOT_DATA + chr(0) * 3 + U_BOOT_SPL_DATA +
chr(0) * 6, data)
self.assertEqual(U_BOOT_DATA + chr(0) * 7 + U_BOOT_SPL_DATA +
chr(0) * 2, data)
def testPackX86RomMeNoDesc(self):
"""Test that an invalid Intel descriptor entry is detected"""
@ -835,6 +848,13 @@ class TestFunctional(unittest.TestCase):
data = self._DoReadFile('47_spl_bss_pad.dts')
self.assertEqual(U_BOOT_SPL_DATA + (chr(0) * 10) + U_BOOT_DATA, data)
with open(self.TestFile('u_boot_ucode_ptr')) as fd:
TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read())
with self.assertRaises(ValueError) as e:
data = self._DoReadFile('47_spl_bss_pad.dts')
self.assertIn('Expected __bss_size symbol in spl/u-boot-spl',
str(e.exception))
def testPackStart16Spl(self):
"""Test that an image with an x86 start16 region can be created"""
data = self._DoReadFile('48_x86-start16-spl.dts')
@ -862,6 +882,32 @@ class TestFunctional(unittest.TestCase):
data = self._DoReadFile('50_intel_mrc.dts')
self.assertEqual(MRC_DATA, data[:len(MRC_DATA)])
def testSplDtb(self):
"""Test that an image with spl/u-boot-spl.dtb can be created"""
data = self._DoReadFile('51_u_boot_spl_dtb.dts')
self.assertEqual(U_BOOT_SPL_DTB_DATA, data[:len(U_BOOT_SPL_DTB_DATA)])
def testSplNoDtb(self):
"""Test that an image with spl/u-boot-spl-nodtb.bin can be created"""
data = self._DoReadFile('52_u_boot_spl_nodtb.dts')
self.assertEqual(U_BOOT_SPL_NODTB_DATA, data[:len(U_BOOT_SPL_NODTB_DATA)])
def testSymbols(self):
"""Test binman can assign symbols embedded in U-Boot"""
elf_fname = self.TestFile('u_boot_binman_syms')
syms = elf.GetSymbols(elf_fname, ['binman', 'image'])
addr = elf.GetSymbolAddress(elf_fname, '__image_copy_start')
self.assertEqual(syms['_binman_u_boot_spl_prop_pos'].address, addr)
with open(self.TestFile('u_boot_binman_syms')) as fd:
TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read())
data = self._DoReadFile('53_symbols.dts')
sym_values = struct.pack('<LQL', 0x24 + 0, 0x24 + 24, 0x24 + 20)
expected = (sym_values + U_BOOT_SPL_DATA[16:] + chr(0xff) +
U_BOOT_DATA +
sym_values + U_BOOT_SPL_DATA[16:])
self.assertEqual(expected, data)
if __name__ == "__main__":
unittest.main()

@ -6,8 +6,12 @@
# Class for an image, the output of binman
#
from __future__ import print_function
from collections import OrderedDict
from operator import attrgetter
import re
import sys
import fdt_util
import tools
@ -45,7 +49,7 @@ class Image:
address.
_entries: OrderedDict() of entries
"""
def __init__(self, name, node):
def __init__(self, name, node, test=False):
global entry
global Entry
import entry
@ -64,8 +68,9 @@ class Image:
self._end_4gb = False
self._entries = OrderedDict()
self._ReadNode()
self._ReadEntries()
if not test:
self._ReadNode()
self._ReadEntries()
def _ReadNode(self):
"""Read properties from the image node"""
@ -119,6 +124,14 @@ class Image:
"""
raise ValueError("Image '%s': %s" % (self._node.path, msg))
def GetPath(self):
"""Get the path of an image (in the FDT)
Returns:
Full path of the node for this image
"""
return self._node.path
def _ReadEntries(self):
for node in self._node.subnodes:
self._entries[node.name] = Entry.Create(self, node)
@ -220,6 +233,11 @@ class Image:
for entry in self._entries.values():
entry.ProcessContents()
def WriteSymbols(self):
"""Write symbol values into binary files for access at run time"""
for entry in self._entries.values():
entry.WriteSymbols(self)
def BuildImage(self):
"""Write the image to a file"""
fname = tools.GetOutputFilename(self._filename)
@ -230,3 +248,58 @@ class Image:
data = entry.GetData()
fd.seek(self._pad_before + entry.pos - self._skip_at_start)
fd.write(data)
def LookupSymbol(self, sym_name, optional, msg):
"""Look up a symbol in an ELF file
Looks up a symbol in an ELF file. Only entry types which come from an
ELF image can be used by this function.
At present the only entry property supported is pos.
Args:
sym_name: Symbol name in the ELF file to look up in the format
_binman_<entry>_prop_<property> where <entry> is the name of
the entry and <property> is the property to find (e.g.
_binman_u_boot_prop_pos). As a special case, you can append
_any to <entry> to have it search for any matching entry. E.g.
_binman_u_boot_any_prop_pos will match entries called u-boot,
u-boot-img and u-boot-nodtb)
optional: True if the symbol is optional. If False this function
will raise if the symbol is not found
msg: Message to display if an error occurs
Returns:
Value that should be assigned to that symbol, or None if it was
optional and not found
Raises:
ValueError if the symbol is invalid or not found, or references a
property which is not supported
"""
m = re.match(r'^_binman_(\w+)_prop_(\w+)$', sym_name)
if not m:
raise ValueError("%s: Symbol '%s' has invalid format" %
(msg, sym_name))
entry_name, prop_name = m.groups()
entry_name = entry_name.replace('_', '-')
entry = self._entries.get(entry_name)
if not entry:
if entry_name.endswith('-any'):
root = entry_name[:-4]
for name in self._entries:
if name.startswith(root):
rest = name[len(root):]
if rest in ['', '-img', '-nodtb']:
entry = self._entries[name]
if not entry:
err = ("%s: Entry '%s' not found in list (%s)" %
(msg, entry_name, ','.join(self._entries.keys())))
if optional:
print('Warning: %s' % err, file=sys.stderr)
return None
raise ValueError(err)
if prop_name == 'pos':
return entry.pos
else:
raise ValueError("%s: No such property '%s'" % (msg, prop_name))

@ -0,0 +1,46 @@
#
# Copyright (c) 2017 Google, Inc
# Written by Simon Glass <sjg@chromium.org>
#
# SPDX-License-Identifier: GPL-2.0+
#
# Test for the image module
import unittest
from image import Image
from elf_test import capture_sys_output
class TestImage(unittest.TestCase):
def testInvalidFormat(self):
image = Image('name', 'node', test=True)
with self.assertRaises(ValueError) as e:
image.LookupSymbol('_binman_something_prop_', False, 'msg')
self.assertIn(
"msg: Symbol '_binman_something_prop_' has invalid format",
str(e.exception))
def testMissingSymbol(self):
image = Image('name', 'node', test=True)
image._entries = {}
with self.assertRaises(ValueError) as e:
image.LookupSymbol('_binman_type_prop_pname', False, 'msg')
self.assertIn("msg: Entry 'type' not found in list ()",
str(e.exception))
def testMissingSymbolOptional(self):
image = Image('name', 'node', test=True)
image._entries = {}
with capture_sys_output() as (stdout, stderr):
val = image.LookupSymbol('_binman_type_prop_pname', True, 'msg')
self.assertEqual(val, None)
self.assertEqual("Warning: msg: Entry 'type' not found in list ()\n",
stderr.getvalue())
self.assertEqual('', stdout.getvalue())
def testBadProperty(self):
image = Image('name', 'node', test=True)
image._entries = {'u-boot': 1}
with self.assertRaises(ValueError) as e:
image.LookupSymbol('_binman_u_boot_prop_bad', False, 'msg')
self.assertIn("msg: No such property 'bad", str(e.exception))

@ -10,7 +10,7 @@
};
u-boot {
pos = <12>;
pos = <20>;
};
};
};

@ -7,11 +7,11 @@
binman {
sort-by-pos;
u-boot {
pos = <10>;
pos = <22>;
};
u-boot-spl {
pos = <5>;
pos = <1>;
};
};
};

@ -7,13 +7,13 @@
binman {
sort-by-pos;
end-at-4gb;
size = <16>;
size = <32>;
u-boot {
pos = <0>;
};
u-boot-spl {
pos = <0xfffffff7>;
pos = <0xffffffeb>;
};
};
};

@ -7,13 +7,13 @@
binman {
sort-by-pos;
end-at-4gb;
size = <16>;
size = <32>;
u-boot {
pos = <0xfffffff0>;
pos = <0xffffffe0>;
};
u-boot-spl {
pos = <0xfffffff7>;
pos = <0xffffffeb>;
};
};
};

@ -0,0 +1,13 @@
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
size = <16>;
u-boot-spl-dtb {
};
};
};

@ -0,0 +1,11 @@
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
u-boot-spl-nodtb {
};
};
};

@ -0,0 +1,20 @@
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
pad-byte = <0xff>;
u-boot-spl {
};
u-boot {
pos = <20>;
};
u-boot-spl2 {
type = "u-boot-spl";
};
};
};

@ -10,8 +10,12 @@
CFLAGS := -march=i386 -m32 -nostdlib -I ../../../include
LDS_UCODE := -T u_boot_ucode_ptr.lds
LDS_BINMAN := -T u_boot_binman_syms.lds
LDS_BINMAN_BAD := -T u_boot_binman_syms_bad.lds
TARGETS = u_boot_ucode_ptr u_boot_no_ucode_ptr bss_data
TARGETS = u_boot_ucode_ptr u_boot_no_ucode_ptr bss_data \
u_boot_binman_syms u_boot_binman_syms.bin u_boot_binman_syms_bad \
u_boot_binman_syms_size
all: $(TARGETS)
@ -24,6 +28,18 @@ u_boot_ucode_ptr: u_boot_ucode_ptr.c
bss_data: CFLAGS += bss_data.lds
bss_data: bss_data.c
u_boot_binman_syms.bin: u_boot_binman_syms
objcopy -O binary $< -R .note.gnu.build-id $@
u_boot_binman_syms: CFLAGS += $(LDS_BINMAN)
u_boot_binman_syms: u_boot_binman_syms.c
u_boot_binman_syms_bad: CFLAGS += $(LDS_BINMAN_BAD)
u_boot_binman_syms_bad: u_boot_binman_syms_bad.c
u_boot_binman_syms_size: CFLAGS += $(LDS_BINMAN)
u_boot_binman_syms_size: u_boot_binman_syms_size.c
clean:
rm -f $(TARGETS)

@ -4,7 +4,7 @@
* SPDX-License-Identifier: GPL-2.0+
*
* Simple program to create a _dt_ucode_base_size symbol which can be read
* by 'nm'. This is used by binman tests.
* by binutils. This is used by binman tests.
*/
int bss_data[10];

@ -0,0 +1,14 @@
/*
* Copyright (c) 2017 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*
* Simple program to create some binman symbols. This is used by binman tests.
*/
#define CONFIG_BINMAN
#include <binman_sym.h>
binman_sym_declare(unsigned long, u_boot_spl, pos);
binman_sym_declare(unsigned long long, u_boot_spl2, pos);
binman_sym_declare(unsigned long, u_boot_any, pos);

@ -0,0 +1,30 @@
/*
* Copyright (c) 2016 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
_start = .;
. = ALIGN(4);
.text :
{
__image_copy_start = .;
*(.text*)
}
. = ALIGN(4);
.binman_sym_table : {
__binman_sym_start = .;
KEEP(*(SORT(.binman_sym*)));
__binman_sym_end = .;
}
}

@ -0,0 +1,29 @@
/*
* Copyright (c) 2016 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
_start = .;
. = ALIGN(4);
.text :
{
*(.text*)
}
. = ALIGN(4);
.binman_sym_table : {
__binman_sym_start = .;
KEEP(*(SORT(.binman_sym*)));
__binman_sym_end = .;
}
}

@ -0,0 +1,12 @@
/*
* Copyright (c) 2017 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*
* Simple program to create some binman symbols. This is used by binman tests.
*/
#define CONFIG_BINMAN
#include <binman_sym.h>
binman_sym_declare(char, u_boot_spl, pos);

@ -4,7 +4,7 @@
* SPDX-License-Identifier: GPL-2.0+
*
* Simple program to create a _dt_ucode_base_size symbol which can be read
* by 'nm'. This is used by binman tests.
* by binutils. This is used by binman tests.
*/
static unsigned long _dt_ucode_base_size[2]

Loading…
Cancel
Save