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. |
