# HG changeset patch # User Mychaela Falconia # Date 1603167115 0 # Node ID a1799f6d6aa7ca3f1afce7bdf17752b8f4db67bd # Parent a8c8a5521073c87bf3fdd9d6e47cccf4d3bef938 doc/Nucleus-change article written diff -r a8c8a5521073 -r a1799f6d6aa7 doc/Nucleus-change --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/Nucleus-change Tue Oct 20 04:11:55 2020 +0000 @@ -0,0 +1,72 @@ +The specific integration of ATI Nucleus PLUS RTOS in TI's stable TCS211 fw +(which served as the baseline for several vendors' production fw) exhibits one +hair-raising bug. While we don't know for sure where and how they maintained +Nucleus library sources for compilation (the version we got has them censored +out), we do see that Nucleus header files (nucleus.h and ??_defs.h) exist in +two different locations in the source tree in two different versions: + +* One version exists under chipsetsw/os/nucleus +* The other version exists under gpf/inc/nuc & gpf/inc/nuc/arm7 + +The two versions of these header files under these two paths in TCS211 are not +the same! The main nucleus.h header file is the same in both places, cs_defs.h +and tm_defs.h versions differ only in comments, but tc_defs.h is the real +kicker: the version under gpf/inc/nuc has an extra field added to the TC_HCB +aka NU_HISR structure, making this structure one word longer than in the other +version! More specifically, in ATI's original Nucleus this structure is 22 +words long with 4 unused dummy words at the end; TI's GPF version adds a fifth +dummy word (thankfully toward the end, not shifting any actually-used members +of the struct), putting the total struct size at 23 words. + +It would be one thing if TI had made this change consistently, but they didn't: +some modules were compiled with one version of the headers and got the 22-word +version of the struct, while other modules were compiled with the other header +file version and got the 23-word version of the struct. How can their fw work +with this bug in it? Answer: TCS211 fw works despite this Nucleus integration +bug because: + +* None of the actually-used members of the struct change offsets between the + two versions; + +* Some places in the code have 22-word structs allocated in memory while other + places have 23-word structs, but when they pass pointers to these structs to + Nucleus API functions, those functions don't access past the actually-used + part at the beginning (the part before dummy words), and they never do + anything like zeroing out the full size of the expected struct. + +* The only place in TCS211 fw where the total size of the struct matters is + where NU_HISR is embedded in another structure, and there is one such place + in GPF. Here breakage would result if different modules using these structs + and arrays were compiled with different header file versions, but all modules + that touch this part are compiled with the GPF version of nucleus.h, NU_DEBUG + and tc_defs.h. + +Needless to say, resolving this bogosity has been an important part of +FreeCalypso firmware deblobbing. Naturally the most ideal solution would have +been to remove the bogus extra word added by TI and consistently use the +original 22-word struct everywhere, but there is one further complication: I +(Mother Mychaela) don't feel comfortable with moving away from the original blob +version of the OSL component of GPF, and these COFF objects have been compiled +with the 23-word version of TC_HCB aka NU_HISR. + +The following alternative approach has been implemented in FC Tourmaline: + +* The new source version of Nucleus by Comrade XVilka has been checked in under + src/nucleus, and this new source version is the one we are using instead of + TI's binary object version. + +* The new Nucleus header files src/nucleus/nucleus.h and src/nucleus/??_defs.h + are the only ones used in Tourmaline - both old versions have been removed + from active -I include paths. + +* The new src/nucleus/tc_defs.h header file has been patched to replicate TI's + 23-word version of TC_HCB aka NU_HISR, and the NU_HISR_SIZE definition in + src/nucleus/nucleus.h has also been adjusted to match. + +Thus we are using the 23-word version of TC_HCB aka NU_HISR everywhere, with 5 +dummy words at the end rather than 4, adding 4 extra bytes of wasted RAM space +to every instance of this struct throughout the firmware - but there are only a +small number of these instances, thus the waste is negligible. In return we +gain 100% consistency (the same version of the struct is used everywhere in our +fw), and we retain the ability to keep the original OSL blobs which I am not +ready to give up.