Hi,
On 22-12-16 11:31, Chen-Yu Tsai wrote:
On Tue, Dec 20, 2016 at 12:17 AM, Hans de Goede <hdego...@redhat.com> wrote:
Hi,
On 19-12-16 17:06, Icenowy Zheng wrote:
19.12.2016, 23:30, "Hans de Goede" <hdego...@redhat.com>:
Hi,
On 19-12-16 16:22, Icenowy Zheng wrote:
Hi everyone,
Today, I and KotCzarny on IRC of linux-sunxi found a problem in the SID
controller of H3 (incl. H2+).
See https://irclog.whitequark.org/linux-sunxi/2016-12-19 .
Two read method of the H3 eFUSE is used in the BSP: by register
accessing, or
directly access 0x01c14200.
From http://linux-sunxi.org/SID_Register_Guide we can see a difference
between
the H3 SIDs read out by sunxi-fel and the H3 SIDs read out by devmem2
(in
legacy kernel).
According to the source of H2+ BSP[1], H2+ and H3 can be differed by
the last
byte of the first word of SID. (0x42 and 0x83 is H2+, 0x00 and 0x81 is
H3,
0x58 is H3D (currently not known SoC) )
However, all the SIDs retrieved by `sunxi-fel sid`, both H2+ and H3,
start
with 0x02004620, which do not match this rule.
The readout by devmem2 is satisfying this rule: their first word is
0x02c00081, matches H3.
Then I found the SID-reading code from BSP U-Boot[2], which is based on
register operations. With this kind of code (I wrote one prototype in
userspace with /dev/mem), I got "02c00081 74004620 50358720 3c27048e"
on
my Orange Pi One. ("02004620 74358720 5027048e 3c0000c3" with sunxi-fel
sid)
And, after accessing to the SID by registers, the value of *0x01c14200
become
also "02c00081".
With direct access to 0x01c14200 after boot with mainline kernel, I got
also
"02004620".
Then I altered the program to do the register operations with
sunxi-fel, the
result is also "02c00081", and changed `sunxi-fel sid` result to
"02c00081".
Summary:
+-----------------------------------------------+----------------+
| Read situation | The first word |
+-----------------------------------------------+----------------+
| Direct read by sunxi-fel | 02004620 |
| Direct read in mainline /dev/mem | 02004620 |
| Direct read in legacy /dev/mem | 02c00081 |
| Register access in FEL | 02c00081 |
| Register access in mainline | 02c00081 |
| Direct read after register access in FEL | 02c00081 |
| Direct read after register access in mainline | 02c00081 |
+-----------------------------------------------+----------------+
According to some facts:
- The register based access to SID is weird: it needs ~5 register
operations per word of SID.
- Reading via register access will change the value when reading by
accessing
0x01c14200.
- In the u-boot code[2] there's some functions which read out the SID
by
registers and then abandoned the value.
- This mismatch do not exist on A64.
I think that: Allwinner designed a "cache" to the SID to make the
simplify the
code to read it, and it automatically loaded the cache when booting;
however,
when doing first cache on H3, some byte shifts occured, and the value
become
wrong. A manual read on H3 can make the cache right again. This is a
silicon
bug, and fixed in A64.
This raises a problem: currently many systems has used the misread SID
value to
generated lots of MAC addresses, and workaround this SID bug will
change them.
However, if this bug is not workarounded, the sun8i-ths driver won't
work well
(as some calibartion value lies in eFUSE). I think some early user of
this
driver has already experienced bad readout value.
(The calibration value differs on my opi1 and KotCzarny's opipc)
And many wrong SID values have been generated by `sunxi-fel sid`.
(Although I
think sunxi-fel must have the workaround)
Note: in this email, "SID" and "eFUSE" both indicate the controller on
H3/A64
at 0x01c14000, which is a OTP memory implemented by eFUSE technique.
Furthermore, A83T may also have this problem, testers are welcome!
[1]
http://filez.zoobab.com/allwinner/h2/201609022/lichee/linux-3.4/arch/arm/mach-sunxi/sun8i.c
[2]
http://filez.zoobab.com/allwinner/h2/201609022/lichee/brandy/u-boot-2011.09/arch/arm/cpu/armv7/sun8iw7/efuse.c
Experiments:
- https://gist.github.com/Icenowy/2f4859ab1bc05814522fc7445179a8c9
A SID readout shell script via FEL with register access.
- https://31.135.195.151:20281/d/efuse/
A SID readout program via /dev/mem with register access by KotCzarny.
(with statically compiled binary)
Good detective work!
I believe this would best be fixed by making u-boot use the register
access
method to get the SID on affected chips, and make sure u-boot reads the
SID at-least once.
Yes.
However, what I considered is that fixing this bug will change H3 devices'
MAC addresses, as they are derived from SID.
I know, but I think we will just need to accept this onetime change
of the fixed MAC addresses to fix this bug. I don't think this is
a big problem since the driver for the H3 ethernet has not been
merged into the mainline kernel yet.
Do we still need to do the CRC32 across the SID values to generate
the MAC addresses?
Yes this does not change that a single word has not enough
randomness in it.
Regards,
Hans
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot