# HG changeset patch # User Mychaela Falconia # Date 1489518434 0 # Node ID 33b35965b4a0c449f9621274d6bc892fc2577bdd # Parent 974835ad720cf2aea1f21320296a981e383845d8 STATUS: began analysis of the differences in the non-exact objects diff -r 974835ad720c -r 33b35965b4a0 STATUS --- a/STATUS Tue Mar 14 08:13:28 2017 +0000 +++ b/STATUS Tue Mar 14 19:07:14 2017 +0000 @@ -1,6 +1,6 @@ Objects in l1_ext.lib: -l1_afunc.obj: not exact, needs review +l1_afunc.obj: not exact, see explanation below l1_async.obj: perfect match l1_cmplx.obj: perfect match to 20070608 version except line number points l1_init.obj: perfect match @@ -12,8 +12,9 @@ l1_dyn_dwl_afunc.obj: perfect match l1_dyn_dwl_apihisr.obj: perfect match l1_dyn_dwl_async.obj: perfect match -l1_dyn_dwl_func.obj: not exact, needs review -l1_dyn_dwl_init.obj: sole diff is in the num_of_primitives oddity +l1_dyn_dwl_func.obj: not exact, see explanation below +l1_dyn_dwl_init.obj: sole diff is in the num_of_primitives oddity, + see explanation below l1_dyn_dwl_sync.obj: perfect match l1audio_abb.obj: perfect match @@ -57,3 +58,112 @@ tpudrv.obj: perfect match tpudrv12.obj: not exact, needs review + +Detailed analysis of differences, i.e., cases where the reconstructed C code +compiles into an object that is not bit-identical to the original blob: + +l1_afunc.obj: + + The l1_afunc.c module from LoCosto is used without any changes: + it compiled right away after adding one constant to l1_const.h, + and the result of recompilation is identical to the original up until + the l1a_clip_txpwr() function, which is the last function in the module. + + Disassembly of the original blob version of this function has been + analyzed and found to be identical in logic to the available C code, + but there must have been some change to the code expression that + results in different output from the compiler. In particular, the + symbolic info indicates the present of a local variable named power + in the original, but no such local var exists in the LoCosto version. + The TSM30 version was of no help as it is entirely different there. + + See g23m/objdiff/l1_ext/l1_afunc.notes for further info. + +l1_sync.obj: needs further review +l1_sync_intram.obj: ditto + +dl1_com.obj: not exact, needs review + +l1_dyn_dwl_func.obj: + + The LoCosto version uses a function (implemented in l1_func.c in + the LoCosto code) named l1_memcpy_16bit() to download patch bits + into the DSP's API RAM; the function does what the name says, and + the logic of using 16-bit accesses when hitting this API RAM makes + perfect sense to me (Mychaela). The original TCS211 code apparently + used plain memcpy(), which the compiler turned into its C$MEMCPY call. + + If one does a #define l1_memcpy_16bit memcpy in l1_dyn_dwl_func.c, + the resulting l1_dyn_dwl_func.obj is almost bit-identical to the + original blob: the only diff is in register allocation - the compiler's + register allocator picks a different choice of registers, but all + instructions still perfectly line up. + + For production use of our reconstructed TCS211 L1 code, we have adopted + the version with l1_memcpy_16bit() - the function body itself has been + moved into l1_dyn_dwl_func.c so that l1_func.c remains a perfect match. + +l1_dyn_dwl_init.obj: + + In the TCS211 configuration without L1_GTT, there are a total of 5 + signals (aka primitives aka L1 messages) which trigger a dynamic + DSP patch download. These 5 signals are enumerated in + signal_patch_array[] in l1_dyn_dwl_afunc.c (which has been reconstructed + to a perfect match), and their total count (which should be 5) goes into + l1a.dyn_dwnld.num_of_primitives, set in l1_dyn_dwnld_initialize_var() in + l1_dyn_dwl_init.c. + + In the original blob version this num_of_primitives variable ends up + being set to 6: first set to 2, then incremented by 4. In the LoCosto + source this var is first set to 0 as they apparently have no patches + that are independent of compilation config options, and then incremented + for every enabled option. + + In our reconstruction we have made the GPRS and AMR_SCH patches and the + primitives that trigger them mandatory, and conditionalized the E2 and + AMR_MMS patches on MELODY_E2. The GPRS and AMR_MMS critters are + preinstalled by the static patch, and get pushed out by AMR_SCH and E2, + respectively. Of the 5 primitives listed in signal_patch_array[] in + the original blob, the first 2 are always-present core ones, whereas + the last 3 are specific to E2. The AMR_MMS patch is reinstated upon + L1_BACK_MELODY_E2_UNLOAD_INSTRUMENT_CON. + + Based on the above reasoning, our reconstructed version sets + l1a.dyn_dwnld.num_of_primitives to 5 in the full configuration: first + sets to 2, then increments by 3. If one makes a sans-MELODY_E2 build, + only the GPRS and AMR_SCH patches will be retained, and only the two + non-E2 primitives for entry into and exit from dedicated mode. + +l1audio_async.obj: + + The only bit diff is in register allocation - the compiler's register + allocator picks a different choice of registers, but all instructions + still perfectly line up. There is also a slight diff in the symbolic + metadata emitted for functions, which might be related to the diff in + the register allocation. + + The root cause of these diffs could not be found, but there is no + functional difference as only some in-function temporary registers + have been interchanged. + +l1audio_cust.obj: + + The original blob version has these demo/test functions at the end of + the module: + + audio_melo_e1_demo1_start() + audio_melo_e1_demo1_stop() + audio_melo_e1_demo2_start() + audio_melo_e1_demo2_stop() + audio_melo_e2_load_lsi() + audio_melo_e2_demo1_start() + audio_melo_e2_demo1_stop() + audio_melo_e2_demo2_start() + audio_melo_e2_demo2_stop() + + These functions are dead code, i.e., they are not called or referenced + from anywhere else in the firmware, and the link succeeds without them + being present. These dead functions have been omitted from the + reconstructed version. The reconstruction is a perfect match otherwise. + +tpudrv12.obj: early reconstruction, needs further review