Various minor sandbox improvements
Better buildman warning handling Misc other things -----BEGIN PGP SIGNATURE----- iQFFBAABCgAvFiEEslwAIq+Gp8wWVbYnfxc6PpAIreYFAlv19KwRHHNqZ0BjaHJv bWl1bS5vcmcACgkQfxc6PpAIreaWtwf/Xq0DuDuTyoqfVuGJk/SyS4PzZ7Z778oz YxX7Do0biHMqT+3QnvhRGsYQQck2jOqP/Romr/U3q1+jDRT53/RDBnJmG4lQ/toF 79mShpx5vm/QZKf1QI1nJv57P1xRrP8VcDaqrHKsJ5v5sAaPls5y0ik+IzfSVlJX mw0rs1cSKeoDKXu7a8AnP2OPJPhGT0C9Gougg5nnjyAwTs2dww8w396vyZmw0S3m KnAOrvxrVGx7AxQFeD1T0/Fvc4jWrR82HBcibuYLuSSxFtnt26iEWfaP9CjKeV6h P5/T3vxFolKesyG+2/OVeIlTvISHeXmsdYBpVtxDbHETWzxU0xDzzQ== =SRxW -----END PGP SIGNATURE----- Merge tag 'pull-tg18' of git://git.denx.de/u-boot-dm Various minor sandbox improvements Better buildman warning handling Misc other things
This commit is contained in:
commit
5830791d91
6
Makefile
6
Makefile
@ -1048,9 +1048,11 @@ u-boot.ldr: u-boot
|
||||
|
||||
# binman
|
||||
# ---------------------------------------------------------------------------
|
||||
# Use 'make BINMAN_DEBUG=1' to enable debugging
|
||||
quiet_cmd_binman = BINMAN $@
|
||||
cmd_binman = $(srctree)/tools/binman/binman -d u-boot.dtb -O . \
|
||||
-I . -I $(srctree)/board/$(BOARDDIR) $<
|
||||
cmd_binman = $(srctree)/tools/binman/binman -u -d u-boot.dtb -O . -m \
|
||||
-I . -I $(srctree) -I $(srctree)/board/$(BOARDDIR) \
|
||||
$(if $(BINMAN_DEBUG),-D) $(BINMAN_$(@F)) $<
|
||||
|
||||
OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
|
||||
|
||||
|
@ -306,7 +306,7 @@ static int setup_mac_address(void)
|
||||
|
||||
ret = misc_read(dev, BSEC_OTP_MAC * 4 + STM32_BSEC_OTP_OFFSET,
|
||||
otp, sizeof(otp));
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
@ -344,7 +344,7 @@ static int setup_serial_number(void)
|
||||
|
||||
ret = misc_read(dev, BSEC_OTP_SERIAL * 4 + STM32_BSEC_OTP_OFFSET,
|
||||
otp, sizeof(otp));
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
sprintf(serial_string, "%08x%08x%08x", otp[0], otp[1], otp[2]);
|
||||
|
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The Chromium OS Authors.
|
||||
*/
|
||||
#define DEBUG
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
@ -105,8 +105,8 @@ void *phys_to_virt(phys_addr_t paddr)
|
||||
state = state_get_current();
|
||||
list_for_each_entry(mentry, &state->mapmem_head, sibling_node) {
|
||||
if (mentry->tag == paddr) {
|
||||
printf("%s: Used map from %lx to %p\n", __func__,
|
||||
(ulong)paddr, mentry->ptr);
|
||||
debug("%s: Used map from %lx to %p\n", __func__,
|
||||
(ulong)paddr, mentry->ptr);
|
||||
return mentry->ptr;
|
||||
}
|
||||
}
|
||||
@ -152,7 +152,7 @@ phys_addr_t virt_to_phys(void *ptr)
|
||||
__func__, ptr, (ulong)gd->ram_size);
|
||||
os_abort();
|
||||
}
|
||||
printf("%s: Used map from %p to %lx\n", __func__, ptr, mentry->tag);
|
||||
debug("%s: Used map from %p to %lx\n", __func__, ptr, mentry->tag);
|
||||
|
||||
return mentry->tag;
|
||||
}
|
||||
|
@ -98,9 +98,8 @@ void os_exit(int exit_code)
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
int os_write_file(const char *name, const void *buf, int size)
|
||||
int os_write_file(const char *fname, const void *buf, int size)
|
||||
{
|
||||
char fname[256];
|
||||
int fd;
|
||||
|
||||
fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT | OS_O_TRUNC);
|
||||
@ -110,14 +109,53 @@ int os_write_file(const char *name, const void *buf, int size)
|
||||
}
|
||||
if (os_write(fd, buf, size) != size) {
|
||||
printf("Cannot write to file '%s'\n", fname);
|
||||
os_close(fd);
|
||||
return -EIO;
|
||||
}
|
||||
os_close(fd);
|
||||
printf("Write '%s', size %#x (%d)\n", name, size, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int os_read_file(const char *fname, void **bufp, int *sizep)
|
||||
{
|
||||
off_t size;
|
||||
int ret = -EIO;
|
||||
int fd;
|
||||
|
||||
fd = os_open(fname, OS_O_RDONLY);
|
||||
if (fd < 0) {
|
||||
printf("Cannot open file '%s'\n", fname);
|
||||
goto err;
|
||||
}
|
||||
size = os_lseek(fd, 0, OS_SEEK_END);
|
||||
if (size < 0) {
|
||||
printf("Cannot seek to end of file '%s'\n", fname);
|
||||
goto err;
|
||||
}
|
||||
if (os_lseek(fd, 0, OS_SEEK_SET) < 0) {
|
||||
printf("Cannot seek to start of file '%s'\n", fname);
|
||||
goto err;
|
||||
}
|
||||
*bufp = os_malloc(size);
|
||||
if (!*bufp) {
|
||||
printf("Not enough memory to read file '%s'\n", fname);
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
if (os_read(fd, *bufp, size) != size) {
|
||||
printf("Cannot read from file '%s'\n", fname);
|
||||
goto err;
|
||||
}
|
||||
os_close(fd);
|
||||
*sizep = size;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
os_close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Restore tty state when we exit */
|
||||
static struct termios orig_term;
|
||||
static bool term_setup;
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
cros_ec: cros-ec {
|
||||
reg = <0 0>;
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "google,cros-ec-sandbox";
|
||||
|
||||
/*
|
||||
@ -27,6 +28,7 @@
|
||||
* that the STM32L flash erases to 0, not 0xff.
|
||||
*/
|
||||
flash {
|
||||
u-boot,dm-pre-reloc;
|
||||
image-pos = <0x08000000>;
|
||||
size = <0x20000>;
|
||||
erase-value = <0>;
|
||||
@ -59,6 +61,7 @@
|
||||
};
|
||||
|
||||
gpio_a: gpios@0 {
|
||||
u-boot,dm-pre-reloc;
|
||||
gpio-controller;
|
||||
compatible = "sandbox,gpio";
|
||||
#gpio-cells = <1>;
|
||||
@ -67,6 +70,7 @@
|
||||
};
|
||||
|
||||
gpio_b: gpios@1 {
|
||||
u-boot,dm-pre-reloc;
|
||||
gpio-controller;
|
||||
compatible = "sandbox,gpio";
|
||||
#gpio-cells = <2>;
|
||||
@ -178,12 +182,14 @@
|
||||
};
|
||||
|
||||
spi@0 {
|
||||
u-boot,dm-pre-reloc;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0 0>;
|
||||
compatible = "sandbox,spi";
|
||||
cs-gpios = <0>, <&gpio_a 0>;
|
||||
firmware_storage_spi: flash@0 {
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0>;
|
||||
compatible = "spansion,m25p16", "sandbox,spi-flash";
|
||||
spi-max-frequency = <40000000>;
|
||||
@ -239,6 +245,7 @@
|
||||
};
|
||||
|
||||
tpm {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "google,sandbox-tpm";
|
||||
};
|
||||
|
||||
@ -256,6 +263,7 @@
|
||||
|
||||
/* Needs to be available prior to relocation */
|
||||
uart0: serial {
|
||||
u-boot,dm-spl;
|
||||
compatible = "sandbox,serial";
|
||||
sandbox,text-colour = "cyan";
|
||||
pinctrl-names = "default";
|
||||
@ -350,3 +358,10 @@
|
||||
|
||||
#include "cros-ec-keyboard.dtsi"
|
||||
#include "sandbox_pmic.dtsi"
|
||||
|
||||
&cros_ec {
|
||||
u-boot,dm-pre-reloc;
|
||||
keyboard-controller {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
};
|
||||
|
@ -113,4 +113,12 @@ int sandbox_osd_get_mem(struct udevice *dev, u8 *buf, size_t buflen);
|
||||
int sandbox_pwm_get_config(struct udevice *dev, uint channel, uint *period_nsp,
|
||||
uint *duty_nsp, bool *enablep, bool *polarityp);
|
||||
|
||||
/**
|
||||
* sandbox_sf_set_block_protect() - Set the BP bits of the status register
|
||||
*
|
||||
* @dev: Device to update
|
||||
* @bp_mask: BP bits to set (bits 2:0, so a value of 0 to 7)
|
||||
*/
|
||||
void sandbox_sf_set_block_protect(struct udevice *dev, int bp_mask);
|
||||
|
||||
#endif
|
||||
|
@ -306,14 +306,16 @@ int checkboard(void)
|
||||
#ifdef CONFIG_BOARD_LATE_INIT
|
||||
int board_late_init(void)
|
||||
{
|
||||
stdio_print_current_devices();
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
if (cros_ec_get_error()) {
|
||||
stdio_print_current_devices();
|
||||
ret = uclass_first_device_err(UCLASS_CROS_EC, &dev);
|
||||
if (ret && ret != -ENODEV) {
|
||||
/* Force console on */
|
||||
gd->flags &= ~GD_FLG_SILENT;
|
||||
|
||||
printf("cros-ec communications failure %d\n",
|
||||
cros_ec_get_error());
|
||||
printf("cros-ec communications failure %d\n", ret);
|
||||
puts("\nPlease reset with Power+Refresh\n\n");
|
||||
panic("Cannot init cros-ec device");
|
||||
return -1;
|
||||
|
@ -247,25 +247,28 @@ sudo /path/to/u-boot -D
|
||||
DHCP
|
||||
....
|
||||
|
||||
set autoload no
|
||||
set ethact eth1
|
||||
setenv autoload no
|
||||
setenv ethrotate no
|
||||
setenv ethact eth1
|
||||
dhcp
|
||||
|
||||
PING
|
||||
....
|
||||
|
||||
set autoload no
|
||||
set ethact eth1
|
||||
setenv autoload no
|
||||
setenv ethrotate no
|
||||
setenv ethact eth1
|
||||
dhcp
|
||||
ping $gatewayip
|
||||
|
||||
TFTP
|
||||
....
|
||||
|
||||
set autoload no
|
||||
set ethact eth1
|
||||
setenv autoload no
|
||||
setenv ethrotate no
|
||||
setenv ethact eth1
|
||||
dhcp
|
||||
set serverip WWW.XXX.YYY.ZZZ
|
||||
setenv serverip WWW.XXX.YYY.ZZZ
|
||||
tftpboot u-boot.bin
|
||||
|
||||
The bridge also supports (to a lesser extent) the localhost interface, 'lo'.
|
||||
@ -287,7 +290,8 @@ operation being tested on the lo interface.
|
||||
TFTP
|
||||
....
|
||||
|
||||
set ethact eth5
|
||||
setenv ethrotate no
|
||||
setenv ethact eth5
|
||||
tftpboot u-boot.bin
|
||||
|
||||
|
||||
|
@ -59,12 +59,15 @@ int board_init(void)
|
||||
#ifdef CONFIG_BOARD_LATE_INIT
|
||||
int board_late_init(void)
|
||||
{
|
||||
if (cros_ec_get_error()) {
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = uclass_first_device_err(UCLASS_CROS_EC, &dev);
|
||||
if (ret && ret != -ENODEV) {
|
||||
/* Force console on */
|
||||
gd->flags &= ~GD_FLG_SILENT;
|
||||
|
||||
printf("cros-ec communications failure %d\n",
|
||||
cros_ec_get_error());
|
||||
printf("cros-ec communications failure %d\n", ret);
|
||||
puts("\nPlease reset with Power+Refresh\n\n");
|
||||
panic("Cannot init cros-ec device");
|
||||
return -1;
|
||||
|
@ -202,7 +202,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
fdt_strerror(err));
|
||||
return 1;
|
||||
}
|
||||
working_fdt = newaddr;
|
||||
set_working_fdt_addr((ulong)newaddr);
|
||||
#ifdef CONFIG_OF_SYSTEM_SETUP
|
||||
/* Call the board-specific fixup routine */
|
||||
} else if (strncmp(argv[1], "sys", 3) == 0) {
|
||||
|
@ -27,6 +27,15 @@ config SPL_BOOTSTAGE
|
||||
information when SPL finishes and load it when U-Boot proper starts
|
||||
up.
|
||||
|
||||
config TPL_BOOTSTAGE
|
||||
bool "Boot timing and reported in TPL"
|
||||
depends on BOOTSTAGE
|
||||
help
|
||||
Enable recording of boot time in SPL. To make this visible to U-Boot
|
||||
proper, enable BOOTSTAGE_STASH as well. This will stash the timing
|
||||
information when TPL finishes and load it when U-Boot proper starts
|
||||
up.
|
||||
|
||||
config BOOTSTAGE_REPORT
|
||||
bool "Display a detailed boot timing report before booting the OS"
|
||||
depends on BOOTSTAGE
|
||||
@ -444,6 +453,16 @@ config LOG
|
||||
|
||||
config SPL_LOG
|
||||
bool "Enable logging support in SPL"
|
||||
depends on LOG
|
||||
help
|
||||
This enables support for logging of status and debug messages. These
|
||||
can be displayed on the console, recorded in a memory buffer, or
|
||||
discarded if not needed. Logging supports various categories and
|
||||
levels of severity.
|
||||
|
||||
config TPL_LOG
|
||||
bool "Enable logging support in TPL"
|
||||
depends on LOG
|
||||
help
|
||||
This enables support for logging of status and debug messages. These
|
||||
can be displayed on the console, recorded in a memory buffer, or
|
||||
@ -660,6 +679,22 @@ config AVB_VERIFY
|
||||
* Helpers to access MMC, similar to drivers/fastboot/fb_mmc.c.
|
||||
* Helpers to alloc/init/free avb ops.
|
||||
|
||||
config SPL_HASH
|
||||
bool # "Support hashing API (SHA1, SHA256, etc.)"
|
||||
help
|
||||
This provides a way to hash data in memory using various supported
|
||||
algorithms (such as SHA1, MD5, CRC32). The API is defined in hash.h
|
||||
and the algorithms it supports are defined in common/hash.c. See
|
||||
also CMD_HASH for command-line access.
|
||||
|
||||
config TPL_HASH
|
||||
bool # "Support hashing API (SHA1, SHA256, etc.)"
|
||||
help
|
||||
This provides a way to hash data in memory using various supported
|
||||
algorithms (such as SHA1, MD5, CRC32). The API is defined in hash.h
|
||||
and the algorithms it supports are defined in common/hash.c. See
|
||||
also CMD_HASH for command-line access.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Update support"
|
||||
|
@ -68,6 +68,7 @@ obj-$(CONFIG_DFU_OVER_USB) += dfu.o
|
||||
endif
|
||||
obj-$(CONFIG_SPL_DFU_SUPPORT) += cli_hush.o
|
||||
obj-$(CONFIG_SPL_HASH_SUPPORT) += hash.o
|
||||
obj-$(CONFIG_TPL_HASH_SUPPORT) += hash.o
|
||||
obj-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o
|
||||
obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o
|
||||
obj-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o
|
||||
@ -76,7 +77,8 @@ ifdef CONFIG_SPL_USB_HOST_SUPPORT
|
||||
obj-$(CONFIG_SPL_USB_SUPPORT) += usb.o usb_hub.o
|
||||
obj-$(CONFIG_USB_STORAGE) += usb_storage.o
|
||||
endif
|
||||
endif
|
||||
endif # CONFIG_SPL_BUILD
|
||||
|
||||
#others
|
||||
obj-$(CONFIG_DDR_SPD) += ddr_spd.o
|
||||
obj-$(CONFIG_SPD_EEPROM) += ddr_spd.o
|
||||
@ -90,14 +92,16 @@ obj-$(CONFIG_SPL_SERIAL_SUPPORT) += console.o
|
||||
endif
|
||||
else
|
||||
obj-y += console.o
|
||||
endif
|
||||
endif # CONFIG_SPL_BUILD
|
||||
|
||||
obj-$(CONFIG_CROS_EC) += cros_ec.o
|
||||
obj-y += dlmalloc.o
|
||||
ifdef CONFIG_SYS_MALLOC_F
|
||||
ifneq ($(CONFIG_$(SPL_)SYS_MALLOC_F_LEN),0)
|
||||
ifneq ($(CONFIG_$(SPL_TPL_)SYS_MALLOC_F_LEN),0)
|
||||
obj-y += malloc_simple.o
|
||||
endif
|
||||
endif
|
||||
|
||||
obj-y += image.o
|
||||
obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o
|
||||
|
@ -25,15 +25,3 @@ struct udevice *board_get_cros_ec_dev(void)
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
|
||||
int cros_ec_get_error(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = uclass_get_device(UCLASS_CROS_EC, 0, &dev);
|
||||
if (ret && ret != -ENODEV)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ static ulong vexpress_osc_clk_get_rate(struct clk *clk)
|
||||
|
||||
data = CLK_FUNCTION | priv->osc;
|
||||
err = misc_read(vexpress_cfg, 0, &data, sizeof(data));
|
||||
if (err)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return data;
|
||||
@ -53,7 +53,7 @@ static ulong vexpress_osc_clk_set_rate(struct clk *clk, ulong rate)
|
||||
buffer[0] = CLK_FUNCTION | priv->osc;
|
||||
buffer[1] = rate;
|
||||
err = misc_write(vexpress_cfg, 0, buffer, 2 * sizeof(u32));
|
||||
if (err)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return rate;
|
||||
|
@ -15,8 +15,8 @@ static void show_devices(struct udevice *dev, int depth, int last_flag)
|
||||
int i, is_last;
|
||||
struct udevice *child;
|
||||
|
||||
/* print the first 11 characters to not break the tree-format. */
|
||||
printf(" %-10.10s %d [ %c ] %-10.10s ", dev->uclass->uc_drv->name,
|
||||
/* print the first 20 characters to not break the tree-format. */
|
||||
printf(" %-10.10s %d [ %c ] %-20.20s ", dev->uclass->uc_drv->name,
|
||||
dev_get_uclass_index(dev, NULL),
|
||||
dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name);
|
||||
|
||||
@ -49,8 +49,8 @@ void dm_dump_all(void)
|
||||
|
||||
root = dm_root();
|
||||
if (root) {
|
||||
printf(" Class index Probed Driver Name\n");
|
||||
printf("-----------------------------------------\n");
|
||||
printf(" Class index Probed Driver Name\n");
|
||||
printf("-----------------------------------------------------------\n");
|
||||
show_devices(root, -1, 0);
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ void display_sysid(void)
|
||||
if (ret)
|
||||
return;
|
||||
ret = misc_read(dev, 0, &sysid, sizeof(sysid));
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
stamp = sysid[1];
|
||||
|
@ -13,6 +13,8 @@
|
||||
* is not reset.
|
||||
*/
|
||||
|
||||
#define LOG_CATEGORY UCLASS_CROS_EC
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <dm.h>
|
||||
@ -41,6 +43,54 @@ enum {
|
||||
CROS_EC_CMD_HASH_TIMEOUT_MS = 2000,
|
||||
};
|
||||
|
||||
#define INVALID_HCMD 0xFF
|
||||
|
||||
/*
|
||||
* Map UHEPI masks to non UHEPI commands in order to support old EC FW
|
||||
* which does not support UHEPI command.
|
||||
*/
|
||||
static const struct {
|
||||
u8 set_cmd;
|
||||
u8 clear_cmd;
|
||||
u8 get_cmd;
|
||||
} event_map[] = {
|
||||
[EC_HOST_EVENT_MAIN] = {
|
||||
INVALID_HCMD, EC_CMD_HOST_EVENT_CLEAR,
|
||||
INVALID_HCMD,
|
||||
},
|
||||
[EC_HOST_EVENT_B] = {
|
||||
INVALID_HCMD, EC_CMD_HOST_EVENT_CLEAR_B,
|
||||
EC_CMD_HOST_EVENT_GET_B,
|
||||
},
|
||||
[EC_HOST_EVENT_SCI_MASK] = {
|
||||
EC_CMD_HOST_EVENT_SET_SCI_MASK, INVALID_HCMD,
|
||||
EC_CMD_HOST_EVENT_GET_SCI_MASK,
|
||||
},
|
||||
[EC_HOST_EVENT_SMI_MASK] = {
|
||||
EC_CMD_HOST_EVENT_SET_SMI_MASK, INVALID_HCMD,
|
||||
EC_CMD_HOST_EVENT_GET_SMI_MASK,
|
||||
},
|
||||
[EC_HOST_EVENT_ALWAYS_REPORT_MASK] = {
|
||||
INVALID_HCMD, INVALID_HCMD, INVALID_HCMD,
|
||||
},
|
||||
[EC_HOST_EVENT_ACTIVE_WAKE_MASK] = {
|
||||
EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD,
|
||||
EC_CMD_HOST_EVENT_GET_WAKE_MASK,
|
||||
},
|
||||
[EC_HOST_EVENT_LAZY_WAKE_MASK_S0IX] = {
|
||||
EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD,
|
||||
EC_CMD_HOST_EVENT_GET_WAKE_MASK,
|
||||
},
|
||||
[EC_HOST_EVENT_LAZY_WAKE_MASK_S3] = {
|
||||
EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD,
|
||||
EC_CMD_HOST_EVENT_GET_WAKE_MASK,
|
||||
},
|
||||
[EC_HOST_EVENT_LAZY_WAKE_MASK_S5] = {
|
||||
EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD,
|
||||
EC_CMD_HOST_EVENT_GET_WAKE_MASK,
|
||||
},
|
||||
};
|
||||
|
||||
void cros_ec_dump_data(const char *name, int cmd, const uint8_t *data, int len)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
@ -227,7 +277,7 @@ static int send_command_proto3(struct cros_ec_dev *cdev,
|
||||
return handle_proto3_response(cdev, dinp, din_len);
|
||||
}
|
||||
|
||||
static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
|
||||
static int send_command(struct cros_ec_dev *dev, uint cmd, int cmd_version,
|
||||
const void *dout, int dout_len,
|
||||
uint8_t **dinp, int din_len)
|
||||
{
|
||||
@ -330,7 +380,7 @@ static int ec_command_inptr(struct udevice *dev, uint8_t cmd,
|
||||
* @param din_len Maximum size of response in bytes
|
||||
* @return number of bytes in response, or -ve on error
|
||||
*/
|
||||
static int ec_command(struct udevice *dev, uint8_t cmd, int cmd_version,
|
||||
static int ec_command(struct udevice *dev, uint cmd, int cmd_version,
|
||||
const void *dout, int dout_len,
|
||||
void *din, int din_len)
|
||||
{
|
||||
@ -365,10 +415,14 @@ int cros_ec_scan_keyboard(struct udevice *dev, struct mbkp_keyscan *scan)
|
||||
int cros_ec_read_id(struct udevice *dev, char *id, int maxlen)
|
||||
{
|
||||
struct ec_response_get_version *r;
|
||||
int ret;
|
||||
|
||||
if (ec_command_inptr(dev, EC_CMD_GET_VERSION, 0, NULL, 0,
|
||||
(uint8_t **)&r, sizeof(*r)) != sizeof(*r))
|
||||
ret = ec_command_inptr(dev, EC_CMD_GET_VERSION, 0, NULL, 0,
|
||||
(uint8_t **)&r, sizeof(*r));
|
||||
if (ret != sizeof(*r)) {
|
||||
log_err("Got rc %d, expected %d\n", ret, sizeof(*r));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (maxlen > (int)sizeof(r->version_string_ro))
|
||||
maxlen = sizeof(r->version_string_ro);
|
||||
@ -381,6 +435,7 @@ int cros_ec_read_id(struct udevice *dev, char *id, int maxlen)
|
||||
memcpy(id, r->version_string_rw, maxlen);
|
||||
break;
|
||||
default:
|
||||
log_err("Invalid EC image %d\n", r->current_image);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -563,6 +618,36 @@ int cros_ec_info(struct udevice *dev, struct ec_response_mkbp_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cros_ec_get_event_mask(struct udevice *dev, uint type, uint32_t *mask)
|
||||
{
|
||||
struct ec_response_host_event_mask rsp;
|
||||
int ret;
|
||||
|
||||
ret = ec_command(dev, type, 0, NULL, 0, &rsp, sizeof(rsp));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else if (ret != sizeof(rsp))
|
||||
return -EINVAL;
|
||||
|
||||
*mask = rsp.mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cros_ec_set_event_mask(struct udevice *dev, uint type, uint32_t mask)
|
||||
{
|
||||
struct ec_params_host_event_mask req;
|
||||
int ret;
|
||||
|
||||
req.mask = mask;
|
||||
|
||||
ret = ec_command(dev, type, 0, &req, sizeof(req), NULL, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cros_ec_get_host_events(struct udevice *dev, uint32_t *events_ptr)
|
||||
{
|
||||
struct ec_response_host_event_mask *resp;
|
||||
@ -616,6 +701,17 @@ int cros_ec_flash_protect(struct udevice *dev, uint32_t set_mask,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cros_ec_entering_mode(struct udevice *dev, int mode)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ec_command(dev, EC_CMD_ENTERING_MODE, 0, &mode, sizeof(mode),
|
||||
NULL, 0);
|
||||
if (rc)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cros_ec_check_version(struct udevice *dev)
|
||||
{
|
||||
struct cros_ec_dev *cdev = dev_get_uclass_priv(dev);
|
||||
@ -650,16 +746,14 @@ static int cros_ec_check_version(struct udevice *dev)
|
||||
cdev->protocol_version = 3;
|
||||
req.in_data = 0;
|
||||
if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
|
||||
(uint8_t **)&resp, sizeof(*resp)) > 0) {
|
||||
(uint8_t **)&resp, sizeof(*resp)) > 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try sending a version 2 packet */
|
||||
cdev->protocol_version = 2;
|
||||
if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
|
||||
(uint8_t **)&resp, sizeof(*resp)) > 0) {
|
||||
(uint8_t **)&resp, sizeof(*resp)) > 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fail if we're still here, since the EC doesn't understand any
|
||||
@ -822,6 +916,9 @@ int cros_ec_flash_write(struct udevice *dev, const uint8_t *data,
|
||||
uint32_t end, off;
|
||||
int ret;
|
||||
|
||||
if (!burst)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* TODO: round up to the nearest multiple of write size. Can get away
|
||||
* without that on link right now because its write size is 4 bytes.
|
||||
@ -844,6 +941,35 @@ int cros_ec_flash_write(struct udevice *dev, const uint8_t *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run verification on a slot
|
||||
*
|
||||
* @param me CrosEc instance
|
||||
* @param region Region to run verification on
|
||||
* @return 0 if success or not applicable. Non-zero if verification failed.
|
||||
*/
|
||||
int cros_ec_efs_verify(struct udevice *dev, enum ec_flash_region region)
|
||||
{
|
||||
struct ec_params_efs_verify p;
|
||||
int rv;
|
||||
|
||||
log_info("EFS: EC is verifying updated image...\n");
|
||||
p.region = region;
|
||||
|
||||
rv = ec_command(dev, EC_CMD_EFS_VERIFY, 0, &p, sizeof(p), NULL, 0);
|
||||
if (rv >= 0) {
|
||||
log_info("EFS: Verification success\n");
|
||||
return 0;
|
||||
}
|
||||
if (rv == -EC_RES_INVALID_COMMAND) {
|
||||
log_info("EFS: EC doesn't support EFS_VERIFY command\n");
|
||||
return 0;
|
||||
}
|
||||
log_info("EFS: Verification failed\n");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a single block from the flash
|
||||
*
|
||||
@ -934,15 +1060,17 @@ int cros_ec_read_nvdata(struct udevice *dev, uint8_t *block, int size)
|
||||
struct ec_params_vbnvcontext p;
|
||||
int len;
|
||||
|
||||
if (size != EC_VBNV_BLOCK_SIZE)
|
||||
if (size != EC_VBNV_BLOCK_SIZE && size != EC_VBNV_BLOCK_SIZE_V2)
|
||||
return -EINVAL;
|
||||
|
||||
p.op = EC_VBNV_CONTEXT_OP_READ;
|
||||
|
||||
len = ec_command(dev, EC_CMD_VBNV_CONTEXT, EC_VER_VBNV_CONTEXT,
|
||||
&p, sizeof(p), block, EC_VBNV_BLOCK_SIZE);
|
||||
if (len < EC_VBNV_BLOCK_SIZE)
|
||||
&p, sizeof(uint32_t) + size, block, size);
|
||||
if (len != size) {
|
||||
log_err("Expected %d bytes, got %d\n", size, len);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -952,19 +1080,33 @@ int cros_ec_write_nvdata(struct udevice *dev, const uint8_t *block, int size)
|
||||
struct ec_params_vbnvcontext p;
|
||||
int len;
|
||||
|
||||
if (size != EC_VBNV_BLOCK_SIZE)
|
||||
if (size != EC_VBNV_BLOCK_SIZE && size != EC_VBNV_BLOCK_SIZE_V2)
|
||||
return -EINVAL;
|
||||
p.op = EC_VBNV_CONTEXT_OP_WRITE;
|
||||
memcpy(p.block, block, sizeof(p.block));
|
||||
memcpy(p.block, block, size);
|
||||
|
||||
len = ec_command_inptr(dev, EC_CMD_VBNV_CONTEXT, EC_VER_VBNV_CONTEXT,
|
||||
&p, sizeof(p), NULL, 0);
|
||||
&p, sizeof(uint32_t) + size, NULL, 0);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cros_ec_battery_cutoff(struct udevice *dev, uint8_t flags)
|
||||
{
|
||||
struct ec_params_battery_cutoff p;
|
||||
int len;
|
||||
|
||||
p.flags = flags;
|
||||
len = ec_command(dev, EC_CMD_BATTERY_CUT_OFF, 1, &p, sizeof(p),
|
||||
NULL, 0);
|
||||
|
||||
if (len < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cros_ec_set_ldo(struct udevice *dev, uint8_t index, uint8_t state)
|
||||
{
|
||||
struct ec_params_ldo_set params;
|
||||
@ -1139,9 +1281,209 @@ int cros_ec_i2c_tunnel(struct udevice *dev, int port, struct i2c_msg *in,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cros_ec_check_feature(struct udevice *dev, int feature)
|
||||
{
|
||||
struct ec_response_get_features r;
|
||||
int rv;
|
||||
|
||||
rv = ec_command(dev, EC_CMD_GET_FEATURES, 0, &r, sizeof(r), NULL, 0);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (feature >= 8 * sizeof(r.flags))
|
||||
return -1;
|
||||
|
||||
return r.flags[feature / 32] & EC_FEATURE_MASK_0(feature);
|
||||
}
|
||||
|
||||
/*
|
||||
* Query the EC for specified mask indicating enabled events.
|
||||
* The EC maintains separate event masks for SMI, SCI and WAKE.
|
||||
*/
|
||||
static int cros_ec_uhepi_cmd(struct udevice *dev, uint mask, uint action,
|
||||
uint64_t *value)
|
||||
{
|
||||
int ret;
|
||||
struct ec_params_host_event req;
|
||||
struct ec_response_host_event rsp;
|
||||
|
||||
req.action = action;
|
||||
req.mask_type = mask;
|
||||
if (action != EC_HOST_EVENT_GET)
|
||||
req.value = *value;
|
||||
else
|
||||
*value = 0;
|
||||
ret = ec_command(dev, EC_CMD_HOST_EVENT, 0, &req, sizeof(req), &rsp,
|
||||
sizeof(rsp));
|
||||
|
||||
if (action != EC_HOST_EVENT_GET)
|
||||
return ret;
|
||||
if (ret == 0)
|
||||
*value = rsp.value;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cros_ec_handle_non_uhepi_cmd(struct udevice *dev, uint hcmd,
|
||||
uint action, uint64_t *value)
|
||||
{
|
||||
int ret = -1;
|
||||
struct ec_params_host_event_mask req;
|
||||
struct ec_response_host_event_mask rsp;
|
||||
|
||||
if (hcmd == INVALID_HCMD)
|
||||
return ret;
|
||||
|
||||
if (action != EC_HOST_EVENT_GET)
|
||||
req.mask = (uint32_t)*value;
|
||||
else
|
||||
*value = 0;
|
||||
|
||||
ret = ec_command(dev, hcmd, 0, &req, sizeof(req), &rsp, sizeof(rsp));
|
||||
if (action != EC_HOST_EVENT_GET)
|
||||
return ret;
|
||||
if (ret == 0)
|
||||
*value = rsp.mask;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool cros_ec_is_uhepi_supported(struct udevice *dev)
|
||||
{
|
||||
#define UHEPI_SUPPORTED 1
|
||||
#define UHEPI_NOT_SUPPORTED 2
|
||||
static int uhepi_support;
|
||||
|
||||
if (!uhepi_support) {
|
||||
uhepi_support = cros_ec_check_feature(dev,
|
||||
EC_FEATURE_UNIFIED_WAKE_MASKS) > 0 ? UHEPI_SUPPORTED :
|
||||
UHEPI_NOT_SUPPORTED;
|
||||
log_debug("Chrome EC: UHEPI %s\n",
|
||||
uhepi_support == UHEPI_SUPPORTED ? "supported" :
|
||||
"not supported");
|
||||
}
|
||||
return uhepi_support == UHEPI_SUPPORTED;
|
||||
}
|
||||
|
||||
static int cros_ec_get_mask(struct udevice *dev, uint type)
|
||||
{
|
||||
u64 value = 0;
|
||||
|
||||
if (cros_ec_is_uhepi_supported(dev)) {
|
||||
cros_ec_uhepi_cmd(dev, type, EC_HOST_EVENT_GET, &value);
|
||||
} else {
|
||||
assert(type < ARRAY_SIZE(event_map));
|
||||
cros_ec_handle_non_uhepi_cmd(dev, event_map[type].get_cmd,
|
||||
EC_HOST_EVENT_GET, &value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static int cros_ec_clear_mask(struct udevice *dev, uint type, u64 mask)
|
||||
{
|
||||
if (cros_ec_is_uhepi_supported(dev))
|
||||
return cros_ec_uhepi_cmd(dev, type, EC_HOST_EVENT_CLEAR, &mask);
|
||||
|
||||
assert(type < ARRAY_SIZE(event_map));
|
||||
|
||||
return cros_ec_handle_non_uhepi_cmd(dev, event_map[type].clear_cmd,
|
||||
EC_HOST_EVENT_CLEAR, &mask);
|
||||
}
|
||||
|
||||
uint64_t cros_ec_get_events_b(struct udevice *dev)
|
||||
{
|
||||
return cros_ec_get_mask(dev, EC_HOST_EVENT_B);
|
||||
}
|
||||
|
||||
int cros_ec_clear_events_b(struct udevice *dev, uint64_t mask)
|
||||
{
|
||||
log_debug("Chrome EC: clear events_b mask to 0x%016llx\n", mask);
|
||||
|
||||
return cros_ec_clear_mask(dev, EC_HOST_EVENT_B, mask);
|
||||
}
|
||||
|
||||
int cros_ec_read_limit_power(struct udevice *dev, int *limit_powerp)
|
||||
{
|
||||
struct ec_params_charge_state p;
|
||||
struct ec_response_charge_state r;
|
||||
int ret;
|
||||
|
||||
p.cmd = CHARGE_STATE_CMD_GET_PARAM;
|
||||
p.get_param.param = CS_PARAM_LIMIT_POWER;
|
||||
ret = ec_command(dev, EC_CMD_CHARGE_STATE, 0, &p, sizeof(p),
|
||||
&r, sizeof(r));
|
||||
|
||||
/*
|
||||
* If our EC doesn't support the LIMIT_POWER parameter, assume that
|
||||
* LIMIT_POWER is not requested.
|
||||
*/
|
||||
if (ret == -EC_RES_INVALID_PARAM || ret == -EC_RES_INVALID_COMMAND) {
|
||||
log_warning("PARAM_LIMIT_POWER not supported by EC\n");
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
if (ret != sizeof(r.get_param))
|
||||
return -EINVAL;
|
||||
|
||||
*limit_powerp = r.get_param.value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cros_ec_config_powerbtn(struct udevice *dev, uint32_t flags)
|
||||
{
|
||||
struct ec_params_config_power_button params;
|
||||
int ret;
|
||||
|
||||
params.flags = flags;
|
||||
ret = ec_command(dev, EC_CMD_CONFIG_POWER_BUTTON, 0,
|
||||
¶ms, sizeof(params), NULL, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cros_ec_get_lid_shutdown_mask(struct udevice *dev)
|
||||
{
|
||||
u32 mask;
|
||||
int ret;
|
||||
|
||||
ret = cros_ec_get_event_mask(dev, EC_CMD_HOST_EVENT_GET_SMI_MASK,
|
||||
&mask);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return !!(mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED));
|
||||
}
|
||||
|
||||
int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable)
|
||||
{
|
||||
u32 mask;
|
||||
int ret;
|
||||
|
||||
ret = cros_ec_get_event_mask(dev, EC_CMD_HOST_EVENT_GET_SMI_MASK,
|
||||
&mask);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
// Set lid close event state in the EC SMI event mask
|
||||
if (enable)
|
||||
mask |= EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED);
|
||||
else
|
||||
mask &= ~EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED);
|
||||
|
||||
ret = cros_ec_set_event_mask(dev, EC_CMD_HOST_EVENT_SET_SMI_MASK, mask);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
printf("EC: %sabled lid close event\n", enable ? "en" : "dis");
|
||||
return 0;
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(cros_ec) = {
|
||||
.id = UCLASS_CROS_EC,
|
||||
.name = "cros_ec",
|
||||
.per_device_auto_alloc_size = sizeof(struct cros_ec_dev),
|
||||
.post_bind = dm_scan_fdt_dev,
|
||||
.flags = DM_UC_FLAG_ALLOC_PRIV_DMA,
|
||||
};
|
||||
|
@ -74,7 +74,7 @@ struct ec_keymatrix_entry {
|
||||
* @recovery_req: Keyboard recovery requested
|
||||
*/
|
||||
struct ec_state {
|
||||
uint8_t vbnv_context[EC_VBNV_BLOCK_SIZE];
|
||||
u8 vbnv_context[EC_VBNV_BLOCK_SIZE_V2];
|
||||
struct fdt_cros_ec ec_config;
|
||||
uint8_t *flash_data;
|
||||
int flash_data_len;
|
||||
|
@ -20,7 +20,7 @@ int misc_sandbox_read(struct udevice *dev, int offset, void *buf, int size)
|
||||
|
||||
memcpy(buf, priv->mem + offset, size);
|
||||
|
||||
return 0;
|
||||
return size;
|
||||
}
|
||||
|
||||
int misc_sandbox_write(struct udevice *dev, int offset, const void *buf,
|
||||
@ -30,7 +30,7 @@ int misc_sandbox_write(struct udevice *dev, int offset, const void *buf,
|
||||
|
||||
memcpy(priv->mem + offset, buf, size);
|
||||
|
||||
return 0;
|
||||
return size;
|
||||
}
|
||||
|
||||
int misc_sandbox_ioctl(struct udevice *dev, unsigned long request, void *buf)
|
||||
|
@ -65,7 +65,7 @@ static int dump_efuses(cmd_tbl_t *cmdtp, int flag,
|
||||
}
|
||||
|
||||
ret = misc_read(dev, 0, &fuses, sizeof(fuses));
|
||||
if (ret) {
|
||||
if (ret < 0) {
|
||||
printf("%s: misc_read failed\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
@ -29,6 +29,9 @@ int fuse_read(u32 bank, u32 word, u32 *val)
|
||||
return ret;
|
||||
ret = misc_read(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
|
||||
val, 4);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -54,6 +57,9 @@ int fuse_prog(u32 bank, u32 word, u32 val)
|
||||
return ret;
|
||||
ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET,
|
||||
&val, 4);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -78,6 +84,9 @@ int fuse_sense(u32 bank, u32 word, u32 *val)
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -103,6 +112,9 @@ int fuse_override(u32 bank, u32 word, u32 val)
|
||||
return ret;
|
||||
ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
|
||||
&val, 4);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -57,6 +57,8 @@ static const char *sandbox_sf_state_name(enum sandbox_sf_state state)
|
||||
/* Bits for the status register */
|
||||
#define STAT_WIP (1 << 0)
|
||||
#define STAT_WEL (1 << 1)
|
||||
#define STAT_BP_SHIFT 2
|
||||
#define STAT_BP_MASK (7 << STAT_BP_SHIFT)
|
||||
|
||||
/* Assume all SPI flashes have 3 byte addresses since they do atm */
|
||||
#define SF_ADDR_LEN 3
|
||||
@ -102,6 +104,14 @@ struct sandbox_spi_flash_plat_data {
|
||||
int cs;
|
||||
};
|
||||
|
||||
void sandbox_sf_set_block_protect(struct udevice *dev, int bp_mask)
|
||||
{
|
||||
struct sandbox_spi_flash *sbsf = dev_get_priv(dev);
|
||||
|
||||
sbsf->status &= ~STAT_BP_MASK;
|
||||
sbsf->status |= bp_mask << STAT_BP_SHIFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a very strange probe function. If it has platform data (which may
|
||||
* have come from the device tree) then this function gets the filename and
|
||||
|
@ -28,6 +28,15 @@ int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len)
|
||||
return log_ret(sf_get_ops(dev)->erase(dev, offset, len));
|
||||
}
|
||||
|
||||
int spl_flash_get_sw_write_prot(struct udevice *dev)
|
||||
{
|
||||
struct dm_spi_flash_ops *ops = sf_get_ops(dev);
|
||||
|
||||
if (!ops->get_sw_write_prot)
|
||||
return -ENOSYS;
|
||||
return log_ret(ops->get_sw_write_prot(dev));
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO(sjg@chromium.org): This is an old-style function. We should remove
|
||||
* it when all SPI flash drivers use dm
|
||||
|
@ -170,6 +170,9 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
|
||||
/* Flash erase(sectors) operation, support all possible erase commands */
|
||||
int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len);
|
||||
|
||||
/* Get software write-protect value (BP bits) */
|
||||
int spi_flash_cmd_get_sw_write_prot(struct spi_flash *flash);
|
||||
|
||||
/* Lock stmicro spi flash region */
|
||||
int stm_lock(struct spi_flash *flash, u32 ofs, size_t len);
|
||||
|
||||
|
@ -124,6 +124,13 @@ static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
|
||||
return spi_flash_cmd_erase_ops(flash, offset, len);
|
||||
}
|
||||
|
||||
static int spi_flash_std_get_sw_write_prot(struct udevice *dev)
|
||||
{
|
||||
struct spi_flash *flash = dev_get_uclass_priv(dev);
|
||||
|
||||
return spi_flash_cmd_get_sw_write_prot(flash);
|
||||
}
|
||||
|
||||
static int spi_flash_std_probe(struct udevice *dev)
|
||||
{
|
||||
struct spi_slave *slave = dev_get_parent_priv(dev);
|
||||
@ -141,6 +148,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = {
|
||||
.read = spi_flash_std_read,
|
||||
.write = spi_flash_std_write,
|
||||
.erase = spi_flash_std_erase,
|
||||
.get_sw_write_prot = spi_flash_std_get_sw_write_prot,
|
||||
};
|
||||
|
||||
static const struct udevice_id spi_flash_std_ids[] = {
|
||||
|
@ -110,6 +110,18 @@ static int write_cr(struct spi_flash *flash, u8 wc)
|
||||
}
|
||||
#endif
|
||||
|
||||
int spi_flash_cmd_get_sw_write_prot(struct spi_flash *flash)
|
||||
{
|
||||
u8 status;
|
||||
int ret;
|
||||
|
||||
ret = read_sr(flash, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return (status >> 2) & 7;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPI_FLASH_BAR
|
||||
/*
|
||||
* This "clean_bar" is necessary in a situation when one was accessing
|
||||
|
@ -774,16 +774,19 @@ int pci_bind_bus_devices(struct udevice *bus)
|
||||
found_multi = false;
|
||||
if (PCI_FUNC(bdf) && !found_multi)
|
||||
continue;
|
||||
|
||||
/* Check only the first access, we don't expect problems */
|
||||
ret = pci_bus_read_config(bus, bdf, PCI_HEADER_TYPE,
|
||||
&header_type, PCI_SIZE_8);
|
||||
ret = pci_bus_read_config(bus, bdf, PCI_VENDOR_ID, &vendor,
|
||||
PCI_SIZE_16);
|
||||
if (ret)
|
||||
goto error;
|
||||
pci_bus_read_config(bus, bdf, PCI_VENDOR_ID, &vendor,
|
||||
PCI_SIZE_16);
|
||||
|
||||
if (vendor == 0xffff || vendor == 0x0000)
|
||||
continue;
|
||||
|
||||
pci_bus_read_config(bus, bdf, PCI_HEADER_TYPE,
|
||||
&header_type, PCI_SIZE_8);
|
||||
|
||||
if (!PCI_FUNC(bdf))
|
||||
found_multi = header_type & 0x80;
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define SPI_DEFAULT_SPEED_HZ 100000
|
||||
|
||||
static int spi_set_speed_mode(struct udevice *bus, int speed, int mode)
|
||||
{
|
||||
struct dm_spi_ops *ops;
|
||||
@ -58,7 +60,7 @@ int dm_spi_claim_bus(struct udevice *dev)
|
||||
speed = spi->max_hz;
|
||||
}
|
||||
if (!speed)
|
||||
speed = 100000;
|
||||
speed = SPI_DEFAULT_SPEED_HZ;
|
||||
if (speed != slave->speed) {
|
||||
int ret = spi_set_speed_mode(bus, speed, slave->mode);
|
||||
|
||||
@ -300,7 +302,13 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
|
||||
}
|
||||
plat = dev_get_parent_platdata(dev);
|
||||
plat->cs = cs;
|
||||
plat->max_hz = speed;
|
||||
if (speed) {
|
||||
plat->max_hz = speed;
|
||||
} else {
|
||||
printf("Warning: SPI speed fallback to %u kHz\n",
|
||||
SPI_DEFAULT_SPEED_HZ / 1000);
|
||||
plat->max_hz = SPI_DEFAULT_SPEED_HZ;
|
||||
}
|
||||
plat->mode = mode;
|
||||
created = true;
|
||||
} else if (ret) {
|
||||
@ -374,7 +382,8 @@ int spi_slave_ofdata_to_platdata(struct udevice *dev,
|
||||
int value;
|
||||
|
||||
plat->cs = dev_read_u32_default(dev, "reg", -1);
|
||||
plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency", 0);
|
||||
plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency",
|
||||
SPI_DEFAULT_SPEED_HZ);
|
||||
if (dev_read_bool(dev, "spi-cpol"))
|
||||
mode |= SPI_CPOL;
|
||||
if (dev_read_bool(dev, "spi-cpha"))
|
||||
|
@ -187,9 +187,11 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf,
|
||||
|
||||
code = get_unaligned_be32(sendbuf + sizeof(uint16_t) +
|
||||
sizeof(uint32_t));
|
||||
#ifdef DEBUG
|
||||
printf("tpm: %zd bytes, recv_len %zd, cmd = %x\n", send_size,
|
||||
*recv_len, code);
|
||||
print_buffer(0, sendbuf, 1, send_size, 0);
|
||||
#endif
|
||||
switch (code) {
|
||||
case TPM_CMD_GET_CAPABILITY:
|
||||
type = get_unaligned_be32(sendbuf + 14);
|
||||
@ -306,6 +308,10 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf,
|
||||
printf("Unknown tpm command %02x\n", code);
|
||||
return -ENOSYS;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("tpm: rx recv_len %zd\n", *recv_len);
|
||||
print_buffer(0, recvbuf, 1, *recv_len, 0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -344,7 +344,7 @@ static void vidconsole_escape_char(struct udevice *dev, char ch)
|
||||
switch (val) {
|
||||
case 0:
|
||||
/* all attributes off */
|
||||
video_set_default_colors(vid_priv);
|
||||
video_set_default_colors(dev->parent, false);
|
||||
break;
|
||||
case 1:
|
||||
/* bold */
|
||||
|
@ -115,18 +115,29 @@ int video_clear(struct udevice *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void video_set_default_colors(struct video_priv *priv)
|
||||
void video_set_default_colors(struct udevice *dev, bool invert)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
int fore, back;
|
||||
|
||||
#ifdef CONFIG_SYS_WHITE_ON_BLACK
|
||||
/* White is used when switching to bold, use light gray here */
|
||||
priv->fg_col_idx = VID_LIGHT_GRAY;
|
||||
priv->colour_fg = vid_console_color(priv, VID_LIGHT_GRAY);
|
||||
priv->colour_bg = vid_console_color(priv, VID_BLACK);
|
||||
fore = VID_LIGHT_GRAY;
|
||||
back = VID_BLACK;
|
||||
#else
|
||||
priv->fg_col_idx = VID_BLACK;
|
||||
priv->colour_fg = vid_console_color(priv, VID_BLACK);
|
||||
priv->colour_bg = vid_console_color(priv, VID_WHITE);
|
||||
fore = VID_BLACK;
|
||||
back = VID_WHITE;
|
||||
#endif
|
||||
if (invert) {
|
||||
int temp;
|
||||
|
||||
temp = fore;
|
||||
fore = back;
|
||||
back = temp;
|
||||
}
|
||||
priv->fg_col_idx = fore;
|
||||
priv->colour_fg = vid_console_color(priv, fore);
|
||||
priv->colour_bg = vid_console_color(priv, back);
|
||||
}
|
||||
|
||||
/* Flush video activity to the caches */
|
||||
@ -219,7 +230,7 @@ static int video_post_probe(struct udevice *dev)
|
||||
priv->fb_size = priv->line_length * priv->ysize;
|
||||
|
||||
/* Set up colors */
|
||||
video_set_default_colors(priv);
|
||||
video_set_default_colors(dev, false);
|
||||
|
||||
if (!CONFIG_IS_ENABLED(NO_FB_CLEAR))
|
||||
video_clear(dev);
|
||||
|
@ -187,6 +187,14 @@ int cros_ec_flash_protect(struct udevice *dev, uint32_t set_mask,
|
||||
uint32_t set_flags,
|
||||
struct ec_response_flash_protect *resp);
|
||||
|
||||
/**
|
||||
* Notify EC of current boot mode
|
||||
*
|
||||
* @param dev CROS-EC device
|
||||
* @param vboot_mode Verified boot mode
|
||||
* @return 0 if ok, <0 on error
|
||||
*/
|
||||
int cros_ec_entering_mode(struct udevice *dev, int mode);
|
||||
|
||||
/**
|
||||
* Run internal tests on the cros_ec interface.
|
||||
@ -397,4 +405,85 @@ struct i2c_msg;
|
||||
int cros_ec_i2c_tunnel(struct udevice *dev, int port, struct i2c_msg *msg,
|
||||
int nmsgs);
|
||||
|
||||
/**
|
||||
* cros_ec_get_events_b() - Get event mask B
|
||||
*
|
||||
* @return value of event mask, default value of 0 if it could not be read
|
||||
*/
|
||||
uint64_t cros_ec_get_events_b(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* cros_ec_clear_events_b() - Clear even mask B
|
||||
*
|
||||
* Any pending events in the B range are cleared
|
||||
*
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int cros_ec_clear_events_b(struct udevice *dev, uint64_t mask);
|
||||
|
||||
/**
|
||||
* cros_ec_efs_verify() - tell the EC to verify one of its images
|
||||
*
|
||||
* @param dev CROS-EC device
|
||||
* @param region Flash region to query
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int cros_ec_efs_verify(struct udevice *dev, enum ec_flash_region region);
|
||||
|
||||
/**
|
||||
* cros_ec_battery_cutoff() - Request that the battery be cut off
|
||||
*
|
||||
* This tells the battery to stop supplying power. This is used before shipping
|
||||
* a device to ensure that the battery remains charged while the device is
|
||||
* shipped or sitting on the shelf waiting to be purchased.
|
||||
*
|
||||
* @param dev CROS-EC device
|
||||
* @param flags Flags to use (EC_BATTERY_CUTOFF_FLAG_...)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int cros_ec_battery_cutoff(struct udevice *dev, uint8_t flags);
|
||||
|
||||
/**
|
||||
* cros_ec_read_limit_power() - Check if power is limited by batter/charger
|
||||
*
|
||||
* Sometimes the battery is low and / or the device is connected to a charger
|
||||
* that cannot supply much power.
|
||||
*
|
||||
* @param dev CROS-EC device
|
||||
* @param limit_powerp Returns whether power is limited (0 or 1)
|
||||
* @return 0 if OK, -ENOSYS if the EC does not support this comment, -EINVAL
|
||||
* if the EC returned an invalid response
|
||||
*/
|
||||
int cros_ec_read_limit_power(struct udevice *dev, int *limit_powerp);
|
||||
|
||||
/**
|
||||
* cros_ec_config_powerbtn() - Configure the behaviour of the power button
|
||||
*
|
||||
* @param dev CROS-EC device
|
||||
* @param flags Flags to use (EC_POWER_BUTTON_...)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int cros_ec_config_powerbtn(struct udevice *dev, uint32_t flags);
|
||||
|
||||
/**
|
||||
* cros_ec_get_lid_shutdown_mask() - Set the lid shutdown mask
|
||||
*
|
||||
* Determines whether a lid close event is reported
|
||||
*
|
||||
* @param dev CROS-EC device
|
||||
* @return shufdown mas if OK, -ve on error
|
||||
*/
|
||||
int cros_ec_get_lid_shutdown_mask(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* cros_ec_set_lid_shutdown_mask() - Set the lid shutdown mask
|
||||
*
|
||||
* Set whether a lid close event is reported
|
||||
*
|
||||
* @param dev CROS-EC device
|
||||
* @param enable true to enable reporting, false to disable
|
||||
* @return shufdown mas if OK, -ve on error
|
||||
*/
|
||||
int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable);
|
||||
|
||||
#endif
|
||||
|
@ -956,6 +956,7 @@ int fdtdec_setup(void);
|
||||
* Called when CONFIG_OF_BOARD is defined, or if CONFIG_OF_SEPARATE is defined
|
||||
* and the board implements it.
|
||||
*/
|
||||
void *board_fdt_blob_setup(void);
|
||||
|
||||
/*
|
||||
* Decode the size of memory
|
||||
|
@ -47,6 +47,7 @@ enum log_category_t {
|
||||
LOGC_DT, /* Device-tree */
|
||||
LOGC_EFI, /* EFI implementation */
|
||||
LOGC_ALLOC, /* Memory allocation */
|
||||
LOGC_SANDBOX, /* Related to the sandbox board */
|
||||
|
||||
LOGC_COUNT, /* Number of log categories */
|
||||
LOGC_END, /* Sentinel value for a list of log categories */
|
||||
|
@ -13,7 +13,7 @@
|
||||
* @buf: pointer to data buffer
|
||||
* @size: data size in bytes to read the device
|
||||
*
|
||||
* Return: 0 if OK, -ve on error
|
||||
* Return: number of bytes read if OK (may be 0 if EOF), -ve on error
|
||||
*/
|
||||
int misc_read(struct udevice *dev, int offset, void *buf, int size);
|
||||
|
||||
@ -24,7 +24,7 @@ int misc_read(struct udevice *dev, int offset, void *buf, int size);
|
||||
* @buf: pointer to data buffer
|
||||
* @size: data size in bytes to write the device
|
||||
*
|
||||
* Return: 0 if OK, -ve on error
|
||||
* Return: number of bytes written if OK (may be < @size), -ve on error
|
||||
*/
|
||||
int misc_write(struct udevice *dev, int offset, void *buf, int size);
|
||||
|
||||
@ -90,7 +90,7 @@ struct misc_ops {
|
||||
* @buf: pointer to data buffer
|
||||
* @size: data size in bytes to read the device
|
||||
*
|
||||
* Return: 0 if OK, -ve on error
|
||||
* Return: number of bytes read if OK (may be 0 if EOF), -ve on error
|
||||
*/
|
||||
int (*read)(struct udevice *dev, int offset, void *buf, int size);
|
||||
|
||||
@ -101,7 +101,7 @@ struct misc_ops {
|
||||
* @buf: pointer to data buffer
|
||||
* @size: data size in bytes to write the device
|
||||
*
|
||||
* Return: 0 if OK, -ve on error
|
||||
* Return: number of bytes written if OK (may be < @size), -ve on error
|
||||
*/
|
||||
int (*write)(struct udevice *dev, int offset, const void *buf,
|
||||
int size);
|
||||
|
14
include/os.h
14
include/os.h
@ -350,4 +350,18 @@ int os_mprotect_allow(void *start, size_t len);
|
||||
*/
|
||||
int os_write_file(const char *name, const void *buf, int size);
|
||||
|
||||
/**
|
||||
* os_read_file() - Read a file from the host filesystem
|
||||
*
|
||||
* This can be useful when reading test data into sandbox for use by test
|
||||
* routines. The data is allocated using os_malloc() and should be freed by
|
||||
* the caller.
|
||||
*
|
||||
* @name: File path to read from
|
||||
* @bufp: Returns buffer containing data read
|
||||
* @sizep: Returns size of data
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int os_read_file(const char *name, void **bufp, int *sizep);
|
||||
|
||||
#endif
|
||||
|
@ -112,6 +112,19 @@ struct dm_spi_flash_ops {
|
||||
int (*write)(struct udevice *dev, u32 offset, size_t len,
|
||||
const void *buf);
|
||||
int (*erase)(struct udevice *dev, u32 offset, size_t len);
|
||||
/**
|
||||
* get_sw_write_prot() - Check state of software write-protect feature
|
||||
*
|
||||
* SPI flash chips can lock a region of the flash defined by a
|
||||
* 'protected area'. This function checks if this protected area is
|
||||
* defined.
|
||||
*
|
||||
* @dev: SPI flash device
|
||||
* @return 0 if no region is write-protected, 1 if a region is
|
||||
* write-protected, -ENOSYS if the driver does not implement this,
|
||||
* other -ve value on error
|
||||
*/
|
||||
int (*get_sw_write_prot)(struct udevice *dev);
|
||||
};
|
||||
|
||||
/* Access the serial operations for a device */
|
||||
@ -153,6 +166,20 @@ int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len,
|
||||
*/
|
||||
int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len);
|
||||
|
||||
/**
|
||||
* spl_flash_get_sw_write_prot() - Check state of software write-protect feature
|
||||
*
|
||||
* SPI flash chips can lock a region of the flash defined by a
|
||||
* 'protected area'. This function checks if this protected area is
|
||||
* defined.
|
||||
*
|
||||
* @dev: SPI flash device
|
||||
* @return 0 if no region is write-protected, 1 if a region is
|
||||
* write-protected, -ENOSYS if the driver does not implement this,
|
||||
* other -ve value on error
|
||||
*/
|
||||
int spl_flash_get_sw_write_prot(struct udevice *dev);
|
||||
|
||||
int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
|
||||
unsigned int max_hz, unsigned int spi_mode,
|
||||
struct udevice **devp);
|
||||
|
@ -191,9 +191,10 @@ void video_set_flush_dcache(struct udevice *dev, bool flush);
|
||||
/**
|
||||
* Set default colors and attributes
|
||||
*
|
||||
* @priv device information
|
||||
* @dev: video device
|
||||
* @invert true to invert colours
|
||||
*/
|
||||
void video_set_default_colors(struct video_priv *priv);
|
||||
void video_set_default_colors(struct udevice *dev, bool invert);
|
||||
|
||||
#endif /* CONFIG_DM_VIDEO */
|
||||
|
||||
|
@ -301,6 +301,14 @@ config LZO
|
||||
help
|
||||
This enables support for LZO compression algorithm.r
|
||||
|
||||
config SPL_LZ4
|
||||
bool "Enable LZ4 decompression support in SPL"
|
||||
help
|
||||
This enables support for tge LZ4 decompression algorithm in SPL. LZ4
|
||||
is a lossless data compression algorithm that is focused on
|
||||
fast compression and decompression speed. It belongs to the LZ77
|
||||
family of byte-oriented compression schemes.
|
||||
|
||||
config SPL_LZO
|
||||
bool "Enable LZO decompression support in SPL"
|
||||
help
|
||||
|
@ -38,7 +38,6 @@ obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o
|
||||
obj-y += initcall.o
|
||||
obj-$(CONFIG_LMB) += lmb.o
|
||||
obj-y += ldiv.o
|
||||
obj-$(CONFIG_LZ4) += lz4_wrapper.o
|
||||
obj-$(CONFIG_MD5) += md5.o
|
||||
obj-y += net_utils.o
|
||||
obj-$(CONFIG_PHYSMEM) += physmem.o
|
||||
@ -64,6 +63,7 @@ obj-$(CONFIG_SHA256) += sha256.o
|
||||
obj-$(CONFIG_$(SPL_)ZLIB) += zlib/
|
||||
obj-$(CONFIG_$(SPL_)GZIP) += gunzip.o
|
||||
obj-$(CONFIG_$(SPL_)LZO) += lzo/
|
||||
obj-$(CONFIG_$(SPL_)LZ4) += lz4_wrapper.o
|
||||
|
||||
obj-$(CONFIG_LIBAVB) += libavb/
|
||||
|
||||
|
@ -1198,7 +1198,8 @@ static int uncompress_blob(const void *src, ulong sz_src, void **dstp)
|
||||
# else
|
||||
static int uncompress_blob(const void *src, ulong sz_src, void **dstp)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
*dstp = (void *)src;
|
||||
return 0;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
@ -15,6 +15,7 @@
|
||||
* reentrant and should be faster). Use only strsep() in new code, please.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/ctype.h>
|
||||
|
@ -21,9 +21,9 @@ static int dm_test_misc(struct unit_test_state *uts)
|
||||
ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "misc-test", &dev));
|
||||
|
||||
/* Read / write tests */
|
||||
ut_assertok(misc_write(dev, 0, "TEST", 4));
|
||||
ut_assertok(misc_write(dev, 4, "WRITE", 5));
|
||||
ut_assertok(misc_read(dev, 0, buf, 9));
|
||||
ut_asserteq(4, misc_write(dev, 0, "TEST", 4));
|
||||
ut_asserteq(5, misc_write(dev, 4, "WRITE", 5));
|
||||
ut_asserteq(9, misc_read(dev, 0, buf, 9));
|
||||
|
||||
ut_assertok(memcmp(buf, "TESTWRITE", 9));
|
||||
|
||||
|
55
test/dm/sf.c
55
test/dm/sf.c
@ -6,15 +6,66 @@
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <fdtdec.h>
|
||||
#include <mapmem.h>
|
||||
#include <os.h>
|
||||
#include <spi.h>
|
||||
#include <spi_flash.h>
|
||||
#include <asm/state.h>
|
||||
#include <asm/test.h>
|
||||
#include <dm/test.h>
|
||||
#include <dm/util.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
/* Test that sandbox SPI flash works correctly */
|
||||
/* Simple test of sandbox SPI flash */
|
||||
static int dm_test_spi_flash(struct unit_test_state *uts)
|
||||
{
|
||||
struct udevice *dev, *emul;
|
||||
int full_size = 0x200000;
|
||||
int size = 0x10000;
|
||||
u8 *src, *dst;
|
||||
int i;
|
||||
|
||||
src = map_sysmem(0x20000, full_size);
|
||||
ut_assertok(os_write_file("spi.bin", src, full_size));
|
||||
ut_assertok(uclass_first_device_err(UCLASS_SPI_FLASH, &dev));
|
||||
|
||||
dst = map_sysmem(0x20000 + full_size, full_size);
|
||||
ut_assertok(spi_flash_read_dm(dev, 0, size, dst));
|
||||
ut_assertok(memcmp(src, dst, size));
|
||||
|
||||
/* Erase */
|
||||
ut_assertok(spi_flash_erase_dm(dev, 0, size));
|
||||
ut_assertok(spi_flash_read_dm(dev, 0, size, dst));
|
||||
for (i = 0; i < size; i++)
|
||||
ut_asserteq(dst[i], 0xff);
|
||||
|
||||
/* Write some new data */
|
||||
for (i = 0; i < size; i++)
|
||||
src[i] = i;
|
||||
ut_assertok(spi_flash_write_dm(dev, 0, size, src));
|
||||
ut_assertok(spi_flash_read_dm(dev, 0, size, dst));
|
||||
ut_assertok(memcmp(src, dst, size));
|
||||
|
||||
/* Try the write-protect stuff */
|
||||
ut_assertok(uclass_first_device_err(UCLASS_SPI_EMUL, &emul));
|
||||
ut_asserteq(0, spl_flash_get_sw_write_prot(dev));
|
||||
sandbox_sf_set_block_protect(emul, 1);
|
||||
ut_asserteq(1, spl_flash_get_sw_write_prot(dev));
|
||||
sandbox_sf_set_block_protect(emul, 0);
|
||||
ut_asserteq(0, spl_flash_get_sw_write_prot(dev));
|
||||
|
||||
/*
|
||||
* Since we are about to destroy all devices, we must tell sandbox
|
||||
* to forget the emulation device
|
||||
*/
|
||||
sandbox_sf_unbind_emul(state_get_current(), 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_spi_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
/* Functional test that sandbox SPI flash works correctly */
|
||||
static int dm_test_spi_flash_func(struct unit_test_state *uts)
|
||||
{
|
||||
/*
|
||||
* Create an empty test file and run the SPI flash tests. This is a
|
||||
@ -39,4 +90,4 @@ static int dm_test_spi_flash(struct unit_test_state *uts)
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_spi_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
DM_TEST(dm_test_spi_flash_func, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
@ -13,7 +13,7 @@ def in_tree(response, name, uclass, drv, depth, last_child):
|
||||
else:
|
||||
leaf = leaf + '`'
|
||||
leaf = leaf + '-- ' + name
|
||||
line = ' *{:10.10} [0-9]* \[ [ +] \] {:10.10} {}$'.format(uclass, drv,leaf)
|
||||
line = ' *{:10.10} [0-9]* \[ [ +] \] {:20.20} {}$'.format(uclass, drv, leaf)
|
||||
prog = re.compile(line)
|
||||
for l in lines:
|
||||
if prog.match(l):
|
||||
@ -28,31 +28,31 @@ def test_bind_unbind_with_node(u_boot_console):
|
||||
response = u_boot_console.run_command("bind /bind-test generic_simple_bus")
|
||||
assert response == ''
|
||||
tree = u_boot_console.run_command("dm tree")
|
||||
assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
|
||||
assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
|
||||
assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False)
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
|
||||
|
||||
#Unbind child #1. No error expected and all devices should be there except for bind-test-child1
|
||||
response = u_boot_console.run_command("unbind /bind-test/bind-test-child1")
|
||||
assert response == ''
|
||||
tree = u_boot_console.run_command("dm tree")
|
||||
assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
|
||||
assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
|
||||
assert "bind-test-child1" not in tree
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
|
||||
|
||||
#bind child #1. No error expected and all devices should be there
|
||||
response = u_boot_console.run_command("bind /bind-test/bind-test-child1 phy_sandbox")
|
||||
assert response == ''
|
||||
tree = u_boot_console.run_command("dm tree")
|
||||
assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
|
||||
assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
|
||||
assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, True)
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, False)
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, False)
|
||||
|
||||
#Unbind child #2. No error expected and all devices should be there except for bind-test-child2
|
||||
response = u_boot_console.run_command("unbind /bind-test/bind-test-child2")
|
||||
assert response == ''
|
||||
tree = u_boot_console.run_command("dm tree")
|
||||
assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
|
||||
assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
|
||||
assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, True)
|
||||
assert "bind-test-child2" not in tree
|
||||
|
||||
@ -61,9 +61,9 @@ def test_bind_unbind_with_node(u_boot_console):
|
||||
response = u_boot_console.run_command("bind /bind-test/bind-test-child2 generic_simple_bus")
|
||||
assert response == ''
|
||||
tree = u_boot_console.run_command("dm tree")
|
||||
assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
|
||||
assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
|
||||
assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False)
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
|
||||
|
||||
#Unbind parent. No error expected. All devices should be removed and unbound
|
||||
response = u_boot_console.run_command("unbind /bind-test")
|
||||
@ -89,9 +89,9 @@ def test_bind_unbind_with_node(u_boot_console):
|
||||
response = u_boot_console.run_command("bind /bind-test generic_simple_bus")
|
||||
assert response == ''
|
||||
tree = u_boot_console.run_command("dm tree")
|
||||
assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
|
||||
assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
|
||||
assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False)
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
|
||||
|
||||
response = u_boot_console.run_command("unbind /bind-test")
|
||||
assert response == ''
|
||||
@ -138,7 +138,7 @@ def test_bind_unbind_with_uclass(u_boot_console):
|
||||
response = u_boot_console.run_command("unbind simple_bus {}".format(child_of_child2_index))
|
||||
assert response == ''
|
||||
tree = u_boot_console.run_command("dm tree")
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
|
||||
assert not in_tree(tree, "generic_simple_bus", "simple_bus", "generic_simple_bus", 2, True)
|
||||
child_of_child2_line = get_next_line(tree, "bind-test-child2")
|
||||
assert child_of_child2_line == ""
|
||||
@ -161,7 +161,7 @@ def test_bind_unbind_with_uclass(u_boot_console):
|
||||
assert response == ''
|
||||
|
||||
tree = u_boot_console.run_command("dm tree")
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
|
||||
assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
|
||||
|
||||
child_of_child2_line = get_next_line(tree, "bind-test-child2")
|
||||
assert child_of_child2_line == ""
|
||||
|
@ -723,6 +723,12 @@ If you need to specify a particular device-tree compiler to use, you can define
|
||||
the DTC environment variable. This can be useful when the system dtc is too
|
||||
old.
|
||||
|
||||
To enable a full backtrace and other debugging features in binman, pass
|
||||
BINMAN_DEBUG=1 to your build:
|
||||
|
||||
make sandbox_defconfig
|
||||
make BINMAN_DEBUG=1
|
||||
|
||||
|
||||
History / Credits
|
||||
-----------------
|
||||
|
@ -60,7 +60,7 @@ class Entry_blob(Entry):
|
||||
except AttributeError:
|
||||
data = lz4.compress(data)
|
||||
'''
|
||||
data = tools.Run('lz4', '-c', self._pathname, )
|
||||
data = tools.Run('lz4', '-c', self._pathname)
|
||||
self.SetContents(data)
|
||||
return True
|
||||
|
||||
|
@ -30,9 +30,8 @@ class Entry_u_boot_elf(Entry_blob):
|
||||
out_fname = tools.GetOutputFilename('%s.stripped' % uniq)
|
||||
tools.WriteFile(out_fname, tools.ReadFile(self._pathname))
|
||||
tools.Run('strip', out_fname)
|
||||
self.SetContents(tools.ReadFile(out_fname))
|
||||
else:
|
||||
self.SetContents(tools.ReadFile(self._pathname))
|
||||
self._pathname = out_fname
|
||||
Entry_blob.ReadBlobContents(self)
|
||||
return True
|
||||
|
||||
def GetDefaultFilename(self):
|
||||
|
@ -290,6 +290,7 @@ class Builder:
|
||||
self._re_function = re.compile('(.*): In function.*')
|
||||
self._re_files = re.compile('In file included from.*')
|
||||
self._re_warning = re.compile('(.*):(\d*):(\d*): warning: .*')
|
||||
self._re_dtb_warning = re.compile('(.*): Warning .*')
|
||||
self._re_note = re.compile('(.*):(\d*):(\d*): note: this is the location of the previous.*')
|
||||
|
||||
self.queue = Queue.Queue()
|
||||
@ -788,7 +789,8 @@ class Builder:
|
||||
self._re_files.match(line)):
|
||||
last_func = line
|
||||
else:
|
||||
is_warning = self._re_warning.match(line)
|
||||
is_warning = (self._re_warning.match(line) or
|
||||
self._re_dtb_warning.match(line))
|
||||
is_note = self._re_note.match(line)
|
||||
if is_warning or (last_was_warning and is_note):
|
||||
if last_func:
|
||||
@ -1194,10 +1196,11 @@ class Builder:
|
||||
Print(' ' + line, newline=True, colour=col)
|
||||
|
||||
|
||||
better = [] # List of boards fixed since last commit
|
||||
worse = [] # List of new broken boards since last commit
|
||||
new = [] # List of boards that didn't exist last time
|
||||
unknown = [] # List of boards that were not built
|
||||
ok_boards = [] # List of boards fixed since last commit
|
||||
warn_boards = [] # List of boards with warnings since last commit
|
||||
err_boards = [] # List of new broken boards since last commit
|
||||
new_boards = [] # List of boards that didn't exist last time
|
||||
unknown_boards = [] # List of boards that were not built
|
||||
|
||||
for target in board_dict:
|
||||
if target not in board_selected:
|
||||
@ -1208,13 +1211,19 @@ class Builder:
|
||||
base_outcome = self._base_board_dict[target].rc
|
||||
outcome = board_dict[target]
|
||||
if outcome.rc == OUTCOME_UNKNOWN:
|
||||
unknown.append(target)
|
||||
unknown_boards.append(target)
|
||||
elif outcome.rc < base_outcome:
|
||||
better.append(target)
|
||||
if outcome.rc == OUTCOME_WARNING:
|
||||
warn_boards.append(target)
|
||||
else:
|
||||
ok_boards.append(target)
|
||||
elif outcome.rc > base_outcome:
|
||||
worse.append(target)
|
||||
if outcome.rc == OUTCOME_WARNING:
|
||||
warn_boards.append(target)
|
||||
else:
|
||||
err_boards.append(target)
|
||||
else:
|
||||
new.append(target)
|
||||
new_boards.append(target)
|
||||
|
||||
# Get a list of errors that have appeared, and disappeared
|
||||
better_err, worse_err = _CalcErrorDelta(self._base_err_lines,
|
||||
@ -1223,16 +1232,18 @@ class Builder:
|
||||
self._base_warn_line_boards, warn_lines, warn_line_boards, 'w')
|
||||
|
||||
# Display results by arch
|
||||
if (better or worse or unknown or new or worse_err or better_err
|
||||
or worse_warn or better_warn):
|
||||
if any((ok_boards, warn_boards, err_boards, unknown_boards, new_boards,
|
||||
worse_err, better_err, worse_warn, better_warn)):
|
||||
arch_list = {}
|
||||
self.AddOutcome(board_selected, arch_list, better, '',
|
||||
self.AddOutcome(board_selected, arch_list, ok_boards, '',
|
||||
self.col.GREEN)
|
||||
self.AddOutcome(board_selected, arch_list, worse, '+',
|
||||
self.AddOutcome(board_selected, arch_list, warn_boards, 'w+',
|
||||
self.col.YELLOW)
|
||||
self.AddOutcome(board_selected, arch_list, err_boards, '+',
|
||||
self.col.RED)
|
||||
self.AddOutcome(board_selected, arch_list, new, '*', self.col.BLUE)
|
||||
self.AddOutcome(board_selected, arch_list, new_boards, '*', self.col.BLUE)
|
||||
if self._show_unknown:
|
||||
self.AddOutcome(board_selected, arch_list, unknown, '?',
|
||||
self.AddOutcome(board_selected, arch_list, unknown_boards, '?',
|
||||
self.col.MAGENTA)
|
||||
for arch, target_list in arch_list.iteritems():
|
||||
Print('%10s: %s' % (arch, target_list))
|
||||
|
@ -66,7 +66,7 @@ def ParseArgs():
|
||||
parser.add_option('-l', '--list-error-boards', action='store_true',
|
||||
default=False, help='Show a list of boards next to each error/warning')
|
||||
parser.add_option('--list-tool-chains', action='store_true', default=False,
|
||||
help='List available tool chains')
|
||||
help='List available tool chains (use -v to see probing detail)')
|
||||
parser.add_option('-n', '--dry-run', action='store_true', dest='dry_run',
|
||||
default=False, help="Do a dry run (describe actions, but do nothing)")
|
||||
parser.add_option('-N', '--no-subdirs', action='store_true', dest='no_subdirs',
|
||||
|
@ -164,7 +164,7 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
|
||||
|
||||
if no_toolchains:
|
||||
toolchains.GetSettings()
|
||||
toolchains.Scan(options.list_tool_chains)
|
||||
toolchains.Scan(options.list_tool_chains and options.verbose)
|
||||
if options.list_tool_chains:
|
||||
toolchains.List()
|
||||
print
|
||||
|
@ -46,8 +46,9 @@ make[1]: *** [main.o] Error 1
|
||||
make: *** [common/libcommon.o] Error 2
|
||||
Make failed
|
||||
''',
|
||||
'''main.c: In function 'main_loop3':
|
||||
main.c:280:6: warning: unused variable 'mary' [-Wunused-variable]
|
||||
'''arch/arm/dts/socfpga_arria10_socdk_sdmmc.dtb: Warning \
|
||||
(avoid_unnecessary_addr_size): /clocks: unnecessary #address-cells/#size-cells \
|
||||
without "ranges" or child "reg" property
|
||||
''',
|
||||
'''powerpc-linux-ld: warning: dot moved backwards before `.bss'
|
||||
powerpc-linux-ld: warning: dot moved backwards before `.bss'
|
||||
@ -96,6 +97,8 @@ boards = [
|
||||
|
||||
BASE_DIR = 'base'
|
||||
|
||||
OUTCOME_OK, OUTCOME_WARN, OUTCOME_ERR = range(3)
|
||||
|
||||
class Options:
|
||||
"""Class that holds build options"""
|
||||
pass
|
||||
@ -165,9 +168,10 @@ class TestBuild(unittest.TestCase):
|
||||
result.combined = result.stdout + result.stderr
|
||||
return result
|
||||
|
||||
def assertSummary(self, text, arch, plus, boards, ok=False):
|
||||
def assertSummary(self, text, arch, plus, boards, outcome=OUTCOME_ERR):
|
||||
col = self._col
|
||||
expected_colour = col.GREEN if ok else col.RED
|
||||
expected_colour = (col.GREEN if outcome == OUTCOME_OK else
|
||||
col.YELLOW if outcome == OUTCOME_WARN else col.RED)
|
||||
expect = '%10s: ' % arch
|
||||
# TODO(sjg@chromium.org): If plus is '', we shouldn't need this
|
||||
expect += ' ' + col.Color(expected_colour, plus)
|
||||
@ -191,6 +195,8 @@ class TestBuild(unittest.TestCase):
|
||||
build.do_make = self.Make
|
||||
board_selected = self.boards.GetSelectedDict()
|
||||
|
||||
# Build the boards for the pre-defined commits and warnings/errors
|
||||
# associated with each. This calls our Make() to inject the fake output.
|
||||
build.BuildBoards(self.commits, board_selected, keep_outputs=False,
|
||||
verbose=False)
|
||||
lines = terminal.GetPrintTestLines()
|
||||
@ -206,33 +212,49 @@ class TestBuild(unittest.TestCase):
|
||||
build.ShowSummary(self.commits, board_selected)
|
||||
#terminal.EchoPrintTestLines()
|
||||
lines = terminal.GetPrintTestLines()
|
||||
|
||||
# Upstream commit: no errors
|
||||
self.assertEqual(lines[0].text, '01: %s' % commits[0][1])
|
||||
|
||||
# Second commit: all archs should fail with warnings
|
||||
self.assertEqual(lines[1].text, '02: %s' % commits[1][1])
|
||||
|
||||
# We expect all archs to fail
|
||||
col = terminal.Color()
|
||||
self.assertSummary(lines[2].text, 'sandbox', '+', ['board4'])
|
||||
self.assertSummary(lines[3].text, 'arm', '+', ['board1'])
|
||||
self.assertSummary(lines[4].text, 'powerpc', '+', ['board2', 'board3'])
|
||||
self.assertSummary(lines[2].text, 'sandbox', 'w+', ['board4'],
|
||||
outcome=OUTCOME_WARN)
|
||||
self.assertSummary(lines[3].text, 'arm', 'w+', ['board1'],
|
||||
outcome=OUTCOME_WARN)
|
||||
self.assertSummary(lines[4].text, 'powerpc', 'w+', ['board2', 'board3'],
|
||||
outcome=OUTCOME_WARN)
|
||||
|
||||
# Now we should have the compiler warning
|
||||
# Second commit: The warnings should be listed
|
||||
self.assertEqual(lines[5].text, 'w+%s' %
|
||||
errors[0].rstrip().replace('\n', '\nw+'))
|
||||
self.assertEqual(lines[5].colour, col.MAGENTA)
|
||||
|
||||
# Third commit: Still fails
|
||||
self.assertEqual(lines[6].text, '03: %s' % commits[2][1])
|
||||
self.assertSummary(lines[7].text, 'sandbox', '+', ['board4'])
|
||||
self.assertSummary(lines[8].text, 'arm', '', ['board1'], ok=True)
|
||||
self.assertSummary(lines[8].text, 'arm', '', ['board1'],
|
||||
outcome=OUTCOME_OK)
|
||||
self.assertSummary(lines[9].text, 'powerpc', '+', ['board2', 'board3'])
|
||||
|
||||
# Compiler error
|
||||
# Expect a compiler error
|
||||
self.assertEqual(lines[10].text, '+%s' %
|
||||
errors[1].rstrip().replace('\n', '\n+'))
|
||||
|
||||
# Fourth commit: Compile errors are fixed, just have warning for board3
|
||||
self.assertEqual(lines[11].text, '04: %s' % commits[3][1])
|
||||
self.assertSummary(lines[12].text, 'sandbox', '', ['board4'], ok=True)
|
||||
self.assertSummary(lines[13].text, 'powerpc', '', ['board2', 'board3'],
|
||||
ok=True)
|
||||
self.assertSummary(lines[12].text, 'sandbox', 'w+', ['board4'],
|
||||
outcome=OUTCOME_WARN)
|
||||
expect = '%10s: ' % 'powerpc'
|
||||
expect += ' ' + col.Color(col.GREEN, '')
|
||||
expect += ' '
|
||||
expect += col.Color(col.GREEN, ' %s' % 'board2')
|
||||
expect += ' ' + col.Color(col.YELLOW, 'w+')
|
||||
expect += ' '
|
||||
expect += col.Color(col.YELLOW, ' %s' % 'board3')
|
||||
self.assertEqual(lines[13].text, expect)
|
||||
|
||||
# Compile error fixed
|
||||
self.assertEqual(lines[14].text, '-%s' %
|
||||
@ -243,9 +265,11 @@ class TestBuild(unittest.TestCase):
|
||||
errors[2].rstrip().replace('\n', '\nw+'))
|
||||
self.assertEqual(lines[15].colour, col.MAGENTA)
|
||||
|
||||
# Fifth commit
|
||||
self.assertEqual(lines[16].text, '05: %s' % commits[4][1])
|
||||
self.assertSummary(lines[17].text, 'sandbox', '+', ['board4'])
|
||||
self.assertSummary(lines[18].text, 'powerpc', '', ['board3'], ok=True)
|
||||
self.assertSummary(lines[18].text, 'powerpc', '', ['board3'],
|
||||
outcome=OUTCOME_OK)
|
||||
|
||||
# The second line of errors[3] is a duplicate, so buildman will drop it
|
||||
expect = errors[3].rstrip().split('\n')
|
||||
@ -256,8 +280,10 @@ class TestBuild(unittest.TestCase):
|
||||
self.assertEqual(lines[20].text, 'w-%s' %
|
||||
errors[2].rstrip().replace('\n', '\nw-'))
|
||||
|
||||
# Sixth commit
|
||||
self.assertEqual(lines[21].text, '06: %s' % commits[5][1])
|
||||
self.assertSummary(lines[22].text, 'sandbox', '', ['board4'], ok=True)
|
||||
self.assertSummary(lines[22].text, 'sandbox', '', ['board4'],
|
||||
outcome=OUTCOME_OK)
|
||||
|
||||
# The second line of errors[3] is a duplicate, so buildman will drop it
|
||||
expect = errors[3].rstrip().split('\n')
|
||||
@ -268,6 +294,7 @@ class TestBuild(unittest.TestCase):
|
||||
self.assertEqual(lines[24].text, 'w-%s' %
|
||||
errors[0].rstrip().replace('\n', '\nw-'))
|
||||
|
||||
# Seventh commit
|
||||
self.assertEqual(lines[25].text, '07: %s' % commits[6][1])
|
||||
self.assertSummary(lines[26].text, 'sandbox', '+', ['board4'])
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user