Commit e35d0edb authored by Jorge Ramirez-Ortiz's avatar Jorge Ramirez-Ortiz
Browse files

Poplar: Initial commit for Poplar E-96Boards

The board features the Hi3798C V200 with an integrated quad-core
64-bit ARM Cortex A53 processor and high performance Mali T720 GPU,
making it capable of running any commercial set-top solution based on
Linux or Android. Its high performance specification also supports a
premium user experience with up to H.265 HEVC decoding of 4K video at
60 frames per second.

SOC  Hisilicon Hi3798CV200
CPU  Quad-core ARM Cortex-A53 64 bit
DRAM DDR3/3L/4 SDRAM interface, maximum 32-bit data width 2 GB
USB  Two USB 2.0 ports One USB 3.0 ports
CONSOLE  USB-micro port for console support
ETHERNET  1 GBe Ethernet
PCIE  One PCIe 2.0 interfaces
JTAG  8-Pin JTAG
EXPANSION INTERFACE  Linaro 96Boards Low Speed Expansion slot
DIMENSION Standard 160×120 mm 96Boards Enterprice Edition form factor
WIFI  802.11AC 2*2 with Bluetooth
CONNECTORS  One connector for Smart Card One connector for TSI

The platform boot sequence is as follows:
    l-loader --> arm_trusted_firmware --> u-boot

Repositories:
 - https://github.com/Linaro/poplar-l-loader.git
 - https://github.com/Linaro/poplar-u-boot.git



U-Boot is also upstream in the project's master branch.

Make sure you are using the correct branch on each one of these
repositories. The definition of "correct" might change over time (at
this moment in time this would be the "latest" branch).

Build Line:
make CROSS_COMPILE=aarch64-linux-gnu-  all fip SPD=none DEBUG=1
PLAT=poplar BL33=/path/to/u-boot.bin
Signed-off-by: default avatarJorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
Signed-off-by: default avatarLeo Yan <leo.yan@linaro.org>
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Tested-by: default avatarJorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
Tested-by: default avatarLeo Yan <leo.yan@linaro.org>
Tested-by: default avatarAlex Elder <elder@linaro.org>
parent ca5ba394
Description
===========
Poplar is the first development board compliant with the 96Boards Enterprise
Edition TV Platform specification.
The board features the Hi3798C V200 with an integrated quad-core 64-bit
ARM Cortex A53 processor and high performance Mali T720 GPU, making it capable
of running any commercial set-top solution based on Linux or Android.
It supports a premium user experience with up to H.265 HEVC decoding of 4K
video at 60 frames per second.
SOC Hisilicon Hi3798CV200
CPU Quad-core ARM Cortex-A53 64 bit
DRAM DDR3/3L/4 SDRAM interface, maximum 32-bit data width 2 GB
USB Two USB 2.0 ports One USB 3.0 ports
CONSOLE USB-micro port for console support
ETHERNET 1 GBe Ethernet
PCIE One PCIe 2.0 interfaces
JTAG 8-Pin JTAG
EXPANSION INTERFACE Linaro 96Boards Low Speed Expansion slot
DIMENSION Standard 160×120 mm 96Boards Enterprice Edition form factor
WIFI 802.11AC 2*2 with Bluetooth
CONNECTORS One connector for Smart Card One connector for TSI
At the start of the boot sequence, the bootROM executes the so called l-loader
binary whose main role is to change the processor state to 64bit mode. This
must happen prior invoking the arm trusted firmware:
l-loader --> arm_trusted_firmware --> u-boot
How to build
============
Code Locations
--------------
- ARM Trusted Firmware:
`link <https://github.com/ARM-software/arm-trusted-firmware>`__
- l-loader:
`link <https://github.com/Linaro/poplar-l-loader.git>`__
- u-boot:
`link <http://git.denx.de/u-boot.git>`__
Build Procedure
---------------
- Fetch all the above 3 repositories into local host.
Make all the repositories in the same ${BUILD\_PATH}.
- Prepare the AARCH64 toolchain.
- Build u-boot using poplar_defconfig
make CROSS_COMPILE=aarch64-linux-gnu- poplar_defconfig
make CROSS_COMPILE=aarch64-linux-gnu-
- Build atf providing the previously generated u-boot.bin as the BL33 image
make CROSS_COMPILE=aarch64-linux-gnu- all fip SPD=none PLAT=poplar
BL33=u-boot.bin
- Build l-loader (generated the final fastboot.bin)
1. copy the atf generated files fip.bin and bl1.bin to l-loader/atf/
2. export ARM_TRUSTED_FIRMWARE=${ATF_SOURCE_PATH)
3. make
Install Procedure
-----------------
- Copy l-loader/fastboot.bin to a FAT partition on a USB pen drive.
- Plug the USB pen drive to any of the USB2 ports
- Power the board while keeping S3 pressed (usb_boot)
The system will boot into a u-boot shell which you can then use to write the
working firmware to eMMC.
Boot trace
==========
Bootrom start
Boot Media: eMMC
Decrypt auxiliary code ...OK
lsadc voltage min: 000000FE, max: 000000FF, aver: 000000FE, index: 00000000
Entry boot auxiliary code
Auxiliary code - v1.00
DDR code - V1.1.2 20160205
Build: Mar 24 2016 - 17:09:44
Reg Version: v134
Reg Time: 2016/03/18 09:44:55
Reg Name: hi3798cv2dmb_hi3798cv200_ddr3_2gbyte_8bitx4_4layers.reg
Boot auxiliary code success
Bootrom success
LOADER: Switched to aarch64 mode
LOADER: Entering ARM TRUSTED FIRMWARE
LOADER: CPU0 executes at 0x000ce000
INFO: BL1: 0xe1000 - 0xe7000 [size = 24576]
NOTICE: Booting Trusted Firmware
NOTICE: BL1: v1.3(debug):v1.3-372-g1ba9c60
NOTICE: BL1: Built : 17:51:33, Apr 30 2017
INFO: BL1: RAM 0xe1000 - 0xe7000
INFO: BL1: Loading BL2
INFO: Loading image id=1 at address 0xe9000
INFO: Image id=1 loaded at address 0xe9000, size = 0x5008
NOTICE: BL1: Booting BL2
INFO: Entry point address = 0xe9000
INFO: SPSR = 0x3c5
NOTICE: BL2: v1.3(debug):v1.3-372-g1ba9c60
NOTICE: BL2: Built : 17:51:33, Apr 30 2017
INFO: BL2: Loading BL31
INFO: Loading image id=3 at address 0x129000
INFO: Image id=3 loaded at address 0x129000, size = 0x8038
INFO: BL2: Loading BL33
INFO: Loading image id=5 at address 0x37000000
INFO: Image id=5 loaded at address 0x37000000, size = 0x58f17
NOTICE: BL1: Booting BL31
INFO: Entry point address = 0x129000
INFO: SPSR = 0x3cd
INFO: Boot bl33 from 0x37000000 for 364311 Bytes
NOTICE: BL31: v1.3(debug):v1.3-372-g1ba9c60
NOTICE: BL31: Built : 17:51:33, Apr 30 2017
INFO: BL31: Initializing runtime services
INFO: BL31: Preparing for EL3 exit to normal world
INFO: Entry point address = 0x37000000
INFO: SPSR = 0x3c9
U-Boot 2017.05-rc2-00130-gd2255b0 (Apr 30 2017 - 17:51:28 +0200)poplar
Model: HiSilicon Poplar Development Board
BOARD: Hisilicon HI3798cv200 Poplar
DRAM: 1 GiB
MMC: Hisilicon DWMMC: 0
In: serial@f8b00000
Out: serial@f8b00000
Err: serial@f8b00000
Net: Net Initialization Skipped
No ethernet found.
Hit any key to stop autoboot: 0
starting USB...
USB0: USB EHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found
USB1: USB EHCI 1.00
scanning bus 1 for devices... 4 USB Device(s) found
scanning usb for storage devices... 1 Storage Device(s) found
scanning usb for ethernet devices... 1 Ethernet Device(s) found
USB device 0:
Device 0: Vendor: SanDisk Rev: 1.00 Prod: Cruzer Blade
Type: Removable Hard Disk
Capacity: 7632.0 MB = 7.4 GB (15630336 x 512)
... is now current device
Scanning usb 0:1...
=>
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <arm_gic.h>
#include <assert.h>
#include <bl_common.h>
#include <debug.h>
#include <delay_timer.h>
#include <errno.h>
#include <mmio.h>
#include <platform.h>
#include <xlat_tables.h>
#include "hi3798cv200.h"
#include "platform_def.h"
#define MAP_DDR MAP_REGION_FLAT(DDR_BASE, \
DDR_SIZE, \
MT_MEMORY | MT_RW | MT_NS)
#define MAP_DEVICE MAP_REGION_FLAT(DEVICE_BASE, \
DEVICE_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
static const mmap_region_t poplar_mmap[] = {
MAP_DDR,
MAP_DEVICE,
{0}
};
#define DEFINE_CONFIGURE_MMU_EL(_el) \
void plat_configure_mmu_el##_el(unsigned long total_base, \
unsigned long total_size, \
unsigned long ro_start, \
unsigned long ro_limit, \
unsigned long coh_start, \
unsigned long coh_limit) \
{ \
mmap_add_region(total_base, total_base, \
total_size, \
MT_MEMORY | MT_RW | MT_SECURE); \
mmap_add_region(ro_start, ro_start, \
ro_limit - ro_start, \
MT_MEMORY | MT_RO | MT_SECURE); \
mmap_add_region(coh_start, coh_start, \
coh_limit - coh_start, \
MT_DEVICE | MT_RW | MT_SECURE); \
mmap_add(poplar_mmap); \
init_xlat_tables(); \
\
enable_mmu_el##_el(0); \
}
DEFINE_CONFIGURE_MMU_EL(3)
DEFINE_CONFIGURE_MMU_EL(1)
unsigned int plat_get_syscnt_freq2(void)
{
return SYS_COUNTER_FREQ_IN_TICKS;
}
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <assert.h>
#include <bl_common.h>
#include <console.h>
#include <debug.h>
#include <errno.h>
#include <generic_delay_timer.h>
#include <mmio.h>
#include <pl061_gpio.h>
#include <platform.h>
#include <platform_def.h>
#include <string.h>
#include <tbbr_img_def.h>
#include "../../bl1/bl1_private.h"
#include "hi3798cv200.h"
#include "plat_private.h"
/* Symbols from link script for conherent section */
extern unsigned long __COHERENT_RAM_START__;
extern unsigned long __COHERENT_RAM_END__;
#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
/* Data structure which holds the extents of the trusted RAM for BL1 */
static meminfo_t bl1_tzram_layout;
meminfo_t *bl1_plat_sec_mem_layout(void)
{
return &bl1_tzram_layout;
}
void bl1_early_platform_setup(void)
{
/* Initialize the console to provide early debug support */
console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
/* Allow BL1 to see the whole Trusted RAM */
bl1_tzram_layout.total_base = BL_MEM_BASE;
bl1_tzram_layout.total_size = BL_MEM_SIZE;
/* Calculate how much RAM BL1 is using and how much remains free */
bl1_tzram_layout.free_base = BL_MEM_BASE;
bl1_tzram_layout.free_size = BL_MEM_SIZE;
reserve_mem(&bl1_tzram_layout.free_base,
&bl1_tzram_layout.free_size,
BL1_RAM_BASE,
BL1_RAM_LIMIT - BL1_RAM_BASE);
INFO("BL1: 0x%lx - 0x%lx [size = %zu]\n", BL1_RAM_BASE, BL1_RAM_LIMIT,
BL1_RAM_LIMIT - BL1_RAM_BASE);
}
void bl1_plat_arch_setup(void)
{
plat_configure_mmu_el3(bl1_tzram_layout.total_base,
bl1_tzram_layout.total_size,
BL_MEM_BASE, /* l-loader and BL1 ROM */
BL1_RO_LIMIT,
BL1_COHERENT_RAM_BASE,
BL1_COHERENT_RAM_LIMIT);
}
void bl1_platform_setup(void)
{
int i;
generic_delay_timer_init();
pl061_gpio_init();
for (i = 0; i < GPIO_MAX; i++)
pl061_gpio_register(GPIO_BASE(i), i);
plat_io_setup();
}
unsigned int bl1_plat_get_next_image_id(void)
{
return BL2_IMAGE_ID;
}
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <assert.h>
#include <bl_common.h>
#include <console.h>
#include <debug.h>
#include <errno.h>
#include <generic_delay_timer.h>
#include <mmio.h>
#include <partition/partition.h>
#include <platform.h>
#include <string.h>
#include "hi3798cv200.h"
#include "plat_private.h"
/* Memory ranges for code and read only data sections */
#define BL2_RO_BASE (unsigned long)(&__RO_START__)
#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
/* Memory ranges for coherent memory section */
#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
typedef struct bl2_to_bl31_params_mem {
bl31_params_t bl31_params;
image_info_t bl31_image_info;
image_info_t bl33_image_info;
entry_point_info_t bl33_ep_info;
entry_point_info_t bl31_ep_info;
} bl2_to_bl31_params_mem_t;
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
static bl2_to_bl31_params_mem_t bl31_params_mem;
meminfo_t *bl2_plat_sec_mem_layout(void)
{
return &bl2_tzram_layout;
}
bl31_params_t *bl2_plat_get_bl31_params(void)
{
bl31_params_t *bl2_to_bl31_params = NULL;
/*
* Initialise the memory for all the arguments that needs to
* be passed to BL3-1
*/
memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
/* Assign memory for TF related information */
bl2_to_bl31_params = &bl31_params_mem.bl31_params;
SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
/* Fill BL3-1 related information */
bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
PARAM_IMAGE_BINARY, VERSION_1, 0);
/* Fill BL3-3 related information */
bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
PARAM_EP, VERSION_1, 0);
/* BL3-3 expects to receive the primary CPU MPID (through x0) */
bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info,
PARAM_IMAGE_BINARY, VERSION_1, 0);
return bl2_to_bl31_params;
}
struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
{
return &bl31_params_mem.bl31_ep_info;
}
void bl2_plat_set_bl31_ep_info(image_info_t *image,
entry_point_info_t *bl31_ep_info)
{
SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
}
static uint32_t hisi_get_spsr_for_bl33_entry(void)
{
unsigned long el_status;
unsigned int mode;
uint32_t spsr;
/* Figure out what mode we enter the non-secure world in */
el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
el_status &= ID_AA64PFR0_ELX_MASK;
mode = (el_status) ? MODE_EL2 : MODE_EL1;
/*
* TODO: Consider the possibility of specifying the SPSR in
* the FIP ToC and allowing the platform to have a say as
* well.
*/
spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
return spsr;
}
void bl2_plat_set_bl33_ep_info(image_info_t *image,
entry_point_info_t *bl33_ep_info)
{
SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
bl33_ep_info->spsr = hisi_get_spsr_for_bl33_entry();
bl33_ep_info->args.arg2 = image->image_size;
}
void bl2_plat_flush_bl31_params(void)
{
flush_dcache_range((unsigned long)&bl31_params_mem,
sizeof(bl2_to_bl31_params_mem_t));
}
void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
{
bl33_meminfo->total_base = DDR_BASE;
bl33_meminfo->total_size = DDR_SIZE;
bl33_meminfo->free_base = DDR_BASE;
bl33_meminfo->free_size = DDR_SIZE;
}
void bl2_early_platform_setup(meminfo_t *mem_layout)
{
console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
/* Enable arch timer */
generic_delay_timer_init();
bl2_tzram_layout = *mem_layout;
}
void bl2_plat_arch_setup(void)
{
plat_configure_mmu_el1(bl2_tzram_layout.total_base,
bl2_tzram_layout.total_size,
BL2_RO_BASE,
BL2_RO_LIMIT,
BL2_COHERENT_RAM_BASE,
BL2_COHERENT_RAM_LIMIT);
}
void bl2_platform_setup(void)
{
plat_io_setup();
}
unsigned long plat_get_ns_image_entrypoint(void)
{
return PLAT_ARM_NS_IMAGE_OFFSET;
}
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
#include <arm_gic.h>
#include <assert.h>
#include <bl31.h>
#include <bl_common.h>
#include <console.h>
#include <cortex_a53.h>
#include <debug.h>
#include <errno.h>
#include <generic_delay_timer.h>
#include <mmio.h>
#include <plat_arm.h>
#include <platform.h>
#include <stddef.h>
#include <string.h>
#include "hi3798cv200.h"
#include "plat_private.h"
#include "platform_def.h"
/* Memory ranges for code and RO data sections */
#define BL31_RO_BASE (unsigned long)(&__RO_START__)
#define BL31_RO_LIMIT (unsigned long)(&__RO_END__)
/* Memory ranges for coherent memory section */
#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
static entry_point_info_t bl33_image_ep_info;
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
{
return &bl33_image_ep_info;
}
void bl31_early_platform_setup(bl31_params_t *from_bl2,
void *plat_params_from_bl2)
{
console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
/* Init console for crash report */
plat_crash_console_init();
bl33_image_ep_info = *from_bl2->bl33_ep_info;
}
void bl31_platform_setup(void)
{
/* Init arch timer */
generic_delay_timer_init();
/* Init GIC distributor and CPU interface */
plat_arm_gic_driver_init();
plat_arm_gic_init();
}
void bl31_plat_runtime_setup(void)
{
/* do nothing */
}
void bl31_plat_arch_setup(void)
{
plat_configure_mmu_el3(BL31_RO_BASE,
(BL31_COHERENT_RAM_LIMIT - BL31_RO_BASE),
BL31_RO_BASE,
BL31_RO_LIMIT,
BL31_COHERENT_RAM_BASE,
BL31_COHERENT_RAM_LIMIT);
INFO("Boot BL33 from 0x%lx for %lu Bytes\n",
bl33_image_ep_info.pc, bl33_image_ep_info.args.arg2);
}
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __HI3798cv200_H__
#define __HI3798cv200_H__
/* PL011 */
#define PL011_UART0_BASE (0xF8B00000)
#define PL011_BAUDRATE (115200)
#define PL011_UART0_CLK_IN_HZ (75000000)
/* Sys Counter */
#define SYS_COUNTER_FREQ_IN_TICKS (24000000)
#define SYS_COUNTER_FREQ_IN_MHZ (24)
/* Timer */
#define SEC_TIMER0_BASE (0xF8008000)
#define TIMER00_LOAD (SEC_TIMER0_BASE + 0x000)
#define TIMER00_VALUE (SEC_TIMER0_BASE + 0x004)
#define TIMER00_CONTROL (SEC_TIMER0_BASE + 0x008)
#define TIMER00_BGLOAD (SEC_TIMER0_BASE + 0x018)
#define SEC_TIMER2_BASE (0xF8009000)
#define TIMER20_LOAD (SEC_TIMER2_BASE + 0x000)
#define TIMER20_VALUE (SEC_TIMER2_BASE + 0x004)
#define TIMER20_CONTROL (SEC_TIMER2_BASE + 0x008)
#define TIMER20_BGLOAD (SEC_TIMER2_BASE + 0x018)
/* GPIO */
#define GPIO_MAX (12)
#define GPIO_BASE(x) (x != 5 ? \
0xf820000 + x * 0x1000 : 0xf8004000)
/* SCTL */
#define REG_BASE_SCTL (0xF8000000)
#define REG_SC_GEN12 (0x00B0)
/* CRG */
#define REG_BASE_CRG (0xF8A22000)
#define REG_CPU_LP (0x48)
#define REG_CPU_RST (0x50)
#define REG_PERI_CRG39 (0x9C)
#define REG_PERI_CRG40 (0xA0)
/* MCI */
#define REG_BASE_MCI (0xF9830000)
#define MCI_CDETECT (0x50)
#define MCI_VERID (0x6C)
#define MCI_VERID_VALUE (0x5342250A)
#define MCI_VERID_VALUE2 (0x5342270A)
/* EMMC */
#define REG_EMMC_PERI_CRG REG_PERI_CRG40
#define REG_SDCARD_PERI_CRG REG_PERI_CRG39
#define EMMC_CLK_MASK (0x7 << 8)
#define EMMC_SRST_REQ (0x1 << 4)
#define EMMC_CKEN (0x1 << 1)
#define EMMC_BUS_CKEN (0x1 << 0)
#define EMMC_CLK_100M (0 << 8)
#define EMMC_CLK_50M (1 << 8)
#define EMMC_CLK_25M (2 << 8)
#define EMMC_DESC_SIZE (0xF0000)
#define EMMC_INIT_PARAMS(base) \
{ .bus_width = EMMC_BUS_WIDTH_8, \
.clk_rate = 25 * 1000 * 1000, \
.desc_base = (base) - EMMC_DESC_SIZE, \
.desc_size = EMMC_DESC_SIZE, \
.flags = EMMC_FLAG_CMD23, \
.reg_base = REG_BASE_MCI, \
}
/* GIC-400 */
#define GICD_BASE (0xF1001000)
#define GICC_BASE (0xF1002000)
#define GICR_BASE (0xF1000000)
/* FIQ platform related define */
#define HISI_IRQ_SEC_SGI_0 8
#define HISI_IRQ_SEC_SGI_1 9
#define HISI_IRQ_SEC_SGI_2 10
#define HISI_IRQ_SEC_SGI_3 11
#define HISI_IRQ_SEC_SGI_4 12
#define HISI_IRQ_SEC_SGI_5 13
#define HISI_IRQ_SEC_SGI_6 14
#define HISI_IRQ_SEC_SGI_7 15
#define HISI_IRQ_SEC_PPI_0 29
#define HISI_IRQ_SEC_TIMER0 60
#define HISI_IRQ_SEC_TIMER1 50
#define HISI_IRQ_SEC_TIMER2 52
#define HISI_IRQ_SEC_TIMER3 88
#define HISI_IRQ_SEC_AXI 110
/* Watchdog */
#define HISI_WDG0_BASE (0xF8A2C000)
#endif /* __HI3798cv200_H__ */
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
.section .rodata.gic_reg_name, "aS"
.macro plat_crash_print_regs
nop
.endm
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __PLAT_PRIVATE_H__
#define __PLAT_PRIVATE_H__
#include <bl_common.h>
#include "hi3798cv200.h"
void plat_configure_mmu_el3(unsigned long total_base,
unsigned long total_size,
unsigned long ro_start,
unsigned long ro_limit,
unsigned long coh_start,
unsigned long coh_limit);
void plat_configure_mmu_el1(unsigned long total_base,
unsigned long total_size,
unsigned long ro_start,
unsigned long ro_limit,
unsigned long coh_start,
unsigned long coh_limit);
void plat_delay_timer_init(void);
void plat_io_setup(void);
#endif /* __PLAT_PRIVATE_H__ */
/*
* 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 <arch.h>
#include <common_def.h>
#include <tbbr/tbbr_img_def.h>
#include "hi3798cv200.h"
#include "poplar_layout.h" /* BL memory region sizes, etc */
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
#define PLAT_ARM_CRASH_UART_BASE PL011_UART0_BASE
#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PL011_UART0_CLK_IN_HZ
#define ARM_CONSOLE_BAUDRATE PL011_BAUDRATE
/* Generic platform constants */
#define PLATFORM_STACK_SIZE (0x800)
#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
#define BOOT_EMMC_NAME "l-loader.bin"
#define PLATFORM_CACHE_LINE_SIZE (64)
#define PLATFORM_CLUSTER_COUNT (1)
#define PLATFORM_CORE_COUNT (4)
#define PLATFORM_MAX_CPUS_PER_CLUSTER (4)
/* IO framework user */
#define MAX_IO_DEVICES (4)
#define MAX_IO_HANDLES (4)
#define MAX_IO_BLOCK_DEVICES (2)
/* Memory map related constants */
#define DDR_BASE (0x00000000)
#define DDR_SIZE (0x40000000)
#define DEVICE_BASE (0xF0000000)
#define DEVICE_SIZE (0x0F000000)
#define TEE_SEC_MEM_BASE (0x70000000)
#define TEE_SEC_MEM_SIZE (0x10000000)
#define BL_MEM_BASE (BL1_RO_BASE)
#define BL_MEM_LIMIT (BL31_LIMIT)
#define BL_MEM_SIZE (BL_MEM_LIMIT - BL_MEM_BASE)
#define PLAT_ARM_NS_IMAGE_OFFSET 0x37000000
/* Page table and MMU setup constants */
#define ADDR_SPACE_SIZE (1ull << 32)
#define MAX_XLAT_TABLES (4)
#define MAX_MMAP_REGIONS (16)
#define CACHE_WRITEBACK_SHIFT (6)
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
/* Power states */
#define PLAT_MAX_PWR_LVL (MPIDR_AFFLVL1)
#define PLAT_MAX_OFF_STATE 2
#define PLAT_MAX_RET_STATE 1
/* Interrupt controller */
#define PLAT_ARM_GICD_BASE GICD_BASE
#define PLAT_ARM_GICC_BASE GICC_BASE
#define PLAT_ARM_G1S_IRQS HISI_IRQ_SEC_SGI_0, \
HISI_IRQ_SEC_SGI_1, \
HISI_IRQ_SEC_SGI_2, \
HISI_IRQ_SEC_SGI_3, \
HISI_IRQ_SEC_SGI_4, \
HISI_IRQ_SEC_SGI_5, \
HISI_IRQ_SEC_SGI_6, \
HISI_IRQ_SEC_SGI_7, \
HISI_IRQ_SEC_TIMER0, \
HISI_IRQ_SEC_TIMER1, \
HISI_IRQ_SEC_TIMER2, \
HISI_IRQ_SEC_TIMER3, \
HISI_IRQ_SEC_AXI
#define PLAT_ARM_G0_IRQS
#endif /* __PLATFORM_DEF_H__ */
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __POPLAR_LAYOUT_H
#define __POPLAR_LAYOUT_H
/*
* Boot memory layout definitions for the HiSilicon Poplar board
*/
/*
* When Poplar is powered on, boot ROM loads the initial content of
* boot media into low memory, verifies it, and begins executing it
* in 32-bit mode. The image loaded is "l-loader.bin", which contains
* a small amount code along with an embedded ARM Trusted Firmware
* BL1 image. The main purpose of "l-loader" is to prepare the
* processor to execute the BL1 image in 64-bit mode, and to trigger
* that execution.
*
* Also embedded in "l-loader.bin" is a FIP image that contains
* other ARM Trusted Firmware images: BL2; BL31; and for BL33,
* U-Boot. When BL1 executes, it unpacks the BL2 image from the FIP
* image into a region of memory set aside to hold it. Similarly,
* BL2 unpacks BL31 into memory reserved for it, and unpacks U-Boot
* into high memory.
*
* Because the BL1 code is embedded in "l-loader", its base address
* in memory is derived from the base address of the "l-loader"
* text section, together with an offset. Memory space for BL2 is
* reserved immediately following BL1, and memory space is reserved
* for BL31 after that. ARM Trusted Firmware requires each of these
* memory regions to be aligned on page boundaries, so the size of
* each region is a multiple of a page size (ending in 000). Note
* that ARM Trusted Firmware requires the read-only and read-write
* regions of memory used for BL1 to be defined separately.
*
* ---------------------
* | (unused memory) |
* +-------------------+ - - - - -
* | (l-loader text) | \
* +-------------------+ \
* | BL1 (read-only) | \ \
* |- - - - - - - - - -| | |
* | BL1 (read-write) | | |
* +-------------------+ > BL Memory |
* | Reserved for BL2 | | > "l-loader.bin" image
* +-------------------+ | |
* | Reserved for BL31 | / |
* +-------------------+ |
* . . . /
* +-------------------+ /
* | FIP | /
* +-------------------+ - - - - -
* . . .
* | (unused memory) |
* . . .
* +-------------------+
* |Reserved for U-Boot|
* +-------------------+
* . . .
* | (unused memory) |
* ---------------------
*
* The size of each of these regions is defined below. The base
* address of the "l-loader" TEXT section and the offset of the BL1
* image within that serve as anchors for defining the positions of
* all other regions. The FIP is placed in a section of its own.
*
* A "BASE" is the memory address of the start of a region; a "LIMIT"
* marks its end. A "SIZE" is the size of a region (in bytes). An
* "OFFSET" is an offset to the start of a region relative to the
* base of the "l-loader" TEXT section (also a multiple of page size).
*/
#define LLOADER_TEXT_BASE 0x00001000 /* page aligned */
#define BL1_OFFSET 0x0000D000 /* page multiple */
#define FIP_BASE 0x00040000
#define BL1_RO_SIZE 0x00008000 /* page multiple */
#define BL1_RW_SIZE 0x00008000 /* page multiple */
#define BL1_SIZE (BL1_RO_SIZE + BL1_RW_SIZE)
#define BL2_SIZE 0x0000c000 /* page multiple */
#define BL31_SIZE 0x00014000
#define FIP_SIZE 0x00068000
/* BL1_OFFSET */ /* (Defined above) */
#define BL1_BASE (LLOADER_TEXT_BASE + BL1_OFFSET)
#define BL1_LIMIT (BL1_BASE + BL1_SIZE)
#define BL1_RO_OFFSET (BL1_OFFSET)
#define BL1_RO_BASE (LLOADER_TEXT_BASE + BL1_RO_OFFSET)
#define BL1_RO_LIMIT (BL1_RO_BASE + BL1_RO_SIZE)
#define BL1_RW_OFFSET (BL1_RO_OFFSET + BL1_RO_SIZE)
#define BL1_RW_BASE (LLOADER_TEXT_BASE + BL1_RW_OFFSET)
#define BL1_RW_LIMIT (BL1_RW_BASE + BL1_RW_SIZE)
#define BL2_OFFSET (BL1_OFFSET + BL1_SIZE)
#define BL2_BASE (LLOADER_TEXT_BASE + BL2_OFFSET)
#define BL2_LIMIT (BL2_BASE + BL2_SIZE)
#define BL31_OFFSET (BL2_OFFSET + BL2_SIZE)
#define BL31_BASE (LLOADER_TEXT_BASE + BL31_OFFSET)
#define BL31_LIMIT (BL31_BASE + BL31_SIZE)
#endif /* !__POPLAR_LAYOUT_H */
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <arm_gic.h>
#include <assert.h>
#include <bl_common.h>
#include <console.h>
#include <context.h>
#include <context_mgmt.h>
#include <debug.h>
#include <mmio.h>
#include <plat_arm.h>
#include <platform.h>
#include <psci.h>
#include "hi3798cv200.h"
#include "plat_private.h"
#include "platform_def.h"
#define REG_PERI_CPU_RVBARADDR 0xF8A80034
#define REG_PERI_CPU_AARCH_MODE 0xF8A80030
#define REG_CPU_LP_CPU_SW_BEGIN 10
#define CPU_REG_COREPO_SRST 12
#define CPU_REG_CORE_SRST 8
static void poplar_cpu_standby(plat_local_state_t cpu_state)
{
dsb();
wfi();
}
static int poplar_pwr_domain_on(u_register_t mpidr)
{
unsigned int cpu = plat_core_pos_by_mpidr(mpidr);
unsigned int regval, regval_bak;
/* Select 400MHz before start slave cores */
regval_bak = mmio_read_32((uintptr_t)(REG_BASE_CRG + REG_CPU_LP));
mmio_write_32((uintptr_t)(REG_BASE_CRG + REG_CPU_LP), 0x206);
mmio_write_32((uintptr_t)(REG_BASE_CRG + REG_CPU_LP), 0x606);
/* Clear the slave cpu arm_por_srst_req reset */
regval = mmio_read_32((uintptr_t)(REG_BASE_CRG + REG_CPU_RST));
regval &= ~(1 << (cpu + CPU_REG_COREPO_SRST));
mmio_write_32((uintptr_t)(REG_BASE_CRG + REG_CPU_RST), regval);
/* Clear the slave cpu reset */
regval = mmio_read_32((uintptr_t)(REG_BASE_CRG + REG_CPU_RST));
regval &= ~(1 << (cpu + CPU_REG_CORE_SRST));
mmio_write_32((uintptr_t)(REG_BASE_CRG + REG_CPU_RST), regval);
/* Restore cpu frequency */
regval = regval_bak & (~(1 << REG_CPU_LP_CPU_SW_BEGIN));
mmio_write_32((uintptr_t)(REG_BASE_CRG + REG_CPU_LP), regval);
mmio_write_32((uintptr_t)(REG_BASE_CRG + REG_CPU_LP), regval_bak);
return PSCI_E_SUCCESS;
}
static void poplar_pwr_domain_off(const psci_power_state_t *target_state)
{
assert(0);
}
static void poplar_pwr_domain_suspend(const psci_power_state_t *target_state)
{
assert(0);
}
static void poplar_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
PLAT_MAX_OFF_STATE);
/* Enable the gic cpu interface */
plat_arm_gic_pcpu_init();
/* Program the gic per-cpu distributor or re-distributor interface */
plat_arm_gic_cpuif_enable();
}
static void poplar_pwr_domain_suspend_finish(
const psci_power_state_t *target_state)
{
assert(0);
}
static void __dead2 poplar_system_off(void)
{
ERROR("Poplar System Off: operation not handled.\n");
panic();
}
static void __dead2 poplar_system_reset(void)
{
mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0xc00), 0x1ACCE551);
mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0x0), 0x00000100);
mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0x8), 0x00000003);
wfi();
ERROR("Poplar System Reset: operation not handled.\n");
panic();
}
static int32_t poplar_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state)
{
VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
int pstate = psci_get_pstate_type(power_state);
assert(req_state);
/* Sanity check the requested state */
if (pstate == PSTATE_TYPE_STANDBY)
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
else
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
/* We expect the 'state id' to be zero */
if (psci_get_pstate_id(power_state))
return PSCI_E_INVALID_PARAMS;
return PSCI_E_SUCCESS;
}
static int poplar_validate_ns_entrypoint(uintptr_t entrypoint)
{
/*
* Check if the non secure entrypoint lies within the non
* secure DRAM.
*/
if ((entrypoint >= DDR_BASE) && (entrypoint < (DDR_BASE + DDR_SIZE)))
return PSCI_E_SUCCESS;
return PSCI_E_INVALID_ADDRESS;
}
static void poplar_get_sys_suspend_power_state(psci_power_state_t *req_state)
{
int i;
for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
}
static const plat_psci_ops_t poplar_plat_psci_ops = {
.cpu_standby = poplar_cpu_standby,
.pwr_domain_on = poplar_pwr_domain_on,
.pwr_domain_off = poplar_pwr_domain_off,
.pwr_domain_suspend = poplar_pwr_domain_suspend,
.pwr_domain_on_finish = poplar_pwr_domain_on_finish,
.pwr_domain_suspend_finish = poplar_pwr_domain_suspend_finish,
.system_off = poplar_system_off,
.system_reset = poplar_system_reset,
.validate_power_state = poplar_validate_power_state,
.validate_ns_entrypoint = poplar_validate_ns_entrypoint,
.get_sys_suspend_power_state = poplar_get_sys_suspend_power_state,
};
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const plat_psci_ops_t **psci_ops)
{
*psci_ops = &poplar_plat_psci_ops;
mmio_write_32((uintptr_t)REG_PERI_CPU_AARCH_MODE, 0xF);
mmio_write_32((uintptr_t)REG_PERI_CPU_RVBARADDR, sec_entrypoint);
return 0;
}
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
#include <firmware_image_package.h>
#include <io_block.h>
#include <io_driver.h>
#include <io_fip.h>
#include <io_memmap.h>
#include <io_storage.h>
#include <mmio.h>
#include <partition/partition.h>
#include <semihosting.h>
#include <string.h>
#include <tbbr_img_def.h>
#include <utils.h>
#include "platform_def.h"
static const io_dev_connector_t *mmap_dev_con;
static const io_dev_connector_t *fip_dev_con;
static uintptr_t mmap_dev_handle;
static uintptr_t fip_dev_handle;
static int open_mmap(const uintptr_t spec);
static int open_fip(const uintptr_t spec);
static const io_block_spec_t loader_fip_spec = {
.offset = FIP_BASE,
.length = FIP_SIZE
};
static const io_uuid_spec_t bl2_uuid_spec = {
.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
};
static const io_uuid_spec_t bl31_uuid_spec = {
.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
};
static const io_uuid_spec_t bl33_uuid_spec = {
.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
};
struct plat_io_policy {
uintptr_t *dev_handle;
uintptr_t image_spec;
int (*check)(const uintptr_t spec);
};
static const struct plat_io_policy policies[] = {
[FIP_IMAGE_ID] = {
&mmap_dev_handle,
(uintptr_t)&loader_fip_spec,
open_mmap
},
[BL2_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl2_uuid_spec,
open_fip
},
[BL31_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl31_uuid_spec,
open_fip
},
[BL33_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl33_uuid_spec,
open_fip
},
};
static int open_mmap(const uintptr_t spec)
{
int result;
uintptr_t local_image_handle;
result = io_dev_init(mmap_dev_handle, (uintptr_t)NULL);
if (result == 0) {
result = io_open(mmap_dev_handle, spec, &local_image_handle);
if (result == 0) {
io_close(local_image_handle);
}
}
return result;
}
static int open_fip(const uintptr_t spec)
{
uintptr_t local_image_handle;
int result;
result = io_dev_init(fip_dev_handle, (uintptr_t) FIP_IMAGE_ID);
if (result == 0) {
result = io_open(fip_dev_handle, spec, &local_image_handle);
if (result == 0) {
io_close(local_image_handle);
} else {
VERBOSE("error opening fip\n");
}
} else {
VERBOSE("error initializing fip\n");
}
return result;
}
int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
uintptr_t *image_spec)
{
const struct plat_io_policy *policy;
int result;
assert(image_id < ARRAY_SIZE(policies));
policy = &policies[image_id];
result = policy->check(policy->image_spec);
assert(result == 0);
*image_spec = policy->image_spec;
*dev_handle = *(policy->dev_handle);
return result;
}
void plat_io_setup(void)
{
int result;
result = register_io_dev_memmap(&mmap_dev_con);
assert(result == 0);
result = register_io_dev_fip(&fip_dev_con);
assert(result == 0);
result = io_dev_open(fip_dev_con, (uintptr_t)&loader_fip_spec,
&fip_dev_handle);
assert(result == 0);
result = io_dev_open(mmap_dev_con, (uintptr_t)NULL, &mmap_dev_handle);
assert(result == 0);
(void) result;
}
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <plat_arm.h>
#include <psci.h>
#include "platform_def.h"
const unsigned char hisi_power_domain_tree_desc[] = {
PLATFORM_CLUSTER_COUNT,
PLATFORM_CORE_COUNT,
};
const unsigned char *plat_get_power_domain_tree_desc(void)
{
return hisi_power_domain_tree_desc;
}
int plat_core_pos_by_mpidr(u_register_t mpidr)
{
if (mpidr & MPIDR_CLUSTER_MASK)
return -1;
if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT)
return -1;
return plat_arm_calc_core_pos(mpidr);
}
#
# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
NEED_BL33 := yes
COLD_BOOT_SINGLE_CPU := 1
PROGRAMMABLE_RESET_ADDRESS := 1
CTX_INCLUDE_FPREGS := 1
ENABLE_PLAT_COMPAT := 0
ERRATA_A53_855873 := 1
ERRATA_A53_835769 := 1
ERRATA_A53_843419 := 1
ARM_GIC_ARCH := 2
$(eval $(call add_define,ARM_GIC_ARCH))
PLAT_PL061_MAX_GPIOS := 104
$(eval $(call add_define,PLAT_PL061_MAX_GPIOS))
PLAT_INCLUDES := -Iplat/hisilicon/poplar/include \
-Iinclude/plat/arm/common/ \
-Iplat/hisilicon/poplar \
-Iinclude/common/tbbr \
-Iinclude/drivers/io
PLAT_BL_COMMON_SOURCES := \
lib/aarch64/xlat_tables.c \
drivers/delay_timer/generic_delay_timer.c \
drivers/arm/gic/common/gic_common.c \
drivers/arm/gic/v2/gicv2_helpers.c \
drivers/delay_timer/delay_timer.c \
drivers/arm/pl011/pl011_console.S \
drivers/arm/gic/v2/gicv2_main.c \
plat/arm/common/aarch64/arm_helpers.S \
plat/arm/common/arm_gicv2.c \
plat/common/plat_gicv2.c \
plat/hisilicon/poplar/aarch64/platform_common.c
BL1_SOURCES += \
lib/cpus/aarch64/cortex_a53.S \
drivers/arm/pl061/pl061_gpio.c \
drivers/io/io_storage.c \
drivers/io/io_block.c \
drivers/gpio/gpio.c \
drivers/io/io_fip.c \
drivers/io/io_memmap.c \
plat/hisilicon/poplar/bl1_plat_setup.c \
plat/hisilicon/poplar/plat_storage.c \
BL2_SOURCES += \
drivers/arm/pl061/pl061_gpio.c \
drivers/io/io_storage.c \
drivers/io/io_block.c \
drivers/io/io_fip.c \
drivers/gpio/gpio.c \
drivers/io/io_memmap.c \
plat/hisilicon/poplar/bl2_plat_setup.c \
plat/hisilicon/poplar/plat_storage.c
BL31_SOURCES += \
lib/cpus/aarch64/aem_generic.S \
lib/cpus/aarch64/cortex_a53.S \
plat/common/aarch64/plat_psci_common.c \
plat/hisilicon/poplar/bl31_plat_setup.c \
plat/hisilicon/poplar/plat_topology.c \
plat/hisilicon/poplar/plat_pm.c
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment