mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-18 13:11:31 +00:00
Merge git://git.denx.de/u-boot-dm
This commit is contained in:
commit
15616a0aa5
61 changed files with 1638 additions and 62 deletions
6
Makefile
6
Makefile
|
@ -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
|
||||
|
|
|
@ -36,6 +36,13 @@ SECTIONS
|
|||
KEEP(*(SORT(.u_boot_list*)));
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.binman_sym_table : {
|
||||
__binman_sym_start = .;
|
||||
KEEP(*(SORT(.binman_sym*)));
|
||||
__binman_sym_end = .;
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
__image_copy_end = .;
|
||||
|
|
40
arch/arm/dts/tegra-u-boot.dtsi
Normal file
40
arch/arm/dts/tegra-u-boot.dtsi
Normal file
|
@ -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)>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
3
arch/arm/dts/tegra114-u-boot.dtsi
Normal file
3
arch/arm/dts/tegra114-u-boot.dtsi
Normal file
|
@ -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;
|
||||
|
|
3
arch/arm/dts/tegra124-u-boot.dtsi
Normal file
3
arch/arm/dts/tegra124-u-boot.dtsi
Normal file
|
@ -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"
|
||||
|
|
3
arch/arm/dts/tegra210-u-boot.dtsi
Normal file
3
arch/arm/dts/tegra210-u-boot.dtsi
Normal file
|
@ -0,0 +1,3 @@
|
|||
#include <config.h>
|
||||
|
||||
#include "tegra-u-boot.dtsi"
|
3
arch/arm/dts/tegra30-u-boot.dtsi
Normal file
3
arch/arm/dts/tegra30-u-boot.dtsi
Normal file
|
@ -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) {
|
||||
|
|
98
drivers/power/pmic/pmic_tps65910_dm.c
Normal file
98
drivers/power/pmic/pmic_tps65910_dm.c
Normal file
|
@ -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
|
||||
|
|
459
drivers/power/regulator/tps65910_regulator.c
Normal file
459
drivers/power/regulator/tps65910_regulator.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
|
93
include/binman_sym.h
Normal file
93
include/binman_sym.h
Normal file
|
@ -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"
|
||||
|
|
130
include/power/tps65910_pmic.h
Normal file
130
include/power/tps65910_pmic.h
Normal file
|
@ -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()
|
||||
|
|
129
tools/binman/elf.py
Normal file
129
tools/binman/elf.py
Normal file
|
@ -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:])
|
122
tools/binman/elf_test.py
Normal file
122
tools/binman/elf_test.py
Normal file
|
@ -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
|
||||
|
|
17
tools/binman/etype/u_boot_spl_dtb.py
Normal file
17
tools/binman/etype/u_boot_spl_dtb.py
Normal file
|
@ -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'
|
17
tools/binman/etype/u_boot_spl_nodtb.py
Normal file
17
tools/binman/etype/u_boot_spl_nodtb.py
Normal file
|
@ -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))
|
||||
|
|
46
tools/binman/image_test.py
Normal file
46
tools/binman/image_test.py
Normal file
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
13
tools/binman/test/51_u_boot_spl_dtb.dts
Normal file
13
tools/binman/test/51_u_boot_spl_dtb.dts
Normal file
|
@ -0,0 +1,13 @@
|
|||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
size = <16>;
|
||||
|
||||
u-boot-spl-dtb {
|
||||
};
|
||||
};
|
||||
};
|
11
tools/binman/test/52_u_boot_spl_nodtb.dts
Normal file
11
tools/binman/test/52_u_boot_spl_nodtb.dts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
u-boot-spl-nodtb {
|
||||
};
|
||||
};
|
||||
};
|
20
tools/binman/test/53_symbols.dts
Normal file
20
tools/binman/test/53_symbols.dts
Normal file
|
@ -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];
|
||||
|
|
BIN
tools/binman/test/u_boot_binman_syms
Executable file
BIN
tools/binman/test/u_boot_binman_syms
Executable file
Binary file not shown.
14
tools/binman/test/u_boot_binman_syms.c
Normal file
14
tools/binman/test/u_boot_binman_syms.c
Normal file
|
@ -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);
|
30
tools/binman/test/u_boot_binman_syms.lds
Normal file
30
tools/binman/test/u_boot_binman_syms.lds
Normal file
|
@ -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 = .;
|
||||
}
|
||||
|
||||
}
|
BIN
tools/binman/test/u_boot_binman_syms_bad
Executable file
BIN
tools/binman/test/u_boot_binman_syms_bad
Executable file
Binary file not shown.
1
tools/binman/test/u_boot_binman_syms_bad.c
Symbolic link
1
tools/binman/test/u_boot_binman_syms_bad.c
Symbolic link
|
@ -0,0 +1 @@
|
|||
u_boot_binman_syms.c
|
29
tools/binman/test/u_boot_binman_syms_bad.lds
Normal file
29
tools/binman/test/u_boot_binman_syms_bad.lds
Normal file
|
@ -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 = .;
|
||||
}
|
||||
|
||||
}
|
BIN
tools/binman/test/u_boot_binman_syms_size
Executable file
BIN
tools/binman/test/u_boot_binman_syms_size
Executable file
Binary file not shown.
12
tools/binman/test/u_boot_binman_syms_size.c
Normal file
12
tools/binman/test/u_boot_binman_syms_size.c
Normal file
|
@ -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…
Add table
Reference in a new issue