[linux-sunxi] Re: Problems to Allwinner H3's eFUSE/SID
Hans de Goede
hdegoede at redhat.com
Thu Dec 22 02:41:01 PST 2016
Hi,
On 22-12-16 11:31, Chen-Yu Tsai wrote:
> On Tue, Dec 20, 2016 at 12:17 AM, Hans de Goede <hdegoede at redhat.com> wrote:
>> Hi,
>>
>>
>> On 19-12-16 17:06, Icenowy Zheng wrote:
>>>
>>>
>>>
>>> 19.12.2016, 23:30, "Hans de Goede" <hdegoede at 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
More information about the linux-arm-kernel
mailing list