Commit 65a9c0e9 authored by Sandrine Bailleux's avatar Sandrine Bailleux
Browse files

Revert "Move architecture timer setup to platform-specific code"

This reverts commit 1c297bf0
because it introduced a bug: the CNTFRQ_EL0 register was no
longer programmed by all CPUs.  bl31_platform_setup() function
is invoked only in the cold boot path and consequently only
on the primary cpu.

A subsequent commit will correctly implement the necessary changes
to the counter frequency setup code.

Fixes ARM-software/tf-issues#125

Conflicts:

	docs/firmware-design.md
	plat/fvp/bl31_plat_setup.c

Change-Id: Ib584ad7ed069707ac04cf86717f836136ad3ab54
parent e6e54a18
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
void bl1_arch_setup(void) void bl1_arch_setup(void)
{ {
unsigned long tmp_reg = 0; unsigned long tmp_reg = 0;
unsigned int counter_base_frequency;
/* Enable alignment checks and set the exception endianess to LE */ /* Enable alignment checks and set the exception endianess to LE */
tmp_reg = read_sctlr_el3(); tmp_reg = read_sctlr_el3();
...@@ -60,6 +61,13 @@ void bl1_arch_setup(void) ...@@ -60,6 +61,13 @@ void bl1_arch_setup(void)
enable_serror(); enable_serror();
enable_debug_exceptions(); enable_debug_exceptions();
/* Read the frequency from Frequency modes table */
counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
/* The first entry of the frequency modes table must not be 0 */
assert(counter_base_frequency != 0);
/* Program the counter frequency */
write_cntfrq_el0(counter_base_frequency);
return; return;
} }
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
void bl31_arch_setup(void) void bl31_arch_setup(void)
{ {
unsigned long tmp_reg = 0; unsigned long tmp_reg = 0;
unsigned int counter_base_frequency;
/* Enable alignment checks and set the exception endianness to LE */ /* Enable alignment checks and set the exception endianness to LE */
tmp_reg = read_sctlr_el3(); tmp_reg = read_sctlr_el3();
...@@ -61,6 +62,13 @@ void bl31_arch_setup(void) ...@@ -61,6 +62,13 @@ void bl31_arch_setup(void)
enable_serror(); enable_serror();
enable_debug_exceptions(); enable_debug_exceptions();
/* Read the frequency from Frequency modes table */
counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
/* The first entry of the frequency modes table must not be 0 */
assert(counter_base_frequency != 0);
/* Program the counter frequency */
write_cntfrq_el0(counter_base_frequency);
return; return;
} }
......
...@@ -151,16 +151,19 @@ BL1 performs minimal architectural initialization as follows. ...@@ -151,16 +151,19 @@ BL1 performs minimal architectural initialization as follows.
and Advanced SIMD execution are configured to not trap to EL3 by and Advanced SIMD execution are configured to not trap to EL3 by
clearing the `CPTR_EL3.TFP` bit. clearing the `CPTR_EL3.TFP` bit.
- `CNTFRQ_EL0`. The `CNTFRQ_EL0` register is programmed with the base
frequency of the system counter, which is retrieved from the first entry
in the frequency modes table.
- Generic Timer. The system level implementation of the generic timer is
enabled through the memory mapped interface.
#### Platform initialization #### Platform initialization
BL1 enables issuing of snoop and DVM (Distributed Virtual Memory) requests BL1 enables issuing of snoop and DVM (Distributed Virtual Memory) requests from
from the CCI-400 slave interface corresponding to the cluster that includes the CCI-400 slave interface corresponding to the cluster that includes the
the primary CPU. BL1 also initializes UART0 (PL011 console), which enables primary CPU. BL1 also initializes UART0 (PL011 console), which enables access to
access to the `printf` family of functions in BL1. The `CNTFRQ_EL0` register is the `printf` family of functions in BL1.
programmed with the base frequency of the system counter, which is retrieved
from the first entry in the frequency modes table. The system level
implementation of the generic timer is enabled through the memory mapped
interface.
#### BL2 image load and execution #### BL2 image load and execution
......
...@@ -446,9 +446,8 @@ This function executes with the MMU and data caches enabled. It is responsible ...@@ -446,9 +446,8 @@ This function executes with the MMU and data caches enabled. It is responsible
for performing any remaining platform-specific setup that can occur after the for performing any remaining platform-specific setup that can occur after the
MMU and data cache have been enabled. MMU and data cache have been enabled.
In the ARM FVP port, this function enables system-level implementation of the In the ARM FVP port, it zeros out the ZI section and enables the system level
generic timer counter. It also initializes counter frequency for CPU's generic implementation of the generic timer counter.
timers.
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.
...@@ -772,7 +771,6 @@ BL3-1 runtime services and normal world software can function correctly. ...@@ -772,7 +771,6 @@ BL3-1 runtime services and normal world software can function correctly.
The ARM FVP port does the following: The ARM FVP port does the following:
* Initializes the generic interrupt controller. * Initializes the generic interrupt controller.
* Configures the CLCD controller. * Configures the CLCD controller.
* Initializes counter frequency for CPU's generic timer
* Grants access to the system counter timer module * Grants access to the system counter timer module
* Initializes the FVP power controller device * Initializes the FVP power controller device
* Detects the system topology. * Detects the system topology.
......
...@@ -112,25 +112,11 @@ void bl1_early_platform_setup(void) ...@@ -112,25 +112,11 @@ void bl1_early_platform_setup(void)
******************************************************************************/ ******************************************************************************/
void bl1_platform_setup(void) void bl1_platform_setup(void)
{ {
unsigned int counter_base_frequency;
/* Initialise the IO layer and register platform IO devices */ /* Initialise the IO layer and register platform IO devices */
io_setup(); io_setup();
/* /* Enable and initialize the System level generic timer */
* Enable and initialize the System level generic timer. Choose base mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_EN);
* frequency for the timer
*/
mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN);
/* Read the frequency from Frequency modes table */
counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
/* The first entry of the frequency modes table must not be 0 */
assert(counter_base_frequency != 0);
/* Program the counter frequency */
write_cntfrq_el0(counter_base_frequency);
} }
......
...@@ -30,9 +30,8 @@ ...@@ -30,9 +30,8 @@
#include <platform.h> #include <platform.h>
#include <fvp_pwrc.h> #include <fvp_pwrc.h>
#include <assert.h>
#include <arch_helpers.h>
#include <console.h> #include <console.h>
#include <bl_common.h>
/******************************************************************************* /*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout * Declarations of linker defined symbols which will help us find the layout
...@@ -129,7 +128,6 @@ void bl31_early_platform_setup(bl31_args *from_bl2, ...@@ -129,7 +128,6 @@ void bl31_early_platform_setup(bl31_args *from_bl2,
void bl31_platform_setup() void bl31_platform_setup()
{ {
unsigned int reg_val; unsigned int reg_val;
unsigned int counter_base_frequency;
/* Initialize the gic cpu and distributor interfaces */ /* Initialize the gic cpu and distributor interfaces */
gic_setup(); gic_setup();
...@@ -143,15 +141,6 @@ void bl31_platform_setup() ...@@ -143,15 +141,6 @@ void bl31_platform_setup()
mmio_write_32(VE_SYSREGS_BASE + V2M_SYS_CFGCTRL, mmio_write_32(VE_SYSREGS_BASE + V2M_SYS_CFGCTRL,
(1ull << 31) | (1 << 30) | (7 << 20) | (0 << 16)); (1ull << 31) | (1 << 30) | (7 << 20) | (0 << 16));
/* Read the frequency from Frequency modes table */
counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
/* The first entry of the frequency modes table must not be 0 */
assert(counter_base_frequency != 0);
/* Program the counter frequency */
write_cntfrq_el0(counter_base_frequency);
/* Allow access to the System counter timer module */ /* Allow access to the System counter timer module */
reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT); reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT);
reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT); reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT);
......
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