Merge pull request #1483 from antonio-nino-diaz-arm/an/rpi3-psci
rpi3: PSCI and Linux boot improvements
This commit is contained in:
commit
992a353613
|
@ -7,8 +7,7 @@ Trusted Firmware-A for Raspberry Pi 3
|
|||
.. contents::
|
||||
|
||||
The `Raspberry Pi 3`_ is an inexpensive single-board computer that contains four
|
||||
Arm Cortex-A53 cores, which makes it possible to have a port of Trusted
|
||||
Firmware-A (TF-A).
|
||||
Arm Cortex-A53 cores.
|
||||
|
||||
The following instructions explain how to use this port of the TF-A with the
|
||||
default distribution of `Raspbian`_ because that's the distribution officially
|
||||
|
@ -66,7 +65,7 @@ Placement of images
|
|||
|
||||
The file ``armstub8.bin`` contains BL1 and the FIP. It is needed to add padding
|
||||
between them so that the addresses they are loaded to match the ones specified
|
||||
when compiling TF-A.
|
||||
when compiling TF-A. This is done automatically by the build system.
|
||||
|
||||
The device tree block is loaded by the VideoCore loader from an appropriate
|
||||
file, but we can specify the address it is loaded to in ``config.txt``.
|
||||
|
@ -108,13 +107,13 @@ secure platform!
|
|||
| ... |
|
||||
| |
|
||||
0x01000000 +-----------------+
|
||||
| Kernel |
|
||||
| DTB | (Loaded by the VideoCore)
|
||||
+-----------------+
|
||||
| |
|
||||
| ... |
|
||||
| |
|
||||
0x02000000 +-----------------+
|
||||
| DTB |
|
||||
| Kernel | (Loaded by the VideoCore)
|
||||
+-----------------+
|
||||
| |
|
||||
| ... |
|
||||
|
@ -123,9 +122,9 @@ secure platform!
|
|||
| Secure SRAM | BL2, BL31
|
||||
0x10100000 +-----------------+
|
||||
| Secure DRAM | BL32 (Secure payload)
|
||||
0x10C00000 +-----------------+
|
||||
| Non-secure DRAM | BL33
|
||||
0x11000000 +-----------------+
|
||||
| Non-secure DRAM | BL33
|
||||
+-----------------+
|
||||
| |
|
||||
| ... |
|
||||
| |
|
||||
|
@ -133,10 +132,10 @@ secure platform!
|
|||
| I/O |
|
||||
0x40000000 +-----------------+
|
||||
|
||||
The area between **0x10000000** and **0x11000000** has to be protected so that
|
||||
the kernel doesn't use it. That is done by adding ``memmap=16M$256M`` to the
|
||||
command line passed to the kernel. See the `Setup SD card`_ instructions to see
|
||||
how to do it.
|
||||
The area between **0x10000000** and **0x11000000** has to be manually protected
|
||||
so that the kernel doesn't use it. That is done by adding ``memmap=16M$256M`` to
|
||||
the command line passed to the kernel. See the `Setup SD card`_ instructions to
|
||||
see how to do it.
|
||||
|
||||
The last 16 MiB of DRAM can only be accessed by the VideoCore, that has
|
||||
different mappings than the Arm cores in which the I/O addresses don't overlap
|
||||
|
@ -159,14 +158,24 @@ The `Linux kernel tree`_ has instructions on how to jump to the Linux kernel
|
|||
in ``Documentation/arm/Booting`` and ``Documentation/arm64/booting.txt``. The
|
||||
bootstrap should take care of this.
|
||||
|
||||
This port support a direct boot of the Linux kernel from the firmware (as a BL33
|
||||
image). Alternatively, U-Boot or other bootloaders may be used.
|
||||
|
||||
Secondary cores
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
This port of the Trusted Firmware-A supports ``PSCI_CPU_ON``,
|
||||
`PSCI_SYSTEM_RESET`` and ``PSCI_SYSTEM_OFF``. The last one doesn't really turn
|
||||
the system off, it simply reboots it and asks the VideoCore firmware to keep it
|
||||
in a low power mode permanently.
|
||||
|
||||
The kernel used by `Raspbian`_ doesn't have support for PSCI, so it is needed to
|
||||
use mailboxes to trap the secondary cores until they are ready to jump to the
|
||||
kernel. This mailbox is located at a different address in the AArch32 default
|
||||
kernel than in the AArch64 kernel.
|
||||
|
||||
Kernels with PSCI support can use the PSCI calls instead for a cleaner boot.
|
||||
|
||||
Also, this port of TF-A has another Trusted Mailbox in Shared BL RAM. During
|
||||
cold boot, all secondary cores wait in a loop until they are given given an
|
||||
address to jump to in this Mailbox (``bl31_warm_entrypoint``).
|
||||
|
@ -187,46 +196,38 @@ To boot a AArch32 kernel, both AArch64 and AArch32 toolchains are required. The
|
|||
AArch32 toolchain is needed for the AArch32 bootstrap needed to load a 32-bit
|
||||
kernel.
|
||||
|
||||
First, clone and compile `Raspberry Pi 3 TF-A bootstrap`_. Choose the one
|
||||
needed for the architecture of your kernel.
|
||||
|
||||
Then compile TF-A. For a AArch32 kernel, use the following command line:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3 \
|
||||
RPI3_BL33_IN_AARCH32=1 \
|
||||
BL33=../rpi3-arm-tf-bootstrap/aarch32/el2-bootstrap.bin
|
||||
|
||||
For a AArch64 kernel, use this other command line:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3 \
|
||||
BL33=../rpi3-arm-tf-bootstrap/aarch64/el2-bootstrap.bin
|
||||
|
||||
The build system concatenates BL1 and the FIP so that the addresses match the
|
||||
ones in the memory map. The resulting file is ``armstub8.bin``, located in the
|
||||
build folder (e.g. ``build/rpi3/debug/armstub8.bin``). Now, follow the
|
||||
instructions in `Setup SD card`_.
|
||||
build folder (e.g. ``build/rpi3/debug/armstub8.bin``). To know how to use this
|
||||
file, follow the instructions in `Setup SD card`_.
|
||||
|
||||
The following build options are supported:
|
||||
|
||||
- ``PRELOADED_BL33_BASE``: Specially useful because the file ``kernel8.img`` can
|
||||
be loaded anywhere by modifying the file ``config.txt``. It doesn't have to
|
||||
contain a kernel, it could have any arbitrary payload.
|
||||
|
||||
- ``RESET_TO_BL31``: Set to 1 by default. If using a 32-bit kernel like
|
||||
`Raspbian`_, the space used by BL1 can overwritten by the kernel when it is
|
||||
being loaded. Even when using a AArch64 kernel the region used by
|
||||
BL1 isn't protected and the kernel could overwrite it. The space used by BL31
|
||||
is reserved by the command line passed to the kernel.
|
||||
|
||||
- ``RPI3_BL33_IN_AARCH32``: This port can load a AArch64 or AArch32 BL33 image.
|
||||
By default this option is 0, which means that TF-A will jump to BL33 in EL2
|
||||
in AArch64 mode. If set to 1, it will jump to BL33 in Hypervisor in AArch32
|
||||
mode.
|
||||
|
||||
- ``PRELOADED_BL33_BASE``: Used to specify the address of a BL33 binary that has
|
||||
been preloaded by any other system than using the firmware. ``BL33`` isn't
|
||||
needed in the build command line if this option is used. Specially useful
|
||||
because the file ``kernel8.img`` can be loaded anywhere by modifying the file
|
||||
``config.txt``. It doesn't have to contain a kernel, it could have any
|
||||
arbitrary payload.
|
||||
|
||||
- ``RPI3_DIRECT_LINUX_BOOT``: Disabled by default. Set to 1 to enable the direct
|
||||
boot of the Linux kernel from the firmware. Option ``RPI3_PRELOADED_DTB_BASE``
|
||||
is mandatory when the direct Linux kernel boot is used. Options
|
||||
``PRELOADED_BL33_BASE`` will most likely be needed as well because it is
|
||||
unlikely that the kernel image will fit in the space reserved for BL33 images.
|
||||
This option can be combined with ``RPI3_BL33_IN_AARCH32`` in order to boot a
|
||||
32-bit kernel. The only thing this option does is to set the arguments in
|
||||
registers x0-x3 or r0-r2 as expected by the kernel.
|
||||
|
||||
- ``RPI3_PRELOADED_DTB_BASE``: Auxiliary build option needed when using
|
||||
``RPI3_DIRECT_LINUX_BOOT=1``. This option allows to specify the location of a
|
||||
DTB in memory.
|
||||
|
||||
- ``BL32``: This port can load and run OP-TEE. The OP-TEE image is optional.
|
||||
Please use the code from `here <https://github.com/OP-TEE/optee_os>`__.
|
||||
Build the Trusted Firmware with option ``BL32=tee-header_v2.bin
|
||||
|
@ -239,15 +240,16 @@ The following build options are supported:
|
|||
This will unfortunately reduce the performance of the USB driver. It is needed
|
||||
when using Raspbian, for example.
|
||||
|
||||
- ``TRUSTED_BOARD_BOOT``: This port supports TBB. Set this option
|
||||
``TRUSTED_BOARD_BOOT=1`` to enable it. In order to use TBB, you might
|
||||
want to set ``GENERATE_COT=1`` to let the contents of the FIP automatically
|
||||
signed by the build process. The ROT key will be generated and output to
|
||||
``rot_key.pem`` in the build directory. It is able to set ROT_KEY to
|
||||
your own key in PEM format.
|
||||
Also in order to build, you need to clone mbedtls from
|
||||
`here <https://github.com/ARMmbed/mbedtls>`__.
|
||||
And set MBEDTLS_DIR to mbedtls source directory.
|
||||
- ``TRUSTED_BOARD_BOOT``: This port supports TBB. Set this option to 1 to enable
|
||||
it. In order to use TBB, you might want to set ``GENERATE_COT=1`` to let the
|
||||
contents of the FIP automatically signed by the build process. The ROT key
|
||||
will be generated and output to ``rot_key.pem`` in the build directory. It is
|
||||
able to set ROT_KEY to your own key in PEM format. Also in order to build,
|
||||
you need to clone mbed TLS from `here <https://github.com/ARMmbed/mbedtls>`__.
|
||||
``MBEDTLS_DIR`` must point at the mbed TLS source directory.
|
||||
|
||||
- ``ENABLE_STACK_PROTECTOR``: Disabled by default. It uses the hardware RNG of
|
||||
the board.
|
||||
|
||||
The following is not currently supported:
|
||||
|
||||
|
@ -257,13 +259,65 @@ The following is not currently supported:
|
|||
address by changing the file ``armstub8.bin``, so there's no point in using
|
||||
TF-A in this case.
|
||||
|
||||
- ``LOAD_IMAGE_V2=0``: Only version 2 is supported.
|
||||
|
||||
- ``MULTI_CONSOLE_API=0``: The multi console API must be enabled. Note that the
|
||||
crash console uses the internal 16550 driver functions directly in order to be
|
||||
able to print error messages during early crashes before setting up the
|
||||
multi console API.
|
||||
|
||||
Building the firmware for kernels that don't support PSCI
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This is the case for the 32-bit image of Raspbian, for example. 64-bit kernels
|
||||
always support PSCI, but they may not know that the system understands PSCI due
|
||||
to an incorrect DTB file.
|
||||
|
||||
First, clone and compile the 32-bit version of the `Raspberry Pi 3 TF-A
|
||||
bootstrap`_. Choose the one needed for the architecture of your kernel.
|
||||
|
||||
Then compile TF-A. For a 32-bit kernel, use the following command line:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3 \
|
||||
RPI3_BL33_IN_AARCH32=1 \
|
||||
BL33=../rpi3-arm-tf-bootstrap/aarch32/el2-bootstrap.bin
|
||||
|
||||
For a 64-bit kernel, use this other command line:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3 \
|
||||
BL33=../rpi3-arm-tf-bootstrap/aarch64/el2-bootstrap.bin
|
||||
|
||||
However, enabling PSCI support in a 64-bit kernel is really easy. In the
|
||||
repository `Raspberry Pi 3 TF-A bootstrap`_ there is a patch that can be applied
|
||||
to the Linux kernel tree maintained by the Raspberry Pi foundation. It modifes
|
||||
the DTS to tell the kernel to use PSCI. Once this patch is applied, follow the
|
||||
instructions in `AArch64 kernel build instructions`_ to get a working 64-bit
|
||||
kernel image and supporting files.
|
||||
|
||||
Building the firmware for kernels that support PSCI
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For a 64-bit kernel:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3 \
|
||||
PRELOADED_BL33_BASE=0x02000000 \
|
||||
RPI3_PRELOADED_DTB_BASE=0x01000000 \
|
||||
RPI3_DIRECT_LINUX_BOOT=1
|
||||
|
||||
For a 32-bit kernel:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3 \
|
||||
PRELOADED_BL33_BASE=0x02000000 \
|
||||
RPI3_PRELOADED_DTB_BASE=0x01000000 \
|
||||
RPI3_DIRECT_LINUX_BOOT=1 \
|
||||
RPI3_BL33_IN_AARCH32=1
|
||||
|
||||
AArch64 kernel build instructions
|
||||
---------------------------------
|
||||
|
||||
|
@ -280,7 +334,7 @@ allows the user to run 64-bit binaries in addition to 32-bit binaries.
|
|||
|
||||
.. code:: shell
|
||||
|
||||
git clone --depth=1 -b rpi-4.14.y https://github.com/raspberrypi/linux
|
||||
git clone --depth=1 -b rpi-4.18.y https://github.com/raspberrypi/linux
|
||||
cd linux
|
||||
|
||||
2. Configure and compile the kernel. Adapt the number after ``-j`` so that it is
|
||||
|
@ -300,6 +354,7 @@ allows the user to run 64-bit binaries in addition to 32-bit binaries.
|
|||
|
||||
cp arch/arm64/boot/Image /path/to/boot/kernel8.img
|
||||
cp arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb /path/to/boot/
|
||||
cp arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dtb /path/to/boot/
|
||||
|
||||
4. Install the kernel modules. Replace the path by the corresponding path to the
|
||||
filesystem partition of the SD card on your computer.
|
||||
|
@ -343,8 +398,8 @@ untouched). They have been tested with the image available in 2018-03-13.
|
|||
::
|
||||
|
||||
enable_uart=1
|
||||
kernel_address=0x01000000
|
||||
device_tree_address=0x02000000
|
||||
kernel_address=0x02000000
|
||||
device_tree_address=0x01000000
|
||||
|
||||
If you connect a serial cable to the Mini UART and your computer, and connect
|
||||
to it (for example, with ``screen /dev/ttyUSB0 115200``) you should see some
|
||||
|
|
|
@ -175,9 +175,5 @@ func plat_reset_handler
|
|||
mov w1, #0x80000000
|
||||
str wzr, [x0, #RPI3_INTC_CONTROL_OFFSET]
|
||||
str w1, [x0, #RPI3_INTC_PRESCALER_OFFSET]
|
||||
|
||||
/* wire mailbox 3 to the FIQ line */
|
||||
mov w1, RPI3_INTC_MBOX_CONTROL_SLOT3_FIQ
|
||||
str w1, [x0, #RPI3_INTC_MBOX_CONTROL_OFFSET]
|
||||
ret
|
||||
endfunc plat_reset_handler
|
||||
|
|
|
@ -70,17 +70,17 @@
|
|||
#define PLAT_RPI3_FIP_BASE ULL(0x00020000)
|
||||
#define PLAT_RPI3_FIP_MAX_SIZE ULL(0x001E0000)
|
||||
|
||||
/* We have 16M of memory reserved at at 256M */
|
||||
/* We have 16M of memory reserved starting at 256M */
|
||||
#define SEC_SRAM_BASE ULL(0x10000000)
|
||||
#define SEC_SRAM_SIZE ULL(0x00100000)
|
||||
|
||||
#define SEC_DRAM0_BASE ULL(0x10100000)
|
||||
#define SEC_DRAM0_SIZE ULL(0x00B00000)
|
||||
|
||||
#define NS_DRAM0_BASE ULL(0x10C00000)
|
||||
#define NS_DRAM0_SIZE ULL(0x00400000)
|
||||
#define SEC_DRAM0_SIZE ULL(0x00F00000)
|
||||
/* End of reserved memory */
|
||||
|
||||
#define NS_DRAM0_BASE ULL(0x11000000)
|
||||
#define NS_DRAM0_SIZE ULL(0x01000000)
|
||||
|
||||
/*
|
||||
* BL33 entrypoint.
|
||||
*/
|
||||
|
@ -117,9 +117,11 @@
|
|||
*/
|
||||
#define PLAT_RPI3_TRUSTED_MAILBOX_BASE SHARED_RAM_BASE
|
||||
|
||||
/* The secure entry point to be used on warm reset by all CPUs. */
|
||||
#define PLAT_RPI3_TM_ENTRYPOINT PLAT_RPI3_TRUSTED_MAILBOX_BASE
|
||||
#define PLAT_RPI3_TM_ENTRYPOINT_SIZE ULL(8)
|
||||
|
||||
/* Hold entries for each CPU. */
|
||||
#define PLAT_RPI3_TM_HOLD_BASE (PLAT_RPI3_TM_ENTRYPOINT + \
|
||||
PLAT_RPI3_TM_ENTRYPOINT_SIZE)
|
||||
#define PLAT_RPI3_TM_HOLD_ENTRY_SIZE ULL(8)
|
||||
|
|
|
@ -90,8 +90,11 @@ WORKAROUND_CVE_2017_5715 := 0
|
|||
# Disable the PSCI platform compatibility layer by default
|
||||
ENABLE_PLAT_COMPAT := 0
|
||||
|
||||
# Enable reset to BL31 by default
|
||||
RESET_TO_BL31 := 1
|
||||
# Disable stack protector by default
|
||||
ENABLE_STACK_PROTECTOR := 0
|
||||
|
||||
# Reset to BL31 isn't supported
|
||||
RESET_TO_BL31 := 0
|
||||
|
||||
# Have different sections for code and rodata
|
||||
SEPARATE_CODE_AND_RODATA := 1
|
||||
|
@ -111,6 +114,9 @@ MULTI_CONSOLE_API := 1
|
|||
# BL33 images are in AArch64 by default
|
||||
RPI3_BL33_IN_AARCH32 := 0
|
||||
|
||||
# Assume that BL33 isn't the Linux kernel by default
|
||||
RPI3_DIRECT_LINUX_BOOT := 0
|
||||
|
||||
# BL32 location
|
||||
RPI3_BL32_RAM_LOCATION := tdram
|
||||
ifeq (${RPI3_BL32_RAM_LOCATION}, tsram)
|
||||
|
@ -126,9 +132,17 @@ endif
|
|||
|
||||
$(eval $(call add_define,RPI3_BL32_RAM_LOCATION_ID))
|
||||
$(eval $(call add_define,RPI3_BL33_IN_AARCH32))
|
||||
$(eval $(call add_define,RPI3_DIRECT_LINUX_BOOT))
|
||||
$(eval $(call add_define,RPI3_PRELOADED_DTB_BASE))
|
||||
|
||||
# Verify build config
|
||||
# -------------------
|
||||
#
|
||||
ifneq (${RPI3_DIRECT_LINUX_BOOT}, 0)
|
||||
ifndef RPI3_PRELOADED_DTB_BASE
|
||||
$(error Error: RPI3_PRELOADED_DTB_BASE needed if RPI3_DIRECT_LINUX_BOOT=1)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (${LOAD_IMAGE_V2}, 1)
|
||||
$(error Error: rpi3 needs LOAD_IMAGE_V2=1)
|
||||
|
@ -138,10 +152,19 @@ ifneq (${MULTI_CONSOLE_API}, 1)
|
|||
$(error Error: rpi3 needs MULTI_CONSOLE_API=1)
|
||||
endif
|
||||
|
||||
ifneq (${RESET_TO_BL31}, 0)
|
||||
$(error Error: rpi3 needs RESET_TO_BL31=0)
|
||||
endif
|
||||
|
||||
ifeq (${ARCH},aarch32)
|
||||
$(error Error: AArch32 not supported on rpi3)
|
||||
endif
|
||||
|
||||
ifneq ($(ENABLE_STACK_PROTECTOR), 0)
|
||||
PLAT_BL_COMMON_SOURCES += plat/rpi3/rpi3_rng.c \
|
||||
plat/rpi3/rpi3_stack_protector.c
|
||||
endif
|
||||
|
||||
ifeq (${SPD},opteed)
|
||||
BL2_SOURCES += \
|
||||
lib/optee/optee_utils.c
|
||||
|
|
|
@ -59,39 +59,6 @@ void bl31_early_platform_setup(void *from_bl2,
|
|||
/* Initialize the console to provide early debug support */
|
||||
rpi3_console_init();
|
||||
|
||||
#if RESET_TO_BL31
|
||||
|
||||
/* There are no parameters from BL2 if BL31 is a reset vector */
|
||||
assert(from_bl2 == NULL);
|
||||
assert(plat_params_from_bl2 == NULL);
|
||||
|
||||
#ifdef BL32_BASE
|
||||
/* Populate entry point information for BL32 */
|
||||
SET_PARAM_HEAD(&bl32_image_ep_info,
|
||||
PARAM_EP,
|
||||
VERSION_1,
|
||||
0);
|
||||
SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
|
||||
bl32_image_ep_info.pc = BL32_BASE;
|
||||
bl32_image_ep_info.spsr = rpi3_get_spsr_for_bl32_entry();
|
||||
#endif /* BL32_BASE */
|
||||
|
||||
/* Populate entry point information for BL33 */
|
||||
SET_PARAM_HEAD(&bl33_image_ep_info,
|
||||
PARAM_EP,
|
||||
VERSION_1,
|
||||
0);
|
||||
/*
|
||||
* Tell BL31 where the non-trusted software image
|
||||
* is located and the entry state information
|
||||
*/
|
||||
bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
|
||||
|
||||
bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry();
|
||||
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
|
||||
|
||||
#else /* RESET_TO_BL31 */
|
||||
|
||||
/*
|
||||
* In debug builds, we pass a special value in 'plat_params_from_bl2'
|
||||
* to verify platform parameters from BL2 to BL31.
|
||||
|
@ -130,7 +97,33 @@ void bl31_early_platform_setup(void *from_bl2,
|
|||
panic();
|
||||
}
|
||||
|
||||
#endif /* RESET_TO_BL31 */
|
||||
#if RPI3_DIRECT_LINUX_BOOT
|
||||
# if RPI3_BL33_IN_AARCH32
|
||||
/*
|
||||
* According to the file ``Documentation/arm/Booting`` of the Linux
|
||||
* kernel tree, Linux expects:
|
||||
* r0 = 0
|
||||
* r1 = machine type number, optional in DT-only platforms (~0 if so)
|
||||
* r2 = Physical address of the device tree blob
|
||||
*/
|
||||
VERBOSE("rpi3: Preparing to boot 32-bit Linux kernel\n");
|
||||
bl33_image_ep_info.args.arg0 = 0U;
|
||||
bl33_image_ep_info.args.arg1 = ~0U;
|
||||
bl33_image_ep_info.args.arg2 = (u_register_t) RPI3_PRELOADED_DTB_BASE;
|
||||
# else
|
||||
/*
|
||||
* According to the file ``Documentation/arm64/booting.txt`` of the
|
||||
* Linux kernel tree, Linux expects the physical address of the device
|
||||
* tree blob (DTB) in x0, while x1-x3 are reserved for future use and
|
||||
* must be 0.
|
||||
*/
|
||||
VERBOSE("rpi3: Preparing to boot 64-bit Linux kernel\n");
|
||||
bl33_image_ep_info.args.arg0 = (u_register_t) RPI3_PRELOADED_DTB_BASE;
|
||||
bl33_image_ep_info.args.arg1 = 0ULL;
|
||||
bl33_image_ep_info.args.arg2 = 0ULL;
|
||||
bl33_image_ep_info.args.arg3 = 0ULL;
|
||||
# endif /* RPI3_BL33_IN_AARCH32 */
|
||||
#endif /* RPI3_DIRECT_LINUX_BOOT */
|
||||
}
|
||||
|
||||
void bl31_plat_arch_setup(void)
|
||||
|
@ -148,12 +141,10 @@ void bl31_plat_arch_setup(void)
|
|||
|
||||
void bl31_platform_setup(void)
|
||||
{
|
||||
#if RESET_TO_BL31
|
||||
/*
|
||||
* Do initial security configuration to allow DRAM/device access
|
||||
* (if earlier BL has not already done so).
|
||||
*/
|
||||
#endif /* RESET_TO_BL31 */
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,24 @@
|
|||
*/
|
||||
#define RPI3_PM_RSTS_WRCFG_HALT U(0x00000555)
|
||||
|
||||
/*
|
||||
* Hardware random number generator.
|
||||
*/
|
||||
#define RPI3_IO_RNG_OFFSET ULL(0x00104000)
|
||||
#define RPI3_RNG_BASE (RPI3_IO_BASE + RPI3_IO_RNG_OFFSET)
|
||||
#define RPI3_RNG_CTRL_OFFSET ULL(0x00000000)
|
||||
#define RPI3_RNG_STATUS_OFFSET ULL(0x00000004)
|
||||
#define RPI3_RNG_DATA_OFFSET ULL(0x00000008)
|
||||
#define RPI3_RNG_INT_MASK_OFFSET ULL(0x00000010)
|
||||
/* Enable/disable RNG */
|
||||
#define RPI3_RNG_CTRL_ENABLE U(0x1)
|
||||
#define RPI3_RNG_CTRL_DISABLE U(0x0)
|
||||
/* Number of currently available words */
|
||||
#define RPI3_RNG_STATUS_NUM_WORDS_SHIFT U(24)
|
||||
#define RPI3_RNG_STATUS_NUM_WORDS_MASK U(0xFF)
|
||||
/* Value to mask interrupts caused by the RNG */
|
||||
#define RPI3_RNG_INT_MASK_DISABLE U(0x1)
|
||||
|
||||
/*
|
||||
* Serial port (called 'Mini UART' in the BCM docucmentation).
|
||||
*/
|
||||
|
|
|
@ -15,11 +15,6 @@
|
|||
|
||||
#include "rpi3_hw.h"
|
||||
|
||||
/*
|
||||
* The secure entry point to be used on warm reset.
|
||||
*/
|
||||
static uintptr_t secure_entrypoint;
|
||||
|
||||
/* Make composite power state parameter till power level 0 */
|
||||
#if PSCI_EXTENDED_STATE_ID
|
||||
|
||||
|
@ -220,10 +215,9 @@ static const plat_psci_ops_t plat_rpi3_psci_pm_ops = {
|
|||
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
|
||||
const plat_psci_ops_t **psci_ops)
|
||||
{
|
||||
uintptr_t *mailbox = (void *)PLAT_RPI3_TRUSTED_MAILBOX_BASE;
|
||||
uintptr_t *entrypoint = (void *) PLAT_RPI3_TM_ENTRYPOINT;
|
||||
|
||||
*mailbox = sec_entrypoint;
|
||||
secure_entrypoint = (uintptr_t)sec_entrypoint;
|
||||
*entrypoint = sec_entrypoint;
|
||||
*psci_ops = &plat_rpi3_psci_pm_ops;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -33,6 +33,9 @@ uint32_t rpi3_get_spsr_for_bl33_entry(void);
|
|||
/* IO storage utility functions */
|
||||
void plat_rpi3_io_setup(void);
|
||||
|
||||
/* Hardware RNG functions */
|
||||
void rpi3_rng_read(void *buf, size_t len);
|
||||
|
||||
/* VideoCore firmware commands */
|
||||
int rpi3_vc_hardware_get_board_revision(uint32_t *revision);
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <mmio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rpi3_hw.h"
|
||||
|
||||
/* Initial amount of values to discard */
|
||||
#define RNG_WARMUP_COUNT U(0x40000)
|
||||
|
||||
static void rpi3_rng_initialize(void)
|
||||
{
|
||||
uint32_t int_mask, ctrl;
|
||||
|
||||
/* Return if it is already enabled */
|
||||
ctrl = mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_CTRL_OFFSET);
|
||||
if ((ctrl & RPI3_RNG_CTRL_ENABLE) != 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mask interrupts */
|
||||
int_mask = mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_INT_MASK_OFFSET);
|
||||
int_mask |= RPI3_RNG_INT_MASK_DISABLE;
|
||||
mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_INT_MASK_OFFSET, int_mask);
|
||||
|
||||
/* Discard several values when initializing to give it time to warmup */
|
||||
mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_STATUS_OFFSET, RNG_WARMUP_COUNT);
|
||||
|
||||
mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_CTRL_OFFSET,
|
||||
RPI3_RNG_CTRL_ENABLE);
|
||||
}
|
||||
|
||||
static uint32_t rpi3_rng_get_word(void)
|
||||
{
|
||||
size_t nwords;
|
||||
|
||||
do {
|
||||
/* Get number of available words to read */
|
||||
nwords = (mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_STATUS_OFFSET)
|
||||
>> RPI3_RNG_STATUS_NUM_WORDS_SHIFT)
|
||||
& RPI3_RNG_STATUS_NUM_WORDS_MASK;
|
||||
} while (nwords == 0U);
|
||||
|
||||
return mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_DATA_OFFSET);
|
||||
}
|
||||
|
||||
void rpi3_rng_read(void *buf, size_t len)
|
||||
{
|
||||
uint32_t data;
|
||||
size_t left = len;
|
||||
uint32_t *dst = buf;
|
||||
|
||||
assert(buf != NULL);
|
||||
assert(len != 0U);
|
||||
assert(check_uptr_overflow((uintptr_t) buf, (uintptr_t) len) == 0);
|
||||
|
||||
rpi3_rng_initialize();
|
||||
|
||||
while (left >= sizeof(uint32_t)) {
|
||||
data = rpi3_rng_get_word();
|
||||
*dst++ = data;
|
||||
left -= sizeof(uint32_t);
|
||||
}
|
||||
|
||||
if (left > 0U) {
|
||||
data = rpi3_rng_get_word();
|
||||
memcpy(dst, &data, left);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <utils.h>
|
||||
|
||||
#include "rpi3_private.h"
|
||||
|
||||
/* Get 128 bits of entropy and fuse the values together to form the canary. */
|
||||
#define TRNG_NBYTES 16U
|
||||
|
||||
u_register_t plat_get_stack_protector_canary(void)
|
||||
{
|
||||
size_t i;
|
||||
u_register_t buf[TRNG_NBYTES / sizeof(u_register_t)];
|
||||
u_register_t ret = 0U;
|
||||
|
||||
rpi3_rng_read(buf, sizeof(buf));
|
||||
|
||||
for (i = 0U; i < ARRAY_SIZE(buf); i++)
|
||||
ret ^= buf[i];
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Reference in New Issue