Merge branch '2023-03-30-assorted-general-upates' into next

- RTC cleanups / improvements, run_commandf() cleanups, fs bugfixes,
  socrates config fix, PCI MPS support, GPIO improvements, other code
  cleanups
This commit is contained in:
Tom Rini 2023-03-31 10:04:23 -04:00
commit b8deed53fe
37 changed files with 971 additions and 92 deletions

18
Kconfig
View file

@ -427,16 +427,16 @@ config REMAKE_ELF
config BUILD_TARGET
string "Build target special images"
default "u-boot-elf.srec" if RCAR_GEN3
default "u-boot-with-spl.bin" if ARCH_AT91 && SPL_NAND_SUPPORT
default "u-boot-with-spl.bin" if MPC85xx && !E500MC && !E5500 && !E6500 && SPL
default "u-boot-with-spl.imx" if ARCH_MX6 && SPL
default "u-boot-with-spl.kwb" if ARMADA_32BIT && SPL
default "u-boot-with-spl.sfp" if TARGET_SOCFPGA_ARRIA10
default "u-boot-with-spl.sfp" if TARGET_SOCFPGA_GEN5
default "u-boot-with-spl.kwb" if ARMADA_32BIT && SPL
default "u-boot-elf.srec" if RCAR_GEN3
default "u-boot.itb" if !BINMAN && SPL_LOAD_FIT && (ARCH_ROCKCHIP || \
ARCH_SUNXI || RISCV || ARCH_ZYNQMP)
default "u-boot.kwb" if (ARCH_KIRKWOOD || ARMADA_32BIT) && !SPL
default "u-boot-with-spl.bin" if MPC85xx && !E500MC && !E5500 && !E6500 && SPL
default "u-boot-with-spl.bin" if ARCH_AT91 && SPL_NAND_SUPPORT
default "u-boot-with-spl.imx" if ARCH_MX6 && SPL
help
Some SoCs need special image types (e.g. U-Boot binary
with a special header) as build targets. By defining
@ -575,14 +575,6 @@ config MP
This provides an option to bringup different processors
in multiprocessor cases.
config EXAMPLES
bool "Compile API examples"
depends on !SANDBOX
default y if ARCH_QEMU
help
U-Boot provides an API for standalone applications. Examples are
provided in directory examples/.
endmenu # General setup
source "api/Kconfig"

View file

@ -1249,6 +1249,12 @@ M: Heiko Schocher <hs@denx.de>
S: Maintained
F: drivers/pci/pci_mpc85xx.c
PCI MPS
M: Stephen Carlson <stcarlso@linux.microsoft.com>
S: Maintained
F: cmd/pci_mps.c
F: test/cmd/pci_mps.c
POWER
M: Jaehoon Chung <jh80.chung@samsung.com>
S: Maintained

View file

@ -10,9 +10,16 @@ config SYS_MMC_MAX_DEVICE
depends on API
default 1
endmenu
config EXAMPLES
bool "Compile API examples"
depends on !SANDBOX
default y if ARCH_QEMU
help
U-Boot provides an API for standalone applications. Examples are
provided in directory examples/.
config STANDALONE_LOAD_ADDR
depends on EXAMPLES
hex "Address in memory to link standalone applications to"
default 0xffffffff80200000 if MIPS && 64BIT
default 0x8c000000 if SH
@ -30,3 +37,5 @@ config STANDALONE_LOAD_ADDR
This option defines a board specific value for the address where
standalone program gets loaded, thus overwriting the architecture
dependent default settings.
endmenu

View file

@ -1004,7 +1004,9 @@ int image_locate_script(void *buf, int size, const char *fit_uname,
switch (genimg_get_format(buf)) {
case IMAGE_FORMAT_LEGACY:
if (IS_ENABLED(CONFIG_LEGACY_IMAGE_FORMAT)) {
if (!IS_ENABLED(CONFIG_LEGACY_IMAGE_FORMAT)) {
goto exit_image_format;
} else {
hdr = buf;
if (!image_check_magic(hdr)) {
@ -1047,7 +1049,9 @@ int image_locate_script(void *buf, int size, const char *fit_uname,
}
break;
case IMAGE_FORMAT_FIT:
if (IS_ENABLED(CONFIG_FIT)) {
if (!IS_ENABLED(CONFIG_FIT)) {
goto exit_image_format;
} else {
fit_hdr = buf;
if (fit_check_format(fit_hdr, IMAGE_SIZE_INVAL)) {
puts("Bad FIT image format\n");
@ -1121,12 +1125,15 @@ fallback:
}
break;
default:
puts("Wrong image format for \"source\" command\n");
return -EPERM;
goto exit_image_format;
}
*datap = (char *)data;
*lenp = len;
return 0;
exit_image_format:
puts("Wrong image format for \"source\" command\n");
return -EPERM;
}

View file

@ -1396,6 +1396,16 @@ config CMD_PCI
peripherals. Sub-commands allow bus enumeration, displaying and
changing configuration space and a few other features.
config CMD_PCI_MPS
bool "pci_mps - Configure PCI device MPS"
depends on PCI
help
Enables PCI Express Maximum Packet Size (MPS) tuning. This
command configures the PCI Express MPS of each endpoint to the
largest value supported by all devices below the root complex.
The Maximum Read Request Size will not be altered. This method is
the same algorithm as used by Linux pci=pcie_bus_safe.
config CMD_PINMUX
bool "pinmux - show pins muxing"
depends on PINCTRL
@ -1542,6 +1552,12 @@ config CMD_USB_MASS_STORAGE
export a block device: U-Boot, the USB device, acts as a simple
external hard drive plugged on the host USB port.
config CMD_UMS_ABORT_KEYED
bool "UMS abort with any key"
depends on CMD_USB_MASS_STORAGE
help
Allow interruption of usb mass storage run with any key pressed.
config CMD_PVBLOCK
bool "Xen para-virtualized block device"
depends on XEN

View file

@ -131,6 +131,7 @@ obj-$(CONFIG_CMD_PART) += part.o
obj-$(CONFIG_CMD_PCAP) += pcap.o
ifdef CONFIG_PCI
obj-$(CONFIG_CMD_PCI) += pci.o
obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o
endif
obj-$(CONFIG_CMD_PINMUX) += pinmux.o
obj-$(CONFIG_CMD_PMC) += pmc.o

View file

@ -1025,6 +1025,7 @@ static int do_env_indirect(struct cmd_tbl *cmdtp, int flag,
char *from = argv[2];
char *default_value = NULL;
int ret = 0;
char *val;
if (argc < 3 || argc > 4) {
return CMD_RET_USAGE;
@ -1034,18 +1035,14 @@ static int do_env_indirect(struct cmd_tbl *cmdtp, int flag,
default_value = argv[3];
}
if (env_get(from) == NULL && default_value == NULL) {
val = env_get(from) ?: default_value;
if (!val) {
printf("## env indirect: Environment variable for <from> (%s) does not exist.\n", from);
return CMD_RET_FAILURE;
}
if (env_get(from) == NULL) {
ret = env_set(to, default_value);
}
else {
ret = env_set(to, env_get(from));
}
ret = env_set(to, val);
if (ret == 0) {
return CMD_RET_SUCCESS;

164
cmd/pci_mps.c Normal file
View file

@ -0,0 +1,164 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2022 Microsoft Corporation <www.microsoft.com>
* Stephen Carlson <stcarlso@linux.microsoft.com>
*
* PCI Express Maximum Packet Size (MPS) configuration
*/
#include <common.h>
#include <bootretry.h>
#include <cli.h>
#include <command.h>
#include <console.h>
#include <dm.h>
#include <init.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <pci.h>
#define PCI_MPS_SAFE 0
#define PCI_MPS_PEER2PEER 1
static int pci_mps_find_safe(struct udevice *bus, unsigned int *min_mps,
unsigned int *n)
{
struct udevice *dev;
int res = 0, addr;
unsigned int mpss;
u32 regval;
if (!min_mps || !n)
return -EINVAL;
for (device_find_first_child(bus, &dev);
dev;
device_find_next_child(&dev)) {
addr = dm_pci_find_capability(dev, PCI_CAP_ID_EXP);
if (addr <= 0)
continue;
res = dm_pci_read_config32(dev, addr + PCI_EXP_DEVCAP,
&regval);
if (res != 0)
return res;
mpss = (unsigned int)(regval & PCI_EXP_DEVCAP_PAYLOAD);
*n += 1;
if (mpss < *min_mps)
*min_mps = mpss;
}
return res;
}
static int pci_mps_set_bus(struct udevice *bus, unsigned int target)
{
struct udevice *dev;
u32 mpss, target_mps = (u32)(target << 5);
u16 mps;
int res = 0, addr;
for (device_find_first_child(bus, &dev);
dev && res == 0;
device_find_next_child(&dev)) {
addr = dm_pci_find_capability(dev, PCI_CAP_ID_EXP);
if (addr <= 0)
continue;
res = dm_pci_read_config32(dev, addr + PCI_EXP_DEVCAP,
&mpss);
if (res != 0)
return res;
/* Do not set device above its maximum MPSS */
mpss = (mpss & PCI_EXP_DEVCAP_PAYLOAD) << 5;
if (target_mps < mpss)
mps = (u16)target_mps;
else
mps = (u16)mpss;
res = dm_pci_clrset_config16(dev, addr + PCI_EXP_DEVCTL,
PCI_EXP_DEVCTL_PAYLOAD, mps);
}
return res;
}
/*
* Sets the MPS of each PCI Express device to the specified policy.
*/
static int pci_mps_set(int policy)
{
struct udevice *bus;
int i, res = 0;
/* 0 = 128B, min value for hotplug */
unsigned int mps = 0;
if (policy == PCI_MPS_SAFE) {
unsigned int min_mps = PCI_EXP_DEVCAP_PAYLOAD_4096B, n = 0;
/* Find maximum MPS supported by all devices */
for (i = 0;
uclass_get_device_by_seq(UCLASS_PCI, i, &bus) == 0 &&
res == 0;
i++)
res = pci_mps_find_safe(bus, &min_mps, &n);
/* If no devices were found, do not reconfigure */
if (n == 0)
return res;
mps = min_mps;
}
/* This message is checked by the sandbox test */
printf("Setting MPS of all devices to %uB\n", 128U << mps);
for (i = 0;
uclass_get_device_by_seq(UCLASS_PCI, i, &bus) == 0 && res == 0;
i++)
res = pci_mps_set_bus(bus, mps);
return res;
}
/*
* PCI MPS tuning commands
*
* Syntax:
* pci_mps safe
* pci_mps peer2peer
*/
static int do_pci_mps(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
char cmd = 'u';
int ret = 0;
if (argc > 1)
cmd = argv[1][0];
switch (cmd) {
case 's': /* safe */
ret = pci_mps_set(PCI_MPS_SAFE);
break;
case 'p': /* peer2peer/hotplug */
ret = pci_mps_set(PCI_MPS_PEER2PEER);
break;
default: /* usage, help */
goto usage;
}
return ret;
usage:
return CMD_RET_USAGE;
}
/***************************************************/
#ifdef CONFIG_SYS_LONGHELP
static char pci_mps_help_text[] =
"safe\n"
" - Set PCI Express MPS of all devices to safe values\n"
"pci_mps peer2peer\n"
" - Set PCI Express MPS of all devices to support hotplug and peer-to-peer DMA\n";
#endif
U_BOOT_CMD(pci_mps, 2, 0, do_pci_mps,
"configure PCI Express MPS", pci_mps_help_text);

View file

@ -231,6 +231,16 @@ static int do_usb_mass_storage(struct cmd_tbl *cmdtp, int flag,
goto cleanup_register;
}
if (IS_ENABLED(CONFIG_CMD_UMS_ABORT_KEYED)) {
/* Abort by pressing any key */
if (tstc()) {
getchar();
printf("\rOperation aborted.\n");
rc = CMD_RET_SUCCESS;
goto cleanup_register;
}
}
schedule();
}

View file

@ -8,6 +8,8 @@
* JinHua Luo, GuangDong Linux Center, <luo.jinhua@gd-linux.com>
*/
#define pr_fmt(fmt) "cli: %s: " fmt, __func__
#include <common.h>
#include <bootstage.h>
#include <cli.h>
@ -20,6 +22,7 @@
#include <malloc.h>
#include <asm/global_data.h>
#include <dm/ofnode.h>
#include <linux/errno.h>
#ifdef CONFIG_CMDLINE
/*
@ -129,16 +132,26 @@ int run_command_list(const char *cmd, int len, int flag)
int run_commandf(const char *fmt, ...)
{
va_list args;
char cmd[128];
int i, ret;
int nbytes;
va_start(args, fmt);
i = vsnprintf(cmd, sizeof(cmd), fmt, args);
/*
* Limit the console_buffer space being used to CONFIG_SYS_CBSIZE,
* because its last byte is used to fit the replacement of \0 by \n\0
* in underlying hush parser
*/
nbytes = vsnprintf(console_buffer, CONFIG_SYS_CBSIZE, fmt, args);
va_end(args);
ret = run_command(cmd, 0);
return ret;
if (nbytes < 0) {
pr_debug("I/O internal error occurred.\n");
return -EIO;
} else if (nbytes >= CONFIG_SYS_CBSIZE) {
pr_debug("'fmt' size:%d exceeds the limit(%d)\n",
nbytes, CONFIG_SYS_CBSIZE);
return -ENOSPC;
}
return run_command(console_buffer, 0);
}
/****************************************************************************/

View file

@ -78,6 +78,7 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_MUX=y
CONFIG_CMD_OSD=y
CONFIG_CMD_PCI=y
CONFIG_CMD_PCI_MPS=y
CONFIG_CMD_READ=y
CONFIG_CMD_REMOTEPROC=y
CONFIG_CMD_SPI=y
@ -268,6 +269,7 @@ CONFIG_SANDBOX_RESET=y
CONFIG_RESET_SYSCON=y
CONFIG_RESET_SCMI=y
CONFIG_DM_RTC=y
CONFIG_RTC_MAX313XX=y
CONFIG_RTC_RV8803=y
CONFIG_RTC_HT1380=y
CONFIG_SCSI=y

View file

@ -18,7 +18,6 @@ CONFIG_SYS_MONITOR_LEN=786432
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_BOOTDELAY=1
CONFIG_AUTOBOOT_KEYED=y

View file

@ -65,26 +65,38 @@ int part_create_block_devices(struct udevice *blk_dev)
return 0;
}
static int blk_part_setup(struct udevice *dev, lbaint_t *startp,
lbaint_t blkcnt)
{
struct disk_part *part;
part = dev_get_uclass_plat(dev);
if (*startp >= part->gpt_part_info.size)
return -E2BIG;
if (*startp + blkcnt > part->gpt_part_info.size)
blkcnt = part->gpt_part_info.size - *startp;
*startp += part->gpt_part_info.start;
return 0;
}
static ulong part_blk_read(struct udevice *dev, lbaint_t start,
lbaint_t blkcnt, void *buffer)
{
struct udevice *parent;
struct disk_part *part;
const struct blk_ops *ops;
int ret;
parent = dev_get_parent(dev);
ops = blk_get_ops(parent);
if (!ops->read)
return -ENOSYS;
part = dev_get_uclass_plat(dev);
if (start >= part->gpt_part_info.size)
ret = blk_part_setup(dev, &start, blkcnt);
if (ret)
return 0;
if ((start + blkcnt) > part->gpt_part_info.size)
blkcnt = part->gpt_part_info.size - start;
start += part->gpt_part_info.start;
return ops->read(parent, start, blkcnt, buffer);
}
@ -92,22 +104,18 @@ static ulong part_blk_write(struct udevice *dev, lbaint_t start,
lbaint_t blkcnt, const void *buffer)
{
struct udevice *parent;
struct disk_part *part;
const struct blk_ops *ops;
int ret;
parent = dev_get_parent(dev);
ops = blk_get_ops(parent);
if (!ops->write)
return -ENOSYS;
part = dev_get_uclass_plat(dev);
if (start >= part->gpt_part_info.size)
ret = blk_part_setup(dev, &start, blkcnt);
if (ret)
return 0;
if ((start + blkcnt) > part->gpt_part_info.size)
blkcnt = part->gpt_part_info.size - start;
start += part->gpt_part_info.start;
return ops->write(parent, start, blkcnt, buffer);
}
@ -115,22 +123,18 @@ static ulong part_blk_erase(struct udevice *dev, lbaint_t start,
lbaint_t blkcnt)
{
struct udevice *parent;
struct disk_part *part;
const struct blk_ops *ops;
int ret;
parent = dev_get_parent(dev);
ops = blk_get_ops(parent);
if (!ops->erase)
return -ENOSYS;
part = dev_get_uclass_plat(dev);
if (start >= part->gpt_part_info.size)
ret = blk_part_setup(dev, &start, blkcnt);
if (ret)
return 0;
if ((start + blkcnt) > part->gpt_part_info.size)
blkcnt = part->gpt_part_info.size - start;
start += part->gpt_part_info.start;
return ops->erase(parent, start, blkcnt);
}

View file

@ -1171,6 +1171,13 @@ int gpio_request_by_line_name(struct udevice *dev, const char *line_name,
{
int ret;
if (!dev) {
uclass_foreach_dev_probe(UCLASS_GPIO, dev)
if (!gpio_request_by_line_name(dev, line_name, desc, flags))
return 0;
return -ENOENT;
}
ret = dev_read_stringlist_search(dev, "gpio-line-names", line_name);
if (ret < 0)
return ret;

View file

@ -48,8 +48,8 @@ config APPLE_SPI_KEYB
config BUTTON_KEYBOARD
bool "Buttons as keyboard"
depends on BUTTON_GPIO
depends on DM_KEYBOARD
select BUTTON_GPIO
help
Enable support for mapping buttons to keycode events. Use linux,code button driver
dt node to define button-event mapping.

View file

@ -111,16 +111,14 @@ static int button_kbd_probe(struct udevice *dev)
return 0;
}
static const struct udevice_id button_kbd_ids[] = {
{ .compatible = "button-kbd" },
{ }
};
U_BOOT_DRIVER(button_kbd) = {
.name = "button_kbd",
.id = UCLASS_KEYBOARD,
.of_match = button_kbd_ids,
.ops = &button_kbd_ops,
.priv_auto = sizeof(struct button_kbd_priv),
.probe = button_kbd_probe,
};
U_BOOT_DRVINFO(button_kbd) = {
.name = "button_kbd"
};

View file

@ -165,6 +165,9 @@ static int sandbox_swap_case_read_config(const struct udevice *emul,
case PCI_CAP_ID_EXP_OFFSET + PCI_CAP_LIST_NEXT:
*valuep = PCI_CAP_ID_MSIX_OFFSET;
break;
case PCI_CAP_ID_EXP_OFFSET + PCI_EXP_DEVCAP:
*valuep = PCI_EXP_DEVCAP_PAYLOAD_256B;
break;
case PCI_CAP_ID_MSIX_OFFSET:
if (sandbox_swap_case_use_ea(emul))
*valuep = (PCI_CAP_ID_EA_OFFSET << 8) | PCI_CAP_ID_MSIX;

View file

@ -134,6 +134,19 @@ config RTC_ISL1208
This driver supports reading and writing the RTC/calendar and detects
total power failures.
config RTC_MAX313XX
bool "Analog Devices MAX313XX RTC driver"
depends on DM_RTC
depends on DM_I2C
help
If you say yes here you will get support for the
Analog Devices MAX313XX series RTC family.
Chip features not currently supported:
- Timestamp registers as SRAM
- Temperature sensor
- CLKOUT generation
config RTC_PCF8563
tristate "Philips PCF8563"
help

View file

@ -19,6 +19,7 @@ obj-$(CONFIG_RTC_HT1380) += ht1380.o
obj-$(CONFIG_$(SPL_TPL_)RTC_SANDBOX) += i2c_rtc_emul.o
obj-$(CONFIG_RTC_ISL1208) += isl1208.o
obj-$(CONFIG_RTC_M41T62) += m41t62.o
obj-$(CONFIG_RTC_MAX313XX) += max313xx.o
obj-$(CONFIG_RTC_MC13XXX) += mc13xxx-rtc.o
obj-$(CONFIG_RTC_MC146818) += mc146818.o
obj-$(CONFIG_MCFRTC) += mcfrtc.o

View file

@ -283,6 +283,16 @@ static int m41t62_rtc_reset(struct udevice *dev)
return m41t62_sqw_enable(dev, true);
}
static int m41t62_rtc_read8(struct udevice *dev, unsigned int reg)
{
return dm_i2c_reg_read(dev, reg);
}
static int m41t62_rtc_write8(struct udevice *dev, unsigned int reg, int val)
{
return dm_i2c_reg_write(dev, reg, val);
}
/*
* Make sure HT bit is cleared. This bit is set on entering battery backup
* mode, so do this before the first read access.
@ -296,6 +306,8 @@ static const struct rtc_ops m41t62_rtc_ops = {
.get = m41t62_rtc_get,
.set = m41t62_rtc_set,
.reset = m41t62_rtc_reset,
.read8 = m41t62_rtc_read8,
.write8 = m41t62_rtc_write8,
};
static const struct udevice_id m41t62_rtc_ids[] = {

459
drivers/rtc/max313xx.c Normal file
View file

@ -0,0 +1,459 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Analog Devices MAX313XX series I2C RTC driver
*
* Copyright 2022 Analog Devices Inc.
*/
#include <bcd.h>
#include <dm.h>
#include <i2c.h>
#include <rtc.h>
#include <dm/device_compat.h>
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/kernel.h>
/* common registers */
#define MAX313XX_INT_ALARM1 BIT(0)
#define MAX313XX_INT_ALARM2 BIT(1)
#define MAX313XX_HRS_F_12_24 BIT(6)
#define MAX313XX_HRS_F_AM_PM BIT(5)
#define MAX313XX_MONTH_CENTURY BIT(7)
#define MAX313XX_TMR_CFG_ENABLE BIT(4)
#define MAX313XX_TMR_CFG_FREQ_MASK GENMASK(1, 0)
#define MAX313XX_TMR_CFG_FREQ_16HZ 0x03
#define MAX313XX_REG_MINUTE 0x01
#define MAX313XX_REG_HOUR 0x02
#define MAX313XX_TIME_SIZE 0x07
/* device specific registers */
#define MAX3134X_CFG2_REG 0x01
#define MAX3134X_CFG2_SET_RTC BIT(1)
#define MAX31341_TRICKLE_RES_MASK GENMASK(1, 0)
#define MAX31341_TRICKLE_DIODE_EN BIT(2)
#define MAX31341_TRICKLE_ENABLE_BIT BIT(3)
#define MAX31341_POWER_MGMT_REG 0x56
#define MAX31341_POWER_MGMT_TRICKLE_BIT BIT(0)
#define MAX3133X_TRICKLE_RES_MASK GENMASK(2, 1)
#define MAX3133X_TRICKLE_DIODE_EN BIT(3)
#define MAX3133X_TRICKLE_ENABLE_BIT BIT(0)
#define MAX31329_TRICKLE_ENABLE_BIT BIT(7)
#define MAX31343_TRICKLE_ENABLE_MASK GENMASK(7, 4)
#define MAX31343_TRICKLE_ENABLE_CODE 5
#define MAX31329_43_TRICKLE_RES_MASK GENMASK(1, 0)
#define MAX31329_43_TRICKLE_DIODE_EN BIT(2)
#define MAX31329_CONFIG2_REG 0x04
#define MAX31329_CONFIG2_CLKIN_EN BIT(2)
#define MAX31329_CONFIG2_CLKIN_FREQ GENMASK(1, 0)
#define MAX31341_42_CONFIG1_REG 0x00
#define MAX31341_42_CONFIG1_CLKIN_EN BIT(7)
#define MAX31341_42_CONFIG1_CLKIN_FREQ GENMASK(5, 4)
#define MAX31341_42_CONFIG1_OSC_DISABLE BIT(3)
#define MAX31341_42_CONFIG1_SWRST BIT(0)
enum max313xx_ids {
ID_MAX31328,
ID_MAX31329,
ID_MAX31331,
ID_MAX31334,
ID_MAX31341,
ID_MAX31342,
ID_MAX31343,
MAX313XX_ID_NR
};
/**
* struct chip_desc - descriptor for MAX313xx variants
* @sec_reg: Offset to seconds register. Used to denote the start of the
* current time registers.
* @alarm1_sec_reg: Offset to Alarm1 seconds register. Used to denote the
* start of the alarm registers.
* @int_en_reg: Offset to the interrupt enable register.
* @int_status_reg: Offset to the interrupt status register.
* @ram_reg: Offset to the timestamp RAM (which can be used as SRAM).
* @ram_size: Size of the timestamp RAM.
* @temp_reg: Offset to the temperature register (or 0 if temperature
* sensor is not supported).
* @trickle_reg: Offset to the trickle charger configuration register (or
* 0 if trickle charger is not supported).
* @rst_reg: Offset to the reset register.
* @rst_bit: Bit within the reset register for the software reset.
*/
struct chip_desc {
u8 sec_reg;
u8 alarm1_sec_reg;
u8 int_en_reg;
u8 int_status_reg;
u8 ram_reg;
u8 ram_size;
u8 temp_reg;
u8 trickle_reg;
u8 rst_reg;
u8 rst_bit;
};
struct max313xx_priv {
enum max313xx_ids id;
const struct chip_desc *chip;
};
static const struct chip_desc chip[MAX313XX_ID_NR] = {
[ID_MAX31328] = {
.int_en_reg = 0x0E,
.int_status_reg = 0x0F,
.sec_reg = 0x00,
.alarm1_sec_reg = 0x07,
.temp_reg = 0x11,
},
[ID_MAX31329] = {
.int_en_reg = 0x01,
.int_status_reg = 0x00,
.sec_reg = 0x06,
.alarm1_sec_reg = 0x0D,
.ram_reg = 0x22,
.ram_size = 64,
.trickle_reg = 0x19,
.rst_reg = 0x02,
.rst_bit = BIT(0),
},
[ID_MAX31331] = {
.int_en_reg = 0x01,
.int_status_reg = 0x00,
.sec_reg = 0x08,
.alarm1_sec_reg = 0x0F,
.ram_reg = 0x20,
.ram_size = 32,
.trickle_reg = 0x1B,
.rst_reg = 0x02,
.rst_bit = BIT(0),
},
[ID_MAX31334] = {
.int_en_reg = 0x01,
.int_status_reg = 0x00,
.sec_reg = 0x09,
.alarm1_sec_reg = 0x10,
.ram_reg = 0x30,
.ram_size = 32,
.trickle_reg = 0x1E,
.rst_reg = 0x02,
.rst_bit = BIT(0),
},
[ID_MAX31341] = {
.int_en_reg = 0x04,
.int_status_reg = 0x05,
.sec_reg = 0x06,
.alarm1_sec_reg = 0x0D,
.ram_reg = 0x16,
.ram_size = 64,
.trickle_reg = 0x57,
.rst_reg = 0x00,
.rst_bit = BIT(0),
},
[ID_MAX31342] = {
.int_en_reg = 0x04,
.int_status_reg = 0x05,
.sec_reg = 0x06,
.alarm1_sec_reg = 0x0D,
.rst_reg = 0x00,
.rst_bit = BIT(0),
},
[ID_MAX31343] = {
.int_en_reg = 0x01,
.int_status_reg = 0x00,
.sec_reg = 0x06,
.alarm1_sec_reg = 0x0D,
.ram_reg = 0x22,
.ram_size = 64,
.temp_reg = 0x1A,
.trickle_reg = 0x19,
.rst_reg = 0x02,
.rst_bit = BIT(0),
},
};
static const u32 max313xx_trickle_ohms[] = { 3000, 6000, 11000 };
static int max313xx_set_bits(struct udevice *dev, unsigned int reg, unsigned int bits)
{
int ret;
ret = dm_i2c_reg_read(dev, reg);
if (ret < 0)
return ret;
return dm_i2c_reg_write(dev, reg, ret | bits);
}
static int max313xx_clear_bits(struct udevice *dev, unsigned int reg, unsigned int bits)
{
int ret;
ret = dm_i2c_reg_read(dev, reg);
if (ret < 0)
return ret;
return dm_i2c_reg_write(dev, reg, ret & ~bits);
}
static int max313xx_get_hour(u8 hour_reg)
{
int hour;
/* 24Hr mode */
if (!FIELD_GET(MAX313XX_HRS_F_12_24, hour_reg))
return bcd2bin(hour_reg & 0x3f);
/* 12Hr mode */
hour = bcd2bin(hour_reg & 0x1f);
if (hour == 12)
hour = 0;
if (FIELD_GET(MAX313XX_HRS_F_AM_PM, hour_reg))
hour += 12;
return hour;
}
static int max313xx_read_time(struct udevice *dev, struct rtc_time *t)
{
struct max313xx_priv *rtc = dev_get_priv(dev);
u8 regs[7];
int ret;
ret = dm_i2c_read(dev, rtc->chip->sec_reg, regs, 7);
if (ret)
return ret;
t->tm_sec = bcd2bin(regs[0] & 0x7f);
t->tm_min = bcd2bin(regs[1] & 0x7f);
t->tm_hour = max313xx_get_hour(regs[2]);
t->tm_wday = bcd2bin(regs[3] & 0x07) - 1;
t->tm_mday = bcd2bin(regs[4] & 0x3f);
t->tm_mon = bcd2bin(regs[5] & 0x1f);
t->tm_year = bcd2bin(regs[6]) + 2000;
if (FIELD_GET(MAX313XX_MONTH_CENTURY, regs[5]))
t->tm_year += 100;
dev_dbg(dev, "read %4d-%02d-%02d (wday=%d) %2d:%02d:%02d\n",
t->tm_year, t->tm_mon, t->tm_mday,
t->tm_wday, t->tm_hour, t->tm_min, t->tm_sec);
return 0;
}
static int max313xx_set_time(struct udevice *dev, const struct rtc_time *t)
{
struct max313xx_priv *rtc = dev_get_priv(dev);
u8 regs[7];
int ret;
dev_dbg(dev, "set %4d-%02d-%02d (wday=%d) %2d:%02d:%02d\n",
t->tm_year, t->tm_mon, t->tm_mday,
t->tm_wday, t->tm_hour, t->tm_min, t->tm_sec);
if (t->tm_year < 2000) {
dev_err(dev, "year %d (before 2000) not supported\n",
t->tm_year);
return -EINVAL;
}
if (rtc->chip->rst_bit) {
ret = max313xx_clear_bits(dev, rtc->chip->rst_reg, rtc->chip->rst_bit);
if (ret)
return ret;
}
regs[0] = bin2bcd(t->tm_sec);
regs[1] = bin2bcd(t->tm_min);
regs[2] = bin2bcd(t->tm_hour);
regs[3] = bin2bcd(t->tm_wday + 1);
regs[4] = bin2bcd(t->tm_mday);
regs[5] = bin2bcd(t->tm_mon);
regs[6] = bin2bcd((t->tm_year - 2000) % 100);
if ((t->tm_year - 2000) >= 200)
regs[5] |= FIELD_PREP(MAX313XX_MONTH_CENTURY, 1);
ret = dm_i2c_write(dev, rtc->chip->sec_reg, regs, 7);
if (ret)
return ret;
switch (rtc->id) {
case ID_MAX31341:
case ID_MAX31342:
ret = max313xx_set_bits(dev, MAX3134X_CFG2_REG,
MAX3134X_CFG2_SET_RTC);
if (ret)
return ret;
udelay(10000);
ret = max313xx_clear_bits(dev, MAX3134X_CFG2_REG,
MAX3134X_CFG2_SET_RTC);
if (ret)
return ret;
break;
default:
break;
}
return ret;
}
static int max313xx_reset(struct udevice *dev)
{
struct max313xx_priv *rtc = dev_get_priv(dev);
int ret = -EINVAL;
if (rtc->chip->rst_bit)
ret = max313xx_set_bits(dev, rtc->chip->rst_reg, rtc->chip->rst_bit);
return ret;
}
static const struct rtc_ops max3133x_rtc_ops = {
.get = max313xx_read_time,
.set = max313xx_set_time,
.reset = max313xx_reset,
};
static int max313xx_init(struct udevice *dev)
{
struct max313xx_priv *rtc = dev_get_priv(dev);
int ret;
switch (rtc->id) {
case ID_MAX31341:
case ID_MAX31342:
ret = max313xx_clear_bits(dev, MAX31341_42_CONFIG1_REG,
MAX31341_42_CONFIG1_OSC_DISABLE);
if (ret)
return ret;
return max313xx_set_bits(dev, MAX31341_42_CONFIG1_REG,
MAX31341_42_CONFIG1_SWRST);
default:
return 0;
}
}
static int max313xx_trickle_charger_setup(struct udevice *dev)
{
struct max313xx_priv *rtc = dev_get_priv(dev);
bool diode;
int index, reg;
u32 ohms;
u32 chargeable;
int ret;
if (dev_read_u32(dev, "trickle-resistor-ohms", &ohms) ||
dev_read_u32(dev, "aux-voltage-chargeable", &chargeable))
return 0;
switch (chargeable) {
case 0:
diode = false;
break;
case 1:
diode = true;
break;
default:
dev_dbg(dev, "unsupported aux-voltage-chargeable value\n");
return -EINVAL;
}
if (!rtc->chip->trickle_reg) {
dev_warn(dev, "device does not have trickle charger\n");
return -ENOTSUPP;
}
index = find_closest(ohms, max313xx_trickle_ohms,
ARRAY_SIZE(max313xx_trickle_ohms)) + 1;
switch (rtc->id) {
case ID_MAX31329:
reg = FIELD_PREP(MAX31329_TRICKLE_ENABLE_BIT, 1) |
FIELD_PREP(MAX31329_43_TRICKLE_RES_MASK, index) |
FIELD_PREP(MAX31329_43_TRICKLE_DIODE_EN, diode);
break;
case ID_MAX31331:
case ID_MAX31334:
reg = FIELD_PREP(MAX3133X_TRICKLE_ENABLE_BIT, 1) |
FIELD_PREP(MAX3133X_TRICKLE_DIODE_EN, diode) |
FIELD_PREP(MAX3133X_TRICKLE_RES_MASK, index);
break;
case ID_MAX31341:
if (index == 1)
index = 0;
reg = FIELD_PREP(MAX31341_TRICKLE_ENABLE_BIT, 1) |
FIELD_PREP(MAX31341_TRICKLE_DIODE_EN, diode) |
FIELD_PREP(MAX31341_TRICKLE_RES_MASK, index);
ret = max313xx_set_bits(dev, MAX31341_POWER_MGMT_REG,
MAX31341_POWER_MGMT_TRICKLE_BIT);
if (ret)
return ret;
break;
case ID_MAX31343:
reg = FIELD_PREP(MAX31329_43_TRICKLE_RES_MASK, index) |
FIELD_PREP(MAX31329_43_TRICKLE_DIODE_EN, diode) |
FIELD_PREP(MAX31343_TRICKLE_ENABLE_MASK,
MAX31343_TRICKLE_ENABLE_CODE);
break;
default:
return -EOPNOTSUPP;
}
return dm_i2c_reg_write(dev, rtc->chip->trickle_reg, reg);
}
static int max313xx_probe(struct udevice *dev)
{
struct max313xx_priv *max313xx = dev_get_priv(dev);
int ret;
max313xx->id = dev_get_driver_data(dev);
max313xx->chip = &chip[max313xx->id];
ret = max313xx_init(dev);
if (ret)
return ret;
return max313xx_trickle_charger_setup(dev);
}
static const struct udevice_id max313xx_of_id[] = {
{ .compatible = "adi,max31328", .data = ID_MAX31328 },
{ .compatible = "adi,max31329", .data = ID_MAX31329 },
{ .compatible = "adi,max31331", .data = ID_MAX31331 },
{ .compatible = "adi,max31334", .data = ID_MAX31334 },
{ .compatible = "adi,max31341", .data = ID_MAX31341 },
{ .compatible = "adi,max31342", .data = ID_MAX31342 },
{ .compatible = "adi,max31343", .data = ID_MAX31343 },
{ }
};
U_BOOT_DRIVER(rtc_max313xx) = {
.name = "rtc-max313xx",
.id = UCLASS_RTC,
.probe = max313xx_probe,
.of_match = max313xx_of_id,
.priv_auto = sizeof(struct max313xx_priv),
.ops = &max3133x_rtc_ops,
};

View file

@ -57,7 +57,7 @@ static int sysinfo_gpio_get_str(struct udevice *dev, int id, size_t size, char *
int i, ret;
u32 revision;
for (i = 0; i < priv->gpio_num; i++) {
for (i = 0; ; i++) {
ret = dev_read_u32_index(dev, "revisions", i,
&revision);
if (ret) {
@ -80,7 +80,8 @@ static int sysinfo_gpio_get_str(struct udevice *dev, int id, size_t size, char *
strncpy(val, name, size);
val[size - 1] = '\0';
return 0;
} default:
}
default:
return -EINVAL;
};
}

View file

@ -473,7 +473,7 @@ static int ext4fs_delete_file(int inodeno)
* special case for symlinks whose target are small enough that
*it fits in struct ext2_inode.b.symlink: no block had been allocated
*/
if ((le16_to_cpu(inode.mode) & S_IFLNK) &&
if (S_ISLNK(le16_to_cpu(inode.mode)) &&
le32_to_cpu(inode.size) <= sizeof(inode.b.symlink)) {
no_blocks = 0;
}

View file

@ -141,6 +141,8 @@ static int set_name(fat_itr *itr, const char *filename, char *shortname)
if (!strcmp(buf, filename)) {
ret = 1;
goto out;
} else if (!strcasecmp(buf, filename)) {
goto out_ret;
}
/* Construct an indexed short name */
@ -177,12 +179,13 @@ static int set_name(fat_itr *itr, const char *filename, char *shortname)
if (find_directory_entry(itr, buf))
continue;
debug("chosen short name: %s\n", buf);
/* Each long name directory entry takes 13 characters. */
ret = (strlen(filename) + 25) / 13;
goto out;
goto out_ret;
}
return -EIO;
out_ret:
debug("chosen short name: %s\n", buf);
/* Each long name directory entry takes 13 characters. */
ret = (strlen(filename) + 25) / 13;
out:
memcpy(shortname, &dirent, SHORT_NAME_SIZE);
return ret;

View file

@ -580,7 +580,8 @@ int gpio_request_by_name(struct udevice *dev, const char *list_name,
* This allows boards to implement common behaviours using GPIOs while not
* requiring specific GPIO offsets be used.
*
* @dev: An instance of a GPIO controller udevice
* @dev: An instance of a GPIO controller udevice, or NULL to search
* all GPIO controller devices
* @line_name: The name of the GPIO (e.g. "bmc-secure-boot")
* @desc: A GPIO descriptor that is populated with the requested GPIO
* upon return

View file

@ -13,6 +13,8 @@
#include <env.h>
#include <linker_lists.h>
#include <linux/compiler_attributes.h>
#ifndef NULL
#define NULL 0
#endif
@ -260,12 +262,17 @@ int run_command_repeatable(const char *cmd, int flag);
/**
* run_commandf() - Run a command created by a format string
*
* The command cannot be larger than 127 characters
*
* @fmt: printf() format string
* @...: Arguments to use (flag is always 0)
*
* The command cannot be larger than (CONFIG_SYS_CBSIZE - 1) characters.
*
* Return:
* Returns 0 on success, -EIO if internal output error occurred, -ENOSPC in
* case of 'fmt' string truncation, or != 0 on error, specific for
* run_command().
*/
int run_commandf(const char *fmt, ...);
int run_commandf(const char *fmt, ...) __printf(1, 2);
/**
* Run a list of commands separated by ; or even \0

View file

@ -284,4 +284,28 @@
offsetof(struct structure, member) == (offset), \
"`struct " #structure "` offset for `" #member "` is not " #offset)
#define __find_closest(x, a, as, op) \
({ \
typeof(as) __fc_i, __fc_as = (as) - 1; \
typeof(x) __fc_x = (x); \
typeof(*a) const *__fc_a = (a); \
for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \
if (__fc_x op DIV_ROUND_CLOSEST(__fc_a[__fc_i] + \
__fc_a[__fc_i + 1], 2)) \
break; \
} \
(__fc_i); \
})
/**
* find_closest - locate the closest element in a sorted array
* @x: The reference value.
* @a: The array in which to look for the closest element. Must be sorted
* in ascending order.
* @as: Size of 'a'.
*
* Returns the index of the element closest to 'x'.
*/
#define find_closest(x, a, as) __find_closest(x, a, as, <=)
#endif

View file

@ -360,6 +360,13 @@
#define PCI_EXP_TYPE_PCIE_BRIDGE 0x8 /* PCI/PCI-X to PCIe Bridge */
#define PCI_EXP_DEVCAP 4 /* Device capabilities */
#define PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */
#define PCI_EXP_DEVCAP_PAYLOAD 0x0007 /* Max payload size supported */
#define PCI_EXP_DEVCAP_PAYLOAD_128B 0x0000 /* 128 Bytes */
#define PCI_EXP_DEVCAP_PAYLOAD_256B 0x0001 /* 256 Bytes */
#define PCI_EXP_DEVCAP_PAYLOAD_512B 0x0002 /* 512 Bytes */
#define PCI_EXP_DEVCAP_PAYLOAD_1024B 0x0003 /* 1024 Bytes */
#define PCI_EXP_DEVCAP_PAYLOAD_2048B 0x0004 /* 2048 Bytes */
#define PCI_EXP_DEVCAP_PAYLOAD_4096B 0x0005 /* 4096 Bytes */
#define PCI_EXP_DEVCTL 8 /* Device Control */
#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */
#define PCI_EXP_DEVCTL_PAYLOAD_128B 0x0000 /* 128 Bytes */

View file

@ -48,6 +48,8 @@ int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]);
int do_ut_pci_mps(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]);
int do_ut_print(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
int do_ut_seama(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
int do_ut_setexpr(struct cmd_tbl *cmdtp, int flag, int argc,

View file

@ -16,7 +16,7 @@ config SYS_NUM_ADDR_MAP
Sets the number of entries in the virtual-physical mapping table.
config SYS_TIMER_COUNTS_DOWN
bool "System timer counts down rathe than up"
bool "System timer counts down rather than up"
config PHYSMEM
bool "Access to physical memory region (> 4G)"

View file

@ -14,6 +14,9 @@ obj-$(CONFIG_CMD_FDT) += fdt.o
obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o
obj-$(CONFIG_CMD_LOADM) += loadm.o
obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o
ifdef CONFIG_CMD_PCI
obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o
endif
obj-$(CONFIG_CMD_PINMUX) += pinmux.o
obj-$(CONFIG_CMD_PWM) += pwm.o
obj-$(CONFIG_CMD_SEAMA) += seama.o

View file

@ -60,20 +60,20 @@ static int cmd_exit_test(struct unit_test_state *uts)
/* Validate that 'exit' behaves the same way as 'exit 0' */
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo ; echo $?", i));
ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo ; echo $?"));
ut_assert_nextline("bar");
ut_assert_nextline("0");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo && echo quux ; echo $?", i));
ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo && echo quux ; echo $?"));
ut_assert_nextline("bar");
ut_assert_nextline("quux");
ut_assert_nextline("0");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo || echo quux ; echo $?", i));
ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo || echo quux ; echo $?"));
ut_assert_nextline("bar");
/* Either 'exit' returns 0, or 'echo quux' returns 0 */
ut_assert_nextline("0");
@ -81,39 +81,39 @@ static int cmd_exit_test(struct unit_test_state *uts)
/* Validate that return value still propagates from 'run' command */
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo ; echo $?", i));
ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo ; echo $?"));
ut_assert_nextline("bar");
ut_assert_nextline("0");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo && echo quux ; echo $?", i));
ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo && echo quux ; echo $?"));
ut_assert_nextline("bar");
ut_assert_nextline("quux");
ut_assert_nextline("0");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo || echo quux ; echo $?", i));
ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo || echo quux ; echo $?"));
ut_assert_nextline("bar");
/* The 'true' returns 0 */
ut_assert_nextline("0");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo ; echo $?", i));
ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo ; echo $?"));
ut_assert_nextline("bar");
ut_assert_nextline("1");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo && echo quux ; echo $?", i));
ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo && echo quux ; echo $?"));
ut_assert_nextline("bar");
ut_assert_nextline("1");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo || echo quux ; echo $?", i));
ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo || echo quux ; echo $?"));
ut_assert_nextline("bar");
ut_assert_nextline("quux");
/* The 'echo quux' returns 0 */

View file

@ -175,7 +175,7 @@ static int fdt_test_addr(struct unit_test_state *uts)
/* Set the working FDT */
set_working_fdt_addr(0);
ut_assert_nextline("Working FDT set to 0");
ut_assertok(run_commandf("fdt addr %08x", addr));
ut_assertok(run_commandf("fdt addr %08lx", addr));
ut_assert_nextline("Working FDT set to %lx", addr);
ut_asserteq(addr, map_to_sysmem(working_fdt));
ut_assertok(ut_check_console_end(uts));
@ -185,7 +185,7 @@ static int fdt_test_addr(struct unit_test_state *uts)
/* Set the control FDT */
fdt_blob = gd->fdt_blob;
gd->fdt_blob = NULL;
ret = run_commandf("fdt addr -c %08x", addr);
ret = run_commandf("fdt addr -c %08lx", addr);
new_fdt = gd->fdt_blob;
gd->fdt_blob = fdt_blob;
ut_assertok(ret);
@ -194,7 +194,7 @@ static int fdt_test_addr(struct unit_test_state *uts)
/* Test setting an invalid FDT */
fdt[0] = 123;
ut_asserteq(1, run_commandf("fdt addr %08x", addr));
ut_asserteq(1, run_commandf("fdt addr %08lx", addr));
ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC");
ut_assertok(ut_check_console_end(uts));
@ -223,19 +223,19 @@ static int fdt_test_addr_resize(struct unit_test_state *uts)
/* Test setting and resizing the working FDT to a larger size */
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("fdt addr %08x %x", addr, newsize));
ut_assertok(run_commandf("fdt addr %08lx %x", addr, newsize));
ut_assert_nextline("Working FDT set to %lx", addr);
ut_assertok(ut_check_console_end(uts));
/* Try shrinking it */
ut_assertok(run_commandf("fdt addr %08x %x", addr, sizeof(fdt) / 4));
ut_assertok(run_commandf("fdt addr %08lx %zx", addr, sizeof(fdt) / 4));
ut_assert_nextline("Working FDT set to %lx", addr);
ut_assert_nextline("New length %d < existing length %d, ignoring",
(int)sizeof(fdt) / 4, newsize);
ut_assertok(ut_check_console_end(uts));
/* ...quietly */
ut_assertok(run_commandf("fdt addr -q %08x %x", addr, sizeof(fdt) / 4));
ut_assertok(run_commandf("fdt addr -q %08lx %zx", addr, sizeof(fdt) / 4));
ut_assert_nextline("Working FDT set to %lx", addr);
ut_assertok(ut_check_console_end(uts));
@ -265,13 +265,13 @@ static int fdt_test_move(struct unit_test_state *uts)
/* Test moving the working FDT to a new location */
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("fdt move %08x %08x %x", addr, newaddr, ts));
ut_assertok(run_commandf("fdt move %08lx %08lx %x", addr, newaddr, ts));
ut_assert_nextline("Working FDT set to %lx", newaddr);
ut_assertok(ut_check_console_end(uts));
/* Compare the source and destination DTs */
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("cmp.b %08x %08x %x", addr, newaddr, ts));
ut_assertok(run_commandf("cmp.b %08lx %08lx %x", addr, newaddr, ts));
ut_assert_nextline("Total of %d byte(s) were the same", ts);
ut_assertok(ut_check_console_end(uts));
@ -1406,7 +1406,7 @@ static int fdt_test_apply(struct unit_test_state *uts)
/* Test simple DTO application */
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("fdt apply 0x%08x", addro));
ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
ut_assertok(run_commandf("fdt print /"));
ut_assert_nextline("/ {");
ut_assert_nextline("\tnewstring = \"newvalue\";");
@ -1451,7 +1451,7 @@ static int fdt_test_apply(struct unit_test_state *uts)
/* Test complex DTO application */
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("fdt apply 0x%08x", addro));
ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
ut_assertok(run_commandf("fdt print /"));
ut_assert_nextline("/ {");
ut_assert_nextline("\tempty-property;");
@ -1495,7 +1495,7 @@ static int fdt_test_apply(struct unit_test_state *uts)
/* Test complex DTO application */
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("fdt apply 0x%08x", addro));
ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
ut_assertok(run_commandf("fdt print /"));
ut_assert_nextline("/ {");
ut_assert_nextline("\tempty-property;");

42
test/cmd/pci_mps.c Normal file
View file

@ -0,0 +1,42 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Tests that the PCI Maximum Payload Size (MPS) command can set the sandbox
* PCI Express device to safe mode and determine the correct payload size.
*
* Copyright 2023 Microsoft
* Written by Stephen Carlson <stcarlso@linux.microsoft.com>
*/
#include <common.h>
#include <console.h>
#include <test/suites.h>
#include <test/ut.h>
#define PCI_MPS_TEST(_name, _flags) UNIT_TEST(_name, _flags, pci_mps_test)
/* Test "pci_mps" command in safe "s" mode */
static int test_pci_mps_safe(struct unit_test_state *uts)
{
/* Enumerate PCI Express first */
ut_assertok(run_command("pci e", 0));
ut_assert_console_end();
/* Test pci_mps s */
ut_assertok(run_command("pci_mps s", 0));
ut_assert_nextline("Setting MPS of all devices to 256B");
ut_assert_console_end();
return 0;
}
PCI_MPS_TEST(test_pci_mps_safe, UT_TESTF_CONSOLE_REC);
int do_ut_pci_mps(struct cmd_tbl *cmdtp, int flag, int argc,
char * const argv[])
{
struct unit_test *tests = UNIT_TEST_SUITE_START(pci_mps_test);
const int n = UNIT_TEST_SUITE_COUNT(pci_mps_test);
return cmd_ut_category("cmd_pci_mps", "pci_mps_test_", tests, n,
argc, argv);
}

View file

@ -110,6 +110,9 @@ static struct cmd_tbl cmd_ut_sub[] = {
#ifdef CONFIG_CMD_LOADM
U_BOOT_CMD_MKENT(loadm, CONFIG_SYS_MAXARGS, 1, do_ut_loadm, "", ""),
#endif
#ifdef CONFIG_CMD_PCI_MPS
U_BOOT_CMD_MKENT(pci_mps, CONFIG_SYS_MAXARGS, 1, do_ut_pci_mps, "", ""),
#endif
#ifdef CONFIG_CMD_SEAMA
U_BOOT_CMD_MKENT(seama, CONFIG_SYS_MAXARGS, 1, do_ut_seama, "", ""),
#endif
@ -209,6 +212,9 @@ static char ut_help_text[] =
#endif
#ifdef CONFIG_UT_OVERLAY
"\noverlay - device tree overlays"
#endif
#ifdef CONFIG_CMD_PCI_MPS
"\npci_mps - PCI Express Maximum Payload Size"
#endif
"\nprint - printing things to the console"
"\nsetexpr - setexpr command"

View file

@ -9,6 +9,8 @@
#include <command.h>
#include <env.h>
#include <log.h>
#include <string.h>
#include <linux/errno.h>
static const char test_cmd[] = "setenv list 1\n setenv list ${list}2; "
"setenv list ${list}3\0"
@ -17,6 +19,8 @@ static const char test_cmd[] = "setenv list 1\n setenv list ${list}2; "
static int do_ut_cmd(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
char long_str[CONFIG_SYS_CBSIZE + 42];
printf("%s: Testing commands\n", __func__);
run_command("env default -f -a", 0);
@ -60,6 +64,36 @@ static int do_ut_cmd(struct cmd_tbl *cmdtp, int flag, int argc,
assert(run_command("'", 0) == 1);
/* Variadic function test-cases */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-zero-length"
assert(run_commandf("") == 0);
#pragma GCC diagnostic pop
assert(run_commandf(" ") == 0);
assert(run_commandf("'") == 1);
assert(run_commandf("env %s %s", "delete -f", "list") == 0);
/* Expected: "Error: "list" not defined" */
assert(run_commandf("printenv list") == 1);
memset(long_str, 'x', sizeof(long_str));
assert(run_commandf("Truncation case: %s", long_str) == -ENOSPC);
if (IS_ENABLED(CONFIG_HUSH_PARSER)) {
assert(run_commandf("env %s %s %s %s", "delete -f", "adder",
"black", "foo") == 0);
assert(run_commandf("setenv foo 'setenv %s 1\nsetenv %s 2'",
"black", "adder") == 0);
run_command("run foo", 0);
assert(env_get("black"));
assert(!strcmp("1", env_get("black")));
assert(env_get("adder"));
assert(!strcmp("2", env_get("adder")));
}
/* Clean up before exit */
run_command("env default -f -a", 0);
printf("%s: Everything went swimmingly\n", __func__);
return 0;
}

View file

@ -8,11 +8,24 @@
This test verifies extended write operation on file system.
"""
import os.path
import pytest
import re
from subprocess import check_output
from fstest_defs import *
from fstest_helpers import assert_fs_integrity
PLAIN_FILE='abcdefgh.txt'
MANGLE_FILE='abcdefghi.txt'
def str2fat(long_filename):
splitext = os.path.splitext(long_filename.upper())
name = splitext[0]
ext = splitext[1][1:]
if len(name) > 8:
name = '%s~1' % name[:6]
return '%-8s %s' % (name, ext)
@pytest.mark.boardspec('sandbox')
@pytest.mark.slow
class TestFsExt(object):
@ -317,3 +330,26 @@ class TestFsExt(object):
assert('FILE0123456789_79' in output)
assert_fs_integrity(fs_type, fs_img)
def test_fs_ext12(self, u_boot_console, fs_obj_ext):
"""
Test Case 12 - write plain and mangle file
"""
fs_type,fs_img,md5val = fs_obj_ext
with u_boot_console.log.section('Test Case 12 - write plain and mangle file'):
# Test Case 12a - Check if command successfully returned
output = u_boot_console.run_command_list([
'host bind 0 %s' % fs_img,
'%swrite host 0:0 %x /%s 0'
% (fs_type, ADDR, PLAIN_FILE),
'%swrite host 0:0 %x /%s 0'
% (fs_type, ADDR, MANGLE_FILE)])
assert('0 bytes written' in ''.join(output))
# Test Case 12b - Read file system content
output = check_output('mdir -i %s' % fs_img, shell=True).decode()
# Test Case 12c - Check if short filename is not mangled
assert(str2fat(PLAIN_FILE) in ''.join(output))
# Test Case 12d - Check if long filename is mangled
assert(str2fat(MANGLE_FILE) in ''.join(output))
assert_fs_integrity(fs_type, fs_img)