Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
1502c4e1
Commit
1502c4e1
authored
Jun 13, 2017
by
davidcunado-arm
Committed by
GitHub
Jun 13, 2017
Browse files
Merge pull request #974 from masahir0y/uniphier
UniPhier Initial Support
parents
42fb35a8
63b3a28e
Changes
30
Hide whitespace changes
Inline
Side-by-side
acknowledgements.md
View file @
1502c4e1
...
...
@@ -7,6 +7,8 @@ Linaro Limited
NVIDIA Corporation
Socionext Inc.
Xilinx, Inc.
Individuals
...
...
docs/plat/socionext-uniphier.md
0 → 100644
View file @
1502c4e1
ARM Trusted Firmware for Socionext UniPhier SoCs
================================================
Socionext UniPhier ARMv8-A SoCs use ARM Trusted Firmware as the secure world
firmware, supporting BL1, BL2, and BL31.
UniPhier SoC family implements its internal boot ROM, so BL1 is used as pseudo
ROM (i.e. runs in RAM). The internal boot ROM loads 64KB [1] image from a
non-volatile storage to the on-chip SRAM. Unfortunately, BL1 does not fit in
the 64KB limit if [Trusted Board Boot] (TBB) is enabled. To solve this problem,
Socionext provides a first stage loader called [UniPhier BL]. This loader runs
in the on-chip SRAM, initializes the DRAM, expands BL1 there, and hands the
control over to it. Therefore, all images of ARM Trusted Firmware run in DRAM.
The UniPhier platform works with/without TBB. See below for the build process
of each case. The image authentication for the UniPhier platform fully
complies with the Trusted Board Boot Requirements (TBBR) specification.
The UniPhier BL does not implement the authentication functionality, that is,
it can not verify the BL1 image by itself. Instead, the UniPhier BL assures
the BL1 validity in a different way; BL1 is GZIP-compressed and appended to
the UniPhier BL. The concatenation of the UniPhier BL and the compressed BL1
fits in the 64KB limit. The concatenated image is loaded by the boot ROM
(and verified if the chip fuses are blown).
[
1
]:
Some
SoCs can load 80KB, but the software implementation must be aligned
to the lowest common denominator.
[
Trusted Board Boot
]:
../trusted-board-boot.md
[
UniPhier BL
]:
https://github.com/uniphier/uniphier-bl
Boot Flow
---------
1.
The Boot ROM
This is hard-wired ROM, so never corrupted. It loads the UniPhier BL (with
compressed-BL1 appended) into the on-chip SRAM. If the SoC fuses are blown,
the image is verified by the SoC's own method.
2.
UniPhier BL
This runs in the on-chip SRAM. After the minimum SoC initialization and DRAM
setup, it decompresses the appended BL1 image into the DRAM, then jumps to
the BL1 entry.
3.
BL1
This runs in the DRAM. It extracts BL2 from FIP (Firmware Image Package).
If TBB is enabled, the BL2 is authenticated by the standard mechanism of ARM
Trusted Firmware.
4.
BL2, BL31, and more
They all run in the DRAM, and are authenticated by the standard mechanism if
TBB is enabled. See [Firmware Design] for details.
[
Firmware Design
]:
../firmware-design.md
Basic Build
-----------
BL1 must be compressed for the reason above. The UniPhier's platform makefile
provides a build target
`bl1_gzip`
for this.
For a non-secure boot loader (aka BL33), U-Boot is well supported for UniPhier
SoCs. The U-Boot image (
`u-boot.bin`
) must be built in advance. For the build
procedure of U-Boot, refer to the document in the [U-Boot] project.
[
U-Boot
]:
https://www.denx.de/wiki/U-Boot
To build minimum functionality for UniPhier (without TBB):
```
make CROSS_COMPILE=<gcc-prefix> PLAT=uniphier BL33=<path-to-BL33> bl1_gzip fip
```
Output images:
-
`bl1.bin.gzip`
-
`fip.bin`
Optional features
-----------------
-
Trusted Board Boot
[mbed TLS] is needed as the cryptographic and image parser modules.
Refer to the [User Guide] for the appropriate version of mbed TLS.
To enable TBB, add the following options to the build command:
```
TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 MBEDTLS_DIR=<path-to-mbedtls>
```
[
mbed TLS
]:
https://tls.mbed.org/
[
User Guide
]:
../user-guide.md
-
System Control Processor (SCP)
If desired, FIP can include an SCP BL2 image. If BL2 finds an SCP BL2 image
in FIP, BL2 loads it into DRAM and kicks the SCP. Most of UniPhier boards
still work without SCP, but SCP provides better power management support.
To include SCP_BL2, add the following option to the build command:
```
SCP_BL2=<path-to-SCP>
```
-
BL32 (Secure Payload)
To enable BL32, add the following option to the build command:
```
SPD=<spd> BL32=<path-to-BL32>
```
If you use TSP for BL32,
`BL32=<path-to-BL32>`
is not required. Just add the
following:
```
SPD=tspd
```
plat/socionext/uniphier/include/plat_macros.S
0 → 100644
View file @
1502c4e1
/*
*
Copyright
(
c
)
2017
,
ARM
Limited
and
Contributors
.
All
rights
reserved
.
*
*
SPDX
-
License
-
Identifier
:
BSD
-
3
-
Clause
*/
#ifndef __PLAT_MACROS_S__
#define __PLAT_MACROS_S__
.
macro
plat_crash_print_regs
.
endm
#endif /* __PLAT_MACROS_S__ */
plat/socionext/uniphier/include/platform_def.h
0 → 100644
View file @
1502c4e1
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __PLATFORM_DEF_H__
#define __PLATFORM_DEF_H__
#include <common_def.h>
#include <tbbr/tbbr_img_def.h>
#define PLATFORM_STACK_SIZE 0x1000
#define CACHE_WRITEBACK_SHIFT 6
#define CACHE_WRITEBACK_GRANULE (1 << (CACHE_WRITEBACK_SHIFT))
/* topology */
#define UNIPHIER_MAX_CPUS_PER_CLUSTER 4
#define UNIPHIER_CLUSTER_COUNT 2
#define PLATFORM_CORE_COUNT \
((UNIPHIER_MAX_CPUS_PER_CLUSTER) * (UNIPHIER_CLUSTER_COUNT))
#define PLAT_MAX_PWR_LVL 1
#define PLAT_MAX_OFF_STATE 2
#define PLAT_MAX_RET_STATE 1
#define UNIPHIER_SEC_DRAM_BASE 0x81000000
#define UNIPHIER_SEC_DRAM_LIMIT 0x82000000
#define UNIPHIER_SEC_DRAM_SIZE ((UNIPHIER_SEC_DRAM_LIMIT) - \
(UNIPHIER_SEC_DRAM_BASE))
#define BL1_RO_BASE 0x80000000
#define BL1_RO_LIMIT 0x80018000
#define BL1_RW_LIMIT (UNIPHIER_SEC_DRAM_LIMIT)
#define BL1_RW_BASE ((BL1_RW_LIMIT) - 0x00040000)
#define BL2_LIMIT (BL1_RW_BASE)
#define BL2_BASE ((BL2_LIMIT) - 0x00040000)
#define BL31_BASE (UNIPHIER_SEC_DRAM_BASE)
#define BL31_LIMIT ((BL31_BASE) + 0x00080000)
#define BL32_BASE (BL31_LIMIT)
#define BL32_LIMIT (UNIPHIER_SEC_DRAM_LIMIT)
#define UNIPHIER_BLOCK_BUF_SIZE 0x00400000
#define UNIPHIER_BLOCK_BUF_BASE ((BL2_LIMIT) - \
(UNIPHIER_BLOCK_BUF_SIZE))
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_XLAT_TABLES_DYNAMIC 1
#define MAX_XLAT_TABLES 7
#define MAX_MMAP_REGIONS 6
#define MAX_IO_HANDLES 2
#define MAX_IO_DEVICES 2
#define MAX_IO_BLOCK_DEVICES 1
#define TSP_SEC_MEM_BASE (BL32_BASE)
#define TSP_SEC_MEM_SIZE ((BL32_LIMIT) - (BL32_BASE))
#define TSP_PROGBITS_LIMIT (UNIPHIER_BLOCK_BUF_BASE)
#define TSP_IRQ_SEC_PHY_TIMER 29
#endif
/* __PLATFORM_DEF_H__ */
plat/socionext/uniphier/platform.mk
0 → 100644
View file @
1502c4e1
#
# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
override COLD_BOOT_SINGLE_CPU
:
= 1
override ENABLE_PLAT_COMPAT
:
= 0
override ERROR_DEPRECATED
:
= 1
override LOAD_IMAGE_V2
:
= 1
override USE_COHERENT_MEM
:
= 1
override USE_TBBR_DEFS
:
= 1
# Cortex-A53 revision r0p4-51rel0
# needed for LD20, unneeded for LD11, PXs3 (no ACE)
ERRATA_A53_855873
:=
1
FIP_ALIGN
:=
512
ifeq
($(NEED_BL32),yes)
$(eval
$(call
add_define,UNIPHIER_LOAD_BL32))
endif
PLAT_PATH
:=
plat/socionext/uniphier
PLAT_INCLUDES
:=
-I
$(PLAT_PATH)
/include
# IO sources for BL1, BL2
IO_SOURCES
:=
drivers/io/io_block.c
\
drivers/io/io_fip.c
\
drivers/io/io_memmap.c
\
drivers/io/io_storage.c
\
$(PLAT_PATH)
/uniphier_boot_device.c
\
$(PLAT_PATH)
/uniphier_emmc.c
\
$(PLAT_PATH)
/uniphier_io_storage.c
\
$(PLAT_PATH)
/uniphier_nand.c
\
$(PLAT_PATH)
/uniphier_usb.c
# common sources for BL1, BL2, BL31
PLAT_BL_COMMON_SOURCES
+=
drivers/console/aarch64/console.S
\
lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
\
lib/xlat_tables_v2/xlat_tables_common.c
\
lib/xlat_tables_v2/xlat_tables_internal.c
\
$(PLAT_PATH)
/uniphier_console.S
\
$(PLAT_PATH)
/uniphier_helpers.S
\
$(PLAT_PATH)
/uniphier_soc_info.c
\
$(PLAT_PATH)
/uniphier_xlat_setup.c
BL1_SOURCES
+=
lib/cpus/aarch64/cortex_a53.S
\
lib/cpus/aarch64/cortex_a72.S
\
$(PLAT_PATH)
/uniphier_bl1_helpers.S
\
$(PLAT_PATH)
/uniphier_bl1_setup.c
\
$(IO_SOURCES)
BL2_SOURCES
+=
common/desc_image_load.c
\
$(PLAT_PATH)
/uniphier_bl2_setup.c
\
$(PLAT_PATH)
/uniphier_image_desc.c
\
$(PLAT_PATH)
/uniphier_scp.c
\
$(IO_SOURCES)
BL31_SOURCES
+=
drivers/arm/cci/cci.c
\
drivers/arm/gic/common/gic_common.c
\
drivers/arm/gic/v3/gicv3_helpers.c
\
drivers/arm/gic/v3/gicv3_main.c
\
lib/cpus/aarch64/cortex_a53.S
\
lib/cpus/aarch64/cortex_a72.S
\
plat/common/plat_gicv3.c
\
plat/common/plat_psci_common.c
\
$(PLAT_PATH)
/uniphier_bl31_setup.c
\
$(PLAT_PATH)
/uniphier_cci.c
\
$(PLAT_PATH)
/uniphier_gicv3.c
\
$(PLAT_PATH)
/uniphier_psci.c
\
$(PLAT_PATH)
/uniphier_scp.c
\
$(PLAT_PATH)
/uniphier_smp.S
\
$(PLAT_PATH)
/uniphier_syscnt.c
\
$(PLAT_PATH)
/uniphier_topology.c
ifeq
(${TRUSTED_BOARD_BOOT},1)
include
drivers/auth/mbedtls/mbedtls_crypto.mk
include
drivers/auth/mbedtls/mbedtls_x509.mk
PLAT_INCLUDES
+=
-Iinclude
/common/tbbr
TBB_SOURCES
:=
drivers/auth/auth_mod.c
\
drivers/auth/crypto_mod.c
\
drivers/auth/img_parser_mod.c
\
drivers/auth/tbbr/tbbr_cot.c
\
plat/common/tbbr/plat_tbbr.c
\
$(PLAT_PATH)
/uniphier_tbbr.c
BL1_SOURCES
+=
$(TBB_SOURCES)
BL2_SOURCES
+=
$(TBB_SOURCES)
endif
.PHONY
:
bl1_gzip
bl1_gzip
:
$(BUILD_PLAT)/bl1.bin.gzip
%.gzip
:
%
@
echo
" GZIP
$@
"
$(Q)
(
cat
$<
|
gzip
-n
-f
-9
>
$@
)
||
(
rm
-f
$@
||
false
)
plat/socionext/uniphier/tsp/tsp-uniphier.mk
0 → 100644
View file @
1502c4e1
#
# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
BL32_SOURCES
+=
plat/common/plat_gicv3.c
\
plat/common/aarch64/platform_mp_stack.S
\
$(PLAT_PATH)
/tsp/uniphier_tsp_setup.c
plat/socionext/uniphier/tsp/uniphier_tsp_setup.c
0 → 100644
View file @
1502c4e1
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <platform_def.h>
#include <xlat_mmu_helpers.h>
#include "../uniphier.h"
#define BL32_END (unsigned long)(&__BL32_END__)
#define BL32_SIZE ((BL32_END) - (BL32_BASE))
void
tsp_early_platform_setup
(
void
)
{
uniphier_console_setup
();
}
void
tsp_platform_setup
(
void
)
{
}
void
tsp_plat_arch_setup
(
void
)
{
uniphier_mmap_setup
(
BL32_BASE
,
BL32_SIZE
,
NULL
);
enable_mmu_el1
(
0
);
}
plat/socionext/uniphier/uniphier.h
0 → 100644
View file @
1502c4e1
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __UNIPHIER_H__
#define __UNIPHIER_H__
#include <stdint.h>
#include <types.h>
unsigned
int
uniphier_get_soc_type
(
void
);
unsigned
int
uniphier_get_soc_model
(
void
);
unsigned
int
uniphier_get_soc_revision
(
void
);
unsigned
int
uniphier_get_soc_id
(
void
);
#define UNIPHIER_SOC_LD11 0
#define UNIPHIER_SOC_LD20 1
#define UNIPHIER_SOC_PXS3 2
#define UNIPHIER_SOC_UNKNOWN 0xffffffff
unsigned
int
uniphier_get_boot_device
(
unsigned
int
soc
);
#define UNIPHIER_BOOT_DEVICE_EMMC 0
#define UNIPHIER_BOOT_DEVICE_NAND 1
#define UNIPHIER_BOOT_DEVICE_NOR 2
#define UNIPHIER_BOOT_DEVICE_USB 3
#define UNIPHIER_BOOT_DEVICE_RSV 0xffffffff
unsigned
int
uniphier_get_boot_master
(
unsigned
int
soc
);
#define UNIPHIER_BOOT_MASTER_THIS 0
#define UNIPHIER_BOOT_MASTER_SCP 1
#define UNIPHIER_BOOT_MASTER_EXT 2
void
uniphier_console_setup
(
void
);
int
uniphier_emmc_init
(
uintptr_t
*
block_dev_spec
);
int
uniphier_nand_init
(
uintptr_t
*
block_dev_spec
);
int
uniphier_usb_init
(
unsigned
int
soc
,
uintptr_t
*
block_dev_spec
);
int
uniphier_io_setup
(
unsigned
int
soc
);
int
uniphier_check_image
(
unsigned
int
image_id
);
void
uniphier_image_descs_fixup
(
void
);
int
uniphier_scp_is_running
(
void
);
void
uniphier_scp_start
(
void
);
void
uniphier_scp_open_com
(
void
);
void
uniphier_scp_system_off
(
void
);
void
uniphier_scp_system_reset
(
void
);
struct
mmap_region
;
void
uniphier_mmap_setup
(
uintptr_t
total_base
,
size_t
total_size
,
const
struct
mmap_region
*
mmap
);
void
uniphier_cci_init
(
unsigned
int
soc
);
void
uniphier_cci_enable
(
void
);
void
uniphier_cci_disable
(
void
);
void
uniphier_gic_driver_init
(
unsigned
int
soc
);
void
uniphier_gic_init
(
void
);
void
uniphier_gic_cpuif_enable
(
void
);
void
uniphier_gic_cpuif_disable
(
void
);
void
uniphier_gic_pcpu_init
(
void
);
unsigned
int
uniphier_calc_core_pos
(
u_register_t
mpidr
);
#define UNIPHIER_NS_DRAM_BASE 0x84000000
#define UNIPHIER_NS_DRAM_SIZE 0x01000000
#define UNIPHIER_BL33_BASE (UNIPHIER_NS_DRAM_BASE)
#define UNIPHIER_BL33_MAX_SIZE 0x00100000
#define UNIPHIER_SCP_BASE ((UNIPHIER_BL33_BASE) + \
(UNIPHIER_BL33_MAX_SIZE))
#define UNIPHIER_SCP_MAX_SIZE 0x00020000
#endif
/* __UNIPHIER_H__ */
plat/socionext/uniphier/uniphier_bl1_helpers.S
0 → 100644
View file @
1502c4e1
/*
*
Copyright
(
c
)
2017
,
ARM
Limited
and
Contributors
.
All
rights
reserved
.
*
*
SPDX
-
License
-
Identifier
:
BSD
-
3
-
Clause
*/
#include <arch.h>
#include <asm_macros.S>
.
globl
plat_get_my_entrypoint
func
plat_get_my_entrypoint
mov
x0
,
#
0
ret
endfunc
plat_get_my_entrypoint
plat/socionext/uniphier/uniphier_bl1_setup.c
0 → 100644
View file @
1502c4e1
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <bl_common.h>
#include <console.h>
#include <debug.h>
#include <errno.h>
#include <platform.h>
#include <platform_def.h>
#include <xlat_mmu_helpers.h>
#include "uniphier.h"
void
bl1_early_platform_setup
(
void
)
{
uniphier_console_setup
();
}
void
bl1_plat_arch_setup
(
void
)
{
uniphier_mmap_setup
(
UNIPHIER_SEC_DRAM_BASE
,
UNIPHIER_SEC_DRAM_SIZE
,
NULL
);
enable_mmu_el3
(
0
);
}
void
bl1_platform_setup
(
void
)
{
unsigned
int
soc
;
int
ret
;
soc
=
uniphier_get_soc_id
();
if
(
soc
==
UNIPHIER_SOC_UNKNOWN
)
{
ERROR
(
"unsupported SoC
\n
"
);
plat_error_handler
(
-
ENOTSUP
);
}
ret
=
uniphier_io_setup
(
soc
);
if
(
ret
)
{
ERROR
(
"failed to setup io devices
\n
"
);
plat_error_handler
(
ret
);
}
}
static
meminfo_t
uniphier_tzram_layout
=
{
.
total_base
=
UNIPHIER_SEC_DRAM_BASE
,
.
total_size
=
UNIPHIER_SEC_DRAM_SIZE
,
};
meminfo_t
*
bl1_plat_sec_mem_layout
(
void
)
{
return
&
uniphier_tzram_layout
;
}
plat/socionext/uniphier/uniphier_bl2_setup.c
0 → 100644
View file @
1502c4e1
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <bl_common.h>
#include <debug.h>
#include <desc_image_load.h>
#include <errno.h>
#include <io/io_storage.h>
#include <platform.h>
#include <platform_def.h>
#include <xlat_tables_v2.h>
#include "uniphier.h"
static
meminfo_t
uniphier_bl2_tzram_layout
__aligned
(
CACHE_WRITEBACK_GRANULE
);
static
int
uniphier_bl2_kick_scp
;
void
bl2_early_platform_setup
(
meminfo_t
*
mem_layout
)
{
uniphier_bl2_tzram_layout
=
*
mem_layout
;
uniphier_console_setup
();
}
static
const
struct
mmap_region
uniphier_bl2_mmap
[]
=
{
/* for SCP, BL33 */
MAP_REGION_FLAT
(
UNIPHIER_NS_DRAM_BASE
,
UNIPHIER_NS_DRAM_SIZE
,
MT_MEMORY
|
MT_RW
|
MT_NS
),
{
.
size
=
0
},
};
void
bl2_plat_arch_setup
(
void
)
{
unsigned
int
soc
;
int
skip_scp
=
0
;
int
ret
;
uniphier_mmap_setup
(
UNIPHIER_SEC_DRAM_BASE
,
UNIPHIER_SEC_DRAM_SIZE
,
uniphier_bl2_mmap
);
enable_mmu_el1
(
0
);
soc
=
uniphier_get_soc_id
();
if
(
soc
==
UNIPHIER_SOC_UNKNOWN
)
{
ERROR
(
"unsupported SoC
\n
"
);
plat_error_handler
(
-
ENOTSUP
);
}
ret
=
uniphier_io_setup
(
soc
);
if
(
ret
)
{
ERROR
(
"failed to setup io devices
\n
"
);
plat_error_handler
(
ret
);
}
switch
(
uniphier_get_boot_master
(
soc
))
{
case
UNIPHIER_BOOT_MASTER_THIS
:
INFO
(
"Booting from this SoC
\n
"
);
skip_scp
=
1
;
break
;
case
UNIPHIER_BOOT_MASTER_SCP
:
INFO
(
"Booting from on-chip SCP
\n
"
);
if
(
uniphier_scp_is_running
())
{
INFO
(
"SCP is already running. SCP_BL2 load will be skipped.
\n
"
);
skip_scp
=
1
;
}
/*
* SCP must be kicked every time even if it is already running
* because it polls this event after the reboot of the backend.
*/
uniphier_bl2_kick_scp
=
1
;
break
;
case
UNIPHIER_BOOT_MASTER_EXT
:
INFO
(
"Booting from external SCP
\n
"
);
skip_scp
=
1
;
break
;
default:
plat_error_handler
(
-
ENOTSUP
);
}
if
(
!
skip_scp
)
{
ret
=
uniphier_check_image
(
SCP_BL2_IMAGE_ID
);
if
(
ret
)
{
WARN
(
"SCP_BL2 image not found. SCP_BL2 load will be skipped.
\n
"
);
WARN
(
"You must setup SCP by other means.
\n
"
);
skip_scp
=
1
;
uniphier_bl2_kick_scp
=
0
;
}
}
if
(
skip_scp
)
uniphier_image_descs_fixup
();
}
void
bl2_platform_setup
(
void
)
{
}
void
plat_flush_next_bl_params
(
void
)
{
flush_bl_params_desc
();
}
bl_load_info_t
*
plat_get_bl_image_load_info
(
void
)
{
return
get_bl_load_info_from_mem_params_desc
();
}
bl_params_t
*
plat_get_next_bl_params
(
void
)
{
return
get_next_bl_params_from_mem_params_desc
();
}
int
bl2_plat_handle_post_image_load
(
unsigned
int
image_id
)
{
if
(
image_id
==
SCP_BL2_IMAGE_ID
&&
uniphier_bl2_kick_scp
)
uniphier_scp_start
();
return
0
;
}
plat/socionext/uniphier/uniphier_bl31_setup.c
0 → 100644
View file @
1502c4e1
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <assert.h>
#include <bl_common.h>
#include <console.h>
#include <debug.h>
#include <errno.h>
#include <mmio.h>
#include <platform.h>
#include <platform_def.h>
#include <xlat_mmu_helpers.h>
#include "uniphier.h"
#define BL31_END (unsigned long)(&__BL31_END__)
#define BL31_SIZE ((BL31_END) - (BL31_BASE))
static
entry_point_info_t
bl32_image_ep_info
;
static
entry_point_info_t
bl33_image_ep_info
;
entry_point_info_t
*
bl31_plat_get_next_image_ep_info
(
uint32_t
type
)
{
assert
(
sec_state_is_valid
(
type
));
return
type
==
NON_SECURE
?
&
bl33_image_ep_info
:
&
bl32_image_ep_info
;
}
void
bl31_early_platform_setup
(
void
*
from_bl2
,
void
*
plat_params_from_bl2
)
{
bl_params_node_t
*
bl_params
=
((
bl_params_t
*
)
from_bl2
)
->
head
;
uniphier_console_setup
();
while
(
bl_params
)
{
if
(
bl_params
->
image_id
==
BL32_IMAGE_ID
)
bl32_image_ep_info
=
*
bl_params
->
ep_info
;
if
(
bl_params
->
image_id
==
BL33_IMAGE_ID
)
bl33_image_ep_info
=
*
bl_params
->
ep_info
;
bl_params
=
bl_params
->
next_params_info
;
}
if
(
bl33_image_ep_info
.
pc
==
0
)
panic
();
}
#define UNIPHIER_SYS_CNTCTL_BASE 0x60E00000
void
bl31_platform_setup
(
void
)
{
unsigned
int
soc
;
soc
=
uniphier_get_soc_id
();
if
(
soc
==
UNIPHIER_SOC_UNKNOWN
)
{
ERROR
(
"unsupported SoC
\n
"
);
plat_error_handler
(
-
ENOTSUP
);
}
uniphier_cci_init
(
soc
);
uniphier_cci_enable
();
/* Initialize the GIC driver, cpu and distributor interfaces */
uniphier_gic_driver_init
(
soc
);
uniphier_gic_init
();
/* Enable and initialize the System level generic timer */
mmio_write_32
(
UNIPHIER_SYS_CNTCTL_BASE
+
CNTCR_OFF
,
CNTCR_FCREQ
(
0
)
|
CNTCR_EN
);
}
void
bl31_plat_arch_setup
(
void
)
{
uniphier_mmap_setup
(
BL31_BASE
,
BL31_SIZE
,
NULL
);
enable_mmu_el3
(
0
);
}
void
bl31_plat_runtime_setup
(
void
)
{
/* Suppress any runtime logs unless DEBUG is defined */
#if !DEBUG
console_uninit
();
#endif
}
plat/socionext/uniphier/uniphier_boot_device.c
0 → 100644
View file @
1502c4e1
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <mmio.h>
#include <stdbool.h>
#include <stddef.h>
#include <utils_def.h>
#include "uniphier.h"
#define UNIPHIER_PINMON0 0x5f900100
#define UNIPHIER_PINMON2 0x5f900108
static
int
uniphier_ld11_is_usb_boot
(
uint32_t
pinmon
)
{
return
!!
(
~
pinmon
&
0x00000080
);
}
static
int
uniphier_ld20_is_usb_boot
(
uint32_t
pinmon
)
{
return
!!
(
~
pinmon
&
0x00000780
);
}
static
int
uniphier_pxs3_is_usb_boot
(
uint32_t
pinmon
)
{
uint32_t
pinmon2
=
mmio_read_32
(
UNIPHIER_PINMON2
);
return
!!
(
pinmon2
&
BIT
(
31
));
}
static
const
unsigned
int
uniphier_ld11_boot_device_table
[]
=
{
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_EMMC
,
UNIPHIER_BOOT_DEVICE_EMMC
,
UNIPHIER_BOOT_DEVICE_EMMC
,
UNIPHIER_BOOT_DEVICE_EMMC
,
UNIPHIER_BOOT_DEVICE_EMMC
,
UNIPHIER_BOOT_DEVICE_EMMC
,
UNIPHIER_BOOT_DEVICE_EMMC
,
UNIPHIER_BOOT_DEVICE_NOR
,
};
static
unsigned
int
uniphier_ld11_get_boot_device
(
uint32_t
pinmon
)
{
unsigned
int
boot_sel
=
(
pinmon
>>
1
)
&
0x1f
;
assert
(
boot_sel
<
ARRAY_SIZE
(
uniphier_ld11_boot_device_table
));
return
uniphier_ld11_boot_device_table
[
boot_sel
];
}
static
const
unsigned
int
uniphier_pxs3_boot_device_table
[]
=
{
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_EMMC
,
UNIPHIER_BOOT_DEVICE_EMMC
,
UNIPHIER_BOOT_DEVICE_EMMC
,
UNIPHIER_BOOT_DEVICE_EMMC
,
UNIPHIER_BOOT_DEVICE_EMMC
,
UNIPHIER_BOOT_DEVICE_EMMC
,
UNIPHIER_BOOT_DEVICE_NAND
,
UNIPHIER_BOOT_DEVICE_NAND
,
};
static
unsigned
int
uniphier_pxs3_get_boot_device
(
uint32_t
pinmon
)
{
unsigned
int
boot_sel
=
(
pinmon
>>
1
)
&
0xf
;
assert
(
boot_sel
<
ARRAY_SIZE
(
uniphier_pxs3_boot_device_table
));
return
uniphier_pxs3_boot_device_table
[
boot_sel
];
}
struct
uniphier_boot_device_info
{
int
(
*
is_usb_boot
)(
uint32_t
pinmon
);
unsigned
int
(
*
get_boot_device
)(
uint32_t
pinmon
);
};
static
const
struct
uniphier_boot_device_info
uniphier_boot_device_info
[]
=
{
[
UNIPHIER_SOC_LD11
]
=
{
.
is_usb_boot
=
uniphier_ld11_is_usb_boot
,
.
get_boot_device
=
uniphier_ld11_get_boot_device
,
},
[
UNIPHIER_SOC_LD20
]
=
{
.
is_usb_boot
=
uniphier_ld20_is_usb_boot
,
.
get_boot_device
=
uniphier_ld11_get_boot_device
,
},
[
UNIPHIER_SOC_PXS3
]
=
{
.
is_usb_boot
=
uniphier_pxs3_is_usb_boot
,
.
get_boot_device
=
uniphier_pxs3_get_boot_device
,
},
};
unsigned
int
uniphier_get_boot_device
(
unsigned
int
soc
)
{
const
struct
uniphier_boot_device_info
*
info
;
uint32_t
pinmon
;
assert
(
soc
<
ARRAY_SIZE
(
uniphier_boot_device_info
));
info
=
&
uniphier_boot_device_info
[
soc
];
pinmon
=
mmio_read_32
(
UNIPHIER_PINMON0
);
if
(
!
(
pinmon
&
BIT
(
29
)))
return
UNIPHIER_BOOT_DEVICE_NOR
;
if
(
info
->
is_usb_boot
(
pinmon
))
return
UNIPHIER_BOOT_DEVICE_USB
;
return
info
->
get_boot_device
(
pinmon
);
}
static
const
bool
uniphier_have_onchip_scp
[]
=
{
[
UNIPHIER_SOC_LD11
]
=
true
,
[
UNIPHIER_SOC_LD20
]
=
true
,
[
UNIPHIER_SOC_PXS3
]
=
false
,
};
unsigned
int
uniphier_get_boot_master
(
unsigned
int
soc
)
{
assert
(
soc
<
ARRAY_SIZE
(
uniphier_have_onchip_scp
));
if
(
uniphier_have_onchip_scp
[
soc
])
{
if
(
mmio_read_32
(
UNIPHIER_PINMON0
)
&
BIT
(
27
))
return
UNIPHIER_BOOT_MASTER_THIS
;
else
return
UNIPHIER_BOOT_MASTER_SCP
;
}
else
{
return
UNIPHIER_BOOT_MASTER_EXT
;
}
}
plat/socionext/uniphier/uniphier_cci.c
0 → 100644
View file @
1502c4e1
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <cci.h>
#include <stddef.h>
#include <utils_def.h>
#include "uniphier.h"
#define UNIPHIER_CCI500_BASE 0x5FD00000
static
const
int
uniphier_cci_map
[]
=
{
0
,
1
};
static
void
__uniphier_cci_init
(
void
)
{
cci_init
(
UNIPHIER_CCI500_BASE
,
uniphier_cci_map
,
ARRAY_SIZE
(
uniphier_cci_map
));
}
static
void
__uniphier_cci_enable
(
void
)
{
cci_enable_snoop_dvm_reqs
(
MPIDR_AFFLVL1_VAL
(
read_mpidr_el1
()));
}
static
void
__uniphier_cci_disable
(
void
)
{
cci_disable_snoop_dvm_reqs
(
MPIDR_AFFLVL1_VAL
(
read_mpidr_el1
()));
}
struct
uniphier_cci_ops
{
void
(
*
init
)(
void
);
void
(
*
enable
)(
void
);
void
(
*
disable
)(
void
);
};
static
const
struct
uniphier_cci_ops
uniphier_cci_ops_table
[]
=
{
[
UNIPHIER_SOC_LD11
]
=
{
.
init
=
NULL
,
.
enable
=
NULL
,
.
disable
=
NULL
,
},
[
UNIPHIER_SOC_LD20
]
=
{
.
init
=
__uniphier_cci_init
,
.
enable
=
__uniphier_cci_enable
,
.
disable
=
__uniphier_cci_disable
,
},
[
UNIPHIER_SOC_PXS3
]
=
{
.
init
=
NULL
,
.
enable
=
NULL
,
.
disable
=
NULL
,
},
};
static
struct
uniphier_cci_ops
uniphier_cci_ops
;
void
uniphier_cci_init
(
unsigned
int
soc
)
{
uniphier_cci_ops
=
uniphier_cci_ops_table
[
soc
];
flush_dcache_range
((
uint64_t
)
&
uniphier_cci_ops
,
sizeof
(
uniphier_cci_ops
));
if
(
uniphier_cci_ops
.
init
)
uniphier_cci_ops
.
init
();
}
void
uniphier_cci_enable
(
void
)
{
if
(
uniphier_cci_ops
.
enable
)
uniphier_cci_ops
.
enable
();
}
void
uniphier_cci_disable
(
void
)
{
if
(
uniphier_cci_ops
.
disable
)
uniphier_cci_ops
.
disable
();
}
plat/socionext/uniphier/uniphier_console.S
0 → 100644
View file @
1502c4e1
/*
*
Copyright
(
c
)
2017
,
ARM
Limited
and
Contributors
.
All
rights
reserved
.
*
*
SPDX
-
License
-
Identifier
:
BSD
-
3
-
Clause
*/
#include <asm_macros.S>
#define UNIPHIER_UART_BASE 0x54006800
#define UNIPHIER_UART_END 0x54006c00
#define UNIPHIER_UART_OFFSET 0x100
#define UNIPHIER_UART_RX 0x00 /* In: Receive buffer */
#define UNIPHIER_UART_TX 0x00 /* Out: Transmit buffer */
#define UNIPHIER_UART_FCR 0x0c /* Char/FIFO Control Register */
#define UNIPHIER_UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */
#define UNIPHIER_UART_LCR_MCR 0x10 /* Line/Modem Control Register */
#define UNIPHIER_UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
#define UNIPHIER_UART_LSR 0x14 /* Line Status Register */
#define UNIPHIER_UART_LSR_TEMT_BIT 6 /* Transmitter empty */
#define UNIPHIER_UART_LSR_THRE_BIT 5 /* Transmit-hold-register empty */
#define UNIPHIER_UART_LSR_DR_BIT 0 /* Receiver data ready */
#define UNIPHIER_UART_DLR 0x24 /* Divisor Latch Register */
/*
*
Uncomment
for
debug
*/
/*
#
define
UNIPHIER_UART_INIT_DIVISOR
*/
#define UNIPHIER_UART_DEFAULT_BASE (UNIPHIER_UART_BASE)
#define UNIPHIER_UART_CLK_RATE 58820000
#define UNIPHIER_UART_DEFAULT_BAUDRATE 115200
/*
*
In
:
x0
-
console
base
address
*
w1
-
uart
clock
in
Hz
*
w2
-
baud
rate
*
Out
:
return
1
on
success
,
or
0
on
error
*/
.
globl
console_core_init
func
console_core_init
cbz
x0
,
1
f
#ifdef UNIPHIER_UART_INIT_DIVISOR
cbz
w1
,
1
f
cbz
w2
,
1
f
/
*
divisor
=
uart_clock
/
(
16
*
baud_rate
)
*/
udiv
w2
,
w1
,
w2
lsr
w2
,
w2
,
#
4
#endif
/
*
Make
sure
the
transmitter
is
empty
before
the
divisor
set
/
change
*/
0
:
ldr
w1
,
[
x0
,
#
UNIPHIER_UART_LSR
]
tbz
w1
,
#
UNIPHIER_UART_LSR_TEMT_BIT
,
0
b
#ifdef UNIPHIER_UART_INIT_DIVISOR
str
w2
,
[
x0
,
#
UNIPHIER_UART_DLR
]
#endif
mov
w2
,
#
UNIPHIER_UART_FCR_ENABLE_FIFO
str
w2
,
[
x0
,
#
UNIPHIER_UART_FCR
]
mov
w2
,
#(
UNIPHIER_UART_LCR_WLEN8
<<
8
)
str
w2
,
[
x0
,
#
UNIPHIER_UART_LCR_MCR
]
mov
w0
,
#
1
ret
1
:
mov
w0
,
#
0
ret
endfunc
console_core_init
/*
*
In
:
w0
-
character
to
be
printed
*
x1
-
console
base
address
*
Out
:
return
the
character
written
,
or
-
1
on
error
*
Clobber
:
x2
*/
.
globl
console_core_putc
func
console_core_putc
/
*
Error
out
if
the
console
is
not
initialized
*/
cbz
x1
,
2
f
/
*
Wait
until
the
transmitter
FIFO
gets
empty
*/
0
:
ldr
w2
,
[
x1
,
#
UNIPHIER_UART_LSR
]
tbz
w2
,
#
UNIPHIER_UART_LSR_THRE_BIT
,
0
b
mov
w2
,
w0
1
:
str
w2
,
[
x1
,
#
UNIPHIER_UART_TX
]
cmp
w2
,
#
'\n'
b.ne
3
f
mov
w2
,
#
'\r'
/*
Append
'\r'
to
'\n'
*/
b
1
b
2
:
mov
w0
,
#-
1
3
:
ret
endfunc
console_core_putc
/*
*
In
:
x0
-
console
base
address
*
Out
:
return
the
character
read
*
Clobber
:
x1
*/
.
globl
console_core_getc
func
console_core_getc
/
*
Error
out
if
the
console
is
not
initialized
*/
cbz
x0
,
1
f
/
*
Wait
while
the
receiver
FIFO
is
empty
*/
0
:
ldr
w1
,
[
x0
,
#
UNIPHIER_UART_LSR
]
tbz
w1
,
#
UNIPHIER_UART_LSR_DR_BIT
,
0
b
ldr
w0
,
[
x0
,
#
UNIPHIER_UART_RX
]
ret
1
:
mov
w0
,
#-
1
ret
endfunc
console_core_getc
/*
*
In
:
x0
-
console
base
address
*
Out
:
return
0
,
or
-
1
on
error
*
Clobber
:
x1
*/
.
global
console_core_flush
func
console_core_flush
/
*
Error
out
if
the
console
is
not
initialized
*/
cbz
x0
,
1
f
/
*
wait
until
the
transmitter
gets
empty
*/
0
:
ldr
w1
,
[
x0
,
#
UNIPHIER_UART_LSR
]
tbz
w1
,
#
UNIPHIER_UART_LSR_TEMT_BIT
,
0
b
mov
w0
,
#
0
ret
1
:
mov
w0
,
#-
1
ret
endfunc
console_core_flush
/*
find
initialized
UART
port
*/
.
macro
uniphier_console_get_base
base
,
tmpx
,
tmpw
ldr
\
base
,
=
UNIPHIER_UART_BASE
0000
:
ldr
\
tmpw
,
[
\
base
,
#
UNIPHIER_UART_DLR
]
mvn
\
tmpw
,
\
tmpw
uxth
\
tmpw
,
\
tmpw
cbnz
\
tmpw
,
0001
f
add
\
base
,
\
base
,
#
UNIPHIER_UART_OFFSET
ldr
\
tmpx
,
=
UNIPHIER_UART_END
cmp
\
base
,
\
tmpx
b.lo
0000
b
mov
\
base
,
#
0
0001
:
.
endm
/*
*
int
plat_crash_console_init
(
void
)
*
Clobber
:
x0
-
x2
*/
.
globl
plat_crash_console_init
func
plat_crash_console_init
#ifdef UNIPHIER_UART_INIT_DIVISOR
ldr
x0
,
=
UNIPHIER_UART_DEFAULT_BASE
ldr
x1
,
=
UNIPHIER_UART_CLK_RATE
ldr
x2
,
=
UNIPHIER_UART_DEFAULT_BAUDRATE
b
console_core_init
#else
ret
#endif
endfunc
plat_crash_console_init
/*
*
int
plat_crash_console_putc
(
int
c
)
*
Clobber
:
x1
,
x2
*/
.
globl
plat_crash_console_putc
func
plat_crash_console_putc
#ifdef UNIPHIER_UART_INIT_DIVISOR
ldr
x1
,
=
UNIPHIER_UART_DEFAULT_BASE
#else
uniphier_console_get_base
x1
,
x2
,
w2
#endif
b
console_core_putc
endfunc
plat_crash_console_putc
/*
*
int
plat_crash_console_flush
(
void
)
*
Clobber
:
x0
,
x1
*/
.
global
plat_crash_console_flush
func
plat_crash_console_flush
#ifdef UNIPHIER_UART_INIT_DIVISOR
ldr
x0
,
=
UNIPHIER_UART_DEFAULT_BASE
#else
uniphier_console_get_base
x0
,
x1
,
w1
#endif
b
console_core_flush
endfunc
plat_crash_console_flush
/*
*
void
uniphier_console_setup
(
void
)
*
Clobber
:
x0
-
x2
*/
.
globl
uniphier_console_setup
func
uniphier_console_setup
#ifdef UNIPHIER_UART_INIT_DIVISOR
ldr
x0
,
=
UNIPHIER_UART_DEFAULT_BASE
ldr
w1
,
=
UNIPHIER_UART_CLK_RATE
ldr
w2
,
=
UNIPHIER_UART_DEFAULT_BAUDRATE
#else
uniphier_console_get_base
x0
,
x1
,
w1
mov
w1
,
#
0
mov
w2
,
#
0
#endif
b
console_init
endfunc
uniphier_console_setup
plat/socionext/uniphier/uniphier_emmc.c
0 → 100644
View file @
1502c4e1
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <assert.h>
#include <io/io_block.h>
#include <mmio.h>
#include <platform_def.h>
#include <sys/types.h>
#include <utils_def.h>
#include "uniphier.h"
#define MMC_CMD_SWITCH 6
#define MMC_CMD_SELECT_CARD 7
#define MMC_CMD_SEND_CSD 9
#define MMC_CMD_READ_MULTIPLE_BLOCK 18
#define EXT_CSD_PART_CONF 179
/* R/W */
#define MMC_RSP_PRESENT BIT(0)
#define MMC_RSP_136 BIT(1)
/* 136 bit response */
#define MMC_RSP_CRC BIT(2)
/* expect valid crc */
#define MMC_RSP_BUSY BIT(3)
/* card may send busy */
#define MMC_RSP_OPCODE BIT(4)
/* response contains opcode */
#define MMC_RSP_NONE (0)
#define MMC_RSP_R1 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
#define MMC_RSP_R1b (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | \
MMC_RSP_BUSY)
#define MMC_RSP_R2 (MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC)
#define MMC_RSP_R3 (MMC_RSP_PRESENT)
#define MMC_RSP_R4 (MMC_RSP_PRESENT)
#define MMC_RSP_R5 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
#define MMC_RSP_R6 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
#define MMC_RSP_R7 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
#define SDHCI_DMA_ADDRESS 0x00
#define SDHCI_BLOCK_SIZE 0x04
#define SDHCI_MAKE_BLKSZ(dma, blksz) ((((dma) & 0x7) << 12) | ((blksz) & 0xFFF))
#define SDHCI_BLOCK_COUNT 0x06
#define SDHCI_ARGUMENT 0x08
#define SDHCI_TRANSFER_MODE 0x0C
#define SDHCI_TRNS_DMA BIT(0)
#define SDHCI_TRNS_BLK_CNT_EN BIT(1)
#define SDHCI_TRNS_ACMD12 BIT(2)
#define SDHCI_TRNS_READ BIT(4)
#define SDHCI_TRNS_MULTI BIT(5)
#define SDHCI_COMMAND 0x0E
#define SDHCI_CMD_RESP_MASK 0x03
#define SDHCI_CMD_CRC 0x08
#define SDHCI_CMD_INDEX 0x10
#define SDHCI_CMD_DATA 0x20
#define SDHCI_CMD_ABORTCMD 0xC0
#define SDHCI_CMD_RESP_NONE 0x00
#define SDHCI_CMD_RESP_LONG 0x01
#define SDHCI_CMD_RESP_SHORT 0x02
#define SDHCI_CMD_RESP_SHORT_BUSY 0x03
#define SDHCI_MAKE_CMD(c, f) ((((c) & 0xff) << 8) | ((f) & 0xff))
#define SDHCI_RESPONSE 0x10
#define SDHCI_HOST_CONTROL 0x28
#define SDHCI_CTRL_DMA_MASK 0x18
#define SDHCI_CTRL_SDMA 0x00
#define SDHCI_BLOCK_GAP_CONTROL 0x2A
#define SDHCI_SOFTWARE_RESET 0x2F
#define SDHCI_RESET_CMD 0x02
#define SDHCI_RESET_DATA 0x04
#define SDHCI_INT_STATUS 0x30
#define SDHCI_INT_RESPONSE BIT(0)
#define SDHCI_INT_DATA_END BIT(1)
#define SDHCI_INT_DMA_END BIT(3)
#define SDHCI_INT_ERROR BIT(15)
#define SDHCI_SIGNAL_ENABLE 0x38
/* RCA assigned by Boot ROM */
#define UNIPHIER_EMMC_RCA 0x1000
struct
uniphier_mmc_cmd
{
unsigned
int
cmdidx
;
unsigned
int
resp_type
;
unsigned
int
cmdarg
;
unsigned
int
is_data
;
};
static
int
uniphier_emmc_block_addressing
;
static
int
uniphier_emmc_send_cmd
(
uintptr_t
host_base
,
struct
uniphier_mmc_cmd
*
cmd
)
{
uint32_t
mode
=
0
;
uint32_t
end_bit
;
uint32_t
stat
,
flags
,
dma_addr
;
mmio_write_32
(
host_base
+
SDHCI_INT_STATUS
,
-
1
);
mmio_write_32
(
host_base
+
SDHCI_SIGNAL_ENABLE
,
0
);
mmio_write_32
(
host_base
+
SDHCI_ARGUMENT
,
cmd
->
cmdarg
);
if
(
cmd
->
is_data
)
mode
=
SDHCI_TRNS_DMA
|
SDHCI_TRNS_BLK_CNT_EN
|
SDHCI_TRNS_ACMD12
|
SDHCI_TRNS_READ
|
SDHCI_TRNS_MULTI
;
mmio_write_16
(
host_base
+
SDHCI_TRANSFER_MODE
,
mode
);
if
(
!
(
cmd
->
resp_type
&
MMC_RSP_PRESENT
))
flags
=
SDHCI_CMD_RESP_NONE
;
else
if
(
cmd
->
resp_type
&
MMC_RSP_136
)
flags
=
SDHCI_CMD_RESP_LONG
;
else
if
(
cmd
->
resp_type
&
MMC_RSP_BUSY
)
flags
=
SDHCI_CMD_RESP_SHORT_BUSY
;
else
flags
=
SDHCI_CMD_RESP_SHORT
;
if
(
cmd
->
resp_type
&
MMC_RSP_CRC
)
flags
|=
SDHCI_CMD_CRC
;
if
(
cmd
->
resp_type
&
MMC_RSP_OPCODE
)
flags
|=
SDHCI_CMD_INDEX
;
if
(
cmd
->
is_data
)
flags
|=
SDHCI_CMD_DATA
;
if
(
cmd
->
resp_type
&
MMC_RSP_BUSY
||
cmd
->
is_data
)
end_bit
=
SDHCI_INT_DATA_END
;
else
end_bit
=
SDHCI_INT_RESPONSE
;
mmio_write_16
(
host_base
+
SDHCI_COMMAND
,
SDHCI_MAKE_CMD
(
cmd
->
cmdidx
,
flags
));
do
{
stat
=
mmio_read_32
(
host_base
+
SDHCI_INT_STATUS
);
if
(
stat
&
SDHCI_INT_ERROR
)
return
-
EIO
;
if
(
stat
&
SDHCI_INT_DMA_END
)
{
mmio_write_32
(
host_base
+
SDHCI_INT_STATUS
,
stat
);
dma_addr
=
mmio_read_32
(
host_base
+
SDHCI_DMA_ADDRESS
);
mmio_write_32
(
host_base
+
SDHCI_DMA_ADDRESS
,
dma_addr
);
}
}
while
(
!
(
stat
&
end_bit
));
return
0
;
}
static
int
uniphier_emmc_switch_part
(
uintptr_t
host_base
,
int
part_num
)
{
struct
uniphier_mmc_cmd
cmd
=
{
0
};
cmd
.
cmdidx
=
MMC_CMD_SWITCH
;
cmd
.
resp_type
=
MMC_RSP_R1b
;
cmd
.
cmdarg
=
(
EXT_CSD_PART_CONF
<<
16
)
|
(
part_num
<<
8
)
|
(
3
<<
24
);
return
uniphier_emmc_send_cmd
(
host_base
,
&
cmd
);
}
static
int
uniphier_emmc_is_over_2gb
(
uintptr_t
host_base
)
{
struct
uniphier_mmc_cmd
cmd
=
{
0
};
uint32_t
csd40
,
csd72
;
/* CSD[71:40], CSD[103:72] */
int
ret
;
cmd
.
cmdidx
=
MMC_CMD_SEND_CSD
;
cmd
.
resp_type
=
MMC_RSP_R2
;
cmd
.
cmdarg
=
UNIPHIER_EMMC_RCA
<<
16
;
ret
=
uniphier_emmc_send_cmd
(
host_base
,
&
cmd
);
if
(
ret
)
return
ret
;
csd40
=
mmio_read_32
(
host_base
+
SDHCI_RESPONSE
+
4
);
csd72
=
mmio_read_32
(
host_base
+
SDHCI_RESPONSE
+
8
);
return
!
(
~
csd40
&
0xffc00380
)
&&
!
(
~
csd72
&
0x3
);
}
static
int
uniphier_emmc_load_image
(
uintptr_t
host_base
,
uint32_t
dev_addr
,
unsigned
long
load_addr
,
uint32_t
block_cnt
)
{
struct
uniphier_mmc_cmd
cmd
=
{
0
};
uint8_t
tmp
;
assert
((
load_addr
>>
32
)
==
0
);
mmio_write_32
(
host_base
+
SDHCI_DMA_ADDRESS
,
load_addr
);
mmio_write_16
(
host_base
+
SDHCI_BLOCK_SIZE
,
SDHCI_MAKE_BLKSZ
(
7
,
512
));
mmio_write_16
(
host_base
+
SDHCI_BLOCK_COUNT
,
block_cnt
);
tmp
=
mmio_read_8
(
host_base
+
SDHCI_HOST_CONTROL
);
tmp
&=
~
SDHCI_CTRL_DMA_MASK
;
tmp
|=
SDHCI_CTRL_SDMA
;
mmio_write_8
(
host_base
+
SDHCI_HOST_CONTROL
,
tmp
);
tmp
=
mmio_read_8
(
host_base
+
SDHCI_BLOCK_GAP_CONTROL
);
tmp
&=
~
1
;
/* clear Stop At Block Gap Request */
mmio_write_8
(
host_base
+
SDHCI_BLOCK_GAP_CONTROL
,
tmp
);
cmd
.
cmdidx
=
MMC_CMD_READ_MULTIPLE_BLOCK
;
cmd
.
resp_type
=
MMC_RSP_R1
;
cmd
.
cmdarg
=
dev_addr
;
cmd
.
is_data
=
1
;
return
uniphier_emmc_send_cmd
(
host_base
,
&
cmd
);
}
static
size_t
uniphier_emmc_read
(
int
lba
,
uintptr_t
buf
,
size_t
size
)
{
uintptr_t
host_base
=
0x5a000200
;
int
ret
;
inv_dcache_range
(
buf
,
size
);
if
(
!
uniphier_emmc_block_addressing
)
lba
*=
512
;
ret
=
uniphier_emmc_load_image
(
host_base
,
lba
,
buf
,
size
/
512
);
inv_dcache_range
(
buf
,
size
);
return
ret
?
0
:
size
;
}
static
const
struct
io_block_dev_spec
uniphier_emmc_dev_spec
=
{
.
buffer
=
{
.
offset
=
UNIPHIER_BLOCK_BUF_BASE
,
.
length
=
UNIPHIER_BLOCK_BUF_SIZE
,
},
.
ops
=
{
.
read
=
uniphier_emmc_read
,
},
.
block_size
=
512
,
};
static
int
uniphier_emmc_hw_init
(
void
)
{
uintptr_t
host_base
=
0x5a000200
;
struct
uniphier_mmc_cmd
cmd
=
{
0
};
int
ret
;
/*
* deselect card before SEND_CSD command.
* Do not check the return code. It fails, but it is OK.
*/
cmd
.
cmdidx
=
MMC_CMD_SELECT_CARD
;
cmd
.
resp_type
=
MMC_RSP_R1
;
uniphier_emmc_send_cmd
(
host_base
,
&
cmd
);
/* CMD7 (arg=0) */
/* reset CMD Line */
mmio_write_8
(
host_base
+
SDHCI_SOFTWARE_RESET
,
SDHCI_RESET_CMD
|
SDHCI_RESET_DATA
);
while
(
mmio_read_8
(
host_base
+
SDHCI_SOFTWARE_RESET
))
;
ret
=
uniphier_emmc_is_over_2gb
(
host_base
);
if
(
ret
<
0
)
return
ret
;
uniphier_emmc_block_addressing
=
ret
;
cmd
.
cmdarg
=
UNIPHIER_EMMC_RCA
<<
16
;
/* select card again */
ret
=
uniphier_emmc_send_cmd
(
host_base
,
&
cmd
);
if
(
ret
)
return
ret
;
/* switch to Boot Partition 1 */
ret
=
uniphier_emmc_switch_part
(
host_base
,
1
);
if
(
ret
)
return
ret
;
return
0
;
}
int
uniphier_emmc_init
(
uintptr_t
*
block_dev_spec
)
{
int
ret
;
ret
=
uniphier_emmc_hw_init
();
if
(
ret
)
return
ret
;
*
block_dev_spec
=
(
uintptr_t
)
&
uniphier_emmc_dev_spec
;
return
0
;
}
plat/socionext/uniphier/uniphier_gicv3.c
0 → 100644
View file @
1502c4e1
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <gicv3.h>
#include <platform.h>
#include <platform_def.h>
#include "uniphier.h"
static
uintptr_t
uniphier_rdistif_base_addrs
[
PLATFORM_CORE_COUNT
];
static
const
unsigned
int
g0_interrupt_array
[]
=
{
8
,
/* SGI0 */
14
,
/* SGI6 */
};
static
const
unsigned
int
g1s_interrupt_array
[]
=
{
29
,
/* Timer */
9
,
/* SGI1 */
10
,
/* SGI2 */
11
,
/* SGI3 */
12
,
/* SGI4 */
13
,
/* SGI5 */
15
,
/* SGI7 */
};
static
unsigned
int
uniphier_mpidr_to_core_pos
(
u_register_t
mpidr
)
{
return
plat_core_pos_by_mpidr
(
mpidr
);
}
static
const
struct
gicv3_driver_data
uniphier_gic_driver_data
[]
=
{
[
UNIPHIER_SOC_LD11
]
=
{
.
gicd_base
=
0x5fe00000
,
.
gicr_base
=
0x5fe40000
,
.
g0_interrupt_num
=
ARRAY_SIZE
(
g0_interrupt_array
),
.
g1s_interrupt_num
=
ARRAY_SIZE
(
g1s_interrupt_array
),
.
g0_interrupt_array
=
g0_interrupt_array
,
.
g1s_interrupt_array
=
g1s_interrupt_array
,
.
rdistif_num
=
PLATFORM_CORE_COUNT
,
.
rdistif_base_addrs
=
uniphier_rdistif_base_addrs
,
.
mpidr_to_core_pos
=
uniphier_mpidr_to_core_pos
,
},
[
UNIPHIER_SOC_LD20
]
=
{
.
gicd_base
=
0x5fe00000
,
.
gicr_base
=
0x5fe80000
,
.
g0_interrupt_num
=
ARRAY_SIZE
(
g0_interrupt_array
),
.
g1s_interrupt_num
=
ARRAY_SIZE
(
g1s_interrupt_array
),
.
g0_interrupt_array
=
g0_interrupt_array
,
.
g1s_interrupt_array
=
g1s_interrupt_array
,
.
rdistif_num
=
PLATFORM_CORE_COUNT
,
.
rdistif_base_addrs
=
uniphier_rdistif_base_addrs
,
.
mpidr_to_core_pos
=
uniphier_mpidr_to_core_pos
,
},
[
UNIPHIER_SOC_PXS3
]
=
{
.
gicd_base
=
0x5fe00000
,
.
gicr_base
=
0x5fe80000
,
.
g0_interrupt_num
=
ARRAY_SIZE
(
g0_interrupt_array
),
.
g1s_interrupt_num
=
ARRAY_SIZE
(
g1s_interrupt_array
),
.
g0_interrupt_array
=
g0_interrupt_array
,
.
g1s_interrupt_array
=
g1s_interrupt_array
,
.
rdistif_num
=
PLATFORM_CORE_COUNT
,
.
rdistif_base_addrs
=
uniphier_rdistif_base_addrs
,
.
mpidr_to_core_pos
=
uniphier_mpidr_to_core_pos
,
},
};
void
uniphier_gic_driver_init
(
unsigned
int
soc
)
{
assert
(
soc
<
ARRAY_SIZE
(
uniphier_gic_driver_data
));
gicv3_driver_init
(
&
uniphier_gic_driver_data
[
soc
]);
}
void
uniphier_gic_init
(
void
)
{
gicv3_distif_init
();
gicv3_rdistif_init
(
plat_my_core_pos
());
gicv3_cpuif_enable
(
plat_my_core_pos
());
}
void
uniphier_gic_cpuif_enable
(
void
)
{
gicv3_cpuif_enable
(
plat_my_core_pos
());
}
void
uniphier_gic_cpuif_disable
(
void
)
{
gicv3_cpuif_disable
(
plat_my_core_pos
());
}
void
uniphier_gic_pcpu_init
(
void
)
{
gicv3_rdistif_init
(
plat_my_core_pos
());
}
plat/socionext/uniphier/uniphier_helpers.S
0 → 100644
View file @
1502c4e1
/*
*
Copyright
(
c
)
2017
,
ARM
Limited
and
Contributors
.
All
rights
reserved
.
*
*
SPDX
-
License
-
Identifier
:
BSD
-
3
-
Clause
*/
#include <asm_macros.S>
#include <platform_def.h>
.
global
uniphier_calc_core_pos
.
global
plat_my_core_pos
.
globl
platform_mem_init
/*
*
unsigned
int
uniphier_calc_core_pos
(
u_register_t
mpidr
)
*
core_pos
=
(
cluster_id
*
max_cpus_per_cluster
)
+
core_id
*/
func
uniphier_calc_core_pos
and
x1
,
x0
,
#
MPIDR_CPU_MASK
and
x0
,
x0
,
#
MPIDR_CLUSTER_MASK
lsr
x0
,
x0
,
#
MPIDR_AFFINITY_BITS
mov
x2
,
#
UNIPHIER_MAX_CPUS_PER_CLUSTER
madd
x0
,
x0
,
x2
,
x1
ret
endfunc
uniphier_calc_core_pos
func
plat_my_core_pos
mrs
x0
,
mpidr_el1
b
uniphier_calc_core_pos
endfunc
plat_my_core_pos
func
platform_mem_init
ret
endfunc
platform_mem_init
plat/socionext/uniphier/uniphier_image_desc.c
0 → 100644
View file @
1502c4e1
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <assert.h>
#include <desc_image_load.h>
#include <platform_def.h>
#include "uniphier.h"
static
struct
bl_mem_params_node
uniphier_image_descs
[]
=
{
{
.
image_id
=
SCP_BL2_IMAGE_ID
,
SET_STATIC_PARAM_HEAD
(
image_info
,
PARAM_EP
,
VERSION_2
,
image_info_t
,
0
),
.
image_info
.
image_base
=
UNIPHIER_SCP_BASE
,
.
image_info
.
image_max_size
=
UNIPHIER_SCP_MAX_SIZE
,
SET_STATIC_PARAM_HEAD
(
ep_info
,
PARAM_EP
,
VERSION_2
,
entry_point_info_t
,
NON_SECURE
|
NON_EXECUTABLE
),
.
next_handoff_image_id
=
INVALID_IMAGE_ID
,
},
{
.
image_id
=
BL31_IMAGE_ID
,
SET_STATIC_PARAM_HEAD
(
image_info
,
PARAM_EP
,
VERSION_2
,
image_info_t
,
0
),
.
image_info
.
image_base
=
BL31_BASE
,
.
image_info
.
image_max_size
=
BL31_LIMIT
-
BL31_BASE
,
SET_STATIC_PARAM_HEAD
(
ep_info
,
PARAM_EP
,
VERSION_2
,
entry_point_info_t
,
SECURE
|
EXECUTABLE
|
EP_FIRST_EXE
),
.
ep_info
.
pc
=
BL31_BASE
,
.
ep_info
.
spsr
=
SPSR_64
(
MODE_EL3
,
MODE_SP_ELX
,
DISABLE_ALL_EXCEPTIONS
),
#ifdef UNIPHIER_LOAD_BL32
.
next_handoff_image_id
=
BL32_IMAGE_ID
,
#else
.
next_handoff_image_id
=
BL33_IMAGE_ID
,
#endif
},
#ifdef UNIPHIER_LOAD_BL32
{
.
image_id
=
BL32_IMAGE_ID
,
SET_STATIC_PARAM_HEAD
(
image_info
,
PARAM_EP
,
VERSION_2
,
image_info_t
,
0
),
.
image_info
.
image_base
=
BL32_BASE
,
.
image_info
.
image_max_size
=
BL32_LIMIT
-
BL32_BASE
,
SET_STATIC_PARAM_HEAD
(
ep_info
,
PARAM_EP
,
VERSION_2
,
entry_point_info_t
,
SECURE
|
EXECUTABLE
),
.
ep_info
.
pc
=
BL32_BASE
,
.
ep_info
.
spsr
=
SPSR_64
(
MODE_EL3
,
MODE_SP_ELX
,
DISABLE_ALL_EXCEPTIONS
),
.
next_handoff_image_id
=
BL33_IMAGE_ID
,
},
#endif
{
.
image_id
=
BL33_IMAGE_ID
,
SET_STATIC_PARAM_HEAD
(
image_info
,
PARAM_EP
,
VERSION_2
,
image_info_t
,
0
),
.
image_info
.
image_base
=
UNIPHIER_BL33_BASE
,
.
image_info
.
image_max_size
=
UNIPHIER_BL33_MAX_SIZE
,
SET_STATIC_PARAM_HEAD
(
ep_info
,
PARAM_EP
,
VERSION_2
,
entry_point_info_t
,
NON_SECURE
|
EXECUTABLE
),
.
ep_info
.
pc
=
UNIPHIER_BL33_BASE
,
.
ep_info
.
spsr
=
SPSR_64
(
MODE_EL1
,
MODE_SP_ELX
,
DISABLE_ALL_EXCEPTIONS
),
.
next_handoff_image_id
=
INVALID_IMAGE_ID
,
},
};
REGISTER_BL_IMAGE_DESCS
(
uniphier_image_descs
)
/* SCP is optional. Allow run-time fixup of the descriptor array. */
void
uniphier_image_descs_fixup
(
void
)
{
struct
bl_mem_params_node
*
desc
;
desc
=
get_bl_mem_params_node
(
SCP_BL2_IMAGE_ID
);
assert
(
desc
!=
NULL
);
desc
->
image_info
.
h
.
attr
|=
IMAGE_ATTRIB_SKIP_LOADING
;
}
plat/socionext/uniphier/uniphier_io_storage.c
0 → 100644
View file @
1502c4e1
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <errno.h>
#include <firmware_image_package.h>
#include <io/io_block.h>
#include <io/io_driver.h>
#include <io/io_fip.h>
#include <io/io_memmap.h>
#include <platform_def.h>
#include <types.h>
#include <utils_def.h>
#include <xlat_tables_v2.h>
#include "uniphier.h"
#define UNIPHIER_ROM_REGION_BASE 0x00000000
#define UNIPHIER_ROM_REGION_SIZE 0x10000000
static
const
io_dev_connector_t
*
uniphier_fip_dev_con
;
static
uintptr_t
uniphier_fip_dev_handle
;
static
const
io_dev_connector_t
*
uniphier_backend_dev_con
;
static
uintptr_t
uniphier_backend_dev_handle
;
static
io_block_spec_t
uniphier_fip_spec
=
{
/* .offset will be set by the io_setup func */
.
length
=
0x00200000
,
};
static
const
io_uuid_spec_t
uniphier_bl2_spec
=
{
.
uuid
=
UUID_TRUSTED_BOOT_FIRMWARE_BL2
,
};
static
const
io_uuid_spec_t
uniphier_scp_spec
=
{
.
uuid
=
UUID_SCP_FIRMWARE_SCP_BL2
,
};
static
const
io_uuid_spec_t
uniphier_bl31_spec
=
{
.
uuid
=
UUID_EL3_RUNTIME_FIRMWARE_BL31
,
};
static
const
io_uuid_spec_t
uniphier_bl32_spec
=
{
.
uuid
=
UUID_SECURE_PAYLOAD_BL32
,
};
static
const
io_uuid_spec_t
uniphier_bl33_spec
=
{
.
uuid
=
UUID_NON_TRUSTED_FIRMWARE_BL33
,
};
#if TRUSTED_BOARD_BOOT
static
const
io_uuid_spec_t
uniphier_tb_fw_cert_spec
=
{
.
uuid
=
UUID_TRUSTED_BOOT_FW_CERT
,
};
static
const
io_uuid_spec_t
uniphier_trusted_key_cert_spec
=
{
.
uuid
=
UUID_TRUSTED_KEY_CERT
,
};
static
const
io_uuid_spec_t
uniphier_scp_fw_key_cert_spec
=
{
.
uuid
=
UUID_SCP_FW_KEY_CERT
,
};
static
const
io_uuid_spec_t
uniphier_soc_fw_key_cert_spec
=
{
.
uuid
=
UUID_SOC_FW_KEY_CERT
,
};
static
const
io_uuid_spec_t
uniphier_tos_fw_key_cert_spec
=
{
.
uuid
=
UUID_TRUSTED_OS_FW_KEY_CERT
,
};
static
const
io_uuid_spec_t
uniphier_nt_fw_key_cert_spec
=
{
.
uuid
=
UUID_NON_TRUSTED_FW_KEY_CERT
,
};
static
const
io_uuid_spec_t
uniphier_scp_fw_cert_spec
=
{
.
uuid
=
UUID_SCP_FW_CONTENT_CERT
,
};
static
const
io_uuid_spec_t
uniphier_soc_fw_cert_spec
=
{
.
uuid
=
UUID_SOC_FW_CONTENT_CERT
,
};
static
const
io_uuid_spec_t
uniphier_tos_fw_cert_spec
=
{
.
uuid
=
UUID_TRUSTED_OS_FW_CONTENT_CERT
,
};
static
const
io_uuid_spec_t
uniphier_nt_fw_cert_spec
=
{
.
uuid
=
UUID_NON_TRUSTED_FW_CONTENT_CERT
,
};
#endif
/* TRUSTED_BOARD_BOOT */
struct
uniphier_io_policy
{
uintptr_t
*
dev_handle
;
uintptr_t
image_spec
;
uintptr_t
init_params
;
};
static
const
struct
uniphier_io_policy
uniphier_io_policies
[]
=
{
[
FIP_IMAGE_ID
]
=
{
.
dev_handle
=
&
uniphier_backend_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_fip_spec
,
},
[
BL2_IMAGE_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_bl2_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
[
SCP_BL2_IMAGE_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_scp_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
[
BL31_IMAGE_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_bl31_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
[
BL32_IMAGE_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_bl32_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
[
BL33_IMAGE_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_bl33_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
#if TRUSTED_BOARD_BOOT
[
TRUSTED_BOOT_FW_CERT_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_tb_fw_cert_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
[
TRUSTED_KEY_CERT_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_trusted_key_cert_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
[
SCP_FW_KEY_CERT_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_scp_fw_key_cert_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
[
SOC_FW_KEY_CERT_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_soc_fw_key_cert_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
[
TRUSTED_OS_FW_KEY_CERT_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_tos_fw_key_cert_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
[
NON_TRUSTED_FW_KEY_CERT_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_nt_fw_key_cert_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
[
SCP_FW_CONTENT_CERT_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_scp_fw_cert_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
[
SOC_FW_CONTENT_CERT_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_soc_fw_cert_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
[
TRUSTED_OS_FW_CONTENT_CERT_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_tos_fw_cert_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
[
NON_TRUSTED_FW_CONTENT_CERT_ID
]
=
{
.
dev_handle
=
&
uniphier_fip_dev_handle
,
.
image_spec
=
(
uintptr_t
)
&
uniphier_nt_fw_cert_spec
,
.
init_params
=
FIP_IMAGE_ID
,
},
#endif
};
static
int
uniphier_io_block_setup
(
size_t
fip_offset
,
uintptr_t
block_dev_spec
)
{
int
ret
;
uniphier_fip_spec
.
offset
=
fip_offset
;
ret
=
register_io_dev_block
(
&
uniphier_backend_dev_con
);
if
(
ret
)
return
ret
;
return
io_dev_open
(
uniphier_backend_dev_con
,
block_dev_spec
,
&
uniphier_backend_dev_handle
);
}
static
int
uniphier_io_memmap_setup
(
size_t
fip_offset
)
{
int
ret
;
uniphier_fip_spec
.
offset
=
fip_offset
;
ret
=
mmap_add_dynamic_region
(
fip_offset
,
fip_offset
,
uniphier_fip_spec
.
length
,
MT_RO_DATA
|
MT_SECURE
);
if
(
ret
)
return
ret
;
ret
=
register_io_dev_memmap
(
&
uniphier_backend_dev_con
);
if
(
ret
)
return
ret
;
return
io_dev_open
(
uniphier_backend_dev_con
,
0
,
&
uniphier_backend_dev_handle
);
}
static
int
uniphier_io_fip_setup
(
void
)
{
int
ret
;
ret
=
register_io_dev_fip
(
&
uniphier_fip_dev_con
);
if
(
ret
)
return
ret
;
return
io_dev_open
(
uniphier_fip_dev_con
,
0
,
&
uniphier_fip_dev_handle
);
}
static
int
uniphier_io_emmc_setup
(
unsigned
int
soc_id
)
{
uintptr_t
block_dev_spec
;
int
ret
;
ret
=
uniphier_emmc_init
(
&
block_dev_spec
);
if
(
ret
)
return
ret
;
return
uniphier_io_block_setup
(
0x20000
,
block_dev_spec
);
}
static
int
uniphier_io_nand_setup
(
unsigned
int
soc_id
)
{
uintptr_t
block_dev_spec
;
int
ret
;
ret
=
uniphier_nand_init
(
&
block_dev_spec
);
if
(
ret
)
return
ret
;
return
uniphier_io_block_setup
(
0x20000
,
block_dev_spec
);
}
static
int
uniphier_io_nor_setup
(
unsigned
int
soc_id
)
{
return
uniphier_io_memmap_setup
(
0x70000
);
}
static
int
uniphier_io_usb_setup
(
unsigned
int
soc_id
)
{
uintptr_t
block_dev_spec
;
int
ret
;
/* use ROM API for loading images from USB storage */
ret
=
mmap_add_dynamic_region
(
UNIPHIER_ROM_REGION_BASE
,
UNIPHIER_ROM_REGION_BASE
,
UNIPHIER_ROM_REGION_SIZE
,
MT_CODE
|
MT_SECURE
);
if
(
ret
)
return
ret
;
ret
=
uniphier_usb_init
(
soc_id
,
&
block_dev_spec
);
if
(
ret
)
return
ret
;
return
uniphier_io_block_setup
(
0x20000
,
block_dev_spec
);
}
static
int
(
*
const
uniphier_io_setup_table
[])(
unsigned
int
)
=
{
[
UNIPHIER_BOOT_DEVICE_EMMC
]
=
uniphier_io_emmc_setup
,
[
UNIPHIER_BOOT_DEVICE_NAND
]
=
uniphier_io_nand_setup
,
[
UNIPHIER_BOOT_DEVICE_NOR
]
=
uniphier_io_nor_setup
,
[
UNIPHIER_BOOT_DEVICE_USB
]
=
uniphier_io_usb_setup
,
};
int
uniphier_io_setup
(
unsigned
int
soc_id
)
{
int
(
*
io_setup
)(
unsigned
int
soc_id
);
unsigned
int
boot_dev
;
int
ret
;
boot_dev
=
uniphier_get_boot_device
(
soc_id
);
if
(
boot_dev
==
UNIPHIER_BOOT_DEVICE_RSV
)
return
-
EINVAL
;
io_setup
=
uniphier_io_setup_table
[
boot_dev
];
ret
=
io_setup
(
soc_id
);
if
(
ret
)
return
ret
;
ret
=
uniphier_io_fip_setup
();
if
(
ret
)
return
ret
;
return
0
;
}
int
plat_get_image_source
(
unsigned
int
image_id
,
uintptr_t
*
dev_handle
,
uintptr_t
*
image_spec
)
{
uintptr_t
init_params
;
assert
(
image_id
<
ARRAY_SIZE
(
uniphier_io_policies
));
*
dev_handle
=
*
(
uniphier_io_policies
[
image_id
].
dev_handle
);
*
image_spec
=
uniphier_io_policies
[
image_id
].
image_spec
;
init_params
=
uniphier_io_policies
[
image_id
].
init_params
;
return
io_dev_init
(
*
dev_handle
,
init_params
);
}
int
uniphier_check_image
(
unsigned
int
image_id
)
{
uintptr_t
dev_handle
,
image_spec
,
image_handle
;
int
ret
;
ret
=
plat_get_image_source
(
image_id
,
&
dev_handle
,
&
image_spec
);
if
(
ret
)
return
ret
;
ret
=
io_open
(
dev_handle
,
image_spec
,
&
image_handle
);
if
(
ret
)
return
ret
;
io_close
(
image_handle
);
return
0
;
}
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment