Merge branch '2022-09-15-general-improvements' into next

- Add uncompressed kernel image support to falcon mode, TEE
  improvements, make xyz-modem timeout configurable, gpio updates and
  other assorted improvements.
This commit is contained in:
Tom Rini 2022-09-15 09:59:47 -04:00
commit d9e85eeeba
31 changed files with 671 additions and 55 deletions

View File

@ -35,7 +35,10 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o
obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o
else
obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o
obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o
ifdef CONFIG_SPL_FRAMEWORK
obj-$(CONFIG_CMD_BOOTI) += image.o
obj-$(CONFIG_CMD_BOOTZ) += zimage.o
endif
obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o
endif
ifdef CONFIG_ARM64

View File

@ -233,6 +233,8 @@
test5-gpios = <&gpio_a 19>;
bool-value;
int8-value = /bits/ 8 <0x12>;
int16-value = /bits/ 16 <0x1234>;
int-value = <1234>;
uint-value = <(-1234)>;
int64-value = /bits/ 64 <0x1111222233334444>;

View File

@ -1194,6 +1194,13 @@ config CMD_LOADS
help
Load an S-Record file over serial line
config CMD_LOADXY_TIMEOUT
int "loadxy_timeout"
range 0 2000
default 90
help
Initial timeout for loadx and loady commands. Zero means infinity.
config CMD_LSBLK
depends on BLK
bool "lsblk - list block drivers and devices"

View File

@ -72,8 +72,13 @@ static char *delete_char (char *buffer, char *p, int *colp, int *np, int plen)
#define getcmd_getch() getchar()
#define getcmd_cbeep() getcmd_putch('\a')
#ifdef CONFIG_SPL_BUILD
#define HIST_MAX 3
#define HIST_SIZE 32
#else
#define HIST_MAX 20
#define HIST_SIZE CONFIG_SYS_CBSIZE
#endif
static int hist_max;
static int hist_add_idx;

View File

@ -116,6 +116,11 @@ int __weak bootz_setup(ulong image, ulong *start, ulong *end)
{
return 1;
}
int __weak booti_setup(ulong image, ulong *relocated_addr, ulong *size, bool force_reloc)
{
return 1;
}
#endif
/* Weak default function for arch/board-specific fixups to the spl_image_info */
@ -391,6 +396,21 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
#endif
#if CONFIG_IS_ENABLED(OS_BOOT)
#if defined(CMD_BOOTI)
ulong start, size;
if (!booti_setup((ulong)header, &start, &size, 0)) {
spl_image->name = "Linux";
spl_image->os = IH_OS_LINUX;
spl_image->load_addr = start;
spl_image->entry_point = start;
spl_image->size = size;
debug(SPL_TPL_PROMPT
"payload Image, load addr: 0x%lx size: %d\n",
spl_image->load_addr, spl_image->size);
return 0;
}
#elif defined(CMD_BOOTZ)
ulong start, end;
if (!bootz_setup((ulong)header, &start, &end)) {
@ -404,6 +424,7 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
spl_image->load_addr, spl_image->size);
return 0;
}
#endif
#endif
if (!spl_parse_board_header(spl_image, bootdev, (const void *)header, sizeof(*header)))

View File

@ -10,7 +10,7 @@
#include <gzip.h>
#include <image.h>
#include <log.h>
#include <malloc.h>
#include <memalign.h>
#include <mapmem.h>
#include <spl.h>
#include <sysinfo.h>
@ -429,7 +429,9 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image,
* depending on how the overlay is stored, so
* don't fail yet if the allocation failed.
*/
tmpbuffer = malloc(CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ);
size_t size = CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ;
tmpbuffer = malloc_cache_aligned(size);
if (!tmpbuffer)
debug("%s: unable to allocate space for overlays\n",
__func__);
@ -537,7 +539,7 @@ static void *spl_get_fit_load_buffer(size_t size)
{
void *buf;
buf = malloc(size);
buf = malloc_cache_aligned(size);
if (!buf) {
pr_err("Could not get FIT buffer of %lu bytes\n", (ulong)size);
pr_err("\tcheck CONFIG_SYS_SPL_MALLOC_SIZE\n");

View File

@ -26,6 +26,7 @@
#include <stdarg.h>
#include <u-boot/crc.h>
#include <watchdog.h>
#include <env.h>
/* Assumption - run xyzModem protocol over the console port */
@ -50,6 +51,8 @@ static struct
int len, mode, total_retries;
int total_SOH, total_STX, total_CAN;
bool crc_mode, at_eof, tx_ack;
bool first_xmodem_packet;
ulong initial_time, timeout;
unsigned long file_length, read_length;
} xyz;
@ -409,6 +412,19 @@ xyzModem_get_hdr (void)
return 0;
}
static
ulong
xyzModem_get_initial_timeout (void)
{
/* timeout is in seconds, non-positive timeout value is infinity */
#if CONFIG_IS_ENABLED(ENV_SUPPORT)
const char *timeout_str = env_get("loadxy_timeout");
if (timeout_str)
return 1000 * simple_strtol(timeout_str, NULL, 10);
#endif
return 1000 * CONFIG_CMD_LOADXY_TIMEOUT;
}
int
xyzModem_stream_open (connection_info_t * info, int *err)
{
@ -439,18 +455,28 @@ xyzModem_stream_open (connection_info_t * info, int *err)
xyz.total_CAN = 0;
xyz.read_length = 0;
xyz.file_length = 0;
xyz.first_xmodem_packet = false;
xyz.initial_time = get_timer(0);
xyz.timeout = xyzModem_get_initial_timeout();
CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
if (xyz.mode == xyzModem_xmodem)
{
/* X-modem doesn't have an information header - exit here */
xyz.first_xmodem_packet = true;
xyz.next_blk = 1;
return 0;
}
while (retries-- > 0)
while (!(xyz.timeout && get_timer(xyz.initial_time) > xyz.timeout))
{
if (--retries <= 0)
{
retries = xyzModem_MAX_RETRIES;
crc_retries = xyzModem_MAX_RETRIES_WITH_CRC;
xyz.crc_mode = true;
}
stat = xyzModem_get_hdr ();
if (stat == 0)
{
@ -503,9 +529,19 @@ xyzModem_stream_read (char *buf, int size, int *err)
retries = xyzModem_MAX_RETRIES;
while (retries-- > 0)
{
if (xyz.first_xmodem_packet && xyz.timeout &&
get_timer(xyz.initial_time) > xyz.timeout)
{
*err = xyzModem_timeout;
xyz.len = -1;
return total;
}
stat = xyzModem_get_hdr ();
if (stat == 0)
{
if (xyz.mode == xyzModem_xmodem && xyz.first_xmodem_packet)
xyz.first_xmodem_packet = false;
if (xyz.blk == xyz.next_blk)
{
xyz.tx_ack = true;
@ -583,7 +619,7 @@ xyzModem_stream_read (char *buf, int size, int *err)
xyz.total_retries++;
ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__));
}
if (stat < 0)
if (stat < 0 && (!xyz.first_xmodem_packet || stat != xyzModem_timeout))
{
*err = stat;
xyz.len = -1;

View File

@ -61,6 +61,13 @@ Configuration
The command is only available if CONFIG_CMD_LOADB=y.
Initial timeout in seconds while waiting for transfer is configured by
config option CMD_LOADXY_TIMEOUT or by env variable $loadxy_timeout.
Setting it to 0 means infinite timeout.
Transfer can be cancelled by pressing 3 times <CTRL+C> after two seconds
of inactivity on terminal.
Return value
------------

View File

@ -488,6 +488,44 @@ static void *of_find_property_value_of_size(const struct device_node *np,
return prop->value;
}
int of_read_u8(const struct device_node *np, const char *propname, u8 *outp)
{
const u8 *val;
debug("%s: %s: ", __func__, propname);
if (!np)
return -EINVAL;
val = of_find_property_value_of_size(np, propname, sizeof(*outp));
if (IS_ERR(val)) {
debug("(not found)\n");
return PTR_ERR(val);
}
*outp = *val;
debug("%#x (%d)\n", *outp, *outp);
return 0;
}
int of_read_u16(const struct device_node *np, const char *propname, u16 *outp)
{
const __be16 *val;
debug("%s: %s: ", __func__, propname);
if (!np)
return -EINVAL;
val = of_find_property_value_of_size(np, propname, sizeof(*outp));
if (IS_ERR(val)) {
debug("(not found)\n");
return PTR_ERR(val);
}
*outp = be16_to_cpup(val);
debug("%#x (%d)\n", *outp, *outp);
return 0;
}
int of_read_u32(const struct device_node *np, const char *propname, u32 *outp)
{
return of_read_u32_index(np, propname, 0, outp);

View File

@ -31,6 +31,68 @@ bool ofnode_name_eq(ofnode node, const char *name)
return (strlen(name) == len) && !strncmp(node_name, name, len);
}
int ofnode_read_u8(ofnode node, const char *propname, u8 *outp)
{
const u8 *cell;
int len;
assert(ofnode_valid(node));
debug("%s: %s: ", __func__, propname);
if (ofnode_is_np(node))
return of_read_u8(ofnode_to_np(node), propname, outp);
cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname,
&len);
if (!cell || len < sizeof(*cell)) {
debug("(not found)\n");
return -EINVAL;
}
*outp = *cell;
debug("%#x (%d)\n", *outp, *outp);
return 0;
}
u8 ofnode_read_u8_default(ofnode node, const char *propname, u8 def)
{
assert(ofnode_valid(node));
ofnode_read_u8(node, propname, &def);
return def;
}
int ofnode_read_u16(ofnode node, const char *propname, u16 *outp)
{
const fdt16_t *cell;
int len;
assert(ofnode_valid(node));
debug("%s: %s: ", __func__, propname);
if (ofnode_is_np(node))
return of_read_u16(ofnode_to_np(node), propname, outp);
cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname,
&len);
if (!cell || len < sizeof(*cell)) {
debug("(not found)\n");
return -EINVAL;
}
*outp = be16_to_cpup(cell);
debug("%#x (%d)\n", *outp, *outp);
return 0;
}
u16 ofnode_read_u16_default(ofnode node, const char *propname, u16 def)
{
assert(ofnode_valid(node));
ofnode_read_u16(node, propname, &def);
return def;
}
int ofnode_read_u32(ofnode node, const char *propname, u32 *outp)
{
return ofnode_read_u32_index(node, propname, 0, outp);

View File

@ -13,6 +13,27 @@
#include <asm/io.h>
#include <linux/ioport.h>
int dev_read_u8(const struct udevice *dev, const char *propname, u8 *outp)
{
return ofnode_read_u8(dev_ofnode(dev), propname, outp);
}
u8 dev_read_u8_default(const struct udevice *dev, const char *propname, u8 def)
{
return ofnode_read_u8_default(dev_ofnode(dev), propname, def);
}
int dev_read_u16(const struct udevice *dev, const char *propname, u16 *outp)
{
return ofnode_read_u16(dev_ofnode(dev), propname, outp);
}
u16 dev_read_u16_default(const struct udevice *dev, const char *propname,
u16 def)
{
return ofnode_read_u16_default(dev_ofnode(dev), propname, def);
}
int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp)
{
return ofnode_read_u32(dev_ofnode(dev), propname, outp);

View File

@ -884,26 +884,31 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
const struct dm_gpio_ops *ops = gpio_get_ops(dev);
struct gpio_dev_priv *priv;
char *str = buf;
const char *label;
int func;
int ret;
int len;
bool used;
BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
*buf = 0;
priv = dev_get_uclass_priv(dev);
ret = gpio_get_raw_function(dev, offset, NULL);
ret = gpio_get_raw_function(dev, offset, &label);
if (ret < 0)
return ret;
func = ret;
len = snprintf(str, buffsize, "%s%d: %s",
priv->bank_name ? priv->bank_name : "",
offset, gpio_function[func]);
if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
func == GPIOF_UNUSED) {
const char *label;
bool used;
switch (func) {
case GPIOF_FUNC:
snprintf(str + len, buffsize - len, " %s", label ? label : "");
break;
case GPIOF_INPUT:
case GPIOF_OUTPUT:
case GPIOF_UNUSED:
ret = ops->get_value(dev, offset);
if (ret < 0)
return ret;
@ -911,8 +916,9 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
ret,
used ? 'x' : ' ',
used ? " " : "",
label ? " " : "",
label ? label : "");
break;
}
return 0;

View File

@ -196,6 +196,8 @@ static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
return GPIOF_OUTPUT;
if (get_gpio_flag(dev, offset, GPIOD_IS_IN))
return GPIOF_INPUT;
if (get_gpio_flag(dev, offset, GPIOD_IS_AF))
return GPIOF_FUNC;
return GPIOF_INPUT; /*GPIO is not configurated */
}
@ -219,6 +221,9 @@ static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
if (args->args[1] & GPIO_OUT_ACTIVE)
desc->flags |= GPIOD_IS_OUT_ACTIVE;
if (args->args[1] & GPIO_AF)
desc->flags |= GPIOD_IS_AF;
return 0;
}

View File

@ -400,14 +400,14 @@ static int usb251xb_of_to_plat(struct udevice *dev)
}
}
if (dev_read_u32(dev, "vendor-id", &hub->vendor_id))
hub->vendor_id = USB251XB_DEF_VENDOR_ID;
hub->vendor_id = dev_read_u16_default(dev, "vendor-id",
USB251XB_DEF_VENDOR_ID);
if (dev_read_u32(dev, "product-id", &hub->product_id))
hub->product_id = data->product_id;
hub->product_id = dev_read_u16_default(dev, "product-id",
data->product_id);
if (dev_read_u32(dev, "device-id", &hub->device_id))
hub->device_id = USB251XB_DEF_DEVICE_ID;
hub->device_id = dev_read_u16_default(dev, "device-id",
USB251XB_DEF_DEVICE_ID);
hub->conf_data1 = USB251XB_DEF_CONFIG_DATA_1;
if (dev_read_bool(dev, "self-powered")) {
@ -513,11 +513,11 @@ static int usb251xb_of_to_plat(struct udevice *dev)
if (!dev_read_u32(dev, "power-on-time-ms", &property_u32))
hub->power_on_time = min_t(u8, property_u32 / 2, 255);
if (dev_read_u32(dev, "language-id", &hub->lang_id))
hub->lang_id = USB251XB_DEF_LANGUAGE_ID;
hub->lang_id = dev_read_u16_default(dev, "language-id",
USB251XB_DEF_LANGUAGE_ID);
if (!dev_read_u32(dev, "boost-up", &hub->boost_up))
hub->boost_up = USB251XB_DEF_BOOST_UP;
hub->boost_up = dev_read_u8_default(dev, "boost-up",
USB251XB_DEF_BOOST_UP);
cproperty_char = dev_read_string(dev, "manufacturer");
strlcpy(str, cproperty_char ? : USB251XB_DEF_MANUFACTURER_STRING,

View File

@ -72,7 +72,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
}
nprps = DIV_ROUND_UP(length, page_size);
num_pages = DIV_ROUND_UP(nprps, prps_per_page);
num_pages = DIV_ROUND_UP(nprps - 1, prps_per_page - 1);
if (nprps > dev->prp_entry_num) {
free(dev->prp_pool);
@ -85,13 +85,13 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
printf("Error: malloc prp_pool fail\n");
return -ENOMEM;
}
dev->prp_entry_num = prps_per_page * num_pages;
dev->prp_entry_num = num_pages * (prps_per_page - 1) + 1;
}
prp_pool = dev->prp_pool;
i = 0;
while (nprps) {
if (i == ((page_size >> 3) - 1)) {
if ((i == (prps_per_page - 1)) && nprps > 1) {
*(prp_pool + i) = cpu_to_le64((ulong)prp_pool +
page_size);
i = 0;
@ -104,7 +104,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
*prp2 = (ulong)dev->prp_pool;
flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool +
dev->prp_entry_num * sizeof(u64));
num_pages * page_size);
return 0;
}

View File

@ -257,10 +257,12 @@ static int stm32_pinctrl_probe(struct udevice *dev)
return 0;
}
static int stm32_gpio_config(struct gpio_desc *desc,
static int stm32_gpio_config(ofnode node,
struct gpio_desc *desc,
const struct stm32_gpio_ctl *ctl)
{
struct stm32_gpio_priv *priv = dev_get_priv(desc->dev);
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc->dev);
struct stm32_gpio_regs *regs = priv->regs;
struct stm32_pinctrl_priv *ctrl_priv;
int ret;
@ -291,6 +293,8 @@ static int stm32_gpio_config(struct gpio_desc *desc,
index = desc->offset;
clrsetbits_le32(&regs->otyper, OTYPE_MSK << index, ctl->otype << index);
uc_priv->name[desc->offset] = strdup(ofnode_get_name(node));
hwspinlock_unlock(&ctrl_priv->hws);
return 0;
@ -385,7 +389,7 @@ static int stm32_pinctrl_config(ofnode node)
if (rv)
return rv;
desc.offset = gpio_dsc.pin;
rv = stm32_gpio_config(&desc, &gpio_ctl);
rv = stm32_gpio_config(node, &desc, &gpio_ctl);
log_debug("rv = %d\n\n", rv);
if (rv)
return rv;

View File

@ -41,6 +41,7 @@ config RNG_NPCM
config RNG_OPTEE
bool "OP-TEE based Random Number Generator support"
depends on DM_RNG && OPTEE
default y if OPTEE_SERVICE_DISCOVERY
help
This driver provides support for the OP-TEE based Random Number
Generator on ARM SoCs where hardware entropy sources are not

View File

@ -11,6 +11,9 @@
#include <dm/device.h>
#include <dm/device_compat.h>
#include <linux/sizes.h>
#include <tee/optee_service.h>
#define DRIVER_NAME "optee-rng"
#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001
@ -35,6 +38,8 @@
#define TA_HWRNG_UUID { 0xab7a617c, 0xb8e7, 0x4d8f, \
{ 0x83, 0x01, 0xd0, 0x9b, 0x61, 0x03, 0x6b, 0x64 } }
OPTEE_SERVICE_DRIVER(optee_rng, TA_HWRNG_UUID, DRIVER_NAME);
/** open_session_ta_hwrng() - Open session with hwrng Trusted App
*
* @dev: device
@ -177,7 +182,7 @@ static const struct dm_rng_ops optee_rng_ops = {
};
U_BOOT_DRIVER(optee_rng) = {
.name = "optee-rng",
.name = DRIVER_NAME,
.id = UCLASS_RNG,
.ops = &optee_rng_ops,
.probe = optee_rng_probe,

View File

@ -37,6 +37,14 @@ config OPTEE_TA_SCP03
help
Enables support for controlling (enabling, provisioning) the
Secure Channel Protocol 03 operation in the OP-TEE SCP03 TA.
config OPTEE_SERVICE_DISCOVERY
bool "OP-TEE service discovery"
default y
help
This implements automated driver binding of OP-TEE service drivers by
requesting OP-TEE firmware to enumerate its hosted services.
endmenu
endif

View File

@ -14,6 +14,7 @@
#include <linux/arm-smccc.h>
#include <linux/err.h>
#include <linux/io.h>
#include <tee/optee_service.h>
#include "optee_smc.h"
#include "optee_msg.h"
@ -22,6 +23,25 @@
#define PAGELIST_ENTRIES_PER_PAGE \
((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1)
/*
* PTA_DEVICE_ENUM interface exposed by OP-TEE to discover enumerated services
*/
#define PTA_DEVICE_ENUM { 0x7011a688, 0xddde, 0x4053, \
{ 0xa5, 0xa9, 0x7b, 0x3c, 0x4d, 0xdf, 0x13, 0xb8 } }
/*
* PTA_CMD_GET_DEVICES - List services without supplicant dependencies
*
* [out] memref[0]: List of the UUIDs of service enumerated by OP-TEE
*/
#define PTA_CMD_GET_DEVICES 0x0
/*
* PTA_CMD_GET_DEVICES_SUPP - List services depending on tee supplicant
*
* [out] memref[0]: List of the UUIDs of service enumerated by OP-TEE
*/
#define PTA_CMD_GET_DEVICES_SUPP 0x1
typedef void (optee_invoke_fn)(unsigned long, unsigned long, unsigned long,
unsigned long, unsigned long, unsigned long,
unsigned long, unsigned long,
@ -42,6 +62,134 @@ struct rpc_param {
u32 a7;
};
static struct optee_service *find_service_driver(const struct tee_optee_ta_uuid *uuid)
{
struct optee_service *service;
u8 loc_uuid[TEE_UUID_LEN];
size_t service_cnt, idx;
service_cnt = ll_entry_count(struct optee_service, optee_service);
service = ll_entry_start(struct optee_service, optee_service);
for (idx = 0; idx < service_cnt; idx++, service++) {
tee_optee_ta_uuid_to_octets(loc_uuid, &service->uuid);
if (!memcmp(uuid, loc_uuid, sizeof(uuid)))
return service;
}
return NULL;
}
static int bind_service_list(struct udevice *dev, struct tee_shm *service_list, size_t count)
{
const struct tee_optee_ta_uuid *service_uuid = (const void *)service_list->addr;
struct optee_service *service;
size_t idx;
int ret;
for (idx = 0; idx < count; idx++) {
service = find_service_driver(service_uuid + idx);
if (!service)
continue;
ret = device_bind_driver(dev, service->driver_name, service->driver_name, NULL);
if (ret) {
dev_warn(dev, "%s was not bound: %d, ignored\n", service->driver_name, ret);
continue;
}
}
return 0;
}
static int __enum_services(struct udevice *dev, struct tee_shm *shm, size_t *shm_size, u32 tee_sess)
{
struct tee_invoke_arg arg = { };
struct tee_param param = { };
int ret = 0;
arg.func = PTA_CMD_GET_DEVICES;
arg.session = tee_sess;
/* Fill invoke cmd params */
param.attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
param.u.memref.shm = shm;
param.u.memref.size = *shm_size;
ret = tee_invoke_func(dev, &arg, 1, &param);
if (ret || (arg.ret && arg.ret != TEE_ERROR_SHORT_BUFFER)) {
dev_err(dev, "PTA_CMD_GET_DEVICES invoke function err: 0x%x\n", arg.ret);
return -EINVAL;
}
*shm_size = param.u.memref.size;
return 0;
}
static int enum_services(struct udevice *dev, struct tee_shm **shm, size_t *count, u32 tee_sess)
{
size_t shm_size = 0;
int ret;
ret = __enum_services(dev, NULL, &shm_size, tee_sess);
if (ret)
return ret;
ret = tee_shm_alloc(dev, shm_size, 0, shm);
if (ret) {
dev_err(dev, "Failed to allocated shared memory: %d\n", ret);
return ret;
}
ret = __enum_services(dev, *shm, &shm_size, tee_sess);
if (!ret)
*count = shm_size / sizeof(struct tee_optee_ta_uuid);
return ret;
}
static int open_enum_session(struct udevice *dev, u32 *tee_sess)
{
const struct tee_optee_ta_uuid pta_uuid = PTA_DEVICE_ENUM;
struct tee_open_session_arg arg = { };
int ret;
tee_optee_ta_uuid_to_octets(arg.uuid, &pta_uuid);
ret = tee_open_session(dev, &arg, 0, NULL);
if (ret || arg.ret) {
if (!ret)
ret = -EIO;
return ret;
}
*tee_sess = arg.session;
return 0;
}
static int bind_service_drivers(struct udevice *dev)
{
struct tee_shm *service_list = NULL;
size_t service_count;
u32 tee_sess;
int ret;
ret = open_enum_session(dev, &tee_sess);
if (ret)
return ret;
ret = enum_services(dev, &service_list, &service_count, tee_sess);
if (!ret)
ret = bind_service_list(dev, service_list, service_count);
tee_shm_free(service_list);
tee_close_session(dev, tee_sess);
return ret;
}
/**
* reg_pair_to_ptr() - Make a pointer of 2 32-bit values
* @reg0: High bits of the pointer
@ -638,11 +786,18 @@ static int optee_of_to_plat(struct udevice *dev)
return 0;
}
static int optee_bind(struct udevice *dev)
{
if (IS_ENABLED(CONFIG_OPTEE_SERVICE_DISCOVERY))
dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);
return 0;
}
static int optee_probe(struct udevice *dev)
{
struct optee_pdata *pdata = dev_get_plat(dev);
u32 sec_caps;
struct udevice *child;
int ret;
if (!is_optee_api(pdata->invoke_fn)) {
@ -668,12 +823,16 @@ static int optee_probe(struct udevice *dev)
return -ENOENT;
}
/*
* in U-Boot, the discovery of TA on the TEE bus is not supported:
* only bind the drivers associated to the supported OP-TEE TA
*/
if (IS_ENABLED(CONFIG_RNG_OPTEE)) {
ret = device_bind_driver(dev, "optee-rng", "optee-rng", &child);
if (IS_ENABLED(CONFIG_OPTEE_SERVICE_DISCOVERY)) {
ret = bind_service_drivers(dev);
if (ret)
return ret;
} else if (IS_ENABLED(CONFIG_RNG_OPTEE)) {
/*
* Discovery of TAs on the TEE bus is not supported in U-Boot:
* only bind the drivers associated to the supported OP-TEE TA
*/
ret = device_bind_driver(dev, "optee-rng", "optee-rng", NULL);
if (ret)
return ret;
}
@ -692,6 +851,7 @@ U_BOOT_DRIVER(optee) = {
.of_match = optee_match,
.of_to_plat = optee_of_to_plat,
.probe = optee_probe,
.bind = optee_bind,
.ops = &optee_ops,
.plat_auto = sizeof(struct optee_pdata),
.priv_auto = sizeof(struct optee_private),

View File

@ -466,7 +466,7 @@ static void __iomem *virtio_pci_map_capability(struct udevice *udev,
unsigned long mask =
PCI_REGION_TYPE | PCI_REGION_SYS_MEMORY | PCI_REGION_RO;
unsigned long flags = PCI_REGION_MEM;
u8 *p = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0 + cap->bar, cap->offset,
u8 *p = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0 + 4 * cap->bar, cap->offset,
cap->length, mask, flags);
return (void __iomem *)p;

View File

@ -127,6 +127,7 @@ struct gpio_desc {
#define GPIOD_OPEN_SOURCE BIT(6) /* GPIO is open source type */
#define GPIOD_PULL_UP BIT(7) /* GPIO has pull-up enabled */
#define GPIOD_PULL_DOWN BIT(8) /* GPIO has pull-down enabled */
#define GPIOD_IS_AF BIT(9) /* GPIO is an alternate function */
/* Flags for updating the above */
#define GPIOD_MASK_DIR (GPIOD_IS_OUT | GPIOD_IS_IN | \

View File

@ -264,6 +264,38 @@ struct device_node *of_find_node_by_prop_value(struct device_node *from,
*/
struct device_node *of_find_node_by_phandle(phandle handle);
/**
* of_read_u8() - Find and read a 8-bit integer from a property
*
* Search for a property in a device node and read a 8-bit value from
* it.
*
* @np: device node from which the property value is to be read.
* @propname: name of the property to be searched.
* @outp: pointer to return value, modified only if return value is 0.
*
* Return: 0 on success, -EINVAL if the property does not exist,
* -ENODATA if property does not have a value, and -EOVERFLOW if the
* property data isn't large enough.
*/
int of_read_u8(const struct device_node *np, const char *propname, u8 *outp);
/**
* of_read_u16() - Find and read a 16-bit integer from a property
*
* Search for a property in a device node and read a 16-bit value from
* it.
*
* @np: device node from which the property value is to be read.
* @propname: name of the property to be searched.
* @outp: pointer to return value, modified only if return value is 0.
*
* Return: 0 on success, -EINVAL if the property does not exist,
* -ENODATA if property does not have a value, and -EOVERFLOW if the
* property data isn't large enough.
*/
int of_read_u16(const struct device_node *np, const char *propname, u16 *outp);
/**
* of_read_u32() - Find and read a 32-bit integer from a property
*

View File

@ -221,6 +221,46 @@ static inline oftree oftree_default(void)
*/
bool ofnode_name_eq(ofnode node, const char *name);
/**
* ofnode_read_u8() - Read a 8-bit integer from a property
*
* @node: valid node reference to read property from
* @propname: name of the property to read from
* @outp: place to put value (if found)
* Return: 0 if OK, -ve on error
*/
int ofnode_read_u8(ofnode node, const char *propname, u8 *outp);
/**
* ofnode_read_u8_default() - Read a 8-bit integer from a property
*
* @node: valid node reference to read property from
* @propname: name of the property to read from
* @def: default value to return if the property has no value
* Return: property value, or @def if not found
*/
u8 ofnode_read_u8_default(ofnode node, const char *propname, u8 def);
/**
* ofnode_read_u16() - Read a 16-bit integer from a property
*
* @node: valid node reference to read property from
* @propname: name of the property to read from
* @outp: place to put value (if found)
* Return: 0 if OK, -ve on error
*/
int ofnode_read_u16(ofnode node, const char *propname, u16 *outp);
/**
* ofnode_read_u16_default() - Read a 16-bit integer from a property
*
* @node: valid node reference to read property from
* @propname: name of the property to read from
* @def: default value to return if the property has no value
* Return: property value, or @def if not found
*/
u16 ofnode_read_u16_default(ofnode node, const char *propname, u16 def);
/**
* ofnode_read_u32() - Read a 32-bit integer from a property
*

View File

@ -31,6 +31,47 @@ static inline const struct device_node *dev_np(const struct udevice *dev)
#endif
#if !defined(CONFIG_DM_DEV_READ_INLINE) || CONFIG_IS_ENABLED(OF_PLATDATA)
/**
* dev_read_u8() - read a 8-bit integer from a device's DT property
*
* @dev: device to read DT property from
* @propname: name of the property to read from
* @outp: place to put value (if found)
* Return: 0 if OK, -ve on error
*/
int dev_read_u8(const struct udevice *dev, const char *propname, u8 *outp);
/**
* dev_read_u8_default() - read a 8-bit integer from a device's DT property
*
* @dev: device to read DT property from
* @propname: name of the property to read from
* @def: default value to return if the property has no value
* Return: property value, or @def if not found
*/
u8 dev_read_u8_default(const struct udevice *dev, const char *propname, u8 def);
/**
* dev_read_u16() - read a 16-bit integer from a device's DT property
*
* @dev: device to read DT property from
* @propname: name of the property to read from
* @outp: place to put value (if found)
* Return: 0 if OK, -ve on error
*/
int dev_read_u16(const struct udevice *dev, const char *propname, u16 *outp);
/**
* dev_read_u16_default() - read a 16-bit integer from a device's DT property
*
* @dev: device to read DT property from
* @propname: name of the property to read from
* @def: default value to return if the property has no value
* Return: property value, or @def if not found
*/
u16 dev_read_u16_default(const struct udevice *dev, const char *propname,
u16 def);
/**
* dev_read_u32() - read a 32-bit integer from a device's DT property
*
@ -772,6 +813,30 @@ phy_interface_t dev_read_phy_mode(const struct udevice *dev);
#else /* CONFIG_DM_DEV_READ_INLINE is enabled */
#include <asm/global_data.h>
static inline int dev_read_u8(const struct udevice *dev,
const char *propname, u8 *outp)
{
return ofnode_read_u8(dev_ofnode(dev), propname, outp);
}
static inline int dev_read_u8_default(const struct udevice *dev,
const char *propname, u8 def)
{
return ofnode_read_u8_default(dev_ofnode(dev), propname, def);
}
static inline int dev_read_u16(const struct udevice *dev,
const char *propname, u16 *outp)
{
return ofnode_read_u16(dev_ofnode(dev), propname, outp);
}
static inline int dev_read_u16_default(const struct udevice *dev,
const char *propname, u16 def)
{
return ofnode_read_u16_default(dev_ofnode(dev), propname, def);
}
static inline int dev_read_u32(const struct udevice *dev,
const char *propname, u32 *outp)
{

View File

@ -21,4 +21,7 @@
/* Bit 18 express GPIO output is active */
#define GPIO_OUT_ACTIVE 0x40000
/* Bit 19 express GPIO set as alternate function */
#define GPIO_AF 0x80000
#endif

View File

@ -0,0 +1,34 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* (C) Copyright 2022 Linaro Limited
*/
#ifndef _OPTEE_SERVICE_H
#define _OPTEE_SERVICE_H
/*
* struct optee_service - Discoverable OP-TEE service
*
* @driver_name - Name of the related driver
* @uuid - UUID of the OP-TEE service related to the driver
*
* Use macro OPTEE_SERVICE_DRIVER() to register a driver related to an
* OP-TEE service discovered when driver asks OP-TEE services enumaration.
*/
struct optee_service {
const char *driver_name;
const struct tee_optee_ta_uuid uuid;
};
#ifdef CONFIG_OPTEE_SERVICE_DISCOVERY
#define OPTEE_SERVICE_DRIVER(__name, __uuid, __drv_name) \
ll_entry_declare(struct optee_service, __name, optee_service) = { \
.uuid = __uuid, \
.driver_name = __drv_name, \
}
#else
#define OPTEE_SERVICE_DRIVER(__name, __uuid, __drv_name) \
static int __name##__COUNTER__ __always_unused
#endif
#endif /* _OPTEE_SERVICE_H */

View File

@ -215,6 +215,8 @@ out:
* @msg_len: Message length
* @hash: Pointer to the expected hash
* @hash_len: Length of the hash
*
* Return: 0 if padding is correct, non-zero otherwise
*/
int padding_pss_verify(struct image_sign_info *info,
const uint8_t *msg, int msg_len,
@ -234,6 +236,9 @@ int padding_pss_verify(struct image_sign_info *info,
uint8_t leftmost_mask;
struct checksum_algo *checksum = info->checksum;
if (db_len <= 0)
return -EINVAL;
/* first, allocate everything */
db_mask = malloc(db_len);
db = malloc(db_len);

View File

@ -228,9 +228,8 @@ static int memory_post_dataline(unsigned long long * pmem)
hi = (temp64>>32) & 0xffffffff;
lo = temp64 & 0xffffffff;
post_log("Memory (data line) error at %08x, "
"wrote %08x%08x, read %08x%08x !\n",
pmem, pathi, patlo, hi, lo);
post_log("Memory (data line) error at %p, wrote %08x%08x, read %08x%08x !\n",
pmem, pathi, patlo, hi, lo);
ret = -1;
}
}
@ -259,9 +258,8 @@ static int memory_post_addrline(ulong *testaddr, ulong *base, ulong size)
}
#endif
if(readback == *testaddr) {
post_log("Memory (address line) error at %08x<->%08x, "
"XOR value %08x !\n",
testaddr, target, xor);
post_log("Memory (address line) error at %p<->%p, XOR value %08lx !\n",
testaddr, target, xor);
ret = -1;
}
}
@ -287,9 +285,8 @@ static int memory_post_test1(unsigned long start,
for (i = 0; i < size / sizeof (ulong) && !ret; i++) {
readback = mem[i];
if (readback != val) {
post_log("Memory error at %08x, "
"wrote %08x, read %08x !\n",
mem + i, val, readback);
post_log("Memory error at %p, wrote %08lx, read %08lx !\n",
mem + i, val, readback);
ret = -1;
break;
@ -317,9 +314,8 @@ static int memory_post_test2(unsigned long start, unsigned long size)
for (i = 0; i < size / sizeof (ulong) && !ret; i++) {
readback = mem[i];
if (readback != (1 << (i % 32))) {
post_log("Memory error at %08x, "
"wrote %08x, read %08x !\n",
mem + i, 1 << (i % 32), readback);
post_log("Memory error at %p, wrote %08lx, read %08lx !\n",
mem + i, 1UL << (i % 32), readback);
ret = -1;
break;
@ -347,9 +343,8 @@ static int memory_post_test3(unsigned long start, unsigned long size)
for (i = 0; i < size / sizeof (ulong) && !ret; i++) {
readback = mem[i];
if (readback != i) {
post_log("Memory error at %08x, "
"wrote %08x, read %08x !\n",
mem + i, i, readback);
post_log("Memory error at %p, wrote %08lx, read %08lx !\n",
mem + i, i, readback);
ret = -1;
break;
@ -377,9 +372,8 @@ static int memory_post_test4(unsigned long start, unsigned long size)
for (i = 0; i < size / sizeof (ulong) && !ret; i++) {
readback = mem[i];
if (readback != ~i) {
post_log("Memory error at %08x, "
"wrote %08x, read %08x !\n",
mem + i, ~i, readback);
post_log("Memory error at %p, wrote %08lx, read %08lx !\n",
mem + i, ~i, readback);
ret = -1;
break;

View File

@ -778,3 +778,33 @@ static int dm_test_gpio_get_values_as_int_base3(struct unit_test_state *uts)
}
DM_TEST(dm_test_gpio_get_values_as_int_base3,
UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
/* Check that gpio_get_status return the label of a GPIO configured as GPIOD_AF */
static int dm_test_gpio_function(struct unit_test_state *uts)
{
struct gpio_desc desc;
struct udevice *dev;
ulong flags;
unsigned int offset, gpio;
char buf[80];
ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
ut_asserteq_str("a-test", dev->name);
/* request gpio_b 5 */
ut_assertok(gpio_request_by_name(dev, "test-gpios", 2, &desc, 0));
/* update gpio_b 5 function to GPIO_AF */
ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_IS_AF, GPIOD_IS_AF));
ut_assertok(dm_gpio_get_flags(&desc, &flags));
ut_asserteq(GPIOD_IS_AF, flags);
/* check using gpio_get_status that label is displayed for a pin with GPIO_AF function */
ut_assertok(gpio_lookup_name("b5", &dev, &offset, &gpio));
ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
ut_asserteq_str("b5: func a-test.test-gpios2", buf);
ut_assertok(dm_gpio_free(dev, &desc));
return 0;
}
DM_TEST(dm_test_gpio_function,
UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);

View File

@ -815,6 +815,8 @@ DM_TEST(dm_test_first_child, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
static int dm_test_read_int(struct unit_test_state *uts)
{
struct udevice *dev;
u8 val8;
u16 val16;
u32 val32;
s32 sval;
uint val;
@ -822,6 +824,23 @@ static int dm_test_read_int(struct unit_test_state *uts)
ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev));
ut_asserteq_str("a-test", dev->name);
ut_assertok(dev_read_u8(dev, "int8-value", &val8));
ut_asserteq(0x12, val8);
ut_asserteq(-EINVAL, dev_read_u8(dev, "missing", &val8));
ut_asserteq(6, dev_read_u8_default(dev, "missing", 6));
ut_asserteq(0x12, dev_read_u8_default(dev, "int8-value", 6));
ut_assertok(dev_read_u16(dev, "int16-value", &val16));
ut_asserteq(0x1234, val16);
ut_asserteq(-EINVAL, dev_read_u16(dev, "missing", &val16));
ut_asserteq(6, dev_read_u16_default(dev, "missing", 6));
ut_asserteq(0x1234, dev_read_u16_default(dev, "int16-value", 6));
ut_assertok(dev_read_u32(dev, "int-value", &val32));
ut_asserteq(1234, val32);