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
Sunxi Tools
Commits
68ce3d4d
Commit
68ce3d4d
authored
May 05, 2016
by
NiteHawk
Browse files
Merge pull request #41 from n1tehawk/sid-command-squashed
fel: Add new readl/writel functionality and a "sid" command
parents
3cf1ef5b
848a054c
Changes
1
Hide whitespace changes
Inline
Side-by-side
fel.c
View file @
68ce3d4d
...
...
@@ -463,6 +463,7 @@ typedef struct {
uint32_t
thunk_size
;
/* Maximal size of the thunk code */
bool
needs_l2en
;
/* Set the L2EN bit */
uint32_t
mmu_tt_addr
;
/* MMU translation table address */
uint32_t
sid_addr
;
/* base address for SID_KEY[0-3] registers */
sram_swap_buffers
*
swap_buffers
;
}
soc_sram_info
;
...
...
@@ -506,59 +507,66 @@ sram_swap_buffers a80_sram_swap_buffers[] = {
soc_sram_info
soc_sram_info_table
[]
=
{
{
.
soc_id
=
0x1623
,
/* Allwinner A10 */
.
scratch_addr
=
0x
2
000
,
.
scratch_addr
=
0x
1
000
,
.
thunk_addr
=
0xAE00
,
.
thunk_size
=
0x200
,
.
swap_buffers
=
a10_a13_a20_sram_swap_buffers
,
.
needs_l2en
=
true
,
.
sid_addr
=
0x01C23800
,
},
{
.
soc_id
=
0x1625
,
/* Allwinner A13 */
.
scratch_addr
=
0x
2
000
,
.
scratch_addr
=
0x
1
000
,
.
thunk_addr
=
0xAE00
,
.
thunk_size
=
0x200
,
.
swap_buffers
=
a10_a13_a20_sram_swap_buffers
,
.
needs_l2en
=
true
,
.
sid_addr
=
0x01C23800
,
},
{
.
soc_id
=
0x1651
,
/* Allwinner A20 */
.
scratch_addr
=
0x
2
000
,
.
scratch_addr
=
0x
1
000
,
.
thunk_addr
=
0xAE00
,
.
thunk_size
=
0x200
,
.
swap_buffers
=
a10_a13_a20_sram_swap_buffers
,
.
sid_addr
=
0x01C23800
,
},
{
.
soc_id
=
0x1650
,
/* Allwinner A23 */
.
scratch_addr
=
0x
2
000
,
.
scratch_addr
=
0x
1
000
,
.
thunk_addr
=
0x46E00
,
.
thunk_size
=
0x200
,
.
swap_buffers
=
a31_sram_swap_buffers
,
.
sid_addr
=
0x01C23800
,
},
{
.
soc_id
=
0x1633
,
/* Allwinner A31 */
.
scratch_addr
=
0x
2
000
,
.
scratch_addr
=
0x
1
000
,
.
thunk_addr
=
0x46E00
,
.
thunk_size
=
0x200
,
.
swap_buffers
=
a31_sram_swap_buffers
,
},
{
.
soc_id
=
0x1667
,
/* Allwinner A33 */
.
scratch_addr
=
0x
2
000
,
.
scratch_addr
=
0x
1
000
,
.
thunk_addr
=
0x46E00
,
.
thunk_size
=
0x200
,
.
swap_buffers
=
a31_sram_swap_buffers
,
.
sid_addr
=
0x01C23800
,
},
{
.
soc_id
=
0x1673
,
/* Allwinner A83T */
.
scratch_addr
=
0x
2
000
,
.
scratch_addr
=
0x
1
000
,
.
thunk_addr
=
0x46E00
,
.
thunk_size
=
0x200
,
.
swap_buffers
=
a31_sram_swap_buffers
,
.
sid_addr
=
0x01C14200
,
},
{
.
soc_id
=
0x1680
,
/* Allwinner H3 */
.
scratch_addr
=
0x
2
000
,
.
scratch_addr
=
0x
1
000
,
.
mmu_tt_addr
=
0x44000
,
.
thunk_addr
=
0x46E00
,
.
thunk_size
=
0x200
,
.
swap_buffers
=
a31_sram_swap_buffers
,
.
sid_addr
=
0x01C14200
,
},
{
.
soc_id
=
0x1639
,
/* Allwinner A80 */
.
spl_addr
=
0x10000
,
.
scratch_addr
=
0x1
2
000
,
.
scratch_addr
=
0x1
1
000
,
.
thunk_addr
=
0x23400
,
.
thunk_size
=
0x200
,
.
swap_buffers
=
a80_sram_swap_buffers
,
},
...
...
@@ -581,7 +589,7 @@ sram_swap_buffers generic_sram_swap_buffers[] = {
};
soc_sram_info
generic_sram_info
=
{
.
scratch_addr
=
0x
2
000
,
.
scratch_addr
=
0x
1
000
,
.
thunk_addr
=
0x5680
,
.
thunk_size
=
0x180
,
.
swap_buffers
=
generic_sram_swap_buffers
,
};
...
...
@@ -662,6 +670,99 @@ void aw_write_arm_cp_reg(libusb_device_handle *usb, soc_sram_info *sram_info,
aw_fel_execute
(
usb
,
sram_info
->
scratch_addr
);
}
/* multiple "readl" from sequential addresses to a destination buffer */
void
aw_fel_readl_n
(
libusb_device_handle
*
usb
,
uint32_t
addr
,
uint32_t
*
dst
,
size_t
count
)
{
soc_sram_info
*
sram_info
=
aw_fel_get_sram_info
(
usb
);
uint32_t
val
;
uint32_t
arm_code
[]
=
{
htole32
(
0xe59f0010
),
/* ldr r0, [pc, #16] */
htole32
(
0xe5901000
),
/* ldr r1, [r0] */
htole32
(
0xe58f100c
),
/* str r1, [pc, #12] */
htole32
(
0xe2800004
),
/* add r0, r0, #4 */
htole32
(
0xe58f0000
),
/* str r0, [pc] */
htole32
(
0xe12fff1e
),
/* bx lr */
htole32
(
addr
),
/* value goes here */
};
/* scratch buffer setup: transfers ARM code and also sets the addr */
aw_fel_write
(
usb
,
arm_code
,
sram_info
->
scratch_addr
,
sizeof
(
arm_code
));
while
(
count
--
>
0
)
{
/*
* Since the scratch code auto-increments addr, we can simply
* execute it repeatedly for sequential "readl"s; retrieving
* one uint32_t each time.
*/
aw_fel_execute
(
usb
,
sram_info
->
scratch_addr
);
aw_fel_read
(
usb
,
sram_info
->
scratch_addr
+
28
,
&
val
,
sizeof
(
val
));
*
dst
++
=
le32toh
(
val
);
}
}
/* "readl" of a single value */
uint32_t
aw_fel_readl
(
libusb_device_handle
*
usb
,
uint32_t
addr
)
{
uint32_t
val
;
aw_fel_readl_n
(
usb
,
addr
,
&
val
,
1
);
return
val
;
}
/* multiple "writel" from a source buffer to sequential addresses */
void
aw_fel_writel_n
(
libusb_device_handle
*
usb
,
uint32_t
addr
,
uint32_t
*
src
,
size_t
count
)
{
if
(
count
==
0
)
return
;
/* on zero count, do not access *src at all */
soc_sram_info
*
sram_info
=
aw_fel_get_sram_info
(
usb
);
uint32_t
arm_code
[]
=
{
htole32
(
0xe59f0010
),
/* ldr r0, [pc, #16] */
htole32
(
0xe59f1010
),
/* ldr r1, [pc, #16] */
htole32
(
0xe5801000
),
/* str r1, [r0] */
htole32
(
0xe2800004
),
/* add r0, r0, #4 */
htole32
(
0xe58f0000
),
/* str r0, [pc] */
htole32
(
0xe12fff1e
),
/* bx lr */
htole32
(
addr
),
htole32
(
*
src
++
)
};
/* scratch buffer setup: transfers ARM code, addr and first value */
aw_fel_write
(
usb
,
arm_code
,
sram_info
->
scratch_addr
,
sizeof
(
arm_code
));
aw_fel_execute
(
usb
,
sram_info
->
scratch_addr
);
/* stores first value */
while
(
--
count
>
0
)
{
/*
* Subsequent transfers only need to set up the next value
* to store (since the scratch code auto-increments addr).
*/
aw_fel_write
(
usb
,
src
++
,
sram_info
->
scratch_addr
+
28
,
sizeof
(
uint32_t
));
aw_fel_execute
(
usb
,
sram_info
->
scratch_addr
);
}
}
/* "writel" of a single value */
void
aw_fel_writel
(
libusb_device_handle
*
usb
,
uint32_t
addr
,
uint32_t
val
)
{
aw_fel_writel_n
(
usb
,
addr
,
&
val
,
1
);
}
void
aw_fel_print_sid
(
libusb_device_handle
*
usb
)
{
soc_sram_info
*
soc_info
=
aw_fel_get_sram_info
(
usb
);
if
(
soc_info
->
sid_addr
)
{
pr_info
(
"SID key (e-fuses) at 0x%08X
\n
"
,
soc_info
->
sid_addr
);
uint32_t
key
[
4
];
aw_fel_readl_n
(
usb
,
soc_info
->
sid_addr
,
key
,
4
);
unsigned
int
i
;
/* output SID in a format similar to U-Boot's "md.l <sid_addr> 4" */
for
(
i
=
0
;
i
<=
3
;
i
++
)
printf
(
"%08x%c"
,
key
[
i
],
i
<
3
?
' '
:
'\n'
);
}
else
{
printf
(
"SID registers for your SoC (id=%04X) are unknown or inaccessible.
\n
"
,
soc_info
->
soc_id
);
}
}
void
aw_enable_l2_cache
(
libusb_device_handle
*
usb
,
soc_sram_info
*
sram_info
)
{
uint32_t
arm_code
[]
=
{
...
...
@@ -1389,6 +1490,8 @@ int main(int argc, char **argv)
" hex[dump] address length Dumps memory region in hex
\n
"
" dump address length Binary memory dump
\n
"
" exe[cute] address Call function address
\n
"
" readl address Read 32-bit value from device memory
\n
"
" writel address value Write 32-bit value to device memory
\n
"
" read address length file Write memory contents into file
\n
"
" write address file Store file contents into memory
\n
"
" write-with-progress addr file
\"
write
\"
with progress bar
\n
"
...
...
@@ -1401,6 +1504,7 @@ int main(int argc, char **argv)
" <#> addr file [addr file [...]]
\n
"
" echo-gauge
\"
some text
\"
Update prompt/caption for gauge output
\n
"
" ver[sion] Show BROM version
\n
"
" sid Retrieve and output 128-bit SID key
\n
"
" clear address length Clear memory
\n
"
" fill address length value Fill memory
\n
"
,
argv
[
0
]
...
...
@@ -1461,12 +1565,19 @@ int main(int argc, char **argv)
}
else
if
(
strncmp
(
argv
[
1
],
"dump"
,
4
)
==
0
&&
argc
>
3
)
{
aw_fel_dump
(
handle
,
strtoul
(
argv
[
2
],
NULL
,
0
),
strtoul
(
argv
[
3
],
NULL
,
0
));
skip
=
3
;
}
else
if
(
strcmp
(
argv
[
1
],
"readl"
)
==
0
&&
argc
>
2
)
{
printf
(
"0x%08x
\n
"
,
aw_fel_readl
(
handle
,
strtoul
(
argv
[
2
],
NULL
,
0
)));
skip
=
2
;
}
else
if
(
strcmp
(
argv
[
1
],
"writel"
)
==
0
&&
argc
>
3
)
{
aw_fel_writel
(
handle
,
strtoul
(
argv
[
2
],
NULL
,
0
),
strtoul
(
argv
[
3
],
NULL
,
0
));
skip
=
3
;
}
else
if
(
strncmp
(
argv
[
1
],
"exe"
,
3
)
==
0
&&
argc
>
2
)
{
aw_fel_execute
(
handle
,
strtoul
(
argv
[
2
],
NULL
,
0
));
skip
=
3
;
}
else
if
(
strncmp
(
argv
[
1
],
"ver"
,
3
)
==
0
&&
argc
>
1
)
{
}
else
if
(
strncmp
(
argv
[
1
],
"ver"
,
3
)
==
0
)
{
aw_fel_print_version
(
handle
);
skip
=
1
;
}
else
if
(
strcmp
(
argv
[
1
],
"sid"
)
==
0
)
{
aw_fel_print_sid
(
handle
);
}
else
if
(
strcmp
(
argv
[
1
],
"write"
)
==
0
&&
argc
>
3
)
{
skip
+=
2
*
file_upload
(
handle
,
1
,
argc
-
2
,
argv
+
2
,
pflag_active
?
progress_bar
:
NULL
);
...
...
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