FreeCalypso > hg > freecalypso-docs
comparison TCS211-fw-arch @ 0:fcd1cf531017
TCS211-fw-arch masterpiece written
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 08 Oct 2018 19:52:50 +0000 |
parents | |
children | 5de1f72ce941 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:fcd1cf531017 |
---|---|
1 This document describes the architecture of TI's TCS211 firmware and that of | |
2 our FreeCalypso Magnetite and Selenite firmwares which are based on it. | |
3 | |
4 What is TCS211, and why we use it as our reference | |
5 ================================================== | |
6 | |
7 TI were in the business of making GSM baseband chipsets for about a decade | |
8 from the late 1990s up until 2009, and over that time span both their silicon | |
9 and their firmware architecture had evolved in many different ways. All of our | |
10 work in the FreeCalypso family of projects is based on one fairly arbitrary | |
11 snapshot, a rather arbitrarily picked single point in that long evolutionary | |
12 line: we use the Calypso chipset as opposed to both the ones before and the | |
13 ones after, and we use TI's TCS211 firmware from 2007 as our golden reference, | |
14 as opposed to other equally valid ways of architecturing the fw that came | |
15 before and after our arbitrarily picked snapshot. | |
16 | |
17 Q: Why do we use the Calypso chipset as opposed to LoCosto or E-Costo or | |
18 whatever was TI's very last offering before they got out of that business? | |
19 | |
20 A: Because that's what Openmoko used: their Neo FreeRunner aka GTA02 smartphones | |
21 were our primary hardware target for many years before we gathered the money | |
22 and the courage to build our own board-level hardware starting from just chips | |
23 bought on the Chinese surplus market. | |
24 | |
25 Q: Why do we use TI's TCS211 firmware from 2007 and its architecture as our | |
26 golden reference, as opposed to any of the other infinitely many equally valid | |
27 ways of architecturing a working firmware implementation for the same Calypso | |
28 chipset? | |
29 | |
30 A: Because it works flawlessly, and is extremely stable as a commercial product. | |
31 The firmware which Openmoko got from TI had only a tiny difference from TI's | |
32 internal TCS211 mainline (TSPACT signal definitions in tpudrv12.h which are | |
33 different between the quadband RFFE on TI's internal reference hw and the | |
34 triband one in FIC's commercial implementation), and with only a few additional | |
35 changes related to our use of a newer flash chip that wasn't supported back in | |
36 TI's and Openmoko's days, this golden reference fw can run equally well on our | |
37 own FCDEV3B. | |
38 | |
39 Relation between TCS211 and FreeCalypso | |
40 ======================================= | |
41 | |
42 The only "pure" TCS211 firmware we got is the one that has been salvaged from | |
43 the ruins of Openmoko. To the best of our knowledge, it is the world's only | |
44 surviving copy of any version of TCS211 - it is entirely possible that even TI | |
45 may not have it any more in any of their archives, given the length of time that | |
46 has passed and the total lack of interest in this "ancient junk". In its pure | |
47 form, this world's sole surviving copy of TI's TCS211 fw is laden with blobs | |
48 (many components exist only as binary object libraries with no corresponding | |
49 source), and it features a build system that is very thoroughly Windows-based. | |
50 And to top it off, that configuration and build system has many critical | |
51 components which also exist only as compiled binaries (Windows executables or | |
52 Java bytecode) with no corresponding source. | |
53 | |
54 We started by replacing the original configuration and build system of TCS211 | |
55 with our own one that is Unix-based rather than Windows-based, and implemented | |
56 in Bourne shell with a few C helpers instead of XML, Java and Perl. The result | |
57 was named FreeCalypso Magnetite. At first we changed only the configuration | |
58 and build system, but kept all of the original TCS211 code, including all of | |
59 the binary-only components. Then we deblobbed it gradually, replacing binary- | |
60 only components with source, one component at a time. Where did we get the | |
61 source for the pieces that came as binary objects with no corresponding source? | |
62 The answer is different for different components: | |
63 | |
64 * For GSM Layer 1 (a very critical and highly chipset-dependent component), we | |
65 did a painstaking reconstruction which you can see in the tcs211-l1-reconst | |
66 repository. That world's last surviving copy of TCS211 which we got only had | |
67 *.c files censored out, while all of the original *.h files were preserved - | |
68 and thanks to the preserved configuration and build system, we also got all | |
69 of the original compilation lines including compiler options, -D definitions | |
70 and -I include paths. For most of the missing *.c files we got a "wrong" | |
71 version from the TCS3/LoCosto source. The reconstruction proceeded by taking | |
72 these "wrong version" *.c files, putting them one module (one *.c file) at a | |
73 time into the TCS211 build environment, and massaging each individual *.c | |
74 file until it compiled into a perfect match to the original binary object. | |
75 Thus we have reconstructed a full C source for the L1 component which for all | |
76 practical purposes can be treated as if it were the lost original source. | |
77 | |
78 * For some small pieces like the tpudrv12 RF driver and the OSL and OSX | |
79 components of GPF it was more of a translation from disassembly to C: the C | |
80 code we use is of our own writing, but it faithfully matches the logic | |
81 implemented by the original blobs as recovered through disassembly. | |
82 | |
83 * The G23M protocol stack is a very large and complex component, and our copy | |
84 of TCS211 (the world's only surviving copy to the best of our knowledge) has | |
85 it in binary-only form. Trying to source-reconstruct it precisely like we | |
86 did with L1 would have been infeasible, hence we took a different approach: | |
87 we put together a TCS2/TCS3 hybrid in which we made a wholesale replacement | |
88 of all G23M components: we adopted the new version of G23M wholesale without | |
89 trying to recreate the old version. | |
90 | |
91 * Both TCS211 and TI's newer TCS3.2 fw for the LoCosto chipset are based on | |
92 Nucleus PLUS RTOS (different versions), and both firmwares have their Nucleus | |
93 only as binary object libraries, no source. However, we got another version | |
94 of Nucleus from about the same time frame (slightly newer than the one TI used | |
95 in TCS211, but slightly older than the one in TCS3.2) from a non-TI source | |
96 (it was posted on a Russian web forum by Comrade XVilka), and in FreeCalypso | |
97 Selenite we use this new Nucleus as a replacement for TCS211 original version | |
98 in the same manner as how we had earlier made a wholesale replacement of the | |
99 G23M protocol stack. | |
100 | |
101 With two major components (Nucleus and the G23M PS) replaced with non-TCS211 | |
102 versions, our Magnetite hybrid and Selenite firmwares are no longer TCS211, but | |
103 they still faithfully follow the _architecture_ of TCS211: in each case when we | |
104 replaced the code, we made the new code version fit perfectly into the original | |
105 architecture without any disruptive changes. Thus anyone who desires to | |
106 understand our current FreeCalypso firmwares (Magnetite and Selenite) needs to | |
107 first understand the original TCS211 architecture, as it is essentially | |
108 unchanged. | |
109 | |
110 Why not use the LoCosto chipset and its TCS3.2 firmware? | |
111 ======================================================== | |
112 | |
113 We went the Calypso route and not the LoCosto route because of the circumstances | |
114 that surrounded the beginning of our family of projects. We did not get all of | |
115 the tools needed for working with LoCosto chips and TI's TCS3.2 fw (CSST and | |
116 SBuild) until the spring of 2015, and by that time we had invested too much into | |
117 the Calypso to throw it all away and restart anew in the uncharted waters of | |
118 LoCosto. Another factor is that the software for talking to LoCosto's ROM | |
119 bootloader (CSST) exists only as Windows binaries sans source, and it would | |
120 require some effort to reverse-engineer the protocol and implement a free and | |
121 Unix-based alternative - whereas for the Calypso this work was already done by | |
122 OsmocomBB folks before we entered the scene. Finally, in the case of the | |
123 Calypso we have read out the actual content of the ROMs (both the ARM boot ROM | |
124 and the DSP ROM) and the ARM boot ROM code has been disassembled and thoroughly | |
125 understood - whereas in the case of LoCosto it is not certain if we can even | |
126 read out the ROM content, as it is said to be protected against reading. | |
127 | |
128 If someone else desires to play with LoCosto, either by hacking a Peek device | |
129 or by building an I-Sample board from the available PADS PCB file, go for it! | |
130 But the FreeCalypso core team is sticking with the Calypso chipset for now, and | |
131 our actively maintained Magnetite and Selenite firmwares follow the architecture | |
132 of TCS211, not that of TCS3.2. | |
133 | |
134 Relation between the ARM and DSP cores in the Calypso | |
135 ===================================================== | |
136 | |
137 The Calypso digital baseband processor chip has two processor cores in it: an | |
138 ARM7TDMI core that runs the main firmware and a C54x DSP core that performs the | |
139 more burdensome signal processing tasks. The DSP is subservient to the ARM: | |
140 only the ARM comes out of reset and starts executing code upon power-up, while | |
141 the DSP is held in reset (does not run) until and unless the ARM firmware starts | |
142 it running. | |
143 | |
144 The ARM core executes code from outside of the Calypso chip itself: in normal | |
145 operation (outside of development) there is a flash memory chip connected to | |
146 Calypso's external memory bus, and the Calypso's ARM core executes firmware | |
147 stored in this flash. There is an optional (enabled or disabled by a hardware | |
148 pin) ARM boot ROM inside the Calypso chip; when this boot ROM is enabled by | |
149 nIBOOT pin strapping on the board (like it is on Openmoko and FreeCalypso | |
150 hardware), the ARM core executes code from this boot ROM first upon power-up or | |
151 reset before jumping to external flash. The tiny piece of code that is hard- | |
152 cast in this mask ROM acts as an unbricking aid: it gives a certain time window | |
153 during which the boot process can be interrupted and diverted if certain magic | |
154 characters are sent into either of Calypso's two UARTs by an external | |
155 development host, and if nothing is received on either UART during that time | |
156 window (as would be the case in normal usage of a Calypso phone or modem), the | |
157 boot ROM transfers control to the firmware image in the external flash. The | |
158 end result is that the ARM core always runs code from outside of the Calypso | |
159 chip itself, either the firmware image in the flash or whatever code is fed by | |
160 an external development host to the boot ROM serially over a UART. | |
161 | |
162 There is also an internal RAM inside the Calypso from which the ARM can execute | |
163 code (512 KiB on the full Calypso version or 256 KiB on Calypso Lite silicon | |
164 used in some historical low-end phones); the primary purpose of this internal | |
165 RAM is to allow chosen sections of code to execute faster without the | |
166 performance penalty of the external memory bus, but it is volatile RAM, not ROM | |
167 or flash, hence it doesn't have any code in it until and unless loaded by the | |
168 firmware copying code from flash or via the serial boot protocol. | |
169 | |
170 In contrast, the DSP is very different. The DSP core can never execute any | |
171 code from outside the chip, and has no access to the Calypso chip's external | |
172 memory bus at all. Instead the only two memories accessible to the DSP are a | |
173 mask ROM and a fast internal RAM. The DSP's dedicated mask ROM is 128 Kwords; | |
174 the DSP's RAM is 28 Kwords, out of which 8 Kwords constitute the so-called API | |
175 RAM which is accessible to both ARM and DSP cores. (The C54x DSP addresses | |
176 memory by words instead of bytes, hence the memory sizes are given in Kwords | |
177 instead of KiB.) | |
178 | |
179 The main bulk of the DSP's operating program is already hard-cast in the silicon | |
180 in the 128 Kword mask ROM. The DSP ROM code is structured in such a way that | |
181 any part of it can be overridden by downloadable patch codes which get loaded | |
182 somewhere in the DSP's 28 Kword RAM, but because the RAM is significantly | |
183 smaller than the ROM, downloadable DSP code cannot replace the entirety of the | |
184 ROM code - instead the code needs to be patched very selectively only where | |
185 necessary to fix a bug that was discovered after the silicon was made or to | |
186 extend the DSP functionality with a new feature. | |
187 | |
188 The DSP ROM code in the Calypso silicon we are using has been successfully read | |
189 out, but it is only the executable binary code and data - we never found a copy | |
190 of the source for this DSP ROM code. And even if we had this source, we would | |
191 not be able to casually modify and recompile it without spending millions of | |
192 dollars to fab a new chip revision with a modified mask ROM. Having this source | |
193 would allow us to develop our own DSP patch codes and to understand and maintain | |
194 the existing ones, hence we need to make an effort to convince TI to release | |
195 the source for the DSP ROM if they have it in their archives, but if no | |
196 surviving copy of this source exists anywhere in the world, the fallback plan | |
197 would be to reverse-engineer the DSP ROM code by disassembly. The latter plan | |
198 has not been pursued yet because of the very high labor cost it would involve. | |
199 | |
200 It is possible to run the Calypso DSP without any patches, i.e., have it run | |
201 only the code that is already in the mask ROM. Our competitor OsmocomBB | |
202 operates in this manner, and we have also built and run modified versions of | |
203 our TCS211-based FreeCalypso firmware with DSP patch loading disabled as an | |
204 experiment. However, all ARM-side firmwares that have been officially released | |
205 by TI for production use including our TCS211-20070608 golden reference do apply | |
206 downloadable patches to the DSP, and are designed to run with this patched DSP; | |
207 running them with DSP patching disabled results in unstable operation. | |
208 | |
209 DSP patch codes that are included in ARM-side Calypso firmwares take the form | |
210 of const char arrays initialized with hex bytes; these C source files with hex | |
211 char arrays inside were apparently produced from C54x COFF files with a tool | |
212 called coff2c, but we never got any of those COFF files or whatever source (C | |
213 or assembly) they were built from. At the present time in the FreeCalypso | |
214 family of projects we use the DSP patch codes (hex char arrays) which we got | |
215 with our copy of TCS211 from 20070608, and we treat the entire DSP block (the | |
216 combination of mask ROM plus patches) as a functional black box. | |
217 | |
218 Having to treat the DSP as a black box is certainly a major shortcoming of our | |
219 FreeCalypso solution. However, I (Mother Mychaela) would much rather have a | |
220 phone or modem in which only the DSP is a black box while I get to maintain all | |
221 of the upper layers with full freedom, as opposed to the status quo alternative | |
222 of a very high-level black box with FOTA backdoors. Unlike the ubiquitous | |
223 high-level black boxes from the likes of Qualcomm, the DSP in the Calypso cannot | |
224 be backdoored: it has no access to the ARM address space, thus no access to the | |
225 flash (cannot surreptitiously modify the firmware) and no access to any of the | |
226 higher-level radio protocol state maintained by the ARM, all it can do is | |
227 modulate and demodulate bursts and run voice codecs _as commanded by the ARM_. | |
228 Furthermore, the DSP has no access to the Calypso chip's TPU (Time Processing | |
229 Unit, the block that controls board-level RF hardware) and thus has no direct | |
230 control over any of the RF hardware: it cannot initiate radio transmission or | |
231 even reception on its own, instead the ARM firmware has to configure the RF | |
232 hardware via the TPU for each and every Rx or Tx time window. | |
233 | |
234 Finally, if anyone is truly paranoid about the possibility of backdoors in the | |
235 DSP, the DSP ROM code has been read out - you are welcome to hire a professional | |
236 reverser of your choice to disassemble and audit it as thoroughly as you like. | |
237 This code is unchangeable by virtue of being hard-cast in a mask ROM in the | |
238 silicon. | |
239 | |
240 The rest of this document covers the firmware that runs on the ARM core; it | |
241 controls the DSP via its API RAM, a form of shared memory interface. | |
242 | |
243 High-level structure of TCS211 firmware | |
244 ======================================= | |
245 | |
246 The code base that makes up TI's TCS211 firmware consists of 3 main divisions: | |
247 chipset software, Condat G23M (GSM and GPRS L23 protocol stacks, ACI and | |
248 optional handset UI layers) and GPF. Let us look at them in turn: | |
249 | |
250 chipsetsw division | |
251 ------------------ | |
252 | |
253 In the original TCS211 delivery there was a top-level directory named chipsetsw | |
254 (chipset software), containing code that is specific to TI's chipsets in | |
255 particular and was never intended to run on any other hardware. This code | |
256 division has been retained intact in our FreeCalypso Magnetite and Selenite | |
257 firmwares, taken in its entirety from our TCS211 golden reference, although we | |
258 have shortened the name: this code division now resides under src/cs in | |
259 Magnetite and Selenite. Aside from a few bits of system glue, this chipsetsw | |
260 breaks down into two further subdivisions: the L1+drivers core and the SSA | |
261 division. | |
262 | |
263 L1+drivers core | |
264 --------------- | |
265 | |
266 This division resides under chipsetsw/layer1 and chipsetsw/drivers/drv_core, or | |
267 under src/cs/layer1 and src/cs/drivers/drv_core in our version. The most | |
268 important piece here is L1 (GSM Layer 1): this code drives the DSP and the RF | |
269 hardware, and thereby makes the Calypso function as a GSM MS (mobile station) | |
270 and not merely as a general purpose microprocessor platform. This code can be | |
271 considered to be the most important part of the entire firmware. | |
272 | |
273 At one time TI had a so-called standalone L1 configuration, selected by the | |
274 OP_L1_STANDALONE C preprocessor symbol. We don't have the bits that are needed | |
275 to build this configuration (they were probably never released outside of TI at | |
276 all), but it appears that this fw build configuration consisted of just Nucleus, | |
277 L1, the drivers under drv_core, the OSL and OSX parts of GPF without the rest, | |
278 and some stubs for the few higher-level functions that are intertied with L1. | |
279 | |
280 The drivers under chipsetsw/drivers are divided into drv_core and drv_app: the | |
281 former are the most essential or fundamental ones, used by L1 and/or needed for | |
282 the OP_L1_STANDALONE config; the latter belong to the higher-level SSA division | |
283 described below. | |
284 | |
285 SSA division | |
286 ------------ | |
287 | |
288 TI had a group called System Software and Applications (SSA), and they supplied | |
289 those parts of the firmware that are neither L1+drv_core nor Condat G23M. The | |
290 more interesting pieces here include the flash file system (FFS), the debug | |
291 trace facility (RVT), the Enhanced Test Mode (ETM) facility that allows | |
292 external development and production tools to poke at the firmware, RiViera Audio | |
293 Service (playing various beeps and ringtones through the DSP, a front-end to L1 | |
294 audio functions), LCD and keypad drivers for Calypso-based handsets, and various | |
295 supportive functions implemented via the Iota ABB: switch-on and switch-off | |
296 logic, battery monitoring and charging, backlight LED control. | |
297 | |
298 All firmware components in the SSA division are built on top of a framework | |
299 called RiViera - more will be said about it later. Everything under | |
300 chipsetsw/drivers/drv_app, chipsetsw/riviera and chipsetsw/services (or under | |
301 src/cs/drivers/drv_app, src/cs/riviera and src/cs/services in our version) | |
302 belongs to the SSA realm. | |
303 | |
304 Condat G23M division | |
305 -------------------- | |
306 | |
307 At the beginning of TI's involvement in the GSM baseband chipset business, they | |
308 only developed and maintained their own L1 code, which eventually grew into the | |
309 larger chipsetsw division described above, while the rest of the protocol stack | |
310 (which is hardware-independent) was licensed from another company called Condat. | |
311 Later Condat as a company was fully acquired by TI, and the once-customer of | |
312 this code became its owner. The name of TI/Condat's implementation of GSM | |
313 layers 2&3 for the MS side is G23M, and it forms its own major division of the | |
314 overall fw architecture. | |
315 | |
316 The overall Condat code realm can be further subdivided into GSM and GPRS L23 | |
317 protocol stacks, the Application Control Interface (ACI) which includes the AT | |
318 command interpreter (ATI), and additional phone UI layers which are only | |
319 included in handset but not modem firmwares. | |
320 | |
321 We don't know exactly how TI maintained this software internally: given that it | |
322 is mostly hardware-independent aside from integration details and some minor | |
323 features which may be present on one hw platform but not on another, it would | |
324 have made the most sense for TI to maintain a single internal mainline common | |
325 to both Calypso and LoCosto, and then integrate the code from this mainline into | |
326 chipset-specific customer releases. We have no way of knowing if TI indeed | |
327 followed this approach or not, but when we took the version of G23M from the | |
328 TCS3.2 source for the LoCosto chipset and grafted it onto the chipsetsw | |
329 foundation from TCS211 for the Calypso to produce our TCS2/TCS3 hybrid, the | |
330 integration went surprisingly smoothly. The full-source version of G23M which | |
331 we took from TCS3/LoCosto is newer than the binary-only version featured in the | |
332 world's last surviving copy of TCS211 from Openmoko. | |
333 | |
334 GPF island of stability | |
335 ----------------------- | |
336 | |
337 Underlying the G23M protocol stack is a special layer called GPF, which was | |
338 originally Condat's Generic Protocol stack Framework. Apparently Condat were | |
339 in the business of developing and maintaining a whole bunch of protocol stacks: | |
340 GSM MS side, GSM network side, TETRA and who knows what else. GPF was their | |
341 common underpinning for all of their protocol stack projects, which ran on top | |
342 of many different OS environments: Nucleus, pSOS, VxWorks, Unix/Linux, Win32 | |
343 and who knows what else. | |
344 | |
345 In the case of TI/FreeCalypso GSM fw, both the protocol stack and the underlying | |
346 OS environment are fixed: GSM and Nucleus, respectively. But GPF is still a | |
347 critically important layer in the firmware architecture: in addition to serving | |
348 as the glue between the G23M stack and Nucleus, it provides some important | |
349 support infrastructure for the protocol stack. | |
350 | |
351 However, what makes GPF very special is the way in which it relates to the rest | |
352 of the firmware architecture. GPF remained common and unchanged across TI's | |
353 many different projects, and it is so independent from the rest of the firmware | |
354 and its build configuration that TI were able to make company-wide GPF library | |
355 builds and then plop them into multiple fw projects which used them as | |
356 configuration-independent prebuilt libraries. All TI firmware (semi-)sources | |
357 we've got use GPF in prebuilt library form and are not set up to recompile any | |
358 part of it from source. | |
359 | |
360 Our FC Magnetite firmware uses the original binary libs from TCS211-Openmoko | |
361 for its GPF component, but for FC Selenite the project requirement is to be | |
362 completely blob-free, hence we had to reconstruct the source for GPF. The | |
363 original source for most parts of GPF was found between TCS3.2 from Peek/FGW | |
364 and TCS211 from OM (the former had the source for the core "frame" modules and | |
365 the latter had the source for misc and tst), but we never got the source for the | |
366 OSL and OSX components, hence we had to reconstruct them from disassembly. OSL | |
367 is the glue layer between GPF and Nucleus, OSX is the glue layer between GPF | |
368 and L1. | |
369 | |
370 Firmware boot process | |
371 ===================== | |
372 | |
373 As already mentioned earlier, the Calypso chip itself includes an ARM boot ROM | |
374 in the silicon that serves as an unbricking aid: it provides a certain time | |
375 window during which the boot process can be interrupted and diverted if certain | |
376 magic characters are sent into either of Calypso's two UARTs by an external | |
377 host, and if nothing is received on either UART during that time window, the | |
378 boot ROM transfers control to the firmware image in the external flash. As we | |
379 understand it, Calypso was TI's first DBB (digital baseband processor) chip to | |
380 include this boot ROM, and their previous DBB chips did not have such: they | |
381 would always execute code directly from external flash immediately out of reset. | |
382 | |
383 TI's TCS211 and earlier firmwares are structured in such a way that they boot | |
384 and run exactly the same way whether the Calypso boot ROM is present and | |
385 enabled, present but disabled, or not present at all. They put magic constant | |
386 0x00000001 in the 32-bit word at flash address 0x2000, which tells the Calypso | |
387 boot ROM (if it is present and enabled) to boot the flash fw image in legacy | |
388 mode: after providing the unbricking time window, the boot ROM moves itself out | |
389 of the way (sets two bits in the FFFF:FB10 register which tell the chip to unmap | |
390 the boot ROM and to map external memory at address 0) and induces a watchdog | |
391 reset, causing the chip to re-execute the reset vector, this time directly out | |
392 of external flash - thus the firmware boots as if the boot ROM weren't there, | |
393 but the ROM's unbricking function is retained. | |
394 | |
395 In order to make it easier to load new firmware images during development on | |
396 pre-Calypso platforms which didn't have a boot ROM, TI had developed a flash- | |
397 resident bootloader stage and included it in their fw architecture. This | |
398 bootloader stage is placed at the beginning of the flash at the reset vector, | |
399 and the rest of the firmware begins at an erase unit boundary. The bootloader | |
400 stage executes first, and before it jumps to the main firmware entry point | |
401 (_INT_Initialize) for normal boot, it offers an opportunity for the boot process | |
402 to be interrupted and diverted if an external host sends certain magic command | |
403 packets into either of the two UARTs during the allotted time window. If the | |
404 external host does interrupt and divert the boot process in this manner, it can | |
405 feed a code image to the bootloader to be written somewhere in target RAM, and | |
406 then command the bootloader to jump to it. It is exactly the same functionality | |
407 (though with different serial protocol specifics) as implemented in the Calypso | |
408 boot ROM. The ROM version is obviously superior because it is unbrickable, but | |
409 the flash-resident, built-with-firmware version is what TI used before they | |
410 came up with the idea of the boot ROM for the Calypso. | |
411 | |
412 When the boot-ROM-equipped Calypso came along, TI kept the flash-resident | |
413 bootloader in the firmware: it does no harm aside from adding a little bit of | |
414 delay to the boot process, it does not conflict with the ROM bootloader as the | |
415 two speak different serial protocols and respond to different interrupt-boot | |
416 sequences, and it allowed TI to keep the same firmware architecture for | |
417 platforms with and without a boot ROM. However, in our FreeCalypso firmwares | |
418 starting with Magnetite we have removed this extra bootloader stage for the | |
419 following reasons: | |
420 | |
421 * It is not useful to us on any of our hardware targets: on those devices that | |
422 have the Calypso boot ROM enabled, we use that boot ROM and get full | |
423 unbrickability, whereas on Mot C1xx phones we have to work with Mot/Compal's | |
424 own different bootloader and serial protocol at least initially, hence it | |
425 makes the most sense to stick with the same after the conversion to | |
426 FreeCalypso as well. | |
427 | |
428 * As delivered by TI with their full production TCS211 fw releases, their | |
429 firmware-resident bootloader works as intended only on hw platforms with | |
430 13 MHz VCXOs like the original D-Sample (Clara RF), and is broken on platforms | |
431 like Rita RF (the only RF chip for which we have driver code!) with 26 MHz | |
432 VCXOs: there is no conditionally-compiled code anywhere in the bootloader | |
433 code path to set the VCLKOUT_DIV2 bit in the CNTL_CLK register on 26 MHz | |
434 platforms, thus the UARTs are fed with 26 MHz instead of the standard 13 MHz | |
435 clock expected in normal operation, and the intended baud rate of 115200 bps | |
436 turns into 230400. Because 230400 bps is a baud rate which Calypso UARTs | |
437 *cannot* produce in normal GSM operation (when the peripheral clock network | |
438 runs at the expected 13 MHz), tools that are designed to talk to Calypso GSM | |
439 devices are typically not designed to support this baud rate. In particular | |
440 for CP2102 USB-serial adapters, the precedent established by the factory | |
441 CP2102 EEPROM programming in the Pirelli DP-L10 phone is that the baud rate | |
442 entry for 230400 bps is replaced with 203125 bps, which is a valid baud rate | |
443 for Calypso UARTs running at 13 MHz. | |
444 | |
445 * We have no source for TI's firmware-resident bootloader, only linkable binary | |
446 objects that came with our world's last surviving copy of TCS211, which are | |
447 incompatible with our goal of blob-free firmware. | |
448 | |
449 Because this extra bootloader stage is ultimately unnecessary in our | |
450 environment, the deblobbing goal was easier accomplished by removing it | |
451 altogether instead of expending effort on a blob-free replacement. Because I | |
452 wasn't comfortable with modifying TMS470 assembly code and linker script magic, | |
453 the removal of the bootloader was accomplished by stubbing out its C body with | |
454 an empty function. In the gcc-built FC Selenite version it is removed | |
455 completely, without any leftover stubs. | |
456 | |
457 Finally, it needs to be noted for the sake of completeness that Compal's | |
458 bootloader used on Mot C1xx phones is a modified version based on TI's original | |
459 bootloader. However, this factoid matters only for historians and genealogists; | |
460 for all practical purposes it is an unrelated animal, as Mot/Compal's serial | |
461 protocol for interrupting and diverting the boot process is their own and bears | |
462 no resemblance to TI's version. And yes, Mot/Compal's version does set the | |
463 VCLKOUT_DIV2 bit in the CNTL_CLK register to adjust for the 26 MHz clock input | |
464 as its first order of business; it was probably the very first issue they had | |
465 to fix. | |
466 | |
467 When we build FC Magnetite or FC Selenite TMS470 firmware for Mot C1xx targets, | |
468 we use dd to strip off the first 64 KiB of the image produced by TI's linker | |
469 (the part where TI's bootloader resides, be it intact or stubbed out) and flash | |
470 the remaining image (the main body of the fw) starting at flash address 0x10000. | |
471 In the gcc-built Selenite version we natively link images that are designed to | |
472 be flashed at 0x10000 without any dirty hacks. Common to all FC firmwares for | |
473 C1xx targets, the bootloader image we put at 0 (in the brickable flash sector) | |
474 is a modified version based on one of Mot/Compal's originals: we have binary- | |
475 patched it to redirect the exception vectors from Mot/Compal's 0x20A0 to 0x10000 | |
476 and to move the main fw entry point from Mot/Compal's 0x20F8 to TI's 0x10058. | |
477 | |
478 None of this muckery applies to our own FreeCalypso hardware or to our | |
479 predecessor Openmoko's hw: on these good hw targets the complete fw image as | |
480 built is flashed at 0, and there is no possibility of bricking because we use | |
481 the boot ROM to gain access irrespective of what's in the flash. | |
482 | |
483 Main firmware entry point | |
484 ------------------------- | |
485 | |
486 With the bootloader distraction out of the way, the main fw entry point is at | |
487 the _INT_Initialize symbol in the int.s assembly module, located in | |
488 src/cs/system/main/int.s in Magnetite and Selenite. The functional equivalent | |
489 for the gcc environment in Selenite is in src/cs/system/main/gcc/bootentry.S. | |
490 This assembly code performs some basic hardware initialization, sets up | |
491 sensible memory timings for the boot path phase before DPLL setup, copies the | |
492 IRAM code (the code that is intended to execute out of the fast internal RAM) | |
493 from flash to where it needs to be, zeros both IRAM and XRAM .bss regions, does | |
494 TI's cinit/auto_init business for initialized data in the TMS470 environment | |
495 (Selenite gcc version copies .data from flash to RAM instead), sets up the | |
496 system, IRQ, FIQ and exception stacks, does some assembly initialization for | |
497 Nucleus and finally jumps to Nucleus' C entry point INC_Initialize(). | |
498 | |
499 Further initialization takes place in the Init_Target() and Init_Drivers() | |
500 functions called from Application_Initialize(), which is the last function | |
501 called by INC_Initialize() before starting the Nucleus task scheduler. | |
502 | |
503 Nucleus environment | |
504 =================== | |
505 | |
506 Like all classic TI firmwares, ours is based on the Nucleus PLUS RTOS. Just | |
507 like TI's original code on which we are based, we use only a small subset of | |
508 the functionality provided by Nucleus - but because the latter is a library, | |
509 the pieces we don't use simply don't get pulled into the link. The main | |
510 function we get out of Nucleus is the scheduling of threads, or tasks as | |
511 Nucleus calls them. | |
512 | |
513 Aside from pre-stack-setup assembly init code and ARM exception handlers, every | |
514 piece of code in the firmware executes in one of the following contexts: | |
515 | |
516 * Application_Initialize(): this function and everything called from it execute | |
517 just before Nucleus' thread scheduler starts; at this point interrupts are | |
518 disabled at the ARM7 core level (in the CPSR) and must not be enabled; the | |
519 stack is Nucleus' "system stack" which is also used by the scheduler and LISRs | |
520 as explained below. | |
521 | |
522 * Regular threads or tasks: once Application_Initialize() finishes, all code | |
523 with the exception of interrupt handlers (LISRs and HISRs as explained below) | |
524 runs in the context of some Nucleus task. Whenever you are trying to debug | |
525 or simply understand some piece of code in the firmware, the first question | |
526 you should ask is "which task does this code execute in?". Most functional | |
527 components run in their own tasks, i.e., a given piece of code is only | |
528 intended to run within the Nucleus task that belongs to the component in | |
529 question. On the other hand, some components are implemented as APIs, | |
530 functions to be called from other components: these don't have their own task | |
531 associated with them, and instead they run in the context of whatever task | |
532 they were called from. Some only get called from one task: for example, the | |
533 "uartfax" driver API calls only get called from the protocol stack's UART | |
534 entity, which is its own task. Other component API functions like FFS and | |
535 trace can get called from just about any task in the system. Many components | |
536 have both their own task and some API functions to be called from other tasks, | |
537 and the API functions oftentimes post messages to the task to be worked on by | |
538 the latter; the just-mentioned FFS and trace functions work in this manner. | |
539 | |
540 In our TCS211-mimicking Magnetite and Selenite firmwares every Nucleus task is | |
541 created either through RiViera or through GPF, and not in any other way - see | |
542 the description of RiViera and GPF below. | |
543 | |
544 * LISRs (Low level Interrupt Service Routines): these are the interrupt handlers | |
545 that run immediately when an ARM IRQ or FIQ comes in. The code at the IRQ and | |
546 FIQ vector entry points calls Nucleus' magic stack switching function | |
547 (switches the CPU from IRQ/FIQ into SVC mode, saves the interrupted thread's | |
548 registers on that thread's stack, and switches to the "system" stack) and | |
549 then calls TI's IRQ dispatcher implemented in C. The latter figures out | |
550 which Calypso interrupt needs to be handled and calls the handler configured | |
551 in the compiled-in table. Nucleus' LISR registration framework is not used | |
552 by the GSM fw, but these interrupt handlers should be viewed as LISRs | |
553 nonetheless. | |
554 | |
555 There is one additional difference between canonical Nucleus and TI's version | |
556 (we've replicated the latter): canonical Nucleus was designed to support | |
557 nested LISRs, i.e., IRQs re-enabled in the magic stack switching function, | |
558 but in TI's version which we follow this IRQ re-enabling is removed: each LISR | |
559 runs with interrupts disabled and cannot be interrupted. (The corner case of | |
560 an FIQ interruping an IRQ remains to be looked at more closely as bugs may be | |
561 hiding there, but Calypso doesn't really use FIQ interrupts.) There is really | |
562 no need for LISR nesting in our GSM fw, as each LISR is very short: most LISRs | |
563 do nothing more than trigger the corresponding HISR. | |
564 | |
565 * HISRs (High level Interrupt Service Routines): these hold an intermediate | |
566 place between LISRs and tasks, similar to softirqs in the Linux kernel. A | |
567 HISR can be activated by a LISR calling NU_Activate_HISR(), and when the LISR | |
568 returns, the HISR will run before the interrupted task (or some higher | |
569 priority task, see below) can resume. HISRs run with CPU interrupts enabled, | |
570 thus more interrupts can occur, with their LISRs executing and possibly | |
571 triggering other HISRs. All triggered HISRs must complete and thereby go | |
572 "quiescent" before task scheduling resumes, i.e., all HISRs as a group have a | |
573 higher scheduling priority than tasks. | |
574 | |
575 Nucleus implements priority scheduling for tasks. Tasks have their priority set | |
576 when they are created (through RiViera or GPF, see below), and a higher priority | |
577 task will run until it gets blocked waiting for something, at which time lower | |
578 priority tasks will run. If a lower priority task sends a message to a higher | |
579 priority task, unblocking the latter which was waiting for incoming messages, | |
580 the lower priority task will effectively suspend itself immediately while the | |
581 higher priority task runs to process the message it was sent. | |
582 | |
583 HISRs oftentimes post messages to their associated tasks as well; if one of | |
584 these messages unblocks a higher priority task, that unblocked task will run | |
585 upon the completion of the HISR instead of the original lower priority task | |
586 that was interrupted by the LISR that triggered the HISR. Nucleus' scheduler | |
587 is fun! | |
588 | |
589 RiViera and GPF | |
590 =============== | |
591 | |
592 RiViera and GPF are two parallel/independent/competing wrappers around or | |
593 layers above Nucleus. GPF comes from Condat and is used by the G23M protocol | |
594 stack and indirectly by L1 (the peculiar way in which L1 ties in with the rest | |
595 of the firmware will be covered later), whereas RiViera is used by the fw | |
596 components from TI's SSA group: flash file system, debug trace, RiViera Audio | |
597 Service and so forth. | |
598 | |
599 At some point in their post-Calypso TCS3.x program TI decided to eliminate | |
600 RiViera as an independent framework and to reimplement RiViera APIs (used by | |
601 peripheral but necessary code such as FFS, ETM, various drivers etc) over GPF. | |
602 This arrangement is used in the TCS3.2 LoCosto firmware from which we have | |
603 lifted our source replacements for much of the code that came as binary objects | |
604 in our reference TCS211 version. However, our current Magnetite and Selenite | |
605 firmwares follow the architecture of TCS211, not that of TCS3.2, and because | |
606 the entire SSA division of the fw including the RiViera core came in full source | |
607 form in our copy of TCS211, it was only natural to keep this code and its | |
608 architecture. | |
609 | |
610 Start-up process continued | |
611 ========================== | |
612 | |
613 As mentioned earlier, Nucleus calls the application's software init function | |
614 called Application_Initialize() after it initializes itself but before starting | |
615 the task scheduler. This function in TCS211 is just the following: | |
616 | |
617 Application_Initialize() | |
618 { | |
619 Init_Target(); | |
620 Init_Drivers(); | |
621 Cust_Init_Layer1(); | |
622 Init_Serial_Flows(); | |
623 StartFrame(); | |
624 Init_Unmask_IT(); | |
625 } | |
626 | |
627 Cust_Init_Layer1() is in L1, StartFrame() is in GPF, and the remaining 4 init | |
628 functions live in the init.c module under src/cs/system/main. | |
629 | |
630 The Init_Target() function finishes the hardware initialization that was | |
631 started by the assembly code at the firmware boot entry point (int.s): among | |
632 other things, it sets up the final memory timings that will be used by the | |
633 running fw and configures the Calypso DPLL which provides multiplied internal | |
634 clocks to both ARM and DSP cores. On Calypso C035 silicon which is used on our | |
635 own FreeCalypso boards and on most of our pre-existing hw targets the DPLL and | |
636 the DSP run at 104 MHz and the ARM gets half of that, running at 52 MHz. | |
637 Init_Target() also calls AI_InitIOConfig(), the function that initializes | |
638 Calypso GPIO directions and initial outputs; both of these functions typically | |
639 need to be tweaked when adding support for a new Calypso board target. | |
640 | |
641 The Init_Drivers() function is primarily responsible for initializing RiViera | |
642 and FFS, although it also does a bit of init related to ABB and SIM drivers. | |
643 | |
644 I mentioned earlier that every Nucleus task in our firmware gets created and | |
645 started either through RiViera or through GPF. All GPF tasks are created and | |
646 placed into the runable state in the Application_Initialize() context: the work | |
647 is done by GPF init code in gpf/frame/frame.c, and the top level GPF init | |
648 function called from Application_Initialize() is StartFrame(). Thus when | |
649 Application_Initialize() finishes and the Nucleus thread scheduler starts | |
650 running for the first time, all GPF tasks are there to be scheduled. | |
651 | |
652 There is a compiled-in table of all protocol stack entities and the tasks in | |
653 which they need to run; in TCS211 these GPF config bits live under | |
654 g23m/condat/frame/config for the GSM+GPRS configuration and under | |
655 g23m/condat/com/src/config for the GSM-only config without GPRS. Canonically | |
656 each protocol stack entity runs in its own task, but sometimes two or more are | |
657 combined to run in the same task: for example, in the minimal GSM "voice only" | |
658 configuration (no CSD, fax or GPRS) CC, SMS and SS entities share the same task | |
659 named CM. Unlike RiViera, GPF does not support dynamic starting and stopping | |
660 of tasks. | |
661 | |
662 As each GPF task starts running (immediately upon entry into Nucleus' scheduling | |
663 loop as Application_Initialize() finishes), pf_TaskEntry() function in | |
664 gpf/frame/frame.c is the first code it runs. This function creates the queue | |
665 for messages to be sent to all entities running within the task in question, | |
666 calls each entity's pei_init() function (repeatedly until it succeeds: it will | |
667 fail until the other entities to which this entity needs to send messages have | |
668 created their message queues), and then falls into the main body of the task: | |
669 for all "regular" entities/tasks except L1, this main body consists of waiting | |
670 for messages (or signals or timeouts) to arrive on the queue and dispatching | |
671 each received message to the appropriate handler in the right entity. | |
672 | |
673 RiViera tasks get started in a different way. The responsible code lives in | |
674 src/cs/system/main/create_RVtasks.c, and the create_tasks() function found in | |
675 that module is called by Init_Drivers() in the Application_Initialize() context. | |
676 But this function does not directly create and start every configured RiViera | |
677 task like StartFrame() does for GPF. Instead it creates a special helper task | |
678 which will do this work once scheduled. Thus at the completion of | |
679 Application_Initialize() and the beginning of scheduling the set of runable | |
680 Nucleus tasks consists of all GPF ones plus the special RV starter task. Once | |
681 the RV starter task gets scheduled, it will call rvm_start_swe() to launch | |
682 every configured RiViera SWE (SoftWare Entity), which in turns entails creating | |
683 the tasks in which these SWEs are to run. | |
684 | |
685 Dynamic memory allocation | |
686 ========================= | |
687 | |
688 All dynamic memory allocation (i.e., all RAM usage beyond statically allocated | |
689 variables and buffers) is once again done either through RiViera or through GPF, | |
690 and in no other way. Ultimately all areas of the physical RAM that will ever | |
691 be used by the fw in any way are allocated when the fw is compiled and linked: | |
692 the areas from which RiViera and GPF serve their dynamic memory allocations are | |
693 statically allocated as char arrays in the respective C modules and placed in | |
694 the appropriate IRAM or XRAM .bss section by the linker script; RiViera and GPF | |
695 then provide API functions that allocate memory dynamically from these | |
696 statically allocated large pools. | |
697 | |
698 RiViera and GPF have entirely separate memory pools from which they serve their | |
699 respective clients, hence there is no possibility of one affecting the other. | |
700 Riviera's memory allocation scheme is very much like the classic malloc&free: | |
701 there is one large unstructured pool from which all allocations are made, one | |
702 can allocate a chunk of any size, free chunks are merged when physically | |
703 adjacent, and fragmentation is an issue: a memory allocation request may fail | |
704 even when there is enough memory available in total if it is too fragmented. | |
705 | |
706 GPF's dynamic memory allocation facility is considerably more robust: while it | |
707 does maintain one or two (depending on configuration) memory pools of the | |
708 traditional "dynamic" kind (like malloc&free, susceptible to fragmentation), | |
709 most GPF memory allocation works on "partition" memory instead. Here GPF | |
710 maintains 3 separate groups of pools: PRIM, TEST and DMEM; each allocation | |
711 request must specify the appropriate pool group and cannot affect the others. | |
712 Within each pool there is a fixed number of partitions of a fixed size: for | |
713 example, in TI's TCS211 GSM+GPRS configuration the PRIM pool group consists of | |
714 190 partitions of 60 bytes, 110 partitions of 128 bytes, 50 partitions of 632 | |
715 bytes and 7 partitions of 1600 bytes. An allocation request from a given pool | |
716 group (e.g., PRIM) can request any arbitrary size in bytes, but it gets rounded | |
717 up to the nearest partition size and allocated out of the respective pool. If | |
718 no free partition is available, the requesting task is suspended until another | |
719 task frees one. Because these partitions are used primarily for intertask | |
720 communication, if none are free, it can only mean (assuming that the firmware | |
721 functions correctly) that all partitions have been allocated and sent to some | |
722 queue for some task to work on, hence eventually they will get freed. | |
723 | |
724 This scheme implemented in GPF is extremely robust in the opinion of this | |
725 author, and the other purely "dynamic" scheme is used (in the case of GPF) only | |
726 for init-time allocations which are never freed, such as task stacks - hence | |
727 the GPF-based part of the firmware is not suspectible at all to the problem of | |
728 memory fragmentation. But Riviera does suffer from this problem, and the | |
729 concern is more than just theoretical: one major user of Riviera-based dynamic | |
730 memory allocation is the trace facility (described in its own section below), | |
731 and my observation of the trace output from Pirelli's proprietary fw (which | |
732 appears to use the same architecture with separate Riviera and GPF) suggests | |
733 that after the fw has been running for a while, Riviera memory gets fragmented | |
734 to a point where many traces are being dropped. Replacing Riviera's poor | |
735 dynamic memory allocation scheme with a GPF-like partition-based one is a to-do | |
736 item for our project. | |
737 | |
738 Message-based intertask communication | |
739 ===================================== | |
740 | |
741 Even though all entities of the G23M protocol stack are linked together into | |
742 one monolithic fw image and there is nothing to stop them from calling each | |
743 other's functions and accessing each other's variables, they don't work that | |
744 way. Instead all communication between entities is done through messages, just | |
745 as if they ran in separate address spaces or even on separate processors. | |
746 Buffers for this message exchange are allocated from a GPF partition pool: an | |
747 entity that needs to send a message to another entity allocates a buffer of the | |
748 needed size, fills it with the message to be sent, and posts it on the recipient | |
749 entity's message queue, all through GPF services. The other entity simply | |
750 processes the stream of messages that arrives on its message queue, freeing each | |
751 message (returning the buffer to the partition pool it came from) as it is | |
752 processed. | |
753 | |
754 Riviera-based tasks use a similar mechanism: unlike G23M protocol stack | |
755 entities, most Riviera-based functional modules provide APIs that are called as | |
756 functions from other tasks, but these API functions typically allocate a memory | |
757 buffer (through Riviera), fill it with the call parameters, and post it to the | |
758 associated task's message queue (also in the Riviera land) to be worked on. | |
759 Once the worker task gets the job done, it will either call a callback function | |
760 or post a response message back to the requestor - the latter option is only | |
761 possible if the requesting entity is also Riviera-based. | |
762 | |
763 A closer look at GPF | |
764 ==================== | |
765 | |
766 There are certain sublayers within GPF which need to be pointed out. The 3 | |
767 major subdivisions within GPF are: | |
768 | |
769 * The meaty core of GPF: this part is the code under src/gpf/frame in our | |
770 Selenite GPF reconstruction, originating from gpf/FRAME in the TCS3.2 source | |
771 from Peek/FGW. It appears that this part was originally intended to be both | |
772 project-independent (same for GSM, TETRA etc) and OS-independent (same for | |
773 Nucleus, pSOS, VxWorks etc). This is the part of GPF that matters for the | |
774 G23M stack: all APIs called by PS entities are implemented here, and so are | |
775 all other PS-facing functions such as startup. (PS = protocol stack) | |
776 | |
777 * OS adaptation layer (OSL): this is the part of GPF that adapts it to a given | |
778 underlying OS, in our case Nucleus. | |
779 | |
780 * Test interface: see the code under gpf/tst in TCS211 from Openmoko or in | |
781 FC Selenite. This part handles the trace output from all entities that run | |
782 under GPF and the mechanism for sending external debug commands to the GPF+PS | |
783 subsystem. | |
784 | |
785 GPF was a difficult step in our GSM firmware deblobbing process because no | |
786 complete source for it could be found anywhere: apparently GPF was so stable | |
787 and so independent of firmware particulars (Calypso or LoCosto, GSM only or | |
788 GSM+GPRS, modem or complete phone with UI etc) that it appears to have been | |
789 used and distributed as prebuilt binary libraries even inside TI. All TI fw | |
790 (semi-)sources we've got use GPF in prebuilt library form and are not set up to | |
791 recompile any part of it from source. (They had to include all GPF header | |
792 files though, as most of them are included by G23M C modules, and it would be | |
793 too much hassle to figure out which ones are or aren't needed, hence all were | |
794 included.) | |
795 | |
796 Fortunately though, we were able to find the sources for most parts of GPF: | |
797 | |
798 * The LoCosto source in TCS3.2_N5.24_M18_V1.11_M23BTH_PSL1_src.zip features the | |
799 source for the "core" part of GPF under gpf/FRAME - these sources aren't | |
800 actually used by that fw's build system (it only uses the prebuilt binary | |
801 libs for GPF), but they are there. | |
802 | |
803 * Our TCS211 semi-src doesn't have any sources for the core part of GPF, but | |
804 instead it features the source for the test interface and some "misc" parts: | |
805 under gpf/MISC and gpf/tst in that source tree - these sources are not present | |
806 in the LoCosto version from Peek. | |
807 | |
808 The GPF frame, misc and tst sources we have found have been verified to match | |
809 the binary objects that came with TCS211 from OM: they can be compiled into a | |
810 bit-for-bit match. However, one critical piece was still missing: the OS | |
811 adaptation layer. It appears that the GPF core (vsi_??? modules) and OSL | |
812 (os_??? modules) were maintained and built together, ending up together in | |
813 frame_<blah>.lib files in the binary form used to build firmwares, but the | |
814 source for the "frame" part in the Peek find contained only vsi_*.c and others, | |
815 but not any of os_*.c. | |
816 | |
817 Our FC Magnetite firmware uses the original binary libs from TCS211-Openmoko | |
818 for its GPF component, but for FC Selenite the project requirement is to be | |
819 completely blob-free, hence we had to reconstruct the source for the OSL part | |
820 of GPF from disassembly. This work was originally done in 2014 in the context | |
821 of our first attempt at gcc-built blob-free GSM fw (FC Citrine, now deemed to | |
822 be a dead end and fully retired); this reconstruction was then dug up and | |
823 adapted for Selenite in 2018. As of this writing, this reconstruction is still | |
824 not 100% complete (one complex error handling function is stubbed out) and not | |
825 yet trusted to be fully correct, thus our fully deblobbed Selenite firmware is | |
826 currently considered experimental; our current production fw is still Magnetite | |
827 with blobs for GPF. | |
828 | |
829 A closer look at L1 | |
830 =================== | |
831 | |
832 The L1 code is remarkable in how little intertie it has with the rest of the | |
833 firmware it is linked into. It is almost entirely self-contained, expecting | |
834 only 4 functions to be provided by the underlying OS environment: | |
835 | |
836 os_alloc_sig -- allocate message buffer | |
837 os_free_sig -- free message buffer | |
838 os_send_sig -- send message to upper layers | |
839 os_receive_sig -- receive message from upper layers | |
840 | |
841 It helps to remember that at the beginning of TI's involvement in the GSM | |
842 baseband chipset business, L1 was the only thing they "owned", while Condat, | |
843 the maintainers of the higher level protocol stack, was a separate company. | |
844 TI's "turnkey" solution must have consisted of their own L1 code plus G23M code | |
845 (including GPF etc) licensed from Condat, but I'm guessing that TI probably | |
846 wanted to retain the ability to sell their chips with their L1 without being | |
847 entangled by Condat: let the customer use their own GSM L23 stack, or perhaps | |
848 work out their own independent licensing arrangements with Condat. I'm | |
849 guessing that L1 was maintained as its own highly independent and at least | |
850 conceptually portable entity for these reasons. | |
851 | |
852 The way in which L1 is intertied into the rest of the fw is the same in all TI | |
853 production firmwares we have seen, including both our TCS211 reference and the | |
854 TCS3.2 LoCosto version. There is a module called OSX, which is an extremely | |
855 thin adaptation layer that implements the APIs expected by L1 in terms of GPF. | |
856 Furthermore, this OSX layer provides header file isolation: the only "outside" | |
857 (non-L1) header included by L1 is cust_os.h, and it defines the necessary | |
858 interface to OSX *without* including any other headers (no GPF headers in | |
859 particular), using only the C language's native types. Apart from this | |
860 cust_os.h header, the entire OSX layer is implemented in one C module (osx.c, | |
861 which we had to reconstruct from osx.obj as the source was missing - but it's | |
862 very simple) which does include some GPF headers and implements the OSX API in | |
863 terms of GPF services. Thus in both TI's production firmwares and our own ones, | |
864 L1 does sit on top of GPF, but very indirectly. | |
865 | |
866 More specifically, the "production" version of OSX implements its API in terms | |
867 of *high-level* GPF functions, i.e., VSI. However, they also had an interesting | |
868 OP_L1_STANDALONE configuration which omitted not only all of G23M, but also the | |
869 core of GPF and possibly the Riviera environment as well. We don't have a way | |
870 to recreate this configuration exactly as it existed inside TI because we don't | |
871 have the source bits specific to this configuration, but we do have a little | |
872 bit of insight into how it worked. | |
873 | |
874 It appears that TI's OP_L1_STANDALONE build used a special "gutted" version of | |
875 GPF in which the "meaty core" (VSI etc) was removed. The OS layer (os_??? | |
876 modules implementing os_*() functions) that interfaces to Nucleus was kept, and | |
877 so was OSX used by L1 - but this time the OSX API functions were implemented in | |
878 terms of os_*() ones (low-level wrappers around Nucleus) instead of the higher- | |
879 level VSI APIs provided by the "meaty core" of GPF. It is purely a guess on my | |
880 part, but perhaps this hack was also done in the days before TI's acquisition | |
881 of Condat, and by omitting the "meaty core" of GPF, TI could claim that their | |
882 OP_L1_STANDALONE configuration did not contain any of Condat's "intellectual | |
883 property". | |
884 | |
885 Run-time structure of L1 | |
886 ======================== | |
887 | |
888 L1 consists of two major parts: L1S and L1A. L1S is the synchronous part where | |
889 the most time-critical functions are performed; it runs as a Nucleus HISR. The | |
890 hardware in the Calypso generates an interrupt on every TDMA frame (4.615 ms, | |
891 or more precisely 60/13 ms), and the LISR handler for this interrupt triggers | |
892 the L1S HISR. L1S communicates with L1A through a shared memory data structure, | |
893 and also sometimes allocates message buffers and posts them to L1A's incoming | |
894 message queue (both via OSX API functions, i.e., via GPF in disguise). | |
895 | |
896 L1A runs as a regular task under Nucleus, and includes a blocking call (to GPF | |
897 via OSX) to wait for incoming messages on its queue. It is one big loop that | |
898 waits for incoming messages, then processes each received message and commands | |
899 L1S to do most of the work. The entry point to L1A in the L1 code proper is | |
900 l1a_task(), although the responsibility for running it as a task falls on some | |
901 "glue" code outside of L1 proper. TI's production firmwares with G23M included | |
902 have an L1 protocol stack entity within G23M whose only job (aside from some | |
903 initialization) is to run l1a_task() in the Nucleus task created by GPF for | |
904 that protocol stack entity; we do the same in our firmwares. | |
905 | |
906 Communication between L1 and G23M | |
907 ================================= | |
908 | |
909 It is remarkable that L1 and G23M don't have any header files in common: L1 | |
910 uses its own (almost fully self-contained), whereas the G23M+GPF realm is its | |
911 own world with its own header files. One has to ask then: how do they | |
912 communicate? OK, we know they communicate through primitives (messages in | |
913 buffers allocated from GPF's PRIM partition memory pool) passed via message | |
914 queues, but what about the data structures in these messages? Where are those | |
915 defined if there are no header files in common between L1 and G23M? | |
916 | |
917 The answer is that there are separate definitions of the L1<->G23M interface on | |
918 each side, and TI must have kept them in sync manually. Not exactly a | |
919 recommended programming or software maintenance practice for sure, but TI took | |
920 care of it, and the existing proprietary products based on TI's firmware are | |
921 rock solid, so it is not really our place to complain. | |
922 | |
923 TI's firmwares from the era we are working with (both our TCS211 golden | |
924 reference and the TCS3.2/LoCosto source from which we took the newer full-source | |
925 version of G23M for our TCS2/TCS3 hybrid) also include a component called ALR. | |
926 It resides in the G23M code realm: G23M coding style, uses Condat header files, | |
927 runs as its own protocol stack entity under GPF. This component appears to | |
928 serve as a glue layer between the rest of the G23M stack (which is supposed to | |
929 be truly hardware-independent) and TI's L1. | |
930 | |
931 Speaking of ALR, it is worth mentioning that there is a little naming | |
932 inconsistency here. ALR is known to the connect-by-name logic in GPF as "PL" | |
933 (physical layer, apparently), while the ACI entity (Application Control | |
934 Interface, the top level entity) is known to the same logic as "MMI". No big | |
935 deal really, but hopefully knowing this quirk will save someone some confusion. | |
936 | |
937 A closer look at our FreeCalypso TCS2/TCS3 hybrid | |
938 ================================================= | |
939 | |
940 Because we don't have an official TI firmware release for the Calypso in full | |
941 source form and because I am not willing to throw away all of our Calypso work | |
942 and restart anew with LoCosto with its own host of unknowns, the only currently | |
943 available way for us to have blob-free production-quality GSM mobile station fw | |
944 is the TCS2/TCS3 hybrid implemented in FC Magnetite and Selenite. This hybrid | |
945 is made by taking the G23M version from TCS3/LoCosto and grafting it onto the | |
946 chipsetsw foundation from TCS211, including the original TCS211/Calypso version | |
947 of L1 which we have meticulously source-reconstructed. The version of GPF used | |
948 for this hybrid is also the TCS211 version in Magnetite or our source | |
949 reconstruction thereof in Selenite. | |
950 | |
951 The Condat G23M pieces have been hybridized as follows: | |
952 | |
953 * cdginc generated header files are a special hybrid version described below; | |
954 | |
955 * The include files under condat/com/inc and condat/com/include are the TCS3 | |
956 version, except for pwr.h and rtc.h for which we use the TCS2 version; | |
957 | |
958 * comlib is the TCS2 version, except for cl_rlcmac.c which is from TCS3; | |
959 | |
960 * config modules (condat/com/src/config and condat/frame/config) are the TCS2 | |
961 version, with some fixes for the needs of the TCS3 version of G23M PS and our | |
962 own FreeCalypso fixes; | |
963 | |
964 * Condat drivers (condat/com/src/driver) are the TCS2 version; | |
965 | |
966 * All G23M PS components are the TCS3 version by necessity, as this is the part | |
967 for which the source is missing in our TCS211 version, with the exception of | |
968 ALR - the original source for the TCS211 version of ALR has miraculously | |
969 survived, the ALR source in TCS211 from OM can be compiled into a perfect | |
970 match for the binary lib version; | |
971 | |
972 * We use the TCS2 version of ALR (the interface to our TCS211 L1) and not the | |
973 TCS3 version (a change from Citrine), but it is compiled with the same hybrid | |
974 cdginc headers as the rest of hybrid G23M, not the old TCS211 ones; | |
975 | |
976 * ACI is the TCS3 version - we have the source for both versions, but trying to | |
977 use the old TCS2 version of ACI on top of the new TCS3 version of the PS | |
978 would cause untold breakage; | |
979 | |
980 * The UI layers (MFW and BMI) for handset fw builds are handled like ACI: we | |
981 have the source for both versions, but we use the TCS3 version which works | |
982 with the TCS3 versions of ACI and cdginc; | |
983 | |
984 * The CST (Customer Specific Task) component is the TCS2 version - while it | |
985 logically belongs in the Condat realm, the code lives in the chipsetsw realm | |
986 under chipsetsw/services/cst (yes, it's under services with SSA stuff even | |
987 though it doesn't use RiViera) and thus our copy of TCS211 from OM has this | |
988 source preserved. | |
989 | |
990 With this hybrid arrangement the main splice point lies above ALR, and there | |
991 are many little splice points throughout the code where some upper-level code | |
992 from TCS3 needs to talk to lower-level code from TCS2. There are no inversions, | |
993 i.e., no places where TCS2 code sits on top of code from TCS3, although there | |
994 are a few instances where TCS2 C code uses some TCS3 header files. | |
995 | |
996 TCS3 feature flags | |
997 ------------------ | |
998 | |
999 Our TCS3.2/LoCosto code from Peek/FGW from 20090327 supports several new GSM | |
1000 features (apparently related to GSM release 99) which are not supported by our | |
1001 TCS211-20070608 golden reference from OM. All of these new features can be | |
1002 enabled or disabled with conditional compilation flags. Our TCS2/TCS3 hybrid | |
1003 currently has all of these new features disabled: it was too difficult for me | |
1004 to figure out if these new features require some support from the hardware or | |
1005 the DSP which is present on LoCosto but not Calypso, and even if our hw and DSP | |
1006 have all of the necessary capabilities, at least some of the new features | |
1007 require adding some code to L1, which is incompatible with my approach of | |
1008 reconstructing TCS211 L1 pristinely. | |
1009 | |
1010 In any case, the GSM functionality we get by using the new version of G23M with | |
1011 new feature flags disabled on top of pristine TCS211 L1 cannot be any worse | |
1012 than what we would have had if we had the full corresponding source for our | |
1013 TCS211-20070608 golden reference, and it is probably a little better because we | |
1014 are using a newer version of G23M code. | |
1015 | |
1016 cdginc headers | |
1017 -------------- | |
1018 | |
1019 Much of the code in the Condat G23M realm makes heavy use of a set of machine- | |
1020 generated C header files called cdginc. These header files contain various | |
1021 definitions related both to the GSM air protocols being implemented and to G23M | |
1022 protocol stack internals (interfaces and message structures between components), | |
1023 and they are generated from a set of message definition files (*.mdf) and | |
1024 primitive definition files (*.pdf) by a tool called ccdgen. The *.{mdf,pdf} | |
1025 inputs to ccdgen are human-readable ASCII, and of course the generated C header | |
1026 files are human-readable too, but we have no source for the ccdgen tool itself, | |
1027 only a Windows binary which we can run under Wine. | |
1028 | |
1029 The ccdgen binary problem is yet another instance of so far incomplete | |
1030 liberation of the GSM firmware. It is currently a very low-priority problem: | |
1031 we do not casually edit any of the *.{mdf,pdf} inputs to ccdgen, and we don't | |
1032 run ccdgen on every fw build - instead we have run ccdgen once and checked its | |
1033 output files (generated C headers) into our Magnetite and Selenite trees as if | |
1034 they were sources. If we are not able to convince TI to dig up and release the | |
1035 source for ccdgen, there is a viable albeit costly alternative: hire a Windows | |
1036 reverser to RE the ccdgen.exe binary (262144 bytes) and produce a C | |
1037 reimplementation that replicates all of its logic. It is a Win32 console app, | |
1038 no GUI, and it is a pure data processing application without any hardware access | |
1039 or OS functions or any other muckery: it is probably pure ANSI C code that reads | |
1040 and parses a bunch of ASCII input files, performs some business logic on the | |
1041 data, and writes another bunch of ASCII text files as outputs. It is currently | |
1042 a very low-priority task though; reversing the Calypso DSP ROM code should | |
1043 probably be a higher priority. | |
1044 | |
1045 The set of cdginc headers for our TCS2/TCS3 hybrid has been generated as | |
1046 follows: | |
1047 | |
1048 * All of the *.mdf files are the TCS3 version; | |
1049 | |
1050 * All of the *.pdf files except mphc.pdf and mphp.pdf are also the TCS3 version; | |
1051 | |
1052 * mphc.pdf and mphp.pdf are the TCS211 version - this is the interface to | |
1053 TCS211 L1; | |
1054 | |
1055 * All new feature flags (see discussion above) are set to disabled. | |
1056 | |
1057 Condat Coder and Decoder (CCD) | |
1058 ------------------------------ | |
1059 | |
1060 CCD is a firmware component in the Condat G23M realm which I haven't really | |
1061 studied yet. It consists of two parts: | |
1062 | |
1063 * A fixed portion which TI used to distribute in binary form and which various | |
1064 firmware projects used as a prebuilt library like GPF - technically TI | |
1065 considered it to be a part of GPF, although we prefer to treat it as its own | |
1066 more independent entity; | |
1067 | |
1068 * The ccddata portion which needs to be compiled with cdginc headers for each | |
1069 given project. | |
1070 | |
1071 We got the source for both parts of CCD only in the TCS3.2/LoCosto version, but | |
1072 not in the TCS211 version, hence the decision was easy: we use the TCS3 version | |
1073 of CCD (both parts) with the TCS3 version of cdginc with the TCS3 version of | |
1074 the G23M PS. | |
1075 | |
1076 TCS3.2 GPF discrepancy | |
1077 ---------------------- | |
1078 | |
1079 A careful examination of the prebuilt GPF libraries under gpf/LIB in the TCS3.2 | |
1080 LoCosto source tree has revealed that a few of the binary objects exhibit some | |
1081 differences from the TCS211 version which we've been treating as our golden | |
1082 reference: | |
1083 | |
1084 * The os_mis module (OSL miscellany) in the IRAM library implements a new | |
1085 function called os_CheckQueueEvent() and defines a new global data object | |
1086 named my_os_mis_Protect; | |
1087 | |
1088 * The os_tim module (OSL timer code) in the flash (XIP) library has some code | |
1089 differences; | |
1090 | |
1091 * The vsi_tim module (VSI timer code) in the flash (XIP) library has some code | |
1092 differences; | |
1093 | |
1094 * The vsi_tim module (VSI timer code) in the IRAM library has some code | |
1095 differences and makes use of the new os_CheckQueueEvent() function. | |
1096 | |
1097 In the case of os_??? modules we have no corresponding source for either | |
1098 version, but the vsi_tim difference is more bizarre: we got our vsi_tim.c source | |
1099 (and the rest of vsi_*.c) from the TCS3.2/LoCosto source, but this source | |
1100 matches the TCS211 binary version and not the newer and different binary version | |
1101 used by the TCS3.2 build system! (Remember that none of TI's firmware build | |
1102 systems that we have seen are set up to recompile any part of GPF from source, | |
1103 they used it only as prebuilt libraries.) | |
1104 | |
1105 Because we have the corresponding source for the "old" version of GPF frame core | |
1106 but not for the "new" version, we are continuing to treat the "old" TCS211 | |
1107 version as our golden reference: we use the source pieces which we got, and we | |
1108 use the "old" os_???.obj blobs as our basis for reconstruction via disassembly. | |
1109 | |
1110 Because the changes in the TCS3.2 binary version of GPF involve only the | |
1111 implementation of a part of VSI but not its API (there are no changes to any | |
1112 part of the GPF API presented to the G23M PS that I can see anywhere), I have | |
1113 every good reason to believe that there is no problem with using the new TCS3.2 | |
1114 version of G23M with the old version of GPF from TCS211: it should work no worse | |
1115 than pure TCS211. | |
1116 | |
1117 It should also be noted that if we ever succeed in getting some more complete | |
1118 GPF source out of TI (including the source for the OS adaptation layer which is | |
1119 difficult to reconstruct), thanks to the great stability and independence of | |
1120 GPF, we will be happy with *any* version, does not need to match either TCS211 | |
1121 or TCS3.2. | |
1122 | |
1123 GPRS implementation differences | |
1124 ------------------------------- | |
1125 | |
1126 There is a visible difference between the way GPRS is implemented in the old | |
1127 TCS211-20070608 blob version of G23M and the way it is implemented in the newer | |
1128 TCS3.2/LoCosto version we are using for our hybrid. The new implementation adds | |
1129 a new protocol stack entity named UPM (User Plane Manager), and the pre-existing | |
1130 SM and SNDCP entities have been significantly changed to work with this UPM. | |
1131 Because we are using the GPRS config modules (condat/frame/config) from TCS211, | |
1132 we had to add a -DFF_UPM compilation flag to include UPM in the GPF | |
1133 configuration for the GSM+GPRS protocol stack. | |
1134 | |
1135 A closer look at ACI | |
1136 ==================== | |
1137 | |
1138 The Application Control Interface (ACI) is the crown that sits on top of the | |
1139 G23M protocol stack. It includes the AT command interpreter (ATI) component, | |
1140 and this AT command interface is brought to the outside world via the UART | |
1141 protocol stack entity. The UART entity implements the GSM 07.10 MUX, can | |
1142 operate the physical UART in either multiplexed or non-multiplexed mode (the | |
1143 latter is the default on boot for a plain ASCII AT command interface) as | |
1144 commanded by ACI, and establishes 1 to 4 logical channels carrying AT commands | |
1145 to ACI. When a CSD or fax call or a GPRS PPP session is in progress, the data | |
1146 path is switched to run between the UART entity and the appropriate GSM or GPRS | |
1147 protocol stack destination. In the case of modem products that are designed to | |
1148 be controlled by an external host via AT commands, this combination of ACI and | |
1149 UART entities provides the ultimate end function of the device. | |
1150 | |
1151 The set of implemented AT commands is defined in ati_cmd.c: this is the C file | |
1152 where new AT commands get added; there is also an enum of command IDs in | |
1153 aci_cmh.h which needs to be extended. For every AT command listed in the table | |
1154 in ati_cmd.c there is a handler function: for example, for the AT+CFUN command | |
1155 there is a setatPlusCFUN() function that handles setting and a queatPlusCFUN() | |
1156 function that handles querying. For some simple AT commands like AT+CGxx | |
1157 queries the function listed in ati_cmd.c does the entirety of the work, but for | |
1158 most of the interesting GSM commands (including the AT+CFUN example just used) | |
1159 the set and query functions implemented in the ATI layer only handle the parsing | |
1160 of ASCII arguments and generation of ASCII output (if any), whereas the actual | |
1161 command implementation happens in the CMH layer below. | |
1162 | |
1163 Below ATI but still within ACI lies the sublayer of command handlers (CMH). | |
1164 For each AT command that does something to the GSM mobile station there is a | |
1165 functional equivalent, a C function that performs the same operation as the | |
1166 spec-defined AT command, but is designed to be used natively from C code, | |
1167 without AT command string parsing or output formatting. For the AT+CFUN example | |
1168 used above, the setatPlusCFUN() ATI function parses the arguments from ASCII | |
1169 and then calls sAT_PlusCFUN() to perform the actual operation, whereas the | |
1170 queatPlusCFUN() ATI function calls qAT_PlusCFUN() to retrieve the current state | |
1171 and then prints it out in ASCII. This functional interface is used by TI's | |
1172 demo/prototype phone UI implementation described in the Handset-UI-fw companion | |
1173 document. | |
1174 | |
1175 Finally, at the bottom of ACI lies the sublayer of Protocol Stack Adapters | |
1176 (PSA): these are pieces of code that execute within the ACI task and exchange | |
1177 primitives with various G23M protocol stack entities below. | |
1178 | |
1179 We have the source for both TCS2 and TCS3 versions of ACI. The TCS2 version is | |
1180 from Openmoko, containing OM's modifications, and we had to go through these | |
1181 changes and additions by OM, reject the bogus ones and reimplement the sensible | |
1182 ones in the new TCS3 version of ACI for our TCS2/TCS3 hybrid going forward. | |
1183 | |
1184 Flash file system | |
1185 ================= | |
1186 | |
1187 Every GSM device that is based on TI's firmware architecture contains not only | |
1188 the firmware image proper, but also a flash file system that is separate from | |
1189 the fw image and is maintained in a different part of the flash chip. The FFS | |
1190 implementation code is a mandatory part of the firmware; in TCS211 it resides | |
1191 in chipsetsw/drivers/drv_app/ffs and logically belongs to the SSA realm. This | |
1192 code initializes early in the fw boot process in the Application_Initialize() | |
1193 context before the start of Nucleus task scheduling; the responsible function | |
1194 is ffs_main_init() called from Init_Drivers(). | |
1195 | |
1196 Flash driver support and FFS location | |
1197 ------------------------------------- | |
1198 | |
1199 Determining the location of the flash area allocated for FFS and the flash | |
1200 driver to be used to write to it is a combination of autodetection and hard- | |
1201 coding. The approach implemented in the original TCS211 code is as follows: | |
1202 there is a piece of autodetection code that reads the flash chip ID, and the | |
1203 autodetected ID is then looked up in a hard-coded table that gives the driver | |
1204 and geometry details and the location of the FFS sectors for each supported | |
1205 flash chip type. However, this approach has its limitations: | |
1206 | |
1207 * The sequence of write operations which TI's autodetection code issues in | |
1208 order to put the flash chip into its Read ID mode worked for older flash | |
1209 chips that were used by TI and Openmoko, but does not work for the newer | |
1210 Spansion S71PL129NC0HFW4B flash chip which we (FreeCalypso) have copied from | |
1211 the Pirelli DP-L10 phone. | |
1212 | |
1213 * While the physical flash chip used on a given phone or modem board is a | |
1214 physical property that can be autodetected, the choice of which flash sectors | |
1215 should be used for FFS is a matter of policy. Before we built our own | |
1216 FreeCalypso hardware, we had to run our fw on some pre-existing "alien" hw | |
1217 targets, and we still support such usage to a limited extent. When we run | |
1218 our FreeCalypso fw on an alien hw target as an aftermarket deal, our | |
1219 aftermarket FFS location needs to be chosen quite carefully. | |
1220 | |
1221 * Some flash chips have two chip select banks, and with such chips it is | |
1222 generally desirable to put the FFS in the second bank. However, it is a | |
1223 matter of board wiring whether that second flash chip select is connected to | |
1224 Calypso chip select nCS2, nCS3 or nCS4 - thus FFS addresses in the second bank | |
1225 have to be hard-coded with conditional compilation per board type and cannot | |
1226 be autodetected. | |
1227 | |
1228 To support our new repertoire of possible hardware targets, the logic has been | |
1229 changed as follows in our Magnetite and Selenite firmwares: | |
1230 | |
1231 * When the target is our own FC hardware family (CONFIG_TARGET_FCFAM) or the | |
1232 Pirelli DP-L10 phone (CONFIG_TARGET_PIRELLI), flash chip type autodetection | |
1233 is disabled and a strictly fixed hard-coded FFS configuration is used; | |
1234 | |
1235 * When the target is one of Mot C1xx subfamilies, the autodetection logic is | |
1236 kept (several different flash chip types are found in these phones), but a | |
1237 different table is used, giving our aftermarket FFS configurations for these | |
1238 Mot C1xx flash chip types; | |
1239 | |
1240 * When the target is gtamodem (Openmoko GTA01/02 modem) or dsample (TI's | |
1241 D-Sample board), we use the original autodetection logic and device table | |
1242 which we got from TI/Openmoko. | |
1243 | |
1244 We have also changed the AMD multibank flash driver to issue write commands in | |
1245 a way that is compatible with our new S71PL129NC0HFW4B chip. | |
1246 | |
1247 FFS life cycle | |
1248 -------------- | |
1249 | |
1250 In products that have been built according to TI's original way, including | |
1251 Openmoko GTA01/02 and our own FreeCalypso devices, the FFS is formatted and | |
1252 initialized with some essential content at the time of device manufacture, and | |
1253 this factory-created and factory-initialized FFS then persists for the lifetime | |
1254 of the device. In our factory environment at FreeCalypso hardware manufacturing | |
1255 we initialize the flash on our freshly assembled boards like this: | |
1256 | |
1257 flash erase 0 0x800000 | |
1258 flash program-bin 0 fwimage.bin | |
1259 flash2 erase 0 0x800000 | |
1260 | |
1261 This factory procedure (which should ONLY be executed at the factory and never | |
1262 by any end users or even sw/fw developers and tinkerers) ensures that the flash | |
1263 is completely blank everywhere except the fw image loaded at the time of | |
1264 production, and when this fw image boots for the first time, it will see blank | |
1265 flash in the FFS sectors. When TI's FFS code in ffs_main_init() sees this | |
1266 condition, it performs what TI called a preformat: it writes a basic FFS block | |
1267 header into each FFS sector, but does not automatically perform a full format - | |
1268 instead the latter needs to be commanded explicitly by the production station | |
1269 via one of TMFFS command packet protocols as described later in this article. | |
1270 In FreeCalypso we have adopted TMFFS2 as our choice of Test Mode FFS access | |
1271 protocol, our host side implementation of this protocol is fc-fsio, and we | |
1272 format and initialize the FFS on our devices with an fc-fsio command script as | |
1273 part of our factory procedure. | |
1274 | |
1275 FFS content and usage | |
1276 --------------------- | |
1277 | |
1278 TI's firmware architecture uses the FFS for many purposes: | |
1279 | |
1280 * The IMEI is stored in the FFS - GSMA can proclaim all they want that it | |
1281 "MUST" be stored in some kind of super-secure one-time programmable fuses, | |
1282 but in TI's architecture and in FreeCalypso it is just a regular file in the | |
1283 FFS. | |
1284 | |
1285 * A number of RF calibration tables are stored in FFS and read by the RF code | |
1286 in L1. If you have a Rohde&Schwarz CMU200 instrument which is itself in good | |
1287 repair and calibration standing and a metrology-grade RF cabling setup whose | |
1288 insertion loss at the relevant GSM frequencies is precisely known, creating | |
1289 or recreating these RF calibration values is as simple as executing one shell | |
1290 script that takes a few minutes to run - this is how we do it at FreeCalypso | |
1291 hw manufacturing - but if you are an ordinary user or sw/fw developer or | |
1292 tinkerer without a professional calibration station setup, you need to use | |
1293 the RF calibration values that have been written into the FFS by the device | |
1294 manufacturer. These RF calibration tables live under /gsm/rf. | |
1295 | |
1296 * /gsm/com/rfcap tells the RR component in the G23M protocol stack (not L1!) | |
1297 which frequency bands are supported on a given device - on our devices it is | |
1298 a factory-programmed file distinguishing between tri900 and tri850 units and | |
1299 telling the firmware which bands it should scan for possible GSM cells. | |
1300 | |
1301 * Manufacturer, model and revision ID strings may be written into /pcm/CGMI, | |
1302 /pcm/CGMM and /pcm/CGMR, respectively, to be returned by the corresponding | |
1303 AT+CGxx query commands. | |
1304 | |
1305 * The G23M protocol stack writes a number of dynamically updated files under | |
1306 the /gsm hierarchy and under /pcm. | |
1307 | |
1308 * TI's demo/prototype UI code (see Handset-UI-fw companion document) writes its | |
1309 persistent state in files under /mmi. | |
1310 | |
1311 * Audio mode configuration files are kept under /aud - see the Audio-mode-config | |
1312 article in freecalypso-tools. | |
1313 | |
1314 * If a given product uses the Melody E1 mechanism, melody files to be played | |
1315 through the RiViera Audio Service are kept in FFS - see the Melody_E1 article | |
1316 in freecalypso-tools. | |
1317 | |
1318 Building firmware for different targets | |
1319 ======================================= | |
1320 | |
1321 TI's TCS3.2 firmware for their LoCosto chipset which was rejected by the Mother | |
1322 for reasons described near the beginning of this article makes a complete break | |
1323 from the past and has no possibility of supporting any pre-LoCosto chips such | |
1324 as our beloved Calypso, but TI's previous evolutionary developments weren't so | |
1325 drastic: the evolution to Calypso from previous chips such as Hercules and | |
1326 Ulysse was smoother, and our reference TCS211 fw is littered with C preprocessor | |
1327 conditionals supporting TI's earlier development boards prior to D-Sample and | |
1328 DBB chips prior to Calypso. | |
1329 | |
1330 TI's configuration management architecture supported only TI's own development | |
1331 boards and not any of the end product boards: unfortunately they did not follow | |
1332 a development model like the Linux kernel where everyone is encouraged to | |
1333 contribute their custom board support bits upstream and the mainline kernel | |
1334 strives to support every hw target that was ever supported with a single source | |
1335 tree, instead it was the divergent model where every end device manufacturer | |
1336 would take TI's reference firmware source and hack it for their specific needs | |
1337 with no concern for upstreamability or support for targets or applications | |
1338 other than their own. TI's firmware build configuration model defined the | |
1339 following C preprocessor symbols relating to support for different hw targets, | |
1340 all numeric, i.e., each symbol is always defined to a number: | |
1341 | |
1342 BOARD identifies which board is to be targeted, with numbers assigned for | |
1343 different development boards made by various TI groups, but generally not for | |
1344 customer boards. The only Calypso-based BOARD number is 41, originally | |
1345 assigned for the D-Sample but then also reused for the Leonardo; all other | |
1346 BOARD numbers are for some other chipsets that aren't Calypso. The previous | |
1347 board before D-Sample was C-Sample, which is BOARD 9, but I am not sure exactly | |
1348 what chipset it had - perhaps it was Ulysse/Nausica/Clara. There is still | |
1349 plenty of support for BOARD 9 and even earlier boards in the firmware source we | |
1350 got. | |
1351 | |
1352 CHIPSET identifies the main DBB chip. The interesting numbers are 7 for the | |
1353 very original Calypso C05 rev A, 8 for Calypso C05 rev B (found on the D-Sample | |
1354 board which the Mother scored in 2015), 10 for Calypso C035 (the Calypso silicon | |
1355 version we work with in FreeCalypso), 11 for Calypso Lite (same as the regular | |
1356 Calypso except for smaller IRAM), 12 for Calypso+ (a short-lived intermediate | |
1357 step between Calypso and LoCosto) and 15 for LoCosto. | |
1358 | |
1359 ANLG_FAM (previously ANALOG) identifies the ABB chip. The numbers are 1 for | |
1360 Nausica, 2 for Iota (what we use) and 3 for Syren (typically used with Calypso+ | |
1361 like on the E-Sample board). | |
1362 | |
1363 RF_FAM (previously just RF) identifies the RF hardware hooked up to the baseband | |
1364 chipset. The interesting numbers are 10 for Clara (D-Sample) and 12 for Rita, | |
1365 the latter being the only RF chip for which we have driver support. | |
1366 | |
1367 Naturally any code that cares about DBB register differences would use the | |
1368 CHIPSET definition, ABB support code would use ANLG_FAM, RF support code would | |
1369 use RF_FAM, and finally code that needs to know about board-level peripherals | |
1370 like LCDs and keypads would use the BOARD symbol. This model worked fine up to | |
1371 D-Sample: for example, the code for C-Sample vs. D-Sample LCDs and keypads is | |
1372 cleanly conditionalized on BOARD 9 vs. BOARD 41. However, the waters got badly | |
1373 muddied when TI introduced their Leonardo board and instead of giving it its | |
1374 own BOARD number, reused BOARD number 41 from D-Sample. | |
1375 | |
1376 D-Sample was TI's primary internal development platform for the Calypso, | |
1377 featuring Iota for the ABB and Clara for the RF part. It was a great solid | |
1378 platform in every way except the RF part: the old Clara RF is inconvenient | |
1379 (needs more external parts) and TI were marketing their newer Rita RF to real | |
1380 end device manufacturers, but the D-Sample still worked great for development: | |
1381 if you aren't working specifically on the RF part, it doesn't matter as long as | |
1382 you have a working driver for it, which we lack. Then TI made another Calypso | |
1383 development board called Leonardo, featuring the same Calypso+Iota baseband | |
1384 plus the newer Rita RF. But this Leonardo never fully replaced the D-Sample | |
1385 for any of the high-level development in the SSA and UI groups. | |
1386 | |
1387 Openmoko's modem is a direct derivative of the Leonardo, the only change being | |
1388 the RFFE (for some reason FIC didn't like TI's quadband RFFE as implemented on | |
1389 Leonardo and E-Sample boards and used their own slightly hobbled triband RFFE | |
1390 instead), and the firmware build given to OM was TI's Leonardo fw with just a | |
1391 few tweaks in tpudrv12.h to account for the RFFE control signal differences. | |
1392 However, because Leonardo never got its own BOARD number and the BOARD symbol | |
1393 is still set to 41, all of the SSA/UI code (LCD, keypad, battery charging etc) | |
1394 is still built as if for D-Sample - but none of that code is used on a pure AT | |
1395 command modem without UI functions or UI hardware, hence OM probably never | |
1396 noticed anything odd. | |
1397 | |
1398 And it wasn't just Openmoko - it appears that TI used their Leonardo boards | |
1399 mostly or perhaps even solely in the ACI configuration without UI layers | |
1400 (MMI=0 build configuration), while all or most UI development was done on | |
1401 D-Sample kits. Their TCS211 reference fw product officially supported both | |
1402 D-Sample and Leonardo targets in both ACI and BMI+MFW configurations, but if | |
1403 one were to build a high-end UI-enabled config for the Leonardo like pdt_2272, | |
1404 it would target a 176x220 pixel color LCD, the LCD output driver would be the | |
1405 one for the D-Sample (expecting memory-mapped LCD registers on nCS3), and the | |
1406 keypad driver would expect D-Sample keypad wiring. Looking at the available | |
1407 Leonardo schematics I see a serial (uWire) LCD interface instead and a more | |
1408 basic keypad with different wiring, so I don't see how those Leonardo+UI | |
1409 firmware builds could possibly work. Perhaps some other group at TI did some | |
1410 UI work on Leonardo boards, but never made it into the internal mainline | |
1411 from which TCS211 releases were cut - who knows... | |
1412 | |
1413 Finally, aside from the basic failure to distinguish properly between D-Sample | |
1414 and Leonardo boards, this whole BOARD number system provides absolutely no | |
1415 mechanism to distinguish between TI's development boards and end product boards | |
1416 derived from them, or between end product boards of vendor A vs. vendor B, or | |
1417 between end product model A and model B from the same vendor - it's always | |
1418 BOARD 41 as far as TI's code is concerned. When TI had to modify their code | |
1419 for OM to support FIC's different TSPACT signal wiring, they just edited the | |
1420 definitions in tpudrv12.h without any conditionals, so one couldn't build | |
1421 binaries for the original Leonardo vs. OM's hardware from the same source tree | |
1422 in different configs. | |
1423 | |
1424 The build system of TCS211 produces a set of generated C header files named | |
1425 *.cfg (instead of the more natural *.h); these generated config headers define | |
1426 all of the C preprocessor symbols listed above and many more. They are included | |
1427 sometimes as #include "board.cfg" and othertimes as #include "config/board.cfg" | |
1428 (ditto for other *.cfg), thus the list of -I directories passed by the build | |
1429 system on compiler invocation lines needs to include both the config directory | |
1430 and its parent. In our Magnetite and Selenite build systems we likewise | |
1431 generate these *.cfg headers; some of the symbols defined therein are variable | |
1432 and originate from Bourne shell variables in our own configuration system, but | |
1433 many others are fixed. See scripts/cfg-template in our Magnetite and Selenite | |
1434 trees for the magic. | |
1435 | |
1436 The BOARD symbol is always fixed at 41 in all FreeCalypso firmwares, | |
1437 corresponding to TI's D-Sample and Leonardo, and we use our own different | |
1438 mechanism to distinguish among our supported targets. The solution adopted in | |
1439 Magnetite and Selenite is as follows: we are supplementing TI's *.cfg files | |
1440 with our own fc-target.cfg (included as #include "fc-target.cfg" or as | |
1441 #include "config/fc-target.cfg" matching whatever existing TI code we are | |
1442 gently extending), and this fc-target.cfg header is populated by the build | |
1443 system by copying the appropriate targets/*.h header file. These targets/*.h | |
1444 header snippets define C preprocessor symbols of our own invention like | |
1445 CONFIG_TARGET_xxx, and whenever we need to know our target in C code, we | |
1446 #include "fc-target.cfg" and use #ifdef logic based on these preprocessor | |
1447 symbols of our own addition. | |
1448 | |
1449 RVTMUX debug and development interface | |
1450 ====================================== | |
1451 | |
1452 The Calypso chip has two UARTs, and TI's TCS211 firmware and its predecessors | |
1453 are designed with the assumption that both of these UARTs are available. Per | |
1454 TI's fw architecture, Calypso's MODEM UART presents the standard AT command | |
1455 interface with GSM 07.10 MUX, CSD, fax and GPRS capabilities as described | |
1456 earlier when we looked at ACI and ATI, whereas the other UART (called the IrDA | |
1457 UART in hardware docs but not used for that purpose) presents a vitally | |
1458 important debug, development and production interface called RVTMUX. This | |
1459 RVTMUX interface can also be moved to the MODEM UART, in which case the standard | |
1460 AT command interface is lost. | |
1461 | |
1462 RVTMUX is a binary packet interface, and it got its name because it is a MUX of | |
1463 multiple logical channels managed by the RiViera Trace (RVT) firmware component. | |
1464 RVTMUX is often thought of as being primarily a debug trace interface, as that | |
1465 is the primary use to which it is put: in normal operation the firmware emits | |
1466 quite voluminous debug trace output on the IrDA UART, encapsulated in 3 | |
1467 different RVTMUX channels as explained below. However, it is also possible to | |
1468 send a number of different debug and development commands to the firmware via | |
1469 this interface, and this functionality is used as a critical component in | |
1470 Calypso GSM device factory production line processes: this RVTMUX interface is | |
1471 the only way by which the FFS can be initialized, RF calibration and tests can | |
1472 be performed and the IMEI can be set at the factory. | |
1473 | |
1474 Communication with a running firmware over this RVTMUX interface in a | |
1475 development or production setting (whether passively reading debug traces or | |
1476 actively sending development or test commands to the running fw) requires | |
1477 specialized host tools. TI originally had a suite of Windows-based tools for | |
1478 this purpose, but we are not using them in FreeCalypso: we only got Windows | |
1479 binaries without any sources, and even in the case of those binaries we only | |
1480 got an incomplete set with some important tools missing. Instead we are using | |
1481 our own Unix-based tools called FreeCalypso host tools; these tools have been | |
1482 developed from scratch by Mother Mychaela after studying the firmware components | |
1483 with which they need to communicate. | |
1484 | |
1485 Debug trace output | |
1486 ================== | |
1487 | |
1488 The firmware component that "owns" the physical UART channel assigned to RVTMUX | |
1489 is RVT, contained in chipsetsw/riviera/rvt in TCS211 or in src/cs/riviera/rvt | |
1490 in our Magnetite and Selenite firmwares. It is a Riviera-based component, | |
1491 and it has a Nucleus task that is created and started through Riviera. All | |
1492 calls to the actual driver for the UART are made from RVT. In the case of | |
1493 output from the Calypso GSM device to an external host, all such output is | |
1494 performed in the context of RVT's Nucleus task; this task drains RVT's message | |
1495 queue and emits the content of allocated buffers posted to it, freeing them | |
1496 afterward. (The dynamic memory allocation system in this case is Riviera's, | |
1497 which is susceptible to fragmentation - see discussion earlier in this article.) | |
1498 Therefore, every trace or other output packet emitted from a GSM device running | |
1499 our fw (or any of the proprietary firmwares based on the same architecture) | |
1500 appears as a result of a message in a dynamically allocated buffer having been | |
1501 posted to RVT's queue. | |
1502 | |
1503 RVT exports several API functions that are intended to be called from other | |
1504 tasks, it is by way of these functions that most output is submitted to RVT. | |
1505 One can call rvt_send_trace_cpy() with a fully prepared output message, and | |
1506 that function will allocate a buffer from Riviera's dynamic memory allocator | |
1507 properly accounted to RVT, fill it and post it to the RVT task's queue. | |
1508 Alternatively, one can call rvt_mem_alloc() to allocate the buffer, fill it in | |
1509 and then pass it to rvt_send_trace_no_cpy(). | |
1510 | |
1511 At higher levels, there are a total of 3 kinds of debug traces that can be | |
1512 emitted: | |
1513 | |
1514 * Riviera traces: these are generated by various components implemented in | |
1515 Riviera land, although in reality any component can generate a trace of this | |
1516 form by calling rvf_send_trace() - this function can be called from any task. | |
1517 | |
1518 * L1 traces: L1 has its own trace facility implemented in | |
1519 src/cs/layer1/cfile/l1_trace.c; it generates its traces as ASCII messages and | |
1520 sends them out via rvt_send_trace_cpy(). | |
1521 | |
1522 * GPF traces: code that runs in GPF/G23M land and uses those header files and | |
1523 coding conventions etc can emit traces through GPF. GPF's trace functions | |
1524 (implemented in gpf/frame/vsi_trc.c) allocate a memory partition from | |
1525 GPF's TEST pool, format the trace into it, and send the trace primitive to | |
1526 GPF's special test interface task. That task receives trace and other GPF | |
1527 test interface primitives on its queue, performs some manipulations on them, | |
1528 and ultimately generates RVT trace output, i.e., a new dynamic memory buffer | |
1529 is allocated in the Riviera land, the trace is copied there, and the Riviera | |
1530 buffer goes to the RVT task for the actual output. | |
1531 | |
1532 Trace masking | |
1533 ============= | |
1534 | |
1535 The RV trace facility invoked via rvf_send_trace() has a crude masking ability, | |
1536 but by default all traces are enabled. In TI's standard firmwares most of the | |
1537 trace output comes from L1: L1's trace output is very voluminous, and most of | |
1538 it is fully enabled by default. | |
1539 | |
1540 On the other hand, GPF and therefore G23M traces are mostly disabled by default. | |
1541 One can turn the trace verbosity level from any GPF-based entity up or down by | |
1542 sending a "system primitive" command to the running fw, and another such command | |
1543 can be used to save these masks in FFS, so that they will be restored on the | |
1544 next boot cycle and be effective at the earliest possible time. Enabling *all* | |
1545 GPF trace output for all entities is generally not useful though, as it is so | |
1546 verbose that a developer trying to make sense of it will likely drown in it - | |
1547 and it will also overwhelm the debug trace facility itself, causing most of | |
1548 these far too voluminous traces to be lost. Therefore, a developer seeking to | |
1549 debug an issue in the G23M protocol stack needs to enable traces very | |
1550 judiciously. | |
1551 | |
1552 GPF compressed trace hack | |
1553 ========================= | |
1554 | |
1555 TI's Windows-based GSM firmware build systems include a hack called str2ind. | |
1556 Seeking to reduce the fw image size by eliminating trace ASCII strings from it, | |
1557 and seeking to reduce the load on the RVTMUX serial interface by eliminating | |
1558 the transmission time of these strings, they passed their sources through an | |
1559 ad hoc preprocessor that replaces these ASCII strings with numeric indices. | |
1560 The compilation process with this str2ind hack becomes very messy: each source | |
1561 file is first passed through the C preprocessor, then the intermediate form is | |
1562 passed through str2ind, and finally the de-string-ified form is compiled, with | |
1563 the compiler being told not to run the C preprocessor again. | |
1564 | |
1565 TI's str2ind tool maintains a table of correspondence between the original trace | |
1566 ASCII strings and the indices they've been turned into, and a copy of this table | |
1567 becomes essential for making sense of GPF trace output: the firmware now emits | |
1568 only numeric indices which are useless without this str2ind.tab mapping table. | |
1569 | |
1570 Our FC Magnetite build system retains the option of using str2ind, but it is | |
1571 disabled by default: str2ind significantly increases firmware compilation times, | |
1572 the resulting fw image sizes without str2ind are fine (the slight increase does | |
1573 not push us over any limits), and we haven't had any issues with ASCII strings | |
1574 overloading the trace interface. However, there is an additional complication | |
1575 stemming from the choice of two possible G23M PS versions, one of which is a | |
1576 set of blob libraries: | |
1577 | |
1578 * If Magnetite is compiled in a pure TCS211 configuration using the original | |
1579 blob version of G23M PS, these blobs already have str2ind indices baked into | |
1580 them instead of trace ASCII strings, hence the frozen str2ind.tab file from | |
1581 Openmoko that maps these indices back to strings needs to be used. | |
1582 | |
1583 * If Magnetite is compiled in a TCS2/TCS3 hybrid config without G23M blobs, | |
1584 then unless you enable it explicitly with USE_STR2IND=1, no str2ind will be | |
1585 used at all. | |
1586 | |
1587 Our blob-free FC Selenite firmware does not support str2ind at all - we shall | |
1588 stick with full ASCII string traces until and unless we run into an actual (as | |
1589 opposed to hypothetical) problem with either fw image size or serial interface | |
1590 load. | |
1591 | |
1592 RVTMUX command input | |
1593 ==================== | |
1594 | |
1595 RVTMUX is not just debug trace output: it is also possible for an external host | |
1596 to send commands to the running fw via RVTMUX. | |
1597 | |
1598 Inside the fw RVTMUX input is handled by the RVT entity by way of a Nucleus | |
1599 HISR. This HISR gets triggered when Rx bytes arrive at the designated UART, | |
1600 and it calls the UART driver to collect the input. RVT code running in this | |
1601 HISR parses the message structure and figures out which fw component the | |
1602 incoming message is addressed to. Any fw component can register to receive | |
1603 RVTMUX packets, and provides a callback function with this registration; this | |
1604 callback function is called in the context of the HISR. | |
1605 | |
1606 In the original TCS211 fw there are only two components that register to receive | |
1607 external host commands via RVTMUX: ETM and GPF, hence these are the only command | |
1608 packet types that can be sent to this original fw. In FreeCalypso we have kept | |
1609 these, and we've also added some new RVTMUX channels of our own invention. | |
1610 | |
1611 Test Mode (TM) and Enhanced Test Mode (ETM) | |
1612 =========================================== | |
1613 | |
1614 A major use of the RVTMUX interface is sending so-called Test Mode commands | |
1615 from an external host to a running GSM device. Depending on the firmware | |
1616 version, a GSM device can be commanded to do any of the following things | |
1617 through this mechanism: | |
1618 | |
1619 * Exercise RF test modes, e.g., transmit continuously at a set frequency and | |
1620 power level; | |
1621 * Read and write arbitrary memory locations in the Calypso ARM7 address space; | |
1622 * Read and write ABB chip registers; | |
1623 * Reboot or power off; | |
1624 * Access and manipulate the device's flash file system (FFS). | |
1625 | |
1626 In the segment of history of interest to us TI has produced two different | |
1627 target firmware components that can receive, interpret and act upon Test Mode | |
1628 command packets: | |
1629 | |
1630 * The original Test Mode component of Layer 1, called L1TM or TML1: this | |
1631 component handles all RF test modes (needed for RF calibration on device | |
1632 production lines), and originally it also implemented memory and ABB register | |
1633 read and write commands, and provided access to TMFFS1 (see below). In the | |
1634 original implementation this component registered itself as the handler for | |
1635 the "TM" RVTMUX channel (RVT packet type 0x14), so it would receive all TM | |
1636 packets sent to the device. | |
1637 | |
1638 * Enhanced Test Mode (ETM) is a later invention. It registers itself (instead | |
1639 of the old TM in L1) with RVT as the handler for the "TM" RVTMUX channel, and | |
1640 then provides a registration service of its own, such that various components | |
1641 in the fw suite can register to receive external command packets passing | |
1642 first through RVT, then through ETM, and can send responses passing through | |
1643 ETM, then through RVT back to the external host. If a given fw version | |
1644 contains both ETM and L1TM like TCS211 does, then L1TM registers itself with | |
1645 ETM; an external host would send exactly the same binary command packets to | |
1646 exercise RF test modes, but inside the firmware they now pass through ETM on | |
1647 their way to L1TM. | |
1648 | |
1649 The ETM_CORE module contained within ETM itself provides some low-level debug | |
1650 commands: by sending the right binary command packets to the GSM device via the | |
1651 RVTMUX serial channel, an external host can examine or modify any memory | |
1652 location and any hardware register, cause the device to reset, etc. Prior to | |
1653 ETM some of these functions (but not all) could be exercised through older TM3 | |
1654 commands, but in FreeCalypso we became familiar with the ETM versions of these | |
1655 commands long before the older ones because we got the ETM component in full | |
1656 source form, whereas the sole surviving copy of TCS211 that serves as our golden | |
1657 reference came with L1TM in binary object form like the rest of L1, and we got | |
1658 to source-reconstructing it only much later. | |
1659 | |
1660 ETM is implemented as a Riviera SWE and has its own Nucleus task; the callback | |
1661 function that gets called from the RVT HISR posts received messages onto ETM's | |
1662 own queue drained by its task. The ETM task gets scheduled, picks up the | |
1663 command posted to its queue, executes it, and sends a response message back to | |
1664 the external host through RVT. | |
1665 | |
1666 Because all ETM commands funnel through ETM's queue and task, and that task | |
1667 won't start looking at a new command until it finished handling the previous | |
1668 one, all ETM commands and responses are in strict lock-step: it is not possible | |
1669 to send two commands and have their responses come in out of order, and it makes | |
1670 no sense to send another ETM command prior to receiving the response to the | |
1671 previous one. (But there can still be debug traces or other traffic intermixed | |
1672 on RVTMUX in between an ETM command and the corresponding response!) | |
1673 | |
1674 L1TM commands get posted to the message queue of the L1A task and then executed | |
1675 in that task's context. | |
1676 | |
1677 FFS access via TM/ETM | |
1678 ===================== | |
1679 | |
1680 One of the essential facilities provided in one form or another in all known | |
1681 incarnations of the Test Mode mechanism (at least in TI's original architecture, | |
1682 as opposed to Motorola's bastardized version) is the ability to access and | |
1683 manipulate the GSM device's flash file system (FFS) that was described earlier | |
1684 in this article. TI's TMFFS1 and TMFFS2 protocols provide a command and | |
1685 response packet interface to the FFS API functions inside the fw, and enable an | |
1686 external host connected to the GSM device via the RVTMUX channel to perform | |
1687 arbitrary read and write operations on the device file system. | |
1688 | |
1689 In the segment of history of interest to us TI has produced two different | |
1690 and entirely incompatible versions of the TMFFS protocol: TMFFS1 and TMFFS2. | |
1691 Or rather, what is now called TMFFS1 was originally just TMFFS, and then came | |
1692 TMFFS2. TMFFS2 works only through ETM, whereas TMFFS1 predates ETM: in the | |
1693 original implementation the tm_ffs() function in the FFS code was called from | |
1694 L1TM code. | |
1695 | |
1696 Our copy of TCS211 reference fw includes the source for both TMFFS1 and TMFFS2; | |
1697 it is theoretically possible to build a firmware image that includes both TMFFS | |
1698 versions (they won't conflict because they respond to different command | |
1699 packets), but it is pretty clear that TI never intended to have both enabled | |
1700 at the same time. Our copy of TCS211 came with TMFFS1 enabled and we didn't | |
1701 change it when we made the moko12 (leo2moko-r1) fw release for the Openmoko | |
1702 community (the previous proprietary mokoN firmwares also implement TMFFS1), | |
1703 but we have subsequently switched to TMFFS2 for our current Magnetite and | |
1704 Selenite firmwares. | |
1705 | |
1706 Our choice of TMFFS2 over TMFFS1 was driven by the need to develop our own host | |
1707 tools to replace TI's original ones which we never got. We needed to develop | |
1708 our own host tools for operating on GSM device FFS via one of the two TMFFS | |
1709 protocols, and after studying the fw source implementing both, I (Mother | |
1710 Mychaela) came to the conclusion that TMFFS2 is both more capable and more | |
1711 reliable; my guess is that TMFFS1 was likely kept around only because some of | |
1712 TI's crappy Weendoze host software depended on it. (See the implementation | |
1713 code in chipsetsw/drivers/drv_app/ffs/board/tmffs.c in TCS211 if you would like | |
1714 to judge for yourself.) Our host tool that speaks the TMFFS2 protocol is | |
1715 fc-fsio. | |
1716 | |
1717 GPF external command input | |
1718 ========================== | |
1719 | |
1720 The other component that can receive external commands is GPF. GPF's test | |
1721 interface can receive so-called "system primitives", which are ASCII string | |
1722 commands parsed and acted upon by GPF, and also binary protocol stack | |
1723 primitives. Remember how all entities in the G23M stack communicate by sending | |
1724 messages to each other? Well, GPF's test interface allows such messages to be | |
1725 injected externally as well, directed to any entity in the running fw. System | |
1726 primitive commands can also be used to cause entities to send their outgoing | |
1727 primitives to the test interface, either instead of or in addition to the | |
1728 originally intended recipient. | |
1729 | |
1730 AT commands over RVTMUX | |
1731 ======================= | |
1732 | |
1733 There is one more use to which we put the RVTMUX debug serial interface that is | |
1734 an original FreeCalypso invention: communicating with the AT command interpreter | |
1735 (ATI). TI's original architecture assumes that if a product is to offer a | |
1736 standard AT command interface (the product is either a GSM/GPRS modem for which | |
1737 this AT command interface is the sole mode of usage or a feature phone that | |
1738 offers a data port as one of its features), then it will be presented on a | |
1739 dedicated UART separate from RVTMUX. | |
1740 | |
1741 However, in the case of our FreeCalypso family of projects about 2 years had | |
1742 passed between our first functional GSM fw attempts in 2015 and us successfully | |
1743 building our own development board in 2017; during this time we had to work on | |
1744 various crippled pre-existing Calypso devices, and many of them had only one | |
1745 UART practically accessible. In response to this situation we developed a way | |
1746 to pass AT commands over RVTMUX. We created a new RVTMUX channel for this | |
1747 interface and assigned it RVT packet type 0x1A. Packets sent from an external | |
1748 host to the GSM device carry AT commands and SMS string input, whereas packets | |
1749 flowing the other way carry ATI's responses to commands and asynchronous | |
1750 notifications such as incoming calls. The host utility for talking AT commands | |
1751 to a FreeCalypso GSM device via RVTMUX is fc-shell, described below. | |
1752 | |
1753 Now that we have built a proper FreeCalypso development board with two UARTs, | |
1754 the use of this AT-over-RVTMUX hack is deprecated for general usage: this hack | |
1755 does not support any data services (CSD or GPRS), and even for SMS it is | |
1756 crippled because maximum-length messages cannot be sent in the more capable PDU | |
1757 mode. However, it still comes in handy during certain casual testing sessions, | |
1758 and it is required if one needs to run our FreeCalypso firmware on Mot C1xx or | |
1759 Pirelli DP-L10 hardware. | |
1760 | |
1761 FC host tools for talking to firmwares via RVTMUX | |
1762 ================================================= | |
1763 | |
1764 The fundamental tool for talking to running firmwares via RVTMUX is a program | |
1765 called rvinterf. It runs on a Unix/Linux host machine, opens a serial port | |
1766 that is expected to be connected to the RVTMUX UART on the target, and then | |
1767 speaks TI's binary packet protocol on that serial port. It then performs two | |
1768 functions: | |
1769 | |
1770 * If rvinterf is run in the foreground in a terminal window (or more precisely, | |
1771 if its default terminal output is not disabled), every packet received from | |
1772 the target is decoded and printed on stdout in human-readable ASCII. For | |
1773 some packets like TM/ETM responses this "human-readable" form is just a hex | |
1774 dump, but the trace messages which the firmware emits on its own are printed | |
1775 in truly human-readable form. This output can also be saved to a log file. | |
1776 | |
1777 * Rvinterf creates a local UNIX domain socket on the machine it is running on, | |
1778 and other host tools can then connect to this socket to exchange packets with | |
1779 the firmware. Client programs connected to rvinterf via this local socket | |
1780 interface can register to receive copies of packets sent by the target on | |
1781 specific RVTMUX channels, and they can also send arbitrary packets to the | |
1782 target. | |
1783 | |
1784 Our main "client" programs for actively interacting with running firmwares via | |
1785 rvinterf are: | |
1786 | |
1787 fc-tmsh This utility speaks the TM/ETM protocol. It supports almost | |
1788 all ETM and L1TM commands that are supported by our reference | |
1789 TCS211 fw with the important exception of TMFFS; support means | |
1790 that fc-tmsh can issue these commands and decode the firmware's | |
1791 responses to them. fc-tmsh operates asynchronously in that the | |
1792 issuance of commands to the target and the display of firmware | |
1793 responses are completely decoupled; this asynchronous model is | |
1794 a good match for L1/RF test mode commands and simple ETM | |
1795 operations, but is a poor fit for FFS manipulation. fc-tmsh's | |
1796 companion fc-fsio implements FFS access via TMFFS2, and we | |
1797 don't have a host side implementation for TI's older TMFFS1 | |
1798 protocol. | |
1799 | |
1800 fc-fsio This utility speaks the TMFFS2 protocol over the TM/ETM RVTMUX | |
1801 channel (same channel as used by fc-tmsh, so don't try to run | |
1802 both at the same time) and implements fairly high-level FFS read | |
1803 and write operations. fc-fsio is used to format and initialize | |
1804 the FFS on newly made devices in our hardware manufacturing | |
1805 environment, it can upload files or entire subtrees into target | |
1806 device FFS, it has higher-level commands for writing some files | |
1807 like the IMEI, rfcap and AT+CGxx ID strings, and it can list and | |
1808 read out FFS content. Unlike fc-tmsh, fc-fsio is synchronous: | |
1809 it is built on command-response (send a command and expect a | |
1810 response) primitives, and a single user command can turn into a | |
1811 large number of command-response exchanges on the RVTMUX | |
1812 interface. fc-fsio also implements a few non-FFS commands | |
1813 because they naturally fit into this ETM synchronous model. | |
1814 | |
1815 fc-shell This tool is asynchronous like fc-tmsh, but instead of talking | |
1816 and listening on the TM/ETM RVTMUX channel, it talks and listens | |
1817 on GPF's channel and on the new AT-over-RVTMUX channel which we | |
1818 added in FreeCalypso. fc-shell can be used to issue system | |
1819 primitive commands to GPF (and to see firmware responses to | |
1820 them), and to talk AT commands via RVTMUX. | |
1821 | |
1822 Finally, if you only need to passively observe the firmware's debug trace output | |
1823 and don't need to make any active pokes at the target, our rvtdump utility is a | |
1824 stripped-down version of rvinterf (or historically its predecessor) that only | |
1825 decodes and prints/logs the output from the target without sending anything to | |
1826 it. | |
1827 | |
1828 Further reading | |
1829 =============== | |
1830 | |
1831 Believe it or not, some of the documentation that was written by the original | |
1832 vendors of the software in question and which we've been able to locate turns | |
1833 out to be fairly relevant and helpful, such that I recommend reading it. | |
1834 | |
1835 Documentation for Nucleus PLUS RTOS: | |
1836 | |
1837 ftp://ftp.freecalypso.org/pub/embedded/Nucleus/nucleus_manuals.tar.bz2 | |
1838 | |
1839 Quite informative, and fits our version of Nucleus just fine. | |
1840 | |
1841 Riviera environment: | |
1842 | |
1843 ftp://ftp.freecalypso.org/pub/GSM/Calypso/riviera_preso.pdf | |
1844 | |
1845 It's in slide presentation form, not a detailed technical document, but | |
1846 it covers a lot of points, and all that Riviera stuff described in the | |
1847 preso *is* present in our fw for real, hence it should be considered | |
1848 relevant. | |
1849 | |
1850 GPF documentation: | |
1851 | |
1852 https://www.freecalypso.org/LoCosto-docs/SW%20doc/frame_users_guide.pdf | |
1853 https://www.freecalypso.org/LoCosto-docs/SW%20doc/vsipei_api.pdf | |
1854 | |
1855 Very good reading, helped me understand GPF when I first reached this | |
1856 part of firmware reintegration. | |
1857 | |
1858 TCS3.x/LoCosto fw architecture: | |
1859 | |
1860 https://www.freecalypso.org/LoCosto-docs/SW%20doc/TCS2_1_to_3_2_Migration_v0_8.pdf | |
1861 ftp://ftp.freecalypso.org/pub/GSM/LoCosto/LoCosto_Software_Architecture_Specification_Document.pdf | |
1862 | |
1863 These TI docs focus mostly on how they changed the fw architecture from | |
1864 their TCS2.x program (Calypso) to their newer TCS3.x (LoCosto), but one | |
1865 can still get a little insight into the "old" TCS211 architecture they | |
1866 were moving away from, which is the architecture we've adopted for | |
1867 FreeCalypso. |