Commit 429421de authored by danh-arm's avatar danh-arm
Browse files

Merge pull request #33 from hliebel/hl/secure-memory

Hl/secure memory
parents 12ae170e ce19cf1b
...@@ -207,15 +207,17 @@ bits. ...@@ -207,15 +207,17 @@ bits.
#### Platform initialization #### Platform initialization
BL2 does not perform any platform initialization that affects subsequent BL2 copies the information regarding the trusted SRAM populated by BL1 using a
stages of the ARM Trusted Firmware or normal world software. It copies the
information regarding the trusted SRAM populated by BL1 using a
platform-specific mechanism. It calculates the limits of DRAM (main memory) platform-specific mechanism. It calculates the limits of DRAM (main memory)
to determine whether there is enough space to load the BL3-3 image. A platform to determine whether there is enough space to load the BL3-3 image. A platform
defined base address is used to specify the load address for the BL3-1 image. defined base address is used to specify the load address for the BL3-1 image.
It also defines the extents of memory available for use by the BL3-2 image. It also defines the extents of memory available for use by the BL3-2 image.
BL2 also initializes UART0 (PL011 console), which enables access to the BL2 also initializes UART0 (PL011 console), which enables access to the
`printf` family of functions in BL2 `printf` family of functions in BL2. Platform security is initialized to allow
access to access controlled components. On the Base FVP a TrustZone controller
(TZC-400) is configured to give full access to the platform DRAM. The storage
abstraction layer is initialized which is used to load further bootloader
images.
#### BL3-1 (EL3 Runtime Firmware) image load #### BL3-1 (EL3 Runtime Firmware) image load
......
...@@ -630,6 +630,10 @@ The non-secure memory extents used for loading BL3-3 are also initialized in ...@@ -630,6 +630,10 @@ The non-secure memory extents used for loading BL3-3 are also initialized in
this function. This information is accessible in the `bl33_meminfo` field in this function. This information is accessible in the `bl33_meminfo` field in
the `bl31_args` structure pointed to by `bl2_to_bl31_args`. the `bl31_args` structure pointed to by `bl2_to_bl31_args`.
Platform security components are configured if required. For the Base FVP the
TZC-400 TrustZone controller is configured to grant secure and non-secure access
to DRAM.
This function is also responsible for initializing the storage abstraction layer This function is also responsible for initializing the storage abstraction layer
which is used to load further bootloader images. which is used to load further bootloader images.
......
...@@ -532,9 +532,15 @@ NOTE: The `-C bp.flashloader0.fname` parameter is used to load a Firmware Image ...@@ -532,9 +532,15 @@ NOTE: The `-C bp.flashloader0.fname` parameter is used to load a Firmware Image
Package at the start of NOR FLASH0 (see the "Building the Trusted Firmware" Package at the start of NOR FLASH0 (see the "Building the Trusted Firmware"
section above). section above).
NOTE: Setting the `-C bp.secure_memory` parameter to `1` is only supported on
FVP versions 5.4 and newer. Setting this parameter to `0` is also supported.
The `-C bp.tzc_400.diagnostics=1` parameter is optional. It instructs the FVP to
provide some helpful information if a secure memory violation occurs.
<path-to>/FVP_Base_AEMv8A-AEMv8A \ <path-to>/FVP_Base_AEMv8A-AEMv8A \
-C pctl.startup=0.0.0.0 \ -C pctl.startup=0.0.0.0 \
-C bp.secure_memory=0 \ -C bp.secure_memory=1 \
-C bp.tzc_400.diagnostics=1 \
-C cluster0.NUM_CORES=4 \ -C cluster0.NUM_CORES=4 \
-C cluster1.NUM_CORES=4 \ -C cluster1.NUM_CORES=4 \
-C cache_state_modelled=1 \ -C cache_state_modelled=1 \
...@@ -560,9 +566,15 @@ NOTE: The `-C bp.flashloader0.fname` parameter is used to load a Firmware Image ...@@ -560,9 +566,15 @@ NOTE: The `-C bp.flashloader0.fname` parameter is used to load a Firmware Image
Package at the start of NOR FLASH0 (see the "Building the Trusted Firmware" Package at the start of NOR FLASH0 (see the "Building the Trusted Firmware"
section above). section above).
NOTE: Setting the `-C bp.secure_memory` parameter to `1` is only supported on
FVP versions 5.4 and newer. Setting this parameter to `0` is also supported.
The `-C bp.tzc_400.diagnostics=1` parameter is optional. It instructs the FVP to
provide some helpful information if a secure memory violation occurs.
<path-to>/FVP_Base_Cortex-A57x4-A53x4 \ <path-to>/FVP_Base_Cortex-A57x4-A53x4 \
-C pctl.startup=0.0.0.0 \ -C pctl.startup=0.0.0.0 \
-C bp.secure_memory=0 \ -C bp.secure_memory=1 \
-C bp.tzc_400.diagnostics=1 \
-C cache_state_modelled=1 \ -C cache_state_modelled=1 \
-C bp.pl011_uart0.untimed_fifos=1 \ -C bp.pl011_uart0.untimed_fifos=1 \
-C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \ -C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \
......
/*
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include "arch_helpers.h"
#include "tzc400.h"
#include "mmio.h"
#include "debug.h"
static uint32_t tzc_read_build_config(uint64_t base)
{
return mmio_read_32(base + BUILD_CONFIG_OFF);
}
static uint32_t tzc_read_gate_keeper(uint64_t base)
{
return mmio_read_32(base + GATE_KEEPER_OFF);
}
static void tzc_write_gate_keeper(uint64_t base, uint32_t val)
{
mmio_write_32(base + GATE_KEEPER_OFF, val);
}
static void tzc_write_action(uint64_t base, enum tzc_action action)
{
mmio_write_32(base + ACTION_OFF, action);
}
static void tzc_write_region_base_low(uint64_t base, uint32_t region, uint32_t val)
{
mmio_write_32(base + REGION_BASE_LOW_OFF + REGION_NUM_OFF(region), val);
}
static void tzc_write_region_base_high(uint64_t base, uint32_t region, uint32_t val)
{
mmio_write_32(base + REGION_BASE_HIGH_OFF + REGION_NUM_OFF(region), val);
}
static void tzc_write_region_top_low(uint64_t base, uint32_t region, uint32_t val)
{
mmio_write_32(base + REGION_TOP_LOW_OFF + REGION_NUM_OFF(region), val);
}
static void tzc_write_region_top_high(uint64_t base, uint32_t region, uint32_t val)
{
mmio_write_32(base + REGION_TOP_HIGH_OFF + REGION_NUM_OFF(region), val);
}
static void tzc_write_region_attributes(uint64_t base, uint32_t region, uint32_t val)
{
mmio_write_32(base + REGION_ATTRIBUTES_OFF + REGION_NUM_OFF(region), val);
}
static void tzc_write_region_id_access(uint64_t base, uint32_t region, uint32_t val)
{
mmio_write_32(base + REGION_ID_ACCESS_OFF + REGION_NUM_OFF(region), val);
}
static uint32_t tzc_read_component_id(uint64_t base)
{
uint32_t id;
id = mmio_read_8(base + CID0_OFF);
id |= (mmio_read_8(base + CID1_OFF) << 8);
id |= (mmio_read_8(base + CID2_OFF) << 16);
id |= (mmio_read_8(base + CID3_OFF) << 24);
return id;
}
static uint32_t tzc_get_gate_keeper(uint64_t base, uint8_t filter)
{
uint32_t tmp;
tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) &
GATE_KEEPER_OS_MASK;
return tmp >> filter;
}
/* This function is not MP safe. */
static void tzc_set_gate_keeper(uint64_t base, uint8_t filter, uint32_t val)
{
uint32_t tmp;
/* Upper half is current state. Lower half is requested state. */
tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) &
GATE_KEEPER_OS_MASK;
if (val)
tmp |= (1 << filter);
else
tmp &= ~(1 << filter);
tzc_write_gate_keeper(base, (tmp & GATE_KEEPER_OR_MASK) <<
GATE_KEEPER_OR_SHIFT);
/* Wait here until we see the change reflected in the TZC status. */
while (((tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) &
GATE_KEEPER_OS_MASK) != tmp)
;
}
void tzc_init(struct tzc_instance *controller)
{
uint32_t tzc_id, tzc_build;
assert(controller != NULL);
/*
* We expect to see a tzc400. Check component ID. The TZC-400 TRM shows
* component ID is expected to be "0xB105F00D".
*/
tzc_id = tzc_read_component_id(controller->base);
if (tzc_id != TZC400_COMPONENT_ID) {
ERROR("TZC : Wrong device ID (0x%x).\n", tzc_id);
panic();
}
/* Save values we will use later. */
tzc_build = tzc_read_build_config(controller->base);
controller->num_filters = ((tzc_build >> BUILD_CONFIG_NF_SHIFT) &
BUILD_CONFIG_NF_MASK) + 1;
controller->addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) &
BUILD_CONFIG_AW_MASK) + 1;
controller->num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) &
BUILD_CONFIG_NR_MASK) + 1;
}
/*
* `tzc_configure_region` is used to program regions into the TrustZone
* controller. A region can be associated with more than one filter. The
* associated filters are passed in as a bitmap (bit0 = filter0).
* NOTE:
* The region 0 covers the whole address space and is enabled on all filters,
* this cannot be changed. It is, however, possible to change some region 0
* permissions.
*/
void tzc_configure_region(const struct tzc_instance *controller,
uint32_t filters,
uint8_t region,
uint64_t region_base,
uint64_t region_top,
enum tzc_region_attributes sec_attr,
uint32_t ns_device_access)
{
uint64_t max_addr;
assert(controller != NULL);
/* Do range checks on filters and regions. */
assert(((filters >> controller->num_filters) == 0) &&
(region < controller->num_regions));
/*
* Do address range check based on TZC configuration. A 64bit address is
* the max and expected case.
*/
max_addr = UINT64_MAX >> (64 - controller->addr_width);
if ((region_top > max_addr) || (region_base >= region_top))
assert(0);
/* region_base and (region_top + 1) must be 4KB aligned */
assert(((region_base | (region_top + 1)) & (4096 - 1)) == 0);
assert(sec_attr <= TZC_REGION_S_RDWR);
/*
* Inputs look ok, start programming registers.
* All the address registers are 32 bits wide and have a LOW and HIGH
* component used to construct a up to a 64bit address.
*/
tzc_write_region_base_low(controller->base, region, (uint32_t)(region_base));
tzc_write_region_base_high(controller->base, region, (uint32_t)(region_base >> 32));
tzc_write_region_top_low(controller->base, region, (uint32_t)(region_top));
tzc_write_region_top_high(controller->base, region, (uint32_t)(region_top >> 32));
/* Assign the region to a filter and set secure attributes */
tzc_write_region_attributes(controller->base, region,
(sec_attr << REGION_ATTRIBUTES_SEC_SHIFT) | filters);
/*
* Specify which non-secure devices have permission to access this
* region.
*/
tzc_write_region_id_access(controller->base, region, ns_device_access);
}
void tzc_set_action(const struct tzc_instance *controller, enum tzc_action action)
{
assert(controller != NULL);
/*
* - Currently no handler is provided to trap an error via interrupt
* or exception.
* - The interrupt action has not been tested.
*/
tzc_write_action(controller->base, action);
}
void tzc_enable_filters(const struct tzc_instance *controller)
{
uint32_t state;
uint32_t filter;
assert(controller != NULL);
for (filter = 0; filter < controller->num_filters; filter++) {
state = tzc_get_gate_keeper(controller->base, filter);
if (state) {
ERROR("TZC : Filter %d Gatekeeper already enabled.\n",
filter);
panic();
}
tzc_set_gate_keeper(controller->base, filter, 1);
}
}
void tzc_disable_filters(const struct tzc_instance *controller)
{
uint32_t filter;
assert(controller != NULL);
/*
* We don't do the same state check as above as the Gatekeepers are
* disabled after reset.
*/
for (filter = 0; filter < controller->num_filters; filter++)
tzc_set_gate_keeper(controller->base, filter, 0);
}
/*
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __TZC400_H__
#define __TZC400_H__
#include <stdint.h>
#define BUILD_CONFIG_OFF 0x000
#define ACTION_OFF 0x004
#define GATE_KEEPER_OFF 0x008
#define SPECULATION_CTRL_OFF 0x00c
#define INT_STATUS 0x010
#define INT_CLEAR 0x014
#define FAIL_ADDRESS_LOW_OFF 0x020
#define FAIL_ADDRESS_HIGH_OFF 0x024
#define FAIL_CONTROL_OFF 0x028
#define FAIL_ID 0x02c
#define REGION_BASE_LOW_OFF 0x100
#define REGION_BASE_HIGH_OFF 0x104
#define REGION_TOP_LOW_OFF 0x108
#define REGION_TOP_HIGH_OFF 0x10c
#define REGION_ATTRIBUTES_OFF 0x110
#define REGION_ID_ACCESS_OFF 0x114
#define REGION_NUM_OFF(region) (0x20 * region)
/* ID Registers */
#define PID0_OFF 0xfe0
#define PID1_OFF 0xfe4
#define PID2_OFF 0xfe8
#define PID3_OFF 0xfec
#define PID4_OFF 0xfd0
#define PID5_OFF 0xfd4
#define PID6_OFF 0xfd8
#define PID7_OFF 0xfdc
#define CID0_OFF 0xff0
#define CID1_OFF 0xff4
#define CID2_OFF 0xff8
#define CID3_OFF 0xffc
#define BUILD_CONFIG_NF_SHIFT 24
#define BUILD_CONFIG_NF_MASK 0x3
#define BUILD_CONFIG_AW_SHIFT 8
#define BUILD_CONFIG_AW_MASK 0x3f
#define BUILD_CONFIG_NR_SHIFT 0
#define BUILD_CONFIG_NR_MASK 0x1f
/* Not describing the case where regions 1 to 8 overlap */
#define ACTION_RV_SHIFT 0
#define ACTION_RV_MASK 0x3
#define ACTION_RV_LOWOK 0x0
#define ACTION_RV_LOWERR 0x1
#define ACTION_RV_HIGHOK 0x2
#define ACTION_RV_HIGHERR 0x3
/*
* Number of gate keepers is implementation defined. But we know the max for
* this device is 4. Get implementation details from BUILD_CONFIG.
*/
#define GATE_KEEPER_OS_SHIFT 16
#define GATE_KEEPER_OS_MASK 0xf
#define GATE_KEEPER_OR_SHIFT 0
#define GATE_KEEPER_OR_MASK 0xf
/* Speculation is enabled by default. */
#define SPECULATION_CTRL_WRITE_DISABLE (1 << 1)
#define SPECULATION_CTRL_READ_DISABLE (1 << 0)
/* Max number of filters allowed is 4. */
#define INT_STATUS_OVERLAP_SHIFT 16
#define INT_STATUS_OVERLAP_MASK 0xf
#define INT_STATUS_OVERRUN_SHIFT 8
#define INT_STATUS_OVERRUN_MASK 0xf
#define INT_STATUS_STATUS_SHIFT 0
#define INT_STATUS_STATUS_MASK 0xf
#define INT_CLEAR_CLEAR_SHIFT 0
#define INT_CLEAR_CLEAR_MASK 0xf
#define FAIL_CONTROL_DIR_SHIFT (1 << 24)
#define FAIL_CONTROL_DIR_READ 0x0
#define FAIL_CONTROL_DIR_WRITE 0x1
#define FAIL_CONTROL_NS_SHIFT (1 << 21)
#define FAIL_CONTROL_NS_SECURE 0x0
#define FAIL_CONTROL_NS_NONSECURE 0x1
#define FAIL_CONTROL_PRIV_SHIFT (1 << 20)
#define FAIL_CONTROL_PRIV_PRIV 0x0
#define FAIL_CONTROL_PRIV_UNPRIV 0x1
/*
* FAIL_ID_ID_MASK depends on AID_WIDTH which is platform specific.
* Platform should provide the value on initialisation.
*/
#define FAIL_ID_VNET_SHIFT 24
#define FAIL_ID_VNET_MASK 0xf
#define FAIL_ID_ID_SHIFT 0
/* Used along with 'tzc_region_attributes_t' below */
#define REGION_ATTRIBUTES_SEC_SHIFT 30
#define REGION_ATTRIBUTES_F_EN_SHIFT 0
#define REGION_ATTRIBUTES_F_EN_MASK 0xf
#define REGION_ID_ACCESS_NSAID_WR_EN_SHIFT 16
#define REGION_ID_ACCESS_NSAID_RD_EN_SHIFT 0
#define REGION_ID_ACCESS_NSAID_ID_MASK 0xf
/* Macros for setting Region ID access permissions based on NSAID */
#define TZC_REGION_ACCESS_RD(id) \
((1 << (id & REGION_ID_ACCESS_NSAID_ID_MASK)) << \
REGION_ID_ACCESS_NSAID_RD_EN_SHIFT)
#define TZC_REGION_ACCESS_WR(id) \
((1 << (id & REGION_ID_ACCESS_NSAID_ID_MASK)) << \
REGION_ID_ACCESS_NSAID_WR_EN_SHIFT)
#define TZC_REGION_ACCESS_RDWR(id) \
(TZC_REGION_ACCESS_RD(id) | TZC_REGION_ACCESS_WR(id))
/* Filters are bit mapped 0 to 3. */
#define TZC400_COMPONENT_ID 0xb105f00d
#ifndef __ASSEMBLY__
/*******************************************************************************
* Function & variable prototypes
******************************************************************************/
/*
* What type of action is expected when an access violation occurs.
* The memory requested is zeroed. But we can also raise and event to
* let the system know it happened.
* We can raise an interrupt(INT) and/or cause an exception(ERR).
* TZC_ACTION_NONE - No interrupt, no Exception
* TZC_ACTION_ERR - No interrupt, raise exception -> sync external
* data abort
* TZC_ACTION_INT - Raise interrupt, no exception
* TZC_ACTION_ERR_INT - Raise interrupt, raise exception -> sync
* external data abort
*/
enum tzc_action {
TZC_ACTION_NONE = 0,
TZC_ACTION_ERR = 1,
TZC_ACTION_INT = 2,
TZC_ACTION_ERR_INT = (TZC_ACTION_ERR | TZC_ACTION_INT)
};
/*
* Controls secure access to a region. If not enabled secure access is not
* allowed to region.
*/
enum tzc_region_attributes {
TZC_REGION_S_NONE = 0,
TZC_REGION_S_RD = 1,
TZC_REGION_S_WR = 2,
TZC_REGION_S_RDWR = (TZC_REGION_S_RD | TZC_REGION_S_WR)
};
/*
* Implementation defined values used to validate inputs later.
* Filters : max of 4 ; 0 to 3
* Regions : max of 9 ; 0 to 8
* Address width : Values between 32 to 64
*/
struct tzc_instance {
uint64_t base;
uint32_t aid_width;
uint8_t addr_width;
uint8_t num_filters;
uint8_t num_regions;
};
void tzc_init(struct tzc_instance *controller);
void tzc_configure_region(const struct tzc_instance *controller, uint32_t filters,
uint8_t region, uint64_t region_base, uint64_t region_top,
enum tzc_region_attributes sec_attr, uint32_t ns_device_access);
void tzc_enable_filters(const struct tzc_instance *controller);
void tzc_disable_filters(const struct tzc_instance *controller);
void tzc_set_action(const struct tzc_instance *controller,
enum tzc_action action);
#endif /*__ASSEMBLY__*/
#endif /* __TZC400__ */
...@@ -147,10 +147,10 @@ ...@@ -147,10 +147,10 @@
#address-cells = <2>; #address-cells = <2>;
#size-cells = <2>; #size-cells = <2>;
ranges; ranges;
frame@2a820000 { frame@2a830000 {
frame-number = <0>; frame-number = <1>;
interrupts = <0 25 4>; interrupts = <0 26 4>;
reg = <0x0 0x2a820000 0x0 0x10000>; reg = <0x0 0x2a830000 0x0 0x10000>;
}; };
}; };
......
...@@ -147,10 +147,10 @@ ...@@ -147,10 +147,10 @@
#address-cells = <2>; #address-cells = <2>;
#size-cells = <2>; #size-cells = <2>;
ranges; ranges;
frame@2a820000 { frame@2a830000 {
frame-number = <0>; frame-number = <1>;
interrupts = <0 25 4>; interrupts = <0 26 4>;
reg = <0x0 0x2a820000 0x0 0x10000>; reg = <0x0 0x2a830000 0x0 0x10000>;
}; };
}; };
......
...@@ -156,10 +156,10 @@ ...@@ -156,10 +156,10 @@
#address-cells = <2>; #address-cells = <2>;
#size-cells = <2>; #size-cells = <2>;
ranges; ranges;
frame@2a820000 { frame@2a830000 {
frame-number = <0>; frame-number = <1>;
interrupts = <0 25 4>; interrupts = <0 26 4>;
reg = <0x0 0x2a820000 0x0 0x10000>; reg = <0x0 0x2a830000 0x0 0x10000>;
}; };
}; };
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
}; };
/ { / {
model = "FVP Base"; model = "FVP Foundation";
compatible = "arm,fvp-base", "arm,vexpress"; compatible = "arm,fvp-base", "arm,vexpress";
interrupt-parent = <&gic>; interrupt-parent = <&gic>;
#address-cells = <2>; #address-cells = <2>;
...@@ -123,10 +123,10 @@ ...@@ -123,10 +123,10 @@
#address-cells = <2>; #address-cells = <2>;
#size-cells = <2>; #size-cells = <2>;
ranges; ranges;
frame@2a820000 { frame@2a830000 {
frame-number = <0>; frame-number = <1>;
interrupts = <0 25 4>; interrupts = <0 26 4>;
reg = <0x0 0x2a820000 0x0 0x10000>; reg = <0x0 0x2a830000 0x0 0x10000>;
}; };
}; };
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
}; };
/ { / {
model = "FVP Base"; model = "FVP Foundation";
compatible = "arm,fvp-base", "arm,vexpress"; compatible = "arm,fvp-base", "arm,vexpress";
interrupt-parent = <&gic>; interrupt-parent = <&gic>;
#address-cells = <2>; #address-cells = <2>;
...@@ -123,10 +123,10 @@ ...@@ -123,10 +123,10 @@
#address-cells = <2>; #address-cells = <2>;
#size-cells = <2>; #size-cells = <2>;
ranges; ranges;
frame@2a820000 { frame@2a830000 {
frame-number = <0>; frame-number = <1>;
interrupts = <0 25 4>; interrupts = <0 26 4>;
reg = <0x0 0x2a820000 0x0 0x10000>; reg = <0x0 0x2a830000 0x0 0x10000>;
}; };
}; };
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
}; };
/ { / {
model = "FVP Base"; model = "FVP Foundation";
compatible = "arm,fvp-base", "arm,vexpress"; compatible = "arm,fvp-base", "arm,vexpress";
interrupt-parent = <&gic>; interrupt-parent = <&gic>;
#address-cells = <2>; #address-cells = <2>;
...@@ -132,10 +132,10 @@ ...@@ -132,10 +132,10 @@
#address-cells = <2>; #address-cells = <2>;
#size-cells = <2>; #size-cells = <2>;
ranges; ranges;
frame@2a820000 { frame@2a830000 {
frame-number = <0>; frame-number = <1>;
interrupts = <0 25 4>; interrupts = <0 26 4>;
reg = <0x0 0x2a820000 0x0 0x10000>; reg = <0x0 0x2a830000 0x0 0x10000>;
}; };
}; };
......
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
#include <stdint.h> #include <stdint.h>
extern void mmio_write_8(uintptr_t addr, uint8_t value);
extern uint8_t mmio_read_8(uintptr_t addr);
extern void mmio_write_32(uintptr_t addr, uint32_t value); extern void mmio_write_32(uintptr_t addr, uint32_t value);
extern uint32_t mmio_read_32(uintptr_t addr); extern uint32_t mmio_read_32(uintptr_t addr);
......
...@@ -30,6 +30,16 @@ ...@@ -30,6 +30,16 @@
#include <stdint.h> #include <stdint.h>
void mmio_write_8(uintptr_t addr, uint8_t value)
{
*(volatile uint8_t*)addr = value;
}
uint8_t mmio_read_8(uintptr_t addr)
{
return *(volatile uint8_t*)addr;
}
void mmio_write_32(uintptr_t addr, uint32_t value) void mmio_write_32(uintptr_t addr, uint32_t value)
{ {
*(volatile uint32_t*)addr = value; *(volatile uint32_t*)addr = value;
......
...@@ -220,6 +220,7 @@ int platform_config_setup(void) ...@@ -220,6 +220,7 @@ int platform_config_setup(void)
platform_config[CONFIG_CPU_SETUP] = 0; platform_config[CONFIG_CPU_SETUP] = 0;
platform_config[CONFIG_BASE_MMAP] = 0; platform_config[CONFIG_BASE_MMAP] = 0;
platform_config[CONFIG_HAS_CCI] = 0; platform_config[CONFIG_HAS_CCI] = 0;
platform_config[CONFIG_HAS_TZC] = 0;
break; break;
case HBI_FVP_BASE: case HBI_FVP_BASE:
midr_pn = (read_midr() >> MIDR_PN_SHIFT) & MIDR_PN_MASK; midr_pn = (read_midr() >> MIDR_PN_SHIFT) & MIDR_PN_MASK;
...@@ -232,6 +233,7 @@ int platform_config_setup(void) ...@@ -232,6 +233,7 @@ int platform_config_setup(void)
platform_config[CONFIG_MAX_AFF1] = 2; platform_config[CONFIG_MAX_AFF1] = 2;
platform_config[CONFIG_BASE_MMAP] = 1; platform_config[CONFIG_BASE_MMAP] = 1;
platform_config[CONFIG_HAS_CCI] = 1; platform_config[CONFIG_HAS_CCI] = 1;
platform_config[CONFIG_HAS_TZC] = 1;
break; break;
default: default:
assert(0); assert(0);
......
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