Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
arm64
Manage
Activity
Members
Plan
Wiki
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
CodeLinaro
la
kernel
arm64
Commits
fddecb4b
Commit
fddecb4b
authored
3 years ago
by
Hongguang Chen
Committed by
Android Partner Code Review
3 years ago
Browse files
Options
Downloads
Plain Diff
Merge "sc2: AUCPU secure fw loading [3/4]" into android-tv-deadpool-4.9-android12
parents
9ed67d90
b0667867
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
drivers/amlogic/dvb/aucpu/aml_aucpu.c
+38
-192
38 additions, 192 deletions
drivers/amlogic/dvb/aucpu/aml_aucpu.c
drivers/amlogic/secmon/secmon.c
+9
-2
9 additions, 2 deletions
drivers/amlogic/secmon/secmon.c
with
47 additions
and
194 deletions
drivers/amlogic/dvb/aucpu/aml_aucpu.c
+
38
−
192
View file @
fddecb4b
...
...
@@ -43,6 +43,8 @@
#include
<linux/signal.h>
#include
<linux/sysfs.h>
#include
<linux/amlogic/secmon.h>
#include
"aml_aucpu.h"
#define AUCPU_PLATFORM_DEVICE_NAME "aml_aucpu"
...
...
@@ -53,8 +55,6 @@
#define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP)
#endif
#define TEMP_FW_LOAD
#define MHz (1000000)
#define AUCPU_MEMORY_SIZE_IN_BYTE (64 * SZ_1K)
...
...
@@ -106,6 +106,8 @@ static s32 dbg_level = AUCPU_LOG_ERR;
#define RESP_TYPE_ADDR (0x84)
#define RESP_RST_ADDR (0x88)
#define VERSION_ADDR (0xA8)
#define DBG_REG_WRPTR (0xC0)
#define DBG_REG_STAGE (0xE8)
#define DBG_REG_ERROR (0xEC)
...
...
@@ -616,51 +618,36 @@ static void do_polling_work(struct work_struct *work)
}
}
#ifdef TEMP_FW_LOAD
#define AUCPU_FW_PATH "/lib/firmware/aucpu_fw.bin"
#define AUCPU_MAX_FW_SZ (48 * SZ_1K)
#include
<linux/fs.h>
#include
<linux/firmware.h>
#include
<linux/arm-smccc.h>
/* rw: 0 read, 1 write */
#define AUCPU_MON_RW (0x8200004A)
#define AUCPU_SRAM_START (0x10000000)
#define DMA_BASE (0xFE09E400)
#define P_AUCPU_CPU_CTRL1 (0xFE09E004)
#define P_RESETCTRL_SEC_RESET0_LEVEL (0xFE002180)
#define PWRCTL_MEM_PD11 (0xFE00C06C)
#define DMA_T0 (u32)(DMA_BASE + 0x00)
#define DMA_STS0 (u32)(DMA_BASE + 0x20)
struct
dma_aucpu_dsc_t
{
union
{
u32
d32
;
struct
{
unsigned
length
:
17
;
unsigned
irq
:
1
;
unsigned
eoc
:
1
;
unsigned
loop
:
1
;
unsigned
mode
:
4
;
unsigned
begin
:
1
;
unsigned
end
:
1
;
unsigned
op_mode
:
2
;
unsigned
enc_sha_only
:
1
;
unsigned
block
:
1
;
unsigned
error
:
1
;
unsigned
owner
:
1
;
}
b
;
}
dsc_cfg
;
u32
src_addr
;
u32
tgt_addr
;
};
#define FID_FW_LOAD (0x82000077)
#define FW_TYPE_AUCPU (0)
#define FW_TYPE_AUCPU_STOP (1)
unsigned
long
sec_
register_rw
(
unsigned
long
addr
,
unsigned
long
value
,
int
rw
)
unsigned
long
sec_
fw_cmd
(
u32
type
,
void
*
fw
,
size_t
size
)
{
struct
arm_smccc_res
smccc
;
void
__iomem
*
sharemem_input_base
;
long
sharemem_phy_input_base
;
sharemem_input_base
=
get_secmon_sharemem_input_base
();
sharemem_phy_input_base
=
get_secmon_phy_input_base
();
if
((
!
sharemem_input_base
)
||
(
!
sharemem_phy_input_base
))
return
-
1
;
sharemem_mutex_lock
();
if
(
size
)
memcpy
(
sharemem_input_base
,
(
const
void
*
)
fw
,
size
);
arm_smccc_smc
(
AUCPU_MON_RW
,
addr
,
value
,
rw
,
0
,
0
,
0
,
0
,
&
smccc
);
//asm __volatile__("" : : : "memory");
arm_smccc_smc
(
FID_FW_LOAD
,
type
,
size
,
0
,
0
,
0
,
0
,
0
,
&
smccc
);
sharemem_mutex_unlock
();
return
smccc
.
a0
;
}
...
...
@@ -668,186 +655,42 @@ unsigned long sec_register_rw(unsigned long addr, unsigned long value, int rw)
static
int
load_start_aucpu_fw
(
struct
device
*
device
)
{
const
struct
firmware
*
my_fw
=
NULL
;
struct
dma_aucpu_dsc_t
*
desc
;
char
*
fw
;
ulong
expires
,
done_val
;
int
result
=
0
;
unsigned
int
length
=
0
;
char
*
buf
=
NULL
;
dma_addr_t
dma_addr_fw
=
0
;
// MEM POWER control
done_val
=
sec_register_rw
(
PWRCTL_MEM_PD11
,
0
,
0
);
done_val
&=
~
(
0x3
<<
4
);
sec_register_rw
(
PWRCTL_MEM_PD11
,
done_val
,
1
);
done_val
=
sec_register_rw
(
PWRCTL_MEM_PD11
,
0
,
0
);
aucpu_pr
(
LOG_ALL
,
" MEM POWER final 0x%lx
\n
"
,
done_val
);
done_val
=
ReadAucpuRegister
(
RESP_SEQ_ADDR
);
if
(
done_val
!=
0
)
{
aucpu_pr
(
LOG_DEBUG
,
"Aucpu already running cmdseq %ld
\n
"
,
done_val
);
}
buf
=
kmalloc
(
AUCPU_MAX_FW_SZ
,
GFP_KERNEL
);
if
(
!
buf
)
{
aucpu_pr
(
LOG_ERROR
,
"[%s] fail to allocate mem %d
\n
"
,
__func__
,
AUCPU_MAX_FW_SZ
);
result
=
AUCPU_DRVERR_MEM_ALLOC
;
return
result
;
}
desc
=
(
struct
dma_aucpu_dsc_t
*
)
buf
;
fw
=
buf
+
sizeof
(
struct
dma_aucpu_dsc_t
);
aucpu_pr
(
LOG_DEBUG
,
"FW desc @ 0x%lx fw @ 0x%lx
\n
"
,
(
ulong
)
desc
,
(
ulong
)
fw
);
request_firmware_into_buf
(
&
my_fw
,
"aucpu_fw.bin"
,
device
,
fw
,
AUCPU_MAX_FW_SZ
-
sizeof
(
struct
dma_aucpu_dsc_t
)
);
aucpu_pr
(
LOG_DEBUG
,
"FW
\n
"
);
request_firmware
(
&
my_fw
,
"aucpu_fw.bin"
,
device
);
if
(
!
my_fw
)
{
aucpu_pr
(
LOG_ERROR
,
"load aucpu_fw.bin fail
\n
"
);
kfree
(
buf
);
result
=
AUCPU_ERROR_NOT_IMPLEMENTED
;
return
result
;
}
fw
=
(
char
*
)
my_fw
->
data
;
length
=
my_fw
->
size
;
release_firmware
(
my_fw
);
aucpu_pr
(
LOG_INFO
,
"FW read size %d data 0x%x-%x-%x-%x
\n
"
,
length
,
fw
[
0
],
fw
[
1
],
fw
[
2
],
fw
[
3
]);
length
+=
sizeof
(
struct
dma_aucpu_dsc_t
);
dma_addr_fw
=
dma_map_single
(
device
,
buf
,
length
,
DMA_TO_DEVICE
);
if
(
dma_mapping_error
(
device
,
dma_addr_fw
))
{
aucpu_pr
(
LOG_ERROR
,
"error mapping dma_addr_key
\n
"
);
kfree
(
buf
);
result
=
AUCPU_DRVERR_MEM_MAP
;
return
result
;
}
//config DMA descriptor
desc
->
src_addr
=
(
u32
)
dma_addr_fw
+
sizeof
(
struct
dma_aucpu_dsc_t
);
desc
->
tgt_addr
=
AUCPU_SRAM_START
;
desc
->
dsc_cfg
.
d32
=
0
;
// clear the config first
desc
->
dsc_cfg
.
b
.
op_mode
=
0
;
desc
->
dsc_cfg
.
b
.
mode
=
0
;
// copy
desc
->
dsc_cfg
.
b
.
length
=
length
-
sizeof
(
struct
dma_aucpu_dsc_t
);
desc
->
dsc_cfg
.
b
.
owner
=
1
;
desc
->
dsc_cfg
.
b
.
eoc
=
1
;
dma_sync_single_for_device
(
device
,
dma_addr_fw
,
length
,
DMA_TO_DEVICE
);
sec_register_rw
(
DMA_STS0
,
0xf
,
1
);
done_val
=
sec_register_rw
(
DMA_STS0
,
0
,
0
);
done_val
=
(
ulong
)
dma_addr_fw
|
2
;
sec_register_rw
(
DMA_T0
,
done_val
,
1
);
aucpu_pr
(
LOG_INFO
,
"DMADES 0x%lx wr 0x%lx fw@0x%x length %d to 0x%x
\n
"
,
(
ulong
)
dma_addr_fw
,
done_val
,
desc
->
src_addr
,
desc
->
dsc_cfg
.
b
.
length
,
desc
->
tgt_addr
);
done_val
=
sec_register_rw
(
DMA_T0
,
0
,
0
);
aucpu_pr
(
LOG_INFO
,
"start download fw to AUCPU read val 0x%lx
\n
"
,
done_val
);
//wait DMA finish
expires
=
jiffies
+
HZ
/
10
;
do
{
//if (readl(DMA_STS0) != 0)
done_val
=
sec_register_rw
(
DMA_STS0
,
0
,
0
);
if
(
done_val
!=
0
)
{
aucpu_pr
(
LOG_INFO
,
"download fw finish %lx
\n
"
,
done_val
);
break
;
}
if
(
time_after
(
jiffies
,
expires
))
{
aucpu_pr
(
LOG_ERROR
,
"AUCPU Command load FW timeout
\n
"
);
result
=
AUCPU_DRVERR_CMD_TIMEOUT
;
break
;
}
usleep_range
(
100
,
2000
);
}
while
(
1
);
result
=
sec_fw_cmd
(
FW_TYPE_AUCPU
,
fw
,
length
);
dma_unmap_single
(
device
,
dma_addr_fw
,
length
,
DMA_TO_DEVICE
);
kfree
(
buf
);
release_firmware
(
my_fw
);
aucpu_pr
(
LOG_INFO
,
"download fw success reset start AUCPU
\n
"
);
done_val
=
sec_register_rw
(
P_RESETCTRL_SEC_RESET0_LEVEL
,
0
,
0
);
done_val
&=
~
(
0xf
<<
9
);
sec_register_rw
(
P_RESETCTRL_SEC_RESET0_LEVEL
,
done_val
,
1
);
done_val
=
sec_register_rw
(
P_RESETCTRL_SEC_RESET0_LEVEL
,
0
,
0
);
aucpu_pr
(
LOG_INFO
,
"RESET0_LEVEL clear value: 0x%lx
\n
"
,
done_val
);
done_val
|=
(
0xf
<<
9
);
sec_register_rw
(
P_RESETCTRL_SEC_RESET0_LEVEL
,
done_val
,
1
);
done_val
=
sec_register_rw
(
P_RESETCTRL_SEC_RESET0_LEVEL
,
0
,
0
);
aucpu_pr
(
LOG_INFO
,
"RESET0_LEVEL Set value: 0x%lx
\n
"
,
done_val
);
//enable clock
done_val
=
sec_register_rw
(
P_AUCPU_CPU_CTRL1
,
0
,
0
);
done_val
|=
(
1
<<
0
);
sec_register_rw
(
P_AUCPU_CPU_CTRL1
,
done_val
,
1
);
done_val
=
sec_register_rw
(
P_AUCPU_CPU_CTRL1
,
0
,
0
);
aucpu_pr
(
LOG_INFO
,
"P_AUCPU_CPU_CTRL1 final value 0x%lx
\n
"
,
done_val
);
expires
=
jiffies
+
HZ
/
10
;
length
=
0
;
do
{
done_val
=
ReadAucpuRegister
(
RESP_SEQ_ADDR
+
length
);
if
(
done_val
==
0xdeadface
)
{
aucpu_pr
(
LOG_INFO
,
"AUCPU hello @ %d
\n
"
,
length
);
break
;
}
if
(
time_after
(
jiffies
,
expires
))
{
aucpu_pr
(
LOG_ERROR
,
"AUCPU Command load FW timeout
\n
"
);
result
=
AUCPU_DRVERR_CMD_TIMEOUT
;
break
;
}
aucpu_pr
(
LOG_ALL
,
"Current resp %d value 0x%lx
\n
"
,
length
,
done_val
);
length
+=
4
;
if
(
length
>=
128
)
{
length
=
0
;
usleep_range
(
200
,
10000
);
}
}
while
(
1
);
aucpu_pr
(
LOG_INFO
,
"[%s] done result %d
\n
"
,
__func__
,
result
);
return
result
;
}
static
void
stop_aucpu_fw
(
struct
device
*
device
)
{
ulong
done_val
;
//disable clock
done_val
=
sec_register_rw
(
P_AUCPU_CPU_CTRL1
,
0
,
0
);
aucpu_pr
(
LOG_INFO
,
"origin CTL1 val: 0x%lx
\n
"
,
done_val
);
done_val
&=
~
(
1
<<
0
);
aucpu_pr
(
LOG_INFO
,
"Set CTL1 val: 0x%lx
\n
"
,
done_val
);
sec_register_rw
(
P_AUCPU_CPU_CTRL1
,
done_val
,
1
);
done_val
=
sec_register_rw
(
P_AUCPU_CPU_CTRL1
,
0
,
0
);
aucpu_pr
(
LOG_INFO
,
"P_AUCPU_CPU_CTRL1 final value 0x%lx
\n
"
,
done_val
);
// OFF MEM POWER control
done_val
=
sec_register_rw
(
PWRCTL_MEM_PD11
,
0
,
0
);
aucpu_pr
(
LOG_ALL
,
"ORIGINAL MEM POWER read 0x%lx
\n
"
,
done_val
);
done_val
|=
(
0x3
<<
4
);
aucpu_pr
(
LOG_ALL
,
" MEM POWER to set 0x%lx
\n
"
,
done_val
);
sec_register_rw
(
PWRCTL_MEM_PD11
,
done_val
,
1
);
done_val
=
sec_register_rw
(
PWRCTL_MEM_PD11
,
0
,
0
);
aucpu_pr
(
LOG_ALL
,
" MEM POWER final 0x%lx
\n
"
,
done_val
);
int
result
=
0
;
result
=
sec_fw_cmd
(
FW_TYPE_AUCPU_STOP
,
NULL
,
0
);
aucpu_pr
(
LOG_INFO
,
"[%s] done result %d
\n
"
,
__func__
,
result
);
}
#else
#define load_start_aucpu_fw(x)
#define stop_aucpu_fw(x)
#endif
s32
aml_aucpu_strm_create
(
struct
aml_aucpu_strm_buf
*
src
,
struct
aml_aucpu_strm_buf
*
dst
,
...
...
@@ -1492,6 +1335,9 @@ static s32 aucpu_probe(struct platform_device *pdev)
aucpu_pr
(
LOG_ERROR
,
"load start_aucpu_fw fail
\n
"
);
goto
ERROR_PROVE_DEVICE
;
}
aucpu_pr
(
LOG_INFO
,
"aucpu fw version: 0x%x
\n
"
,
ReadAucpuRegister
(
VERSION_ADDR
));
mutex_init
(
&
pctx
->
mutex
);
/*setup the DEBUG buffer */
setup_debug_polling
();
...
...
This diff is collapsed.
Click to expand it.
drivers/amlogic/secmon/secmon.c
+
9
−
2
View file @
fddecb4b
...
...
@@ -39,9 +39,9 @@ static unsigned long secmon_start_virt;
static
unsigned
int
mem_size
;
#ifdef CONFIG_ARM64
#define IN_SIZE 0x
1
000
#define IN_SIZE 0x
6
000
#else
#define IN_SIZE 0x
1
000
#define IN_SIZE 0x
6
000
#endif
#define OUT_SIZE 0x1000
static
DEFINE_MUTEX
(
sharemem_mutex
);
...
...
@@ -184,15 +184,20 @@ void sharemem_mutex_lock(void)
{
mutex_lock
(
&
sharemem_mutex
);
}
EXPORT_SYMBOL
(
sharemem_mutex_lock
);
void
sharemem_mutex_unlock
(
void
)
{
mutex_unlock
(
&
sharemem_mutex
);
}
EXPORT_SYMBOL
(
sharemem_mutex_unlock
);
void
__iomem
*
get_secmon_sharemem_input_base
(
void
)
{
return
sharemem_in_base
;
}
EXPORT_SYMBOL
(
get_secmon_sharemem_input_base
);
void
__iomem
*
get_secmon_sharemem_output_base
(
void
)
{
return
sharemem_out_base
;
...
...
@@ -202,6 +207,8 @@ long get_secmon_phy_input_base(void)
{
return
phy_in_base
;
}
EXPORT_SYMBOL
(
get_secmon_phy_input_base
);
long
get_secmon_phy_output_base
(
void
)
{
return
phy_out_base
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment