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
a542faad
Unverified
Commit
a542faad
authored
Aug 30, 2018
by
Soby Mathew
Committed by
GitHub
Aug 30, 2018
Browse files
Merge pull request #1514 from glneo/for-upstream-psci
K3 PSCI Support
parents
2a7c9e15
c8761b4d
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
plat/ti/k3/board/generic/include/board_def.h
View file @
a542faad
...
...
@@ -32,4 +32,7 @@
#define PLAT_MAX_OFF_STATE U(2)
#define PLAT_MAX_RET_STATE U(1)
#define PLAT_PROC_START_ID 32
#define PLAT_PROC_DEVICE_START_ID 202
#endif
/* BOARD_DEF_H */
plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
0 → 100644
View file @
a542faad
/*
* Texas Instruments K3 Secure Proxy Driver
* Based on Linux and U-Boot implementation
*
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <debug.h>
#include <errno.h>
#include <mmio.h>
#include <platform_def.h>
#include <stdlib.h>
#include <utils.h>
#include <utils_def.h>
#include "sec_proxy.h"
/* SEC PROXY RT THREAD STATUS */
#define RT_THREAD_STATUS (0x0)
#define RT_THREAD_STATUS_ERROR_SHIFT (31)
#define RT_THREAD_STATUS_ERROR_MASK BIT(31)
#define RT_THREAD_STATUS_CUR_CNT_SHIFT (0)
#define RT_THREAD_STATUS_CUR_CNT_MASK GENMASK(7, 0)
/* SEC PROXY SCFG THREAD CTRL */
#define SCFG_THREAD_CTRL (0x1000)
#define SCFG_THREAD_CTRL_DIR_SHIFT (31)
#define SCFG_THREAD_CTRL_DIR_MASK BIT(31)
#define SEC_PROXY_THREAD(base, x) ((base) + (0x1000 * (x)))
#define THREAD_IS_RX (1)
#define THREAD_IS_TX (0)
/**
* struct k3_sec_proxy_desc - Description of secure proxy integration
* @timeout_us: Timeout for communication (in Microseconds)
* @max_msg_size: Message size in bytes
* @data_start_offset: Offset of the First data register of the thread
* @data_end_offset: Offset of the Last data register of the thread
*/
struct
k3_sec_proxy_desc
{
uint32_t
timeout_us
;
uint16_t
max_msg_size
;
uint16_t
data_start_offset
;
uint16_t
data_end_offset
;
};
/**
* struct k3_sec_proxy_thread - Description of a secure proxy Thread
* @id: Thread ID
* @data: Thread Data path region for target
* @scfg: Secure Config Region for Thread
* @rt: RealTime Region for Thread
*/
struct
k3_sec_proxy_thread
{
uint32_t
id
;
uintptr_t
data
;
uintptr_t
scfg
;
uintptr_t
rt
;
};
/**
* struct k3_sec_proxy_mbox - Description of a Secure Proxy Instance
* @desc: Description of the SoC integration
* @chans: Array for valid thread instances
*/
struct
k3_sec_proxy_mbox
{
const
struct
k3_sec_proxy_desc
desc
;
struct
k3_sec_proxy_thread
threads
[];
};
/*
* Thread ID #0: DMSC notify
* Thread ID #1: DMSC request response
* Thread ID #2: DMSC request high priority
* Thread ID #3: DMSC request low priority
* Thread ID #4: DMSC notify response
*/
#define SP_THREAD(_x) \
[_x] = { \
.id = _x, \
.data = SEC_PROXY_THREAD(SEC_PROXY_DATA_BASE, _x), \
.scfg = SEC_PROXY_THREAD(SEC_PROXY_SCFG_BASE, _x), \
.rt = SEC_PROXY_THREAD(SEC_PROXY_RT_BASE, _x), \
}
static
struct
k3_sec_proxy_mbox
spm
=
{
.
desc
=
{
.
timeout_us
=
SEC_PROXY_TIMEOUT_US
,
.
max_msg_size
=
SEC_PROXY_MAX_MESSAGE_SIZE
,
.
data_start_offset
=
0x4
,
.
data_end_offset
=
0x3C
,
},
.
threads
=
{
SP_THREAD
(
SP_NOTIFY
),
SP_THREAD
(
SP_RESPONSE
),
SP_THREAD
(
SP_HIGH_PRIORITY
),
SP_THREAD
(
SP_LOW_PRIORITY
),
SP_THREAD
(
SP_NOTIFY_RESP
),
},
};
/**
* struct sec_msg_hdr - Message header for secure messages and responses
* @checksum: CRC of message for integrity checking
*/
union
sec_msg_hdr
{
struct
{
uint16_t
checksum
;
uint16_t
reserved
;
}
__packed
;
uint32_t
data
;
};
/**
* k3_sec_proxy_verify_thread() - Verify thread status before
* sending/receiving data
* @spt: Pointer to Secure Proxy thread description
* @dir: Direction of the thread
*
* Return: 0 if all goes well, else appropriate error message
*/
static
inline
int
k3_sec_proxy_verify_thread
(
struct
k3_sec_proxy_thread
*
spt
,
uint32_t
dir
)
{
/* Check for any errors already available */
if
(
mmio_read_32
(
spt
->
rt
+
RT_THREAD_STATUS
)
&
RT_THREAD_STATUS_ERROR_MASK
)
{
ERROR
(
"Thread %d is corrupted, cannot send data
\n
"
,
spt
->
id
);
return
-
EINVAL
;
}
/* Make sure thread is configured for right direction */
if
((
mmio_read_32
(
spt
->
scfg
+
SCFG_THREAD_CTRL
)
&
SCFG_THREAD_CTRL_DIR_MASK
)
!=
(
dir
<<
SCFG_THREAD_CTRL_DIR_SHIFT
))
{
if
(
dir
)
ERROR
(
"Trying to receive data on tx Thread %d
\n
"
,
spt
->
id
);
else
ERROR
(
"Trying to send data on rx Thread %d
\n
"
,
spt
->
id
);
return
-
EINVAL
;
}
/* Check the message queue before sending/receiving data */
uint32_t
tick_start
=
(
uint32_t
)
read_cntpct_el0
();
uint32_t
ticks_per_us
=
SYS_COUNTER_FREQ_IN_TICKS
/
1000000
;
while
(
!
(
mmio_read_32
(
spt
->
rt
+
RT_THREAD_STATUS
)
&
RT_THREAD_STATUS_CUR_CNT_MASK
))
{
VERBOSE
(
"Waiting for thread %d to clear
\n
"
,
spt
->
id
);
if
(((
uint32_t
)
read_cntpct_el0
()
-
tick_start
)
>
(
spm
.
desc
.
timeout_us
*
ticks_per_us
))
{
ERROR
(
"Timeout waiting for thread %d to clear
\n
"
,
spt
->
id
);
return
-
ETIMEDOUT
;
}
}
return
0
;
}
/**
* k3_sec_proxy_send() - Send data over a Secure Proxy thread
* @id: Channel Identifier
* @msg: Pointer to k3_sec_proxy_msg
*
* Return: 0 if all goes well, else appropriate error message
*/
int
k3_sec_proxy_send
(
enum
k3_sec_proxy_chan_id
id
,
const
struct
k3_sec_proxy_msg
*
msg
)
{
struct
k3_sec_proxy_thread
*
spt
=
&
spm
.
threads
[
id
];
union
sec_msg_hdr
secure_header
;
int
num_words
,
trail_bytes
,
i
,
ret
;
uintptr_t
data_reg
;
ret
=
k3_sec_proxy_verify_thread
(
spt
,
THREAD_IS_TX
);
if
(
ret
)
{
ERROR
(
"Thread %d verification failed (%d)
\n
"
,
spt
->
id
,
ret
);
return
ret
;
}
/* Check the message size */
if
(
msg
->
len
+
sizeof
(
secure_header
)
>
spm
.
desc
.
max_msg_size
)
{
ERROR
(
"Thread %d message length %lu > max msg size
\n
"
,
spt
->
id
,
msg
->
len
);
return
-
EINVAL
;
}
/* TODO: Calculate checksum */
secure_header
.
checksum
=
0
;
/* Send the secure header */
data_reg
=
spm
.
desc
.
data_start_offset
;
mmio_write_32
(
spt
->
data
+
data_reg
,
secure_header
.
data
);
data_reg
+=
sizeof
(
uint32_t
);
/* Send whole words */
num_words
=
msg
->
len
/
sizeof
(
uint32_t
);
for
(
i
=
0
;
i
<
num_words
;
i
++
)
{
mmio_write_32
(
spt
->
data
+
data_reg
,
((
uint32_t
*
)
msg
->
buf
)[
i
]);
data_reg
+=
sizeof
(
uint32_t
);
}
/* Send remaining bytes */
trail_bytes
=
msg
->
len
%
sizeof
(
uint32_t
);
if
(
trail_bytes
)
{
uint32_t
data_trail
=
0
;
i
=
msg
->
len
-
trail_bytes
;
while
(
trail_bytes
--
)
{
data_trail
<<=
8
;
data_trail
|=
msg
->
buf
[
i
++
];
}
mmio_write_32
(
spt
->
data
+
data_reg
,
data_trail
);
data_reg
+=
sizeof
(
uint32_t
);
}
/*
* 'data_reg' indicates next register to write. If we did not already
* write on tx complete reg(last reg), we must do so for transmit
*/
if
(
data_reg
<=
spm
.
desc
.
data_end_offset
)
mmio_write_32
(
spt
->
data
+
spm
.
desc
.
data_end_offset
,
0
);
VERBOSE
(
"Message successfully sent on thread %ud
\n
"
,
id
);
return
0
;
}
/**
* k3_sec_proxy_recv() - Receive data from a Secure Proxy thread
* @id: Channel Identifier
* @msg: Pointer to k3_sec_proxy_msg
*
* Return: 0 if all goes well, else appropriate error message
*/
int
k3_sec_proxy_recv
(
uint32_t
id
,
struct
k3_sec_proxy_msg
*
msg
)
{
struct
k3_sec_proxy_thread
*
spt
=
&
spm
.
threads
[
id
];
union
sec_msg_hdr
secure_header
;
uintptr_t
data_reg
;
int
num_words
,
trail_bytes
,
i
,
ret
;
ret
=
k3_sec_proxy_verify_thread
(
spt
,
THREAD_IS_RX
);
if
(
ret
)
{
ERROR
(
"Thread %d verification failed (%d)
\n
"
,
spt
->
id
,
ret
);
return
ret
;
}
/* Read secure header */
data_reg
=
spm
.
desc
.
data_start_offset
;
secure_header
.
data
=
mmio_read_32
(
spt
->
data
+
data_reg
);
data_reg
+=
sizeof
(
uint32_t
);
/* Read whole words */
num_words
=
msg
->
len
/
sizeof
(
uint32_t
);
for
(
i
=
0
;
i
<
num_words
;
i
++
)
{
((
uint32_t
*
)
msg
->
buf
)[
i
]
=
mmio_read_32
(
spt
->
data
+
data_reg
);
data_reg
+=
sizeof
(
uint32_t
);
}
/* Read remaining bytes */
trail_bytes
=
msg
->
len
%
sizeof
(
uint32_t
);
if
(
trail_bytes
)
{
uint32_t
data_trail
=
mmio_read_32
(
spt
->
data
+
data_reg
);
data_reg
+=
sizeof
(
uint32_t
);
i
=
msg
->
len
-
trail_bytes
;
while
(
trail_bytes
--
)
{
msg
->
buf
[
i
]
=
data_trail
&
0xff
;
data_trail
>>=
8
;
}
}
/*
* 'data_reg' indicates next register to read. If we did not already
* read on rx complete reg(last reg), we must do so for receive
*/
if
(
data_reg
<=
spm
.
desc
.
data_end_offset
)
mmio_read_32
(
spt
->
data
+
spm
.
desc
.
data_end_offset
);
/* TODO: Verify checksum */
(
void
)
secure_header
.
checksum
;
VERBOSE
(
"Message successfully received from thread %ud
\n
"
,
id
);
return
0
;
}
plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
0 → 100644
View file @
a542faad
/*
* Texas Instruments K3 Secure Proxy Driver
* Based on Linux and U-Boot implementation
*
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef K3_SEC_PROXY_H
#define K3_SEC_PROXY_H
#include <stdint.h>
/**
* enum k3_sec_proxy_chan_id - Secure Proxy thread IDs
*
* These the available IDs used in k3_sec_proxy_{send,recv}()
*/
enum
k3_sec_proxy_chan_id
{
SP_NOTIFY
=
0
,
SP_RESPONSE
,
SP_HIGH_PRIORITY
,
SP_LOW_PRIORITY
,
SP_NOTIFY_RESP
,
};
/**
* struct k3_sec_proxy_msg - Secure proxy message structure
* @len: Length of data in the Buffer
* @buf: Buffer pointer
*
* This is the structure for data used in k3_sec_proxy_{send,recv}()
*/
struct
k3_sec_proxy_msg
{
size_t
len
;
uint8_t
*
buf
;
};
/**
* k3_sec_proxy_send() - Send data over a Secure Proxy thread
* @id: Channel Identifier
* @msg: Pointer to k3_sec_proxy_msg
*
* Return: 0 if all goes well, else appropriate error message
*/
int
k3_sec_proxy_send
(
enum
k3_sec_proxy_chan_id
id
,
const
struct
k3_sec_proxy_msg
*
msg
);
/**
* k3_sec_proxy_recv() - Receive data from a Secure Proxy thread
* @id: Channel Identifier
* @msg: Pointer to k3_sec_proxy_msg
*
* Return: 0 if all goes well, else appropriate error message
*/
int
k3_sec_proxy_recv
(
enum
k3_sec_proxy_chan_id
id
,
struct
k3_sec_proxy_msg
*
msg
);
#endif
/* K3_SEC_PROXY_H */
plat/ti/k3/common/drivers/ti_sci/ti_sci.c
0 → 100644
View file @
a542faad
This diff is collapsed.
Click to expand it.
plat/ti/k3/common/drivers/ti_sci/ti_sci.h
0 → 100644
View file @
a542faad
/*
* Texas Instruments System Control Interface API
* Based on Linux and U-Boot implementation
*
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __TI_SCI_H
#define __TI_SCI_H
#include <stdint.h>
#include <stdbool.h>
/**
* Device control operations
*
* - ti_sci_device_set_state - Set device state helper
* @flags: flags to setup for the device
* @state: State to move the device to
* - ti_sci_device_get_state - Get device state helper
* @clcnt: Pointer to Context Loss Count
* @resets: pointer to resets
* @p_state: pointer to p_state
* @c_state: pointer to c_state
* - ti_sci_device_get - command to request for device managed by TISCI
* - ti_sci_device_idle - Command to idle a device managed by TISCI
* - ti_sci_device_put - command to release a device managed by TISCI
* - ti_sci_device_is_valid - Is the device valid
* - ti_sci_device_get_clcnt - Get context loss counter
* @count: Pointer to Context Loss counter to populate
* - ti_sci_device_is_idle - Check if the device is requested to be idle
* @r_state: true if requested to be idle
* - ti_sci_device_is_stop - Check if the device is requested to be stopped
* @r_state: true if requested to be stopped
* @curr_state: true if currently stopped.
* - ti_sci_device_is_on - Check if the device is requested to be ON
* @r_state: true if requested to be ON
* @curr_state: true if currently ON and active
* - ti_sci_device_is_trans - Check if the device is currently transitioning
* @curr_state: true if currently transitioning.
* - ti_sci_device_set_resets - Command to set resets for
* device managed by TISCI
* @reset_state: Device specific reset bit field
* - ti_sci_device_get_resets - Get reset state for device managed by TISCI
* @reset_state: Pointer to reset state to populate
*
* NOTE: for all these functions, the following are generic in nature:
* @id: Device Identifier
* Returns 0 for successful request, else returns corresponding error message.
*
* Request for the device - NOTE: the client MUST maintain integrity of
* usage count by balancing get_device with put_device. No refcounting is
* managed by driver for that purpose.
*/
int
ti_sci_device_set_state
(
uint32_t
id
,
uint32_t
flags
,
uint8_t
state
);
int
ti_sci_device_get_state
(
uint32_t
id
,
uint32_t
*
clcnt
,
uint32_t
*
resets
,
uint8_t
*
p_state
,
uint8_t
*
c_state
);
int
ti_sci_device_get
(
uint32_t
id
);
int
ti_sci_device_idle
(
uint32_t
id
);
int
ti_sci_device_put
(
uint32_t
id
);
int
ti_sci_device_is_valid
(
uint32_t
id
);
int
ti_sci_device_get_clcnt
(
uint32_t
id
,
uint32_t
*
count
);
int
ti_sci_device_is_idle
(
uint32_t
id
,
bool
*
r_state
);
int
ti_sci_device_is_stop
(
uint32_t
id
,
bool
*
r_state
,
bool
*
curr_state
);
int
ti_sci_device_is_on
(
uint32_t
id
,
bool
*
r_state
,
bool
*
curr_state
);
int
ti_sci_device_is_trans
(
uint32_t
id
,
bool
*
curr_state
);
int
ti_sci_device_set_resets
(
uint32_t
id
,
uint32_t
reset_state
);
int
ti_sci_device_get_resets
(
uint32_t
id
,
uint32_t
*
reset_state
);
/**
* Clock control operations
*
* - ti_sci_clock_set_state - Set clock state helper
* @flags: Header flags as needed
* @state: State to request for the clock.
* - ti_sci_clock_get_state - Get clock state helper
* @programmed_state: State requested for clock to move to
* @current_state: State that the clock is currently in
* - ti_sci_clock_get - Get control of a clock from TI SCI
* @needs_ssc: 'true' iff Spread Spectrum clock is desired
* @can_change_freq: 'true' iff frequency change is desired
* @enable_input_term: 'true' iff input termination is desired
* - ti_sci_clock_idle - Idle a clock which is in our control
* - ti_sci_clock_put - Release a clock from our control
* - ti_sci_clock_is_auto - Is the clock being auto managed
* @req_state: state indicating if the clock is auto managed
* - ti_sci_clock_is_on - Is the clock ON
* @req_state: state indicating if the clock is managed by us and enabled
* @curr_state: state indicating if the clock is ready for operation
* - ti_sci_clock_is_off - Is the clock OFF
* @req_state: state indicating if the clock is managed by us and disabled
* @curr_state: state indicating if the clock is NOT ready for operation
* - ti_sci_clock_set_parent - Set the clock source of a specific device clock
* @parent_id: Parent clock identifier to set
* - ti_sci_clock_get_parent - Get current parent clock source
* @parent_id: Current clock parent
* - ti_sci_clock_get_num_parents - Get num parents of the current clk source
* @num_parents: Returns he number of parents to the current clock.
* - ti_sci_clock_get_match_freq - Find a good match for frequency
* @match_freq: Frequency match in Hz response.
* - ti_sci_clock_set_freq - Set a frequency for clock
* - ti_sci_clock_get_freq - Get current frequency
* @freq: Currently frequency in Hz
*
* NOTE: for all these functions, the following are generic in nature:
* @dev_id: Device identifier this request is for
* @clk_id: Clock identifier for the device for this request.
* Each device has its own set of clock inputs. This indexes
* which clock input to modify.
* @min_freq: The minimum allowable frequency in Hz. This is the minimum
* allowable programmed frequency and does not account for clock
* tolerances and jitter.
* @target_freq: The target clock frequency in Hz. A frequency will be
* processed as close to this target frequency as possible.
* @max_freq: The maximum allowable frequency in Hz. This is the maximum
* allowable programmed frequency and does not account for clock
* tolerances and jitter.
* Returns 0 for successful request, else returns corresponding error message.
*
* Request for the clock - NOTE: the client MUST maintain integrity of
* usage count by balancing get_clock with put_clock. No refcounting is
* managed by driver for that purpose.
*/
int
ti_sci_clock_set_state
(
uint32_t
dev_id
,
uint8_t
clk_id
,
uint32_t
flags
,
uint8_t
state
);
int
ti_sci_clock_get_state
(
uint32_t
dev_id
,
uint8_t
clk_id
,
uint8_t
*
programmed_state
,
uint8_t
*
current_state
);
int
ti_sci_clock_get
(
uint32_t
dev_id
,
uint8_t
clk_id
,
bool
needs_ssc
,
bool
can_change_freq
,
bool
enable_input_term
);
int
ti_sci_clock_idle
(
uint32_t
dev_id
,
uint8_t
clk_id
);
int
ti_sci_clock_put
(
uint32_t
dev_id
,
uint8_t
clk_id
);
int
ti_sci_clock_is_auto
(
uint32_t
dev_id
,
uint8_t
clk_id
,
bool
*
req_state
);
int
ti_sci_clock_is_on
(
uint32_t
dev_id
,
uint8_t
clk_id
,
bool
*
req_state
,
bool
*
curr_state
);
int
ti_sci_clock_is_off
(
uint32_t
dev_id
,
uint8_t
clk_id
,
bool
*
req_state
,
bool
*
curr_state
);
int
ti_sci_clock_set_parent
(
uint32_t
dev_id
,
uint8_t
clk_id
,
uint8_t
parent_id
);
int
ti_sci_clock_get_parent
(
uint32_t
dev_id
,
uint8_t
clk_id
,
uint8_t
*
parent_id
);
int
ti_sci_clock_get_num_parents
(
uint32_t
dev_id
,
uint8_t
clk_id
,
uint8_t
*
num_parents
);
int
ti_sci_clock_get_match_freq
(
uint32_t
dev_id
,
uint8_t
clk_id
,
uint64_t
min_freq
,
uint64_t
target_freq
,
uint64_t
max_freq
,
uint64_t
*
match_freq
);
int
ti_sci_clock_set_freq
(
uint32_t
dev_id
,
uint8_t
clk_id
,
uint64_t
min_freq
,
uint64_t
target_freq
,
uint64_t
max_freq
);
int
ti_sci_clock_get_freq
(
uint32_t
dev_id
,
uint8_t
clk_id
,
uint64_t
*
freq
);
/**
* Core control operations
*
* - ti_sci_core_reboot() - Command to request system reset
*
* Return: 0 if all went well, else returns appropriate error value.
*/
int
ti_sci_core_reboot
(
void
);
/**
* Processor control operations
*
* - ti_sci_proc_request - Command to request a physical processor control
* - ti_sci_proc_release - Command to release a physical processor control
* - ti_sci_proc_handover - Command to handover a physical processor control to
* a host in the processor's access control list.
* @host_id: Host ID to get the control of the processor
* - ti_sci_proc_set_boot_cfg - Command to set the processor boot configuration flags
* @config_flags_set: Configuration flags to be set
* @config_flags_clear: Configuration flags to be cleared.
* - ti_sci_proc_set_boot_ctrl - Command to set the processor boot control flags
* @control_flags_set: Control flags to be set
* @control_flags_clear: Control flags to be cleared
* - ti_sci_proc_auth_boot_image - Command to authenticate and load the image
* and then set the processor configuration flags.
* @cert_addr: Memory address at which payload image certificate is located.
* - ti_sci_proc_get_boot_status - Command to get the processor boot status
*
* NOTE: for all these functions, the following are generic in nature:
* @proc_id: Processor ID
* Returns 0 for successful request, else returns corresponding error message.
*/
int
ti_sci_proc_request
(
uint8_t
proc_id
);
int
ti_sci_proc_release
(
uint8_t
proc_id
);
int
ti_sci_proc_handover
(
uint8_t
proc_id
,
uint8_t
host_id
);
int
ti_sci_proc_set_boot_cfg
(
uint8_t
proc_id
,
uint64_t
bootvector
,
uint32_t
config_flags_set
,
uint32_t
config_flags_clear
);
int
ti_sci_proc_set_boot_ctrl
(
uint8_t
proc_id
,
uint32_t
control_flags_set
,
uint32_t
control_flags_clear
);
int
ti_sci_proc_auth_boot_image
(
uint8_t
proc_id
,
uint64_t
cert_addr
);
int
ti_sci_proc_get_boot_status
(
uint8_t
proc_id
,
uint64_t
*
bv
,
uint32_t
*
cfg_flags
,
uint32_t
*
ctrl_flags
,
uint32_t
*
sts_flags
);
/**
* ti_sci_init() - Basic initialization
*
* Return: 0 if all goes good, else appropriate error message.
*/
int
ti_sci_init
(
void
);
#endif
/* __TI_SCI_H */
plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
0 → 100644
View file @
a542faad
This diff is collapsed.
Click to expand it.
plat/ti/k3/common/k3_bl31_setup.c
View file @
a542faad
...
...
@@ -14,6 +14,7 @@
#include <platform_def.h>
#include <k3_gicv3.h>
#include <string.h>
#include <ti_sci.h>
/* Table of regions to map using the MMU */
const
mmap_region_t
plat_arm_mmap
[]
=
{
...
...
@@ -21,6 +22,9 @@ const mmap_region_t plat_arm_mmap[] = {
MAP_REGION_FLAT
(
K3_USART_BASE_ADDRESS
,
K3_USART_SIZE
,
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
MAP_REGION_FLAT
(
K3_GICD_BASE
,
K3_GICD_SIZE
,
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
MAP_REGION_FLAT
(
K3_GICR_BASE
,
K3_GICR_SIZE
,
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
MAP_REGION_FLAT
(
SEC_PROXY_RT_BASE
,
SEC_PROXY_RT_SIZE
,
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
MAP_REGION_FLAT
(
SEC_PROXY_SCFG_BASE
,
SEC_PROXY_SCFG_SIZE
,
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
MAP_REGION_FLAT
(
SEC_PROXY_DATA_BASE
,
SEC_PROXY_DATA_SIZE
,
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
{
/* sentinel */
}
};
...
...
@@ -118,6 +122,8 @@ void bl31_platform_setup(void)
{
k3_gic_driver_init
(
K3_GICD_BASE
,
K3_GICR_BASE
);
k3_gic_init
();
ti_sci_init
();
}
void
platform_mem_init
(
void
)
...
...
plat/ti/k3/common/k3_psci.c
View file @
a542faad
...
...
@@ -9,8 +9,11 @@
#include <debug.h>
#include <k3_gicv3.h>
#include <psci.h>
#include <platform.h>
#include <stdbool.h>
#include <ti_sci.h>
#define STUB() ERROR("stub %s called\n", __func__)
uintptr_t
k3_sec_entrypoint
;
...
...
@@ -33,9 +36,40 @@ static void k3_cpu_standby(plat_local_state_t cpu_state)
static
int
k3_pwr_domain_on
(
u_register_t
mpidr
)
{
sev
();
/* TODO: Indicate to System firmware about powering up */
int
core_id
,
proc
,
device
,
ret
;
core_id
=
plat_core_pos_by_mpidr
(
mpidr
);
if
(
core_id
<
0
)
{
ERROR
(
"Could not get target core id: %d
\n
"
,
core_id
);
return
PSCI_E_INTERN_FAIL
;
}
proc
=
PLAT_PROC_START_ID
+
core_id
;
device
=
PLAT_PROC_DEVICE_START_ID
+
core_id
;
ret
=
ti_sci_proc_request
(
proc
);
if
(
ret
)
{
ERROR
(
"Request for processor failed: %d
\n
"
,
ret
);
return
PSCI_E_INTERN_FAIL
;
}
ret
=
ti_sci_proc_set_boot_cfg
(
proc
,
k3_sec_entrypoint
,
0
,
0
);
if
(
ret
)
{
ERROR
(
"Request to set core boot address failed: %d
\n
"
,
ret
);
return
PSCI_E_INTERN_FAIL
;
}
ret
=
ti_sci_device_get
(
device
);
if
(
ret
)
{
ERROR
(
"Request to start core failed: %d
\n
"
,
ret
);
return
PSCI_E_INTERN_FAIL
;
}
ret
=
ti_sci_proc_release
(
proc
);
if
(
ret
)
{
/* this is not fatal */
WARN
(
"Could not release processor control: %d
\n
"
,
ret
);
}
return
PSCI_E_SUCCESS
;
}
...
...
@@ -58,8 +92,8 @@ void k3_pwr_domain_on_finish(const psci_power_state_t *target_state)
static
void
__dead2
k3_system_reset
(
void
)
{
/*
TODO: Indicate to System firmware about system reset
*/
STUB
();
/*
Send the system reset request to system firmware
*/
ti_sci_core_reboot
();
while
(
true
)
wfi
();
...
...
plat/ti/k3/common/plat_common.mk
View file @
a542faad
...
...
@@ -36,6 +36,8 @@ PLAT_INCLUDES += \
-I
${PLAT_PATH}
/include
\
-Iinclude
/plat/arm/common/
\
-Iinclude
/plat/arm/common/aarch64/
\
-I
${PLAT_PATH}
/common/drivers/sec_proxy
\
-I
${PLAT_PATH}
/common/drivers/ti_sci
\
K3_CONSOLE_SOURCES
+=
\
drivers/console/aarch64/console.S
\
...
...
@@ -53,6 +55,12 @@ K3_PSCI_SOURCES += \
plat/common/plat_psci_common.c
\
${PLAT_PATH}
/common/k3_psci.c
\
K3_SEC_PROXY_SOURCES
+=
\
${PLAT_PATH}
/common/drivers/sec_proxy/sec_proxy.c
\
K3_TI_SCI_SOURCES
+=
\
${PLAT_PATH}
/common/drivers/ti_sci/ti_sci.c
\
PLAT_BL_COMMON_SOURCES
+=
\
plat/arm/common/arm_common.c
\
lib/cpus/aarch64/cortex_a53.S
\
...
...
@@ -65,3 +73,5 @@ BL31_SOURCES += \
${PLAT_PATH}
/common/k3_topology.c
\
${K3_GIC_SOURCES}
\
${K3_PSCI_SOURCES}
\
${K3_SEC_PROXY_SOURCES}
\
${K3_TI_SCI_SOURCES}
\
plat/ti/k3/include/platform_def.h
View file @
a542faad
...
...
@@ -106,7 +106,7 @@
* runtime memory used, choose the smallest value needed to register the
* required regions for each BL stage.
*/
#define MAX_MMAP_REGIONS
8
#define MAX_MMAP_REGIONS
11
/*
* Defines the total size of the address space in bytes. For example, for a 32
...
...
@@ -193,4 +193,17 @@
#define K3_GICR_BASE 0x01880000
#define K3_GICR_SIZE 0x100000
#define SEC_PROXY_DATA_BASE 0x32C00000
#define SEC_PROXY_DATA_SIZE 0x80000
#define SEC_PROXY_SCFG_BASE 0x32800000
#define SEC_PROXY_SCFG_SIZE 0x80000
#define SEC_PROXY_RT_BASE 0x32400000
#define SEC_PROXY_RT_SIZE 0x80000
#define SEC_PROXY_TIMEOUT_US 1000000
#define SEC_PROXY_MAX_MESSAGE_SIZE 56
#define TI_SCI_HOST_ID 10
#define TI_SCI_MAX_MESSAGE_SIZE 52
#endif
/* __PLATFORM_DEF_H__ */
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