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
992a3536
Unverified
Commit
992a3536
authored
Jul 19, 2018
by
danh-arm
Committed by
GitHub
Jul 19, 2018
Browse files
Merge pull request #1483 from antonio-nino-diaz-arm/an/rpi3-psci
rpi3: PSCI and Linux boot improvements
parents
224e1aba
aa49bde8
Changes
10
Hide whitespace changes
Inline
Side-by-side
docs/plat/rpi3.rst
View file @
992a3536
...
@@ -7,8 +7,7 @@ Trusted Firmware-A for Raspberry Pi 3
...
@@ -7,8 +7,7 @@ Trusted Firmware-A for Raspberry Pi 3
.. contents::
.. contents::
The `Raspberry Pi 3`_ is an inexpensive single-board computer that contains four
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
Arm Cortex-A53 cores.
Firmware-A (TF-A).
The following instructions explain how to use this port of the TF-A with the
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
default distribution of `Raspbian`_ because that's the distribution officially
...
@@ -66,7 +65,7 @@ Placement of images
...
@@ -66,7 +65,7 @@ Placement of images
The file ``armstub8.bin`` contains BL1 and the FIP. It is needed to add padding
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
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
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``.
file, but we can specify the address it is loaded to in ``config.txt``.
...
@@ -108,13 +107,13 @@ secure platform!
...
@@ -108,13 +107,13 @@ secure platform!
| ... |
| ... |
| |
| |
0x01000000 +-----------------+
0x01000000 +-----------------+
|
Kernel
|
|
DTB
|
(Loaded by the VideoCore)
+-----------------+
+-----------------+
| |
| |
| ... |
| ... |
| |
| |
0x02000000 +-----------------+
0x02000000 +-----------------+
|
DTB |
|
Kernel | (Loaded by the VideoCore)
+-----------------+
+-----------------+
| |
| |
| ... |
| ... |
...
@@ -123,9 +122,9 @@ secure platform!
...
@@ -123,9 +122,9 @@ secure platform!
| Secure SRAM | BL2, BL31
| Secure SRAM | BL2, BL31
0x10100000 +-----------------+
0x10100000 +-----------------+
| Secure DRAM | BL32 (Secure payload)
| Secure DRAM | BL32 (Secure payload)
0x10C00000 +-----------------+
| Non-secure DRAM | BL33
0x11000000 +-----------------+
0x11000000 +-----------------+
| Non-secure DRAM | BL33
+-----------------+
| |
| |
| ... |
| ... |
| |
| |
...
@@ -133,10 +132,10 @@ secure platform!
...
@@ -133,10 +132,10 @@ secure platform!
| I/O |
| I/O |
0x40000000 +-----------------+
0x40000000 +-----------------+
The area between **0x10000000** and **0x11000000** has to be protected
so that
The area between **0x10000000** and **0x11000000** has to be
manually
protected
the kernel doesn't use it. That is done by adding ``memmap=16M$256M`` to
the
so that
the kernel doesn't use it. That is done by adding ``memmap=16M$256M`` to
command line passed to the kernel. See the `Setup SD card`_ instructions to
see
the
command line passed to the kernel. See the `Setup SD card`_ instructions to
how to do it.
see
how to do it.
The last 16 MiB of DRAM can only be accessed by the VideoCore, that has
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
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
...
@@ -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
in ``Documentation/arm/Booting`` and ``Documentation/arm64/booting.txt``. The
bootstrap should take care of this.
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
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
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
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. This mailbox is located at a different address in the AArch32 default
kernel than in the AArch64 kernel.
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
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
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``).
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
...
@@ -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
AArch32 toolchain is needed for the AArch32 bootstrap needed to load a 32-bit
kernel.
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
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
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
build folder (e.g. ``build/rpi3/debug/armstub8.bin``).
To know how to use this
instructions in `Setup SD card`_.
file, follow the
instructions in `Setup SD card`_.
The following build options are supported:
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.
- ``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
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
in AArch64 mode. If set to 1, it will jump to BL33 in Hypervisor in AArch32
mode.
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.
- ``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>`__.
Please use the code from `here <https://github.com/OP-TEE/optee_os>`__.
Build the Trusted Firmware with option ``BL32=tee-header_v2.bin
Build the Trusted Firmware with option ``BL32=tee-header_v2.bin
...
@@ -239,15 +240,16 @@ The following build options are supported:
...
@@ -239,15 +240,16 @@ The following build options are supported:
This will unfortunately reduce the performance of the USB driver. It is needed
This will unfortunately reduce the performance of the USB driver. It is needed
when using Raspbian, for example.
when using Raspbian, for example.
- ``TRUSTED_BOARD_BOOT``: This port supports TBB. Set this option
- ``TRUSTED_BOARD_BOOT``: This port supports TBB. Set this option to 1 to enable
``TRUSTED_BOARD_BOOT=1`` to enable it. In order to use TBB, you might
it. In order to use TBB, you might want to set ``GENERATE_COT=1`` to let the
want to set ``GENERATE_COT=1`` to let the contents of the FIP automatically
contents of the FIP automatically signed by the build process. The ROT key
signed by the build process. The ROT key will be generated and output to
will be generated and output to ``rot_key.pem`` in the build directory. It is
``rot_key.pem`` in the build directory. It is able to set ROT_KEY to
able to set ROT_KEY to your own key in PEM format. Also in order to build,
your own key in PEM format.
you need to clone mbed TLS from `here <https://github.com/ARMmbed/mbedtls>`__.
Also in order to build, you need to clone mbedtls from
``MBEDTLS_DIR`` must point at the mbed TLS source directory.
`here <https://github.com/ARMmbed/mbedtls>`__.
And set MBEDTLS_DIR to mbedtls source directory.
- ``ENABLE_STACK_PROTECTOR``: Disabled by default. It uses the hardware RNG of
the board.
The following is not currently supported:
The following is not currently supported:
...
@@ -257,13 +259,65 @@ 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
address by changing the file ``armstub8.bin``, so there's no point in using
TF-A in this case.
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
- ``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
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
able to print error messages during early crashes before setting up the
multi console API.
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
AArch64 kernel build instructions
---------------------------------
---------------------------------
...
@@ -280,7 +334,7 @@ allows the user to run 64-bit binaries in addition to 32-bit binaries.
...
@@ -280,7 +334,7 @@ allows the user to run 64-bit binaries in addition to 32-bit binaries.
.. code:: shell
.. code:: shell
git clone --depth=1 -b rpi-4.1
4
.y https://github.com/raspberrypi/linux
git clone --depth=1 -b rpi-4.1
8
.y https://github.com/raspberrypi/linux
cd linux
cd linux
2. Configure and compile the kernel. Adapt the number after ``-j`` so that it is
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.
...
@@ -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/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.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
4. Install the kernel modules. Replace the path by the corresponding path to the
filesystem partition of the SD card on your computer.
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.
...
@@ -343,8 +398,8 @@ untouched). They have been tested with the image available in 2018-03-13.
::
::
enable_uart=1
enable_uart=1
kernel_address=0x0
1
000000
kernel_address=0x0
2
000000
device_tree_address=0x0
2
000000
device_tree_address=0x0
1
000000
If you connect a serial cable to the Mini UART and your computer, and connect
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
to it (for example, with ``screen /dev/ttyUSB0 115200``) you should see some
...
...
plat/rpi3/aarch64/plat_helpers.S
View file @
992a3536
...
@@ -175,9 +175,5 @@ func plat_reset_handler
...
@@ -175,9 +175,5 @@ func plat_reset_handler
mov
w1
,
#
0x80000000
mov
w1
,
#
0x80000000
str
wzr
,
[
x0
,
#
RPI3_INTC_CONTROL_OFFSET
]
str
wzr
,
[
x0
,
#
RPI3_INTC_CONTROL_OFFSET
]
str
w1
,
[
x0
,
#
RPI3_INTC_PRESCALER_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
ret
endfunc
plat_reset_handler
endfunc
plat_reset_handler
plat/rpi3/include/platform_def.h
View file @
992a3536
...
@@ -70,17 +70,17 @@
...
@@ -70,17 +70,17 @@
#define PLAT_RPI3_FIP_BASE ULL(0x00020000)
#define PLAT_RPI3_FIP_BASE ULL(0x00020000)
#define PLAT_RPI3_FIP_MAX_SIZE ULL(0x001E0000)
#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_BASE ULL(0x10000000)
#define SEC_SRAM_SIZE ULL(0x00100000)
#define SEC_SRAM_SIZE ULL(0x00100000)
#define SEC_DRAM0_BASE ULL(0x10100000)
#define SEC_DRAM0_BASE ULL(0x10100000)
#define SEC_DRAM0_SIZE ULL(0x00B00000)
#define SEC_DRAM0_SIZE ULL(0x00F00000)
#define NS_DRAM0_BASE ULL(0x10C00000)
#define NS_DRAM0_SIZE ULL(0x00400000)
/* End of reserved memory */
/* End of reserved memory */
#define NS_DRAM0_BASE ULL(0x11000000)
#define NS_DRAM0_SIZE ULL(0x01000000)
/*
/*
* BL33 entrypoint.
* BL33 entrypoint.
*/
*/
...
@@ -117,9 +117,11 @@
...
@@ -117,9 +117,11 @@
*/
*/
#define PLAT_RPI3_TRUSTED_MAILBOX_BASE SHARED_RAM_BASE
#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 PLAT_RPI3_TRUSTED_MAILBOX_BASE
#define PLAT_RPI3_TM_ENTRYPOINT_SIZE ULL(8)
#define PLAT_RPI3_TM_ENTRYPOINT_SIZE ULL(8)
/* Hold entries for each CPU. */
#define PLAT_RPI3_TM_HOLD_BASE (PLAT_RPI3_TM_ENTRYPOINT + \
#define PLAT_RPI3_TM_HOLD_BASE (PLAT_RPI3_TM_ENTRYPOINT + \
PLAT_RPI3_TM_ENTRYPOINT_SIZE)
PLAT_RPI3_TM_ENTRYPOINT_SIZE)
#define PLAT_RPI3_TM_HOLD_ENTRY_SIZE ULL(8)
#define PLAT_RPI3_TM_HOLD_ENTRY_SIZE ULL(8)
...
...
plat/rpi3/platform.mk
View file @
992a3536
...
@@ -90,8 +90,11 @@ WORKAROUND_CVE_2017_5715 := 0
...
@@ -90,8 +90,11 @@ WORKAROUND_CVE_2017_5715 := 0
# Disable the PSCI platform compatibility layer by default
# Disable the PSCI platform compatibility layer by default
ENABLE_PLAT_COMPAT
:=
0
ENABLE_PLAT_COMPAT
:=
0
# Enable reset to BL31 by default
# Disable stack protector by default
RESET_TO_BL31
:=
1
ENABLE_STACK_PROTECTOR
:=
0
# Reset to BL31 isn't supported
RESET_TO_BL31
:=
0
# Have different sections for code and rodata
# Have different sections for code and rodata
SEPARATE_CODE_AND_RODATA
:=
1
SEPARATE_CODE_AND_RODATA
:=
1
...
@@ -111,6 +114,9 @@ MULTI_CONSOLE_API := 1
...
@@ -111,6 +114,9 @@ MULTI_CONSOLE_API := 1
# BL33 images are in AArch64 by default
# BL33 images are in AArch64 by default
RPI3_BL33_IN_AARCH32
:=
0
RPI3_BL33_IN_AARCH32
:=
0
# Assume that BL33 isn't the Linux kernel by default
RPI3_DIRECT_LINUX_BOOT
:=
0
# BL32 location
# BL32 location
RPI3_BL32_RAM_LOCATION
:=
tdram
RPI3_BL32_RAM_LOCATION
:=
tdram
ifeq
(${RPI3_BL32_RAM_LOCATION}, tsram)
ifeq
(${RPI3_BL32_RAM_LOCATION}, tsram)
...
@@ -126,9 +132,17 @@ endif
...
@@ -126,9 +132,17 @@ endif
$(eval
$(call
add_define,RPI3_BL32_RAM_LOCATION_ID))
$(eval
$(call
add_define,RPI3_BL32_RAM_LOCATION_ID))
$(eval
$(call
add_define,RPI3_BL33_IN_AARCH32))
$(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
# 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)
ifneq
(${LOAD_IMAGE_V2}, 1)
$(error Error
:
rpi3 needs LOAD_IMAGE_V2=1)
$(error Error
:
rpi3 needs LOAD_IMAGE_V2=1)
...
@@ -138,10 +152,19 @@ ifneq (${MULTI_CONSOLE_API}, 1)
...
@@ -138,10 +152,19 @@ ifneq (${MULTI_CONSOLE_API}, 1)
$(error Error
:
rpi3 needs MULTI_CONSOLE_API=1)
$(error Error
:
rpi3 needs MULTI_CONSOLE_API=1)
endif
endif
ifneq
(${RESET_TO_BL31}, 0)
$(error Error
:
rpi3 needs RESET_TO_BL31=0)
endif
ifeq
(${ARCH},aarch32)
ifeq
(${ARCH},aarch32)
$(error Error
:
AArch32 not supported on rpi3)
$(error Error
:
AArch32 not supported on rpi3)
endif
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)
ifeq
(${SPD},opteed)
BL2_SOURCES
+=
\
BL2_SOURCES
+=
\
lib/optee/optee_utils.c
lib/optee/optee_utils.c
...
...
plat/rpi3/rpi3_bl31_setup.c
View file @
992a3536
...
@@ -59,39 +59,6 @@ void bl31_early_platform_setup(void *from_bl2,
...
@@ -59,39 +59,6 @@ void bl31_early_platform_setup(void *from_bl2,
/* Initialize the console to provide early debug support */
/* Initialize the console to provide early debug support */
rpi3_console_init
();
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'
* In debug builds, we pass a special value in 'plat_params_from_bl2'
* to verify platform parameters from BL2 to BL31.
* to verify platform parameters from BL2 to BL31.
...
@@ -130,7 +97,33 @@ void bl31_early_platform_setup(void *from_bl2,
...
@@ -130,7 +97,33 @@ void bl31_early_platform_setup(void *from_bl2,
panic
();
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
)
void
bl31_plat_arch_setup
(
void
)
...
@@ -148,12 +141,10 @@ void bl31_plat_arch_setup(void)
...
@@ -148,12 +141,10 @@ void bl31_plat_arch_setup(void)
void
bl31_platform_setup
(
void
)
void
bl31_platform_setup
(
void
)
{
{
#if RESET_TO_BL31
/*
/*
* Do initial security configuration to allow DRAM/device access
* Do initial security configuration to allow DRAM/device access
* (if earlier BL has not already done so).
* (if earlier BL has not already done so).
*/
*/
#endif
/* RESET_TO_BL31 */
return
;
return
;
}
}
plat/rpi3/rpi3_hw.h
View file @
992a3536
...
@@ -58,6 +58,24 @@
...
@@ -58,6 +58,24 @@
*/
*/
#define RPI3_PM_RSTS_WRCFG_HALT U(0x00000555)
#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).
* Serial port (called 'Mini UART' in the BCM docucmentation).
*/
*/
...
...
plat/rpi3/rpi3_pm.c
View file @
992a3536
...
@@ -15,11 +15,6 @@
...
@@ -15,11 +15,6 @@
#include "rpi3_hw.h"
#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 */
/* Make composite power state parameter till power level 0 */
#if PSCI_EXTENDED_STATE_ID
#if PSCI_EXTENDED_STATE_ID
...
@@ -220,10 +215,9 @@ static const plat_psci_ops_t plat_rpi3_psci_pm_ops = {
...
@@ -220,10 +215,9 @@ static const plat_psci_ops_t plat_rpi3_psci_pm_ops = {
int
plat_setup_psci_ops
(
uintptr_t
sec_entrypoint
,
int
plat_setup_psci_ops
(
uintptr_t
sec_entrypoint
,
const
plat_psci_ops_t
**
psci_ops
)
const
plat_psci_ops_t
**
psci_ops
)
{
{
uintptr_t
*
mailbox
=
(
void
*
)
PLAT_RPI3_T
RUSTED_MAILBOX_BASE
;
uintptr_t
*
entrypoint
=
(
void
*
)
PLAT_RPI3_T
M_ENTRYPOINT
;
*
mailbox
=
sec_entrypoint
;
*
entrypoint
=
sec_entrypoint
;
secure_entrypoint
=
(
uintptr_t
)
sec_entrypoint
;
*
psci_ops
=
&
plat_rpi3_psci_pm_ops
;
*
psci_ops
=
&
plat_rpi3_psci_pm_ops
;
return
0
;
return
0
;
...
...
plat/rpi3/rpi3_private.h
View file @
992a3536
...
@@ -33,6 +33,9 @@ uint32_t rpi3_get_spsr_for_bl33_entry(void);
...
@@ -33,6 +33,9 @@ uint32_t rpi3_get_spsr_for_bl33_entry(void);
/* IO storage utility functions */
/* IO storage utility functions */
void
plat_rpi3_io_setup
(
void
);
void
plat_rpi3_io_setup
(
void
);
/* Hardware RNG functions */
void
rpi3_rng_read
(
void
*
buf
,
size_t
len
);
/* VideoCore firmware commands */
/* VideoCore firmware commands */
int
rpi3_vc_hardware_get_board_revision
(
uint32_t
*
revision
);
int
rpi3_vc_hardware_get_board_revision
(
uint32_t
*
revision
);
...
...
plat/rpi3/rpi3_rng.c
0 → 100644
View file @
992a3536
/*
* 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
);
}
}
plat/rpi3/rpi3_stack_protector.c
0 → 100644
View file @
992a3536
/*
* 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
;
}
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