u-boot/test/dm/remoteproc.c
Simon Glass e180c2b129 dm: Rename DM test flags to make them more generic
The test flags used by driver model are currently not available to other
tests. Rather than creating two sets of flags, make these flags generic
by changing the DM_ prefix to UT_ and moving them to the test.h header.

This will allow adding other test flags without confusion.

Signed-off-by: Simon Glass <sjg@chromium.org>
2020-08-07 22:31:32 -04:00

259 lines
7.6 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2015
* Texas Instruments Incorporated - http://www.ti.com/
*/
#include <common.h>
#include <dm.h>
#include <elf.h>
#include <errno.h>
#include <remoteproc.h>
#include <asm/io.h>
#include <dm/test.h>
#include <test/test.h>
#include <test/ut.h>
/**
* dm_test_remoteproc_base() - test the operations after initializations
* @uts: unit test state
*
* Return: 0 if test passed, else error
*/
static int dm_test_remoteproc_base(struct unit_test_state *uts)
{
if (!rproc_is_initialized())
ut_assertok(rproc_init());
/* Ensure we are initialized */
ut_asserteq(true, rproc_is_initialized());
/* platform data device 1 */
ut_assertok(rproc_stop(0));
ut_assertok(rproc_reset(0));
/* -> invalid attempt tests */
ut_asserteq(-EINVAL, rproc_start(0));
ut_asserteq(-EINVAL, rproc_ping(0));
/* Valid tests */
ut_assertok(rproc_load(0, 1, 0));
ut_assertok(rproc_start(0));
ut_assertok(rproc_is_running(0));
ut_assertok(rproc_ping(0));
ut_assertok(rproc_reset(0));
ut_assertok(rproc_stop(0));
/* dt device device 1 */
ut_assertok(rproc_stop(1));
ut_assertok(rproc_reset(1));
ut_assertok(rproc_load(1, 1, 0));
ut_assertok(rproc_start(1));
ut_assertok(rproc_is_running(1));
ut_assertok(rproc_ping(1));
ut_assertok(rproc_reset(1));
ut_assertok(rproc_stop(1));
/* dt device device 2 */
ut_assertok(rproc_stop(0));
ut_assertok(rproc_reset(0));
/* -> invalid attempt tests */
ut_asserteq(-EINVAL, rproc_start(0));
ut_asserteq(-EINVAL, rproc_ping(0));
/* Valid tests */
ut_assertok(rproc_load(2, 1, 0));
ut_assertok(rproc_start(2));
ut_assertok(rproc_is_running(2));
ut_assertok(rproc_ping(2));
ut_assertok(rproc_reset(2));
ut_assertok(rproc_stop(2));
return 0;
}
DM_TEST(dm_test_remoteproc_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
#define DEVICE_TO_PHYSICAL_OFFSET 0x1000
/**
* dm_test_remoteproc_elf() - test the ELF operations
* @uts: unit test state
*
* Return: 0 if test passed, else error
*/
static int dm_test_remoteproc_elf(struct unit_test_state *uts)
{
u8 valid_elf32[] = {
/* @0x00 - ELF HEADER - */
/* ELF magic */
0x7f, 0x45, 0x4c, 0x46,
/* 32 Bits */
0x01,
/* Endianness */
#ifdef __LITTLE_ENDIAN
0x01,
#else
0x02,
#endif
/* Version */
0x01,
/* Padding */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* Type : executable */
0x02, 0x00,
/* Machine: ARM */
0x28, 0x00,
/* Version */
0x01, 0x00, 0x00, 0x00,
/* Entry */
0x00, 0x00, 0x00, 0x08,
/* phoff (program header offset @ 0x40)*/
0x40, 0x00, 0x00, 0x00,
/* shoff (section header offset @ 0x90) */
0x90, 0x00, 0x00, 0x00,
/* flags */
0x00, 0x00, 0x00, 0x00,
/* ehsize (elf header size = 0x34) */
0x34, 0x00,
/* phentsize (program header size = 0x20) */
0x20, 0x00,
/* phnum (program header number : 1) */
0x01, 0x00,
/* shentsize (section header size : 40 bytes) */
0x28, 0x00,
/* shnum (section header number: 3) */
0x02, 0x00,
/* shstrndx (section header name section index: 1) */
0x01, 0x00,
/* padding */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
/* @0x40 - PROGRAM HEADER TABLE - */
/* type : PT_LOAD */
0x01, 0x00, 0x00, 0x00,
/* offset */
0x00, 0x00, 0x00, 0x00,
/* vaddr */
0x00, 0x00, 0x00, 0x00,
/* paddr : physical address */
0x00, 0x00, 0x00, 0x00,
/* filesz : 0x20 bytes (program header size) */
0x20, 0x00, 0x00, 0x00,
/* memsz = filesz */
0x20, 0x00, 0x00, 0x00,
/* flags : readable and exectuable */
0x05, 0x00, 0x00, 0x00,
/* padding */
0x00, 0x00, 0x00, 0x00,
/* @0x60 - RESOURCE TABLE SECTION - */
/* version */
0x01, 0x00, 0x00, 0x00,
/* num (0, no entries) */
0x00, 0x00, 0x00, 0x00,
/* Reserved */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* @0x70 - SECTION'S NAMES SECTION - */
/* section 0 name (".shrtrtab") */
0x2e, 0x73, 0x68, 0x73, 0x74, 0x72, 0x74, 0x61, 0x62, 0x00,
/* section 1 name (".resource_table") */
0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f,
0x74, 0x61, 0x62, 0x6c, 0x65, 0x00,
/* padding */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* @0x90 - SECTION HEADER TABLE - */
/* Section 0 : resource table header */
/* sh_name - index into section header string table section */
0x0a, 0x00, 0x00, 0x00,
/* sh_type and sh_flags */
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
/* sh_addr = where the resource table has to be copied to */
0x00, 0x00, 0x00, 0x00,
/* sh_offset = 0x60 */
0x60, 0x00, 0x00, 0x00,
/* sh_size = 16 bytes */
0x10, 0x00, 0x00, 0x00,
/* sh_link, sh_info, sh_addralign, sh_entsize */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* Section 1 : section's names section header */
/* sh_name - index into section header string table section */
0x00, 0x00, 0x00, 0x00,
/* sh_type and sh_flags */
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* sh_addr */
0x00, 0x00, 0x00, 0x00,
/* sh_offset = 0x70 */
0x70, 0x00, 0x00, 0x00,
/* sh_size = 27 bytes */
0x1b, 0x00, 0x00, 0x00,
/* sh_link, sh_info, sh_addralign, sh_entsize */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
unsigned int size = ARRAY_SIZE(valid_elf32);
struct udevice *dev;
phys_addr_t loaded_firmware_paddr, loaded_rsc_table_paddr;
void *loaded_firmware, *loaded_rsc_table;
u32 loaded_firmware_size, rsc_table_size;
ulong rsc_addr, rsc_size;
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)valid_elf32;
Elf32_Phdr *phdr = (Elf32_Phdr *)(valid_elf32 + ehdr->e_phoff);
Elf32_Shdr *shdr = (Elf32_Shdr *)(valid_elf32 + ehdr->e_shoff);
ut_assertok(uclass_get_device(UCLASS_REMOTEPROC, 0, &dev));
/*
* In its Program Header Table, let the firmware specifies to be loaded
* at SDRAM_BASE *device* address (p_paddr field).
* Its size is defined by the p_filesz field.
*/
phdr->p_paddr = CONFIG_SYS_SDRAM_BASE;
loaded_firmware_size = phdr->p_filesz;
/*
* This *device* address is converted to a *physical* address by the
* device_to_virt() operation of sandbox_test_rproc which returns
* DeviceAddress + DEVICE_TO_PHYSICAL_OFFSET.
* This is where we expect to get the firmware loaded.
*/
loaded_firmware_paddr = phdr->p_paddr + DEVICE_TO_PHYSICAL_OFFSET;
loaded_firmware = map_physmem(loaded_firmware_paddr,
loaded_firmware_size, MAP_NOCACHE);
ut_assertnonnull(loaded_firmware);
memset(loaded_firmware, 0, loaded_firmware_size);
/* Load firmware in loaded_firmware, and verify it */
ut_assertok(rproc_elf32_load_image(dev, (ulong)valid_elf32, size));
ut_asserteq_mem(loaded_firmware, valid_elf32, loaded_firmware_size);
ut_asserteq(rproc_elf_get_boot_addr(dev, (unsigned long)valid_elf32),
0x08000000);
unmap_physmem(loaded_firmware, MAP_NOCACHE);
/* Resource table */
shdr->sh_addr = CONFIG_SYS_SDRAM_BASE;
rsc_table_size = shdr->sh_size;
loaded_rsc_table_paddr = shdr->sh_addr + DEVICE_TO_PHYSICAL_OFFSET;
loaded_rsc_table = map_physmem(loaded_rsc_table_paddr,
rsc_table_size, MAP_NOCACHE);
ut_assertnonnull(loaded_rsc_table);
memset(loaded_rsc_table, 0, rsc_table_size);
/* Load and verify */
ut_assertok(rproc_elf32_load_rsc_table(dev, (ulong)valid_elf32, size,
&rsc_addr, &rsc_size));
ut_asserteq(rsc_addr, CONFIG_SYS_SDRAM_BASE);
ut_asserteq(rsc_size, rsc_table_size);
ut_asserteq_mem(loaded_firmware, valid_elf32 + shdr->sh_offset,
shdr->sh_size);
unmap_physmem(loaded_firmware, MAP_NOCACHE);
/* Invalid ELF Magic */
valid_elf32[0] = 0;
ut_asserteq(-EPROTONOSUPPORT,
rproc_elf32_sanity_check((ulong)valid_elf32, size));
return 0;
}
DM_TEST(dm_test_remoteproc_elf, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);