From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1esqST-0005vq-1A for linux-mtd@lists.infradead.org; Mon, 05 Mar 2018 13:47:19 +0000 Date: Mon, 5 Mar 2018 14:47:02 +0100 From: Boris Brezillon To: Cyrille Pitchen Cc: David Woodhouse , Brian Norris , Boris Brezillon , Marek Vasut , Richard Weinberger , linux-mtd@lists.infradead.org, Mark Brown , linux-spi@vger.kernel.org, Peter Pan , Frieder Schrempf , Vignesh R , Yogesh Gaur , =?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?= , Kamal Dasu , Sourav Poddar Subject: Re: [RFC PATCH 1/6] spi: Extend the core to ease integration of SPI memory controllers Message-ID: <20180305144702.0afd663e@bbrezillon> In-Reply-To: <7314a397-2821-ceb8-a9ff-f14d0dd2a176@wedev4u.fr> References: <20180205232120.5851-1-boris.brezillon@bootlin.com> <20180205232120.5851-2-boris.brezillon@bootlin.com> <20180305100025.3b25ae3d@bbrezillon> <7314a397-2821-ceb8-a9ff-f14d0dd2a176@wedev4u.fr> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , On Mon, 5 Mar 2018 14:01:59 +0100 Cyrille Pitchen wrote: > Hi Boris, >=20 > Le 05/03/2018 =C3=A0 10:00, Boris Brezillon a =C3=A9crit=C2=A0: > > Hello Cyrille, > >=20 > > On Sun, 4 Mar 2018 22:15:20 +0100 > > Cyrille Pitchen wrote: > > =20 > >>> + > >>> +static int spi_check_buswidth_req(struct spi_mem *mem, u8 buswidth, = bool tx) > >>> +{ > >>> + u32 mode =3D mem->spi->mode; > >>> + > >>> + switch (buswidth) { > >>> + case 1: > >>> + return 0; > >>> + > >>> + case 2: > >>> + if ((tx && (mode & (SPI_TX_DUAL | SPI_TX_QUAD))) || > >>> + (!tx && (mode & (SPI_RX_DUAL | SPI_RX_QUAD)))) =20 > >> > >> Some SPI (flash) controller may support Quad protocols but no Duals > >> protocols at all. Hence you should only test SPI_{R,T]X_DUAL. =20 > >=20 > > Hm, I'd rather not change that, since it's what have been used so far. > > Note that a controller that wants to put more constraints can still > > implement the ->supports_op() hook. > > =20 > >> > >> Anyway, I think the function should completely be removed because > >> SPI_{R,T}X_{DUAL,QUAD} flags should be deprecated. > >> > >> They were fine when introduced long time ago when Quad SPI flashes only > >> supported Fast Read 1-1-4 and maybe few of them Page Program 1-1-4. > >> > >> However for many years now, Quad SPI flashes support far much SPI prot= ocols > >> and commands. For instance: > >> Fast Read 1-1-4 > >> Fast Read 1-4-4 > >> (Fast Read 4-4-4) > >> Page Program 1-1-4 > >> Page Program 1-4-4 > >> Page Program 4-4-4 > >> > >> Fast Read x-y-z means that: > >> - the op code is transfered (tx) on x I/O line(s) > >> - the address, mode and dummies are transfered (tx) on y I/O line(s) > >> - the data are received (rx) on z I/O line(s) > >> > >> Page Program x-y-z stands for: > >> - the op code being transfered (tx) on x I/O line(s) > >> - the address is transfered (tx) on y I/O line(s) > >> the data are transfered (tx) on z I/O line(s) > >> > >> Then some SPI flash controllers and/or memories may support Fast Read = 1-4-4 > >> but not Page Program 1-1-4 whereas others may support Page Program 1-1= -4 > >> but not Fast Read 1-4-4. > >> > >> So using only SPI_{R,T}X_{DUAL,QUAD} flags, how do we make the differe= nce > >> between support of Fast Read 1-4-4 and Page Program 1-1-4 or between > >> Fast Read 1-1-4 and Fast Read 1-4-4 ? =20 > >=20 > > I think you're mixing 2 different things: > >=20 > > 1/ The RX/TX buswidth capabilities for generic SPI/DualSPI/QuadSPI > > transfers, which is, I guess, what these flags have been created for > >=20 > > 2/ The buswidth of each instruction of a memory-like operation (by > > instruction I mean, CMD, ADDR, DATA cycles) > >=20 > > There is no reason for a generic SPI controller to specify things for > > #2, because it doesn't know anything about this spi-mem protocol, all > > it can do is send/recv data using a specific bus width. > > =20 >=20 > I might be wrong but I think SPI flashes are the only SPI devices using m= ore > than one I/O line to send and receive data. FPGAs, and I there are and will be other devices using the spi-mem protocol to address non-memory devices. After all, this protocol is just enforcing a specific sequence that has nothing memory-specific. >=20 > Anyway, let assume devices other than SPI flash also use many I/O lines > hence make use of the SPI_{R,T}X_{DUAL,QUAD} flags. >=20 > It looks like this series is dealing a new SPI API dedicated to SPI memor= ies. I said memory-like devices, and it's actually about supporting any kind of devices that follow the spi-mem protocol, or in other words, any kind of communication where transactions are of the following form: 1/ an opcode 2/ 0 to N address cycles 3/ 0 to N dummy cycles 4/ 0 to N data in/out cycles > Just my opinion but 1/ and the associated SPI_{R,T}X_{DUAL,QUAD} flags sh= ould > be left only for the generic SPI API, - with spi_sync(), 'struct spi_mess= age', > 'struct spi_transfer' and so on. And that's what pretty much what I'm doing: a controller implementing the spi_mem_ops interface can check the operation by itself, if the default check based on SPI_{R,T}X_{DUAL,QUAD} flags is not sufficient. >=20 > On the other hand, the new SPI flash dedicated API should only focus on 2/ > and totally ignore the SPI_{R,T}X_{DUAL,QUAD} flags. Not when we fallback to the generic API, but otherwise, I'm fine with making ->supports_op() mandatory and only providing the generic checks as a helper. >=20 > If we take the example of the sama5d2 QSPI controller, we can use more th= an one > I/O line only when configure in "serial flash memory" mode. However when = in "spi" > mode, when can only use regular MOSI and MISO lines. >=20 > With spi_mem_supports_op() as proposed below, we would have to set both S= PI_RX_QUAD > and SPI_TX_QUAD to allow Fast Read 1-4-4 when in "serial flash memory" mo= de. > However with other SPI devices, hence when in "spi" mode, the SPI_{R,T}X_= QUAD flags > would still be set though the controller cannot support more than a singl= e I/O line. Okay, that's a good reason to get this generic check out of the spi_mem_supports_op() path and instead provide a generic helper that can be used by drivers which wants to rely on SPI_{R,T}X_{DUAL,QUAD} flags. >=20 > The SPI_{R,T}_{DUAL,QUAD} flags could be tested in a default implementati= on of > spi_mem_supports_op() but should not be tested as mandatory flags for all= SPI > (flash) controllers. Agreed. I still think we need a way to restrict the number of IO-lines based on board-related information, and if spi->mode is not appropriate for that, we need it somewhere else. Otherwise, you might end-up assuming QSPI is supported by both the device and the controller, while the connections on the board is, for instance, limiting it to SPI or DualSPI. > > =20 > >>> + > >>> +/** > >>> + * struct spi_mem_op - describes a SPI memory operation > >>> + * @cmd.buswidth: number of IO lines used to transmit the command > >>> + * @cmd.opcode: operation opcode > >>> + * @addr.nbytes: number of address bytes to send. Can be zero if the= operation > >>> + * does not need to send an address > >>> + * @addr.buswidth: number of IO lines used to transmit the address c= ycles > >>> + * @addr.buf: buffer storing the address bytes > >>> + * @dummy.nbytes: number of dummy bytes to send after an opcode or a= ddress. Can > >>> + * be zero if the operation does not require dummy bytes > >>> + * @dummy.buswidth: number of IO lanes used to transmit the dummy by= tes > >>> + * @data.buswidth: number of IO lanes used to send/receive the data > >>> + * @data.dir: direction of the transfer > >>> + * @data.buf.in: input buffer > >>> + * @data.buf.out: output buffer > >>> + */ > >>> +struct spi_mem_op { > >>> + struct { > >>> + u8 buswidth; > >>> + u8 opcode; > >>> + } cmd; > >>> + > >>> + struct { > >>> + u8 nbytes; > >>> + u8 buswidth; > >>> + const u8 *buf; =20 > >> > >> For the address value, I would rather use some loff_t type, instead of > >> const u8 *.=20 > >> Actually, most (if not all) SPI flash controllers have some hardware > >> register to set the address value of the SPI flash command to be > >> sent. Hence having this value directly in the right format would avoid= to > >> convert. =20 > >=20 > > What is the appropriate format? An address encoded in a 64-bit integer > > does not give any information on how these bytes should be transmitted > > on the bus. SPI NOR is passing the address in big endian, SPI NAND seems > > to do the same, but we're not sure this will be the case for all kind of > > memories or devices using this spi-mem protocol. > >=20 > > Also, by passing it through an integer we limit ourselves to 8 bytes. > > That should be enough, but who knows :-). > >=20 > > If we go for this loff_t field, we'll have to add an endianness field > > here and force all drivers to check it. > > =20 >=20 > I don't think we need any endianness field. We already use loff_t only, > without additional endianness paramater, in spi-nor but also in the above > MTD layer (see 'struct mtd_info') and till now it has just worked fine. It's not about the MTD layer. Can you predict that all devices will transmit the address in big-endian? I can't. >=20 > Most, if not all, SPI flash controllers have a dedicated field in one of > their registers to write the address value into it. Generally, this regis= ter > is written with an integer in the CPU native byte order so no need to con= vert. It's not about how you write your register, but in which order address bytes are transmitted on the SPI wire. Currently, SPI NOR use the MSB first scheme, but that won't necessarily be the case for other SPI devices. >=20 > And anyway, if some conversion is ever needed, the SPI flash controller > driver knows it so we could set as a rule that the integer value for the > address is always stored in the native CPU byte order. At least most SPI = flash > controller driver won't have to convert from a const u8 * to some unsigned > integral type more suited to their register accesses. They will have to at least make sure it's properly encoded: if the device is expecting the address to be transmitted LSB first (AKA little-endian), they'll have to swap address bytes before writing the value to the register. > =20 > >> AFAIK, only m25p80 needs to convert from loff_t to u8 * and only > >> when using the regular SPI API, ie spi_sync(), as the 'struct > >> spi_flash_read_messag' already uses some integral type too. =20 > >=20 > > And I'm not sure this was a good idea. > > =20 > >> > >> =20 > >>> + } addr; > >>> + > >>> + struct { > >>> + u8 nbytes; > >>> + u8 buswidth; > >>> + } dummy; > >>> + > >>> + struct { > >>> + u8 buswidth; > >>> + enum spi_mem_data_dir dir; > >>> + unsigned int nbytes; > >>> + /* buf.{in,out} must be DMA-able. */ > >>> + union { > >>> + void *in; > >>> + const void *out; > >>> + } buf; > >>> + } data; =20 > >> > >> Also, you should add another member in this structure to set the 'type= ' of > >> operation for the SPI flash command: > >> - register read > >> - register write > >> - memory read > >> - memory write > >> - memory erase > >> [- SFDP read ? ] > >> [- OTP read/write ? ] =20 > >=20 > > No, really, that's not belonging here. It's entirely SPI NOR specific. > > =20 >=20 > I disagree with you on that. Except for SFDP of course, this will also ap= ply to > SPI NAND as well. And this information should be passed down to the SPI (= flash) > controller driver, instead of being lost at the SPI NAND/NOR levels, I'm not saying we should keep these information at the spi-nor/nand level, just saying we should find a way to make it look like a generic solution so that SPI controllers don't have to guess what they should do based on the memory operation type. Typically, why should a SPI controller care about whether the operation is an erase, a reg read or a reg write. From the controller PoV, it's just an spi-mem operation. The use cases you want to optimize are read/write user-data, and this can be done in different ways (direct memory mapping is one solution). > so the SPI > controller driver could take the proper actions (data cache flush/invalid= ation > for memory operations, This one has to do with direct mapping, so an API to allow direct mapping should help address that. > enabling/disabling on-the-fly data scrambling, And what's the problem with passing the scramble information on a per-operation basis and letting the upper layer decide when it's a good idea to use it or not? > and other > controller specific constraints). Could you be more specific? I really have the feeling you're reviewing that with your SPI NOR maintainer eye, while, as I said several times, I'm trying to address the problem more generically. My intent is not to move every bits you have in the spi-nor layer to the spi layer. Instead, we can progressively provide a consistent API that helps you deal with memory devices (I guess supporting direct memory mapping is the next step if we want to get the best perfs out of these advanced controllers) in a device agnostic fashion. Regards, Boris --=20 Boris Brezillon, Bootlin (formerly Free Electrons) Embedded Linux and Kernel engineering https://bootlin.com From mboxrd@z Thu Jan 1 00:00:00 1970 From: Boris Brezillon Subject: Re: [RFC PATCH 1/6] spi: Extend the core to ease integration of SPI memory controllers Date: Mon, 5 Mar 2018 14:47:02 +0100 Message-ID: <20180305144702.0afd663e@bbrezillon> References: <20180205232120.5851-1-boris.brezillon@bootlin.com> <20180205232120.5851-2-boris.brezillon@bootlin.com> <20180305100025.3b25ae3d@bbrezillon> <7314a397-2821-ceb8-a9ff-f14d0dd2a176@wedev4u.fr> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Cc: Boris Brezillon , Yogesh Gaur , Vignesh R , Kamal Dasu , Richard Weinberger , linux-spi@vger.kernel.org, Peter Pan , Marek Vasut , Frieder Schrempf , Mark Brown , linux-mtd@lists.infradead.org, =?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?= , Sourav Poddar , Brian Norris , David Woodhouse To: Cyrille Pitchen Return-path: In-Reply-To: <7314a397-2821-ceb8-a9ff-f14d0dd2a176@wedev4u.fr> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+gldm-linux-mtd-36=gmane.org@lists.infradead.org List-Id: linux-spi.vger.kernel.org T24gTW9uLCA1IE1hciAyMDE4IDE0OjAxOjU5ICswMTAwCkN5cmlsbGUgUGl0Y2hlbiA8Y3lyaWxs ZS5waXRjaGVuQHdlZGV2NHUuZnI+IHdyb3RlOgoKPiBIaSBCb3JpcywKPiAKPiBMZSAwNS8wMy8y MDE4IMOgIDEwOjAwLCBCb3JpcyBCcmV6aWxsb24gYSDDqWNyaXTCoDoKPiA+IEhlbGxvIEN5cmls bGUsCj4gPiAKPiA+IE9uIFN1biwgNCBNYXIgMjAxOCAyMjoxNToyMCArMDEwMAo+ID4gQ3lyaWxs ZSBQaXRjaGVuIDxjeXJpbGxlLnBpdGNoZW5Ad2VkZXY0dS5mcj4gd3JvdGU6Cj4gPiAgIAo+ID4+ PiArCj4gPj4+ICtzdGF0aWMgaW50IHNwaV9jaGVja19idXN3aWR0aF9yZXEoc3RydWN0IHNwaV9t ZW0gKm1lbSwgdTggYnVzd2lkdGgsIGJvb2wgdHgpCj4gPj4+ICt7Cj4gPj4+ICsJdTMyIG1vZGUg PSBtZW0tPnNwaS0+bW9kZTsKPiA+Pj4gKwo+ID4+PiArCXN3aXRjaCAoYnVzd2lkdGgpIHsKPiA+ Pj4gKwljYXNlIDE6Cj4gPj4+ICsJCXJldHVybiAwOwo+ID4+PiArCj4gPj4+ICsJY2FzZSAyOgo+ ID4+PiArCQlpZiAoKHR4ICYmIChtb2RlICYgKFNQSV9UWF9EVUFMIHwgU1BJX1RYX1FVQUQpKSkg fHwKPiA+Pj4gKwkJICAgICghdHggJiYgKG1vZGUgJiAoU1BJX1JYX0RVQUwgfCBTUElfUlhfUVVB RCkpKSkgICAgCj4gPj4KPiA+PiBTb21lIFNQSSAoZmxhc2gpIGNvbnRyb2xsZXIgbWF5IHN1cHBv cnQgUXVhZCBwcm90b2NvbHMgYnV0IG5vIER1YWxzCj4gPj4gcHJvdG9jb2xzIGF0IGFsbC4gSGVu Y2UgeW91IHNob3VsZCBvbmx5IHRlc3QgU1BJX3tSLFRdWF9EVUFMLiAgCj4gPiAKPiA+IEhtLCBJ J2QgcmF0aGVyIG5vdCBjaGFuZ2UgdGhhdCwgc2luY2UgaXQncyB3aGF0IGhhdmUgYmVlbiB1c2Vk IHNvIGZhci4KPiA+IE5vdGUgdGhhdCBhIGNvbnRyb2xsZXIgdGhhdCB3YW50cyB0byBwdXQgbW9y ZSBjb25zdHJhaW50cyBjYW4gc3RpbGwKPiA+IGltcGxlbWVudCB0aGUgLT5zdXBwb3J0c19vcCgp IGhvb2suCj4gPiAgIAo+ID4+Cj4gPj4gQW55d2F5LCBJIHRoaW5rIHRoZSBmdW5jdGlvbiBzaG91 bGQgY29tcGxldGVseSBiZSByZW1vdmVkIGJlY2F1c2UKPiA+PiBTUElfe1IsVH1YX3tEVUFMLFFV QUR9IGZsYWdzIHNob3VsZCBiZSBkZXByZWNhdGVkLgo+ID4+Cj4gPj4gVGhleSB3ZXJlIGZpbmUg d2hlbiBpbnRyb2R1Y2VkIGxvbmcgdGltZSBhZ28gd2hlbiBRdWFkIFNQSSBmbGFzaGVzIG9ubHkK PiA+PiBzdXBwb3J0ZWQgRmFzdCBSZWFkIDEtMS00IGFuZCBtYXliZSBmZXcgb2YgdGhlbSBQYWdl IFByb2dyYW0gMS0xLTQuCj4gPj4KPiA+PiBIb3dldmVyIGZvciBtYW55IHllYXJzIG5vdywgUXVh ZCBTUEkgZmxhc2hlcyBzdXBwb3J0IGZhciBtdWNoIFNQSSBwcm90b2NvbHMKPiA+PiBhbmQgY29t bWFuZHMuIEZvciBpbnN0YW5jZToKPiA+PiBGYXN0IFJlYWQgMS0xLTQKPiA+PiBGYXN0IFJlYWQg MS00LTQKPiA+PiAoRmFzdCBSZWFkIDQtNC00KQo+ID4+IFBhZ2UgUHJvZ3JhbSAxLTEtNAo+ID4+ IFBhZ2UgUHJvZ3JhbSAxLTQtNAo+ID4+IFBhZ2UgUHJvZ3JhbSA0LTQtNAo+ID4+Cj4gPj4gRmFz dCBSZWFkIHgteS16IG1lYW5zIHRoYXQ6Cj4gPj4gLSB0aGUgb3AgY29kZSBpcyB0cmFuc2ZlcmVk ICh0eCkgb24geCBJL08gbGluZShzKQo+ID4+IC0gdGhlIGFkZHJlc3MsIG1vZGUgYW5kIGR1bW1p ZXMgYXJlIHRyYW5zZmVyZWQgKHR4KSBvbiB5IEkvTyBsaW5lKHMpCj4gPj4gLSB0aGUgZGF0YSBh cmUgcmVjZWl2ZWQgKHJ4KSBvbiB6IEkvTyBsaW5lKHMpCj4gPj4KPiA+PiBQYWdlIFByb2dyYW0g eC15LXogc3RhbmRzIGZvcjoKPiA+PiAtIHRoZSBvcCBjb2RlIGJlaW5nIHRyYW5zZmVyZWQgKHR4 KSBvbiB4IEkvTyBsaW5lKHMpCj4gPj4gLSB0aGUgYWRkcmVzcyBpcyB0cmFuc2ZlcmVkICh0eCkg b24geSBJL08gbGluZShzKQo+ID4+IHRoZSBkYXRhIGFyZSB0cmFuc2ZlcmVkICh0eCkgb24geiBJ L08gbGluZShzKQo+ID4+Cj4gPj4gVGhlbiBzb21lIFNQSSBmbGFzaCBjb250cm9sbGVycyBhbmQv b3IgbWVtb3JpZXMgbWF5IHN1cHBvcnQgRmFzdCBSZWFkIDEtNC00Cj4gPj4gYnV0IG5vdCBQYWdl IFByb2dyYW0gMS0xLTQgd2hlcmVhcyBvdGhlcnMgbWF5IHN1cHBvcnQgUGFnZSBQcm9ncmFtIDEt MS00Cj4gPj4gYnV0IG5vdCBGYXN0IFJlYWQgMS00LTQuCj4gPj4KPiA+PiBTbyB1c2luZyBvbmx5 IFNQSV97UixUfVhfe0RVQUwsUVVBRH0gZmxhZ3MsIGhvdyBkbyB3ZSBtYWtlIHRoZSBkaWZmZXJl bmNlCj4gPj4gYmV0d2VlbiBzdXBwb3J0IG9mIEZhc3QgUmVhZCAxLTQtNCBhbmQgUGFnZSBQcm9n cmFtIDEtMS00IG9yIGJldHdlZW4KPiA+PiBGYXN0IFJlYWQgMS0xLTQgYW5kIEZhc3QgUmVhZCAx LTQtNCA/ICAKPiA+IAo+ID4gSSB0aGluayB5b3UncmUgbWl4aW5nIDIgZGlmZmVyZW50IHRoaW5n czoKPiA+IAo+ID4gMS8gVGhlIFJYL1RYIGJ1c3dpZHRoIGNhcGFiaWxpdGllcyBmb3IgZ2VuZXJp YyBTUEkvRHVhbFNQSS9RdWFkU1BJCj4gPiAgICB0cmFuc2ZlcnMsIHdoaWNoIGlzLCBJIGd1ZXNz LCB3aGF0IHRoZXNlIGZsYWdzIGhhdmUgYmVlbiBjcmVhdGVkIGZvcgo+ID4gCj4gPiAyLyBUaGUg YnVzd2lkdGggb2YgZWFjaCBpbnN0cnVjdGlvbiBvZiBhIG1lbW9yeS1saWtlIG9wZXJhdGlvbiAo YnkKPiA+ICAgIGluc3RydWN0aW9uIEkgbWVhbiwgQ01ELCBBRERSLCBEQVRBIGN5Y2xlcykKPiA+ IAo+ID4gVGhlcmUgaXMgbm8gcmVhc29uIGZvciBhIGdlbmVyaWMgU1BJIGNvbnRyb2xsZXIgdG8g c3BlY2lmeSB0aGluZ3MgZm9yCj4gPiAjMiwgYmVjYXVzZSBpdCBkb2Vzbid0IGtub3cgYW55dGhp bmcgYWJvdXQgdGhpcyBzcGktbWVtIHByb3RvY29sLCBhbGwKPiA+IGl0IGNhbiBkbyBpcyBzZW5k L3JlY3YgZGF0YSB1c2luZyBhIHNwZWNpZmljIGJ1cyB3aWR0aC4KPiA+ICAKPiAKPiBJIG1pZ2h0 IGJlIHdyb25nIGJ1dCBJIHRoaW5rIFNQSSBmbGFzaGVzIGFyZSB0aGUgb25seSBTUEkgZGV2aWNl cyB1c2luZyBtb3JlCj4gdGhhbiBvbmUgSS9PIGxpbmUgdG8gc2VuZCBhbmQgcmVjZWl2ZSBkYXRh LgoKRlBHQXMsIGFuZCBJIHRoZXJlIGFyZSBhbmQgd2lsbCBiZSBvdGhlciBkZXZpY2VzIHVzaW5n IHRoZSBzcGktbWVtCnByb3RvY29sIHRvIGFkZHJlc3Mgbm9uLW1lbW9yeSBkZXZpY2VzLiBBZnRl ciBhbGwsIHRoaXMgcHJvdG9jb2wgaXMKanVzdCBlbmZvcmNpbmcgYSBzcGVjaWZpYyBzZXF1ZW5j ZSB0aGF0IGhhcyBub3RoaW5nIG1lbW9yeS1zcGVjaWZpYy4KCj4gCj4gQW55d2F5LCBsZXQgYXNz dW1lIGRldmljZXMgb3RoZXIgdGhhbiBTUEkgZmxhc2ggYWxzbyB1c2UgbWFueSBJL08gbGluZXMK PiBoZW5jZSBtYWtlIHVzZSBvZiB0aGUgU1BJX3tSLFR9WF97RFVBTCxRVUFEfSBmbGFncy4KPiAK PiBJdCBsb29rcyBsaWtlIHRoaXMgc2VyaWVzIGlzIGRlYWxpbmcgYSBuZXcgU1BJIEFQSSBkZWRp Y2F0ZWQgdG8gU1BJIG1lbW9yaWVzLgoKSSBzYWlkIG1lbW9yeS1saWtlIGRldmljZXMsIGFuZCBp dCdzIGFjdHVhbGx5IGFib3V0IHN1cHBvcnRpbmcgYW55IGtpbmQKb2YgZGV2aWNlcyB0aGF0IGZv bGxvdyB0aGUgc3BpLW1lbSBwcm90b2NvbCwgb3IgaW4gb3RoZXIgd29yZHMsIGFueQpraW5kIG9m IGNvbW11bmljYXRpb24gd2hlcmUgdHJhbnNhY3Rpb25zIGFyZSBvZiB0aGUgZm9sbG93aW5nIGZv cm06CgoxLyBhbiBvcGNvZGUKMi8gMCB0byBOIGFkZHJlc3MgY3ljbGVzCjMvIDAgdG8gTiBkdW1t eSBjeWNsZXMKNC8gMCB0byBOIGRhdGEgaW4vb3V0IGN5Y2xlcwoKPiBKdXN0IG15IG9waW5pb24g YnV0IDEvIGFuZCB0aGUgYXNzb2NpYXRlZCBTUElfe1IsVH1YX3tEVUFMLFFVQUR9IGZsYWdzIHNo b3VsZAo+IGJlIGxlZnQgb25seSBmb3IgdGhlIGdlbmVyaWMgU1BJIEFQSSwgLSB3aXRoIHNwaV9z eW5jKCksICdzdHJ1Y3Qgc3BpX21lc3NhZ2UnLAo+ICdzdHJ1Y3Qgc3BpX3RyYW5zZmVyJyBhbmQg c28gb24uCgpBbmQgdGhhdCdzIHdoYXQgcHJldHR5IG11Y2ggd2hhdCBJJ20gZG9pbmc6IGEgY29u dHJvbGxlciBpbXBsZW1lbnRpbmcKdGhlIHNwaV9tZW1fb3BzIGludGVyZmFjZSBjYW4gY2hlY2sg dGhlIG9wZXJhdGlvbiBieSBpdHNlbGYsIGlmIHRoZQpkZWZhdWx0IGNoZWNrIGJhc2VkIG9uIFNQ SV97UixUfVhfe0RVQUwsUVVBRH0gZmxhZ3MgaXMgbm90IHN1ZmZpY2llbnQuCgo+IAo+IE9uIHRo ZSBvdGhlciBoYW5kLCB0aGUgbmV3IFNQSSBmbGFzaCBkZWRpY2F0ZWQgQVBJIHNob3VsZCBvbmx5 IGZvY3VzIG9uIDIvCj4gYW5kIHRvdGFsbHkgaWdub3JlIHRoZSBTUElfe1IsVH1YX3tEVUFMLFFV QUR9IGZsYWdzLgoKTm90IHdoZW4gd2UgZmFsbGJhY2sgdG8gdGhlIGdlbmVyaWMgQVBJLCBidXQg b3RoZXJ3aXNlLCBJJ20gZmluZSB3aXRoCm1ha2luZyAtPnN1cHBvcnRzX29wKCkgbWFuZGF0b3J5 IGFuZCBvbmx5IHByb3ZpZGluZyB0aGUgZ2VuZXJpYyBjaGVja3MKYXMgYSBoZWxwZXIuCgo+IAo+ IElmIHdlIHRha2UgdGhlIGV4YW1wbGUgb2YgdGhlIHNhbWE1ZDIgUVNQSSBjb250cm9sbGVyLCB3 ZSBjYW4gdXNlIG1vcmUgdGhhbiBvbmUKPiBJL08gbGluZSBvbmx5IHdoZW4gY29uZmlndXJlIGlu ICJzZXJpYWwgZmxhc2ggbWVtb3J5IiBtb2RlLiBIb3dldmVyIHdoZW4gaW4gInNwaSIKPiBtb2Rl LCB3aGVuIGNhbiBvbmx5IHVzZSByZWd1bGFyIE1PU0kgYW5kIE1JU08gbGluZXMuCj4gCj4gV2l0 aCBzcGlfbWVtX3N1cHBvcnRzX29wKCkgYXMgcHJvcG9zZWQgYmVsb3csIHdlIHdvdWxkIGhhdmUg dG8gc2V0IGJvdGggU1BJX1JYX1FVQUQKPiBhbmQgU1BJX1RYX1FVQUQgdG8gYWxsb3cgRmFzdCBS ZWFkIDEtNC00IHdoZW4gaW4gInNlcmlhbCBmbGFzaCBtZW1vcnkiIG1vZGUuCj4gSG93ZXZlciB3 aXRoIG90aGVyIFNQSSBkZXZpY2VzLCBoZW5jZSB3aGVuIGluICJzcGkiIG1vZGUsIHRoZSBTUElf e1IsVH1YX1FVQUQgZmxhZ3MKPiB3b3VsZCBzdGlsbCBiZSBzZXQgdGhvdWdoIHRoZSBjb250cm9s bGVyIGNhbm5vdCBzdXBwb3J0IG1vcmUgdGhhbiBhIHNpbmdsZSBJL08gbGluZS4KCk9rYXksIHRo YXQncyBhIGdvb2QgcmVhc29uIHRvIGdldCB0aGlzIGdlbmVyaWMgY2hlY2sgb3V0IG9mIHRoZQpz cGlfbWVtX3N1cHBvcnRzX29wKCkgcGF0aCBhbmQgaW5zdGVhZCBwcm92aWRlIGEgZ2VuZXJpYyBo ZWxwZXIgdGhhdApjYW4gYmUgdXNlZCBieSBkcml2ZXJzIHdoaWNoIHdhbnRzIHRvIHJlbHkgb24g U1BJX3tSLFR9WF97RFVBTCxRVUFEfQpmbGFncy4KCj4gCj4gVGhlIFNQSV97UixUfV97RFVBTCxR VUFEfSBmbGFncyBjb3VsZCBiZSB0ZXN0ZWQgaW4gYSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9m Cj4gc3BpX21lbV9zdXBwb3J0c19vcCgpIGJ1dCBzaG91bGQgbm90IGJlIHRlc3RlZCBhcyBtYW5k YXRvcnkgZmxhZ3MgZm9yIGFsbCBTUEkKPiAoZmxhc2gpIGNvbnRyb2xsZXJzLgoKQWdyZWVkLiBJ IHN0aWxsIHRoaW5rIHdlIG5lZWQgYSB3YXkgdG8gcmVzdHJpY3QgdGhlIG51bWJlciBvZiBJTy1s aW5lcwpiYXNlZCBvbiBib2FyZC1yZWxhdGVkIGluZm9ybWF0aW9uLCBhbmQgaWYgc3BpLT5tb2Rl IGlzIG5vdCBhcHByb3ByaWF0ZQpmb3IgdGhhdCwgd2UgbmVlZCBpdCBzb21ld2hlcmUgZWxzZS4g T3RoZXJ3aXNlLCB5b3UgbWlnaHQgZW5kLXVwCmFzc3VtaW5nIFFTUEkgaXMgc3VwcG9ydGVkIGJ5 IGJvdGggdGhlIGRldmljZSBhbmQgdGhlIGNvbnRyb2xsZXIsIHdoaWxlCnRoZSBjb25uZWN0aW9u cyBvbiB0aGUgYm9hcmQgaXMsIGZvciBpbnN0YW5jZSwgbGltaXRpbmcgaXQgdG8gU1BJIG9yCkR1 YWxTUEkuCgoKPiA+ICAgCj4gPj4+ICsKPiA+Pj4gKy8qKgo+ID4+PiArICogc3RydWN0IHNwaV9t ZW1fb3AgLSBkZXNjcmliZXMgYSBTUEkgbWVtb3J5IG9wZXJhdGlvbgo+ID4+PiArICogQGNtZC5i dXN3aWR0aDogbnVtYmVyIG9mIElPIGxpbmVzIHVzZWQgdG8gdHJhbnNtaXQgdGhlIGNvbW1hbmQK PiA+Pj4gKyAqIEBjbWQub3Bjb2RlOiBvcGVyYXRpb24gb3Bjb2RlCj4gPj4+ICsgKiBAYWRkci5u Ynl0ZXM6IG51bWJlciBvZiBhZGRyZXNzIGJ5dGVzIHRvIHNlbmQuIENhbiBiZSB6ZXJvIGlmIHRo ZSBvcGVyYXRpb24KPiA+Pj4gKyAqCQkgZG9lcyBub3QgbmVlZCB0byBzZW5kIGFuIGFkZHJlc3MK PiA+Pj4gKyAqIEBhZGRyLmJ1c3dpZHRoOiBudW1iZXIgb2YgSU8gbGluZXMgdXNlZCB0byB0cmFu c21pdCB0aGUgYWRkcmVzcyBjeWNsZXMKPiA+Pj4gKyAqIEBhZGRyLmJ1ZjogYnVmZmVyIHN0b3Jp bmcgdGhlIGFkZHJlc3MgYnl0ZXMKPiA+Pj4gKyAqIEBkdW1teS5uYnl0ZXM6IG51bWJlciBvZiBk dW1teSBieXRlcyB0byBzZW5kIGFmdGVyIGFuIG9wY29kZSBvciBhZGRyZXNzLiBDYW4KPiA+Pj4g KyAqCQkgIGJlIHplcm8gaWYgdGhlIG9wZXJhdGlvbiBkb2VzIG5vdCByZXF1aXJlIGR1bW15IGJ5 dGVzCj4gPj4+ICsgKiBAZHVtbXkuYnVzd2lkdGg6IG51bWJlciBvZiBJTyBsYW5lcyB1c2VkIHRv IHRyYW5zbWl0IHRoZSBkdW1teSBieXRlcwo+ID4+PiArICogQGRhdGEuYnVzd2lkdGg6IG51bWJl ciBvZiBJTyBsYW5lcyB1c2VkIHRvIHNlbmQvcmVjZWl2ZSB0aGUgZGF0YQo+ID4+PiArICogQGRh dGEuZGlyOiBkaXJlY3Rpb24gb2YgdGhlIHRyYW5zZmVyCj4gPj4+ICsgKiBAZGF0YS5idWYuaW46 IGlucHV0IGJ1ZmZlcgo+ID4+PiArICogQGRhdGEuYnVmLm91dDogb3V0cHV0IGJ1ZmZlcgo+ID4+ PiArICovCj4gPj4+ICtzdHJ1Y3Qgc3BpX21lbV9vcCB7Cj4gPj4+ICsJc3RydWN0IHsKPiA+Pj4g KwkJdTggYnVzd2lkdGg7Cj4gPj4+ICsJCXU4IG9wY29kZTsKPiA+Pj4gKwl9IGNtZDsKPiA+Pj4g Kwo+ID4+PiArCXN0cnVjdCB7Cj4gPj4+ICsJCXU4IG5ieXRlczsKPiA+Pj4gKwkJdTggYnVzd2lk dGg7Cj4gPj4+ICsJCWNvbnN0IHU4ICpidWY7ICAgIAo+ID4+Cj4gPj4gRm9yIHRoZSBhZGRyZXNz IHZhbHVlLCBJIHdvdWxkIHJhdGhlciB1c2Ugc29tZSBsb2ZmX3QgdHlwZSwgaW5zdGVhZCBvZgo+ ID4+IGNvbnN0IHU4ICouIAo+ID4+IEFjdHVhbGx5LCBtb3N0IChpZiBub3QgYWxsKSBTUEkgZmxh c2ggY29udHJvbGxlcnMgaGF2ZSBzb21lIGhhcmR3YXJlCj4gPj4gcmVnaXN0ZXIgdG8gc2V0IHRo ZSBhZGRyZXNzIHZhbHVlIG9mIHRoZSBTUEkgZmxhc2ggY29tbWFuZCB0byBiZQo+ID4+IHNlbnQu IEhlbmNlIGhhdmluZyB0aGlzIHZhbHVlIGRpcmVjdGx5IGluIHRoZSByaWdodCBmb3JtYXQgd291 bGQgYXZvaWQgdG8KPiA+PiBjb252ZXJ0LiAgCj4gPiAKPiA+IFdoYXQgaXMgdGhlIGFwcHJvcHJp YXRlIGZvcm1hdD8gQW4gYWRkcmVzcyBlbmNvZGVkIGluIGEgNjQtYml0IGludGVnZXIKPiA+IGRv ZXMgbm90IGdpdmUgYW55IGluZm9ybWF0aW9uIG9uIGhvdyB0aGVzZSBieXRlcyBzaG91bGQgYmUg dHJhbnNtaXR0ZWQKPiA+IG9uIHRoZSBidXMuIFNQSSBOT1IgaXMgcGFzc2luZyB0aGUgYWRkcmVz cyBpbiBiaWcgZW5kaWFuLCBTUEkgTkFORCBzZWVtcwo+ID4gdG8gZG8gdGhlIHNhbWUsIGJ1dCB3 ZSdyZSBub3Qgc3VyZSB0aGlzIHdpbGwgYmUgdGhlIGNhc2UgZm9yIGFsbCBraW5kIG9mCj4gPiBt ZW1vcmllcyBvciBkZXZpY2VzIHVzaW5nIHRoaXMgc3BpLW1lbSBwcm90b2NvbC4KPiA+IAo+ID4g QWxzbywgYnkgcGFzc2luZyBpdCB0aHJvdWdoIGFuIGludGVnZXIgd2UgbGltaXQgb3Vyc2VsdmVz IHRvIDggYnl0ZXMuCj4gPiBUaGF0IHNob3VsZCBiZSBlbm91Z2gsIGJ1dCB3aG8ga25vd3MgOi0p Lgo+ID4gCj4gPiBJZiB3ZSBnbyBmb3IgdGhpcyBsb2ZmX3QgZmllbGQsIHdlJ2xsIGhhdmUgdG8g YWRkIGFuIGVuZGlhbm5lc3MgZmllbGQKPiA+IGhlcmUgYW5kIGZvcmNlIGFsbCBkcml2ZXJzIHRv IGNoZWNrIGl0Lgo+ID4gIAo+IAo+IEkgZG9uJ3QgdGhpbmsgd2UgbmVlZCBhbnkgZW5kaWFubmVz cyBmaWVsZC4gV2UgYWxyZWFkeSB1c2UgbG9mZl90IG9ubHksCj4gd2l0aG91dCBhZGRpdGlvbmFs IGVuZGlhbm5lc3MgcGFyYW1hdGVyLCBpbiBzcGktbm9yIGJ1dCBhbHNvIGluIHRoZSBhYm92ZQo+ IE1URCBsYXllciAoc2VlICdzdHJ1Y3QgbXRkX2luZm8nKSBhbmQgdGlsbCBub3cgaXQgaGFzIGp1 c3Qgd29ya2VkIGZpbmUuCgpJdCdzIG5vdCBhYm91dCB0aGUgTVREIGxheWVyLiBDYW4geW91IHBy ZWRpY3QgdGhhdCBhbGwgZGV2aWNlcyB3aWxsCnRyYW5zbWl0IHRoZSBhZGRyZXNzIGluIGJpZy1l bmRpYW4/IEkgY2FuJ3QuCgo+IAo+IE1vc3QsIGlmIG5vdCBhbGwsIFNQSSBmbGFzaCBjb250cm9s bGVycyBoYXZlIGEgZGVkaWNhdGVkIGZpZWxkIGluIG9uZSBvZgo+IHRoZWlyIHJlZ2lzdGVycyB0 byB3cml0ZSB0aGUgYWRkcmVzcyB2YWx1ZSBpbnRvIGl0LiBHZW5lcmFsbHksIHRoaXMgcmVnaXN0 ZXIKPiBpcyB3cml0dGVuIHdpdGggYW4gaW50ZWdlciBpbiB0aGUgQ1BVIG5hdGl2ZSBieXRlIG9y ZGVyIHNvIG5vIG5lZWQgdG8gY29udmVydC4KCkl0J3Mgbm90IGFib3V0IGhvdyB5b3Ugd3JpdGUg eW91ciByZWdpc3RlciwgYnV0IGluIHdoaWNoIG9yZGVyIGFkZHJlc3MKYnl0ZXMgYXJlIHRyYW5z bWl0dGVkIG9uIHRoZSBTUEkgd2lyZS4gQ3VycmVudGx5LCBTUEkgTk9SIHVzZSB0aGUgTVNCCmZp cnN0IHNjaGVtZSwgYnV0IHRoYXQgd29uJ3QgbmVjZXNzYXJpbHkgYmUgdGhlIGNhc2UgZm9yIG90 aGVyIFNQSQpkZXZpY2VzLgoKPiAKPiBBbmQgYW55d2F5LCBpZiBzb21lIGNvbnZlcnNpb24gaXMg ZXZlciBuZWVkZWQsIHRoZSBTUEkgZmxhc2ggY29udHJvbGxlcgo+IGRyaXZlciBrbm93cyBpdCBz byB3ZSBjb3VsZCBzZXQgYXMgYSBydWxlIHRoYXQgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZQo+ IGFkZHJlc3MgaXMgYWx3YXlzIHN0b3JlZCBpbiB0aGUgbmF0aXZlIENQVSBieXRlIG9yZGVyLiBB dCBsZWFzdCBtb3N0IFNQSSBmbGFzaAo+IGNvbnRyb2xsZXIgZHJpdmVyIHdvbid0IGhhdmUgdG8g Y29udmVydCBmcm9tIGEgY29uc3QgdTggKiB0byBzb21lIHVuc2lnbmVkCj4gaW50ZWdyYWwgdHlw ZSBtb3JlIHN1aXRlZCB0byB0aGVpciByZWdpc3RlciBhY2Nlc3Nlcy4KClRoZXkgd2lsbCBoYXZl IHRvIGF0IGxlYXN0IG1ha2Ugc3VyZSBpdCdzIHByb3Blcmx5IGVuY29kZWQ6IGlmIHRoZQpkZXZp Y2UgaXMgZXhwZWN0aW5nIHRoZSBhZGRyZXNzIHRvIGJlIHRyYW5zbWl0dGVkIExTQiBmaXJzdCAo QUtBCmxpdHRsZS1lbmRpYW4pLCB0aGV5J2xsIGhhdmUgdG8gc3dhcCBhZGRyZXNzIGJ5dGVzIGJl Zm9yZSB3cml0aW5nIHRoZQp2YWx1ZSB0byB0aGUgcmVnaXN0ZXIuCgo+ICAKPiA+PiBBRkFJSywg b25seSBtMjVwODAgbmVlZHMgdG8gY29udmVydCBmcm9tIGxvZmZfdCB0byB1OCAqIGFuZCBvbmx5 Cj4gPj4gd2hlbiB1c2luZyB0aGUgcmVndWxhciBTUEkgQVBJLCBpZSBzcGlfc3luYygpLCBhcyB0 aGUgJ3N0cnVjdAo+ID4+IHNwaV9mbGFzaF9yZWFkX21lc3NhZycgYWxyZWFkeSB1c2VzIHNvbWUg aW50ZWdyYWwgdHlwZSB0b28uICAKPiA+IAo+ID4gQW5kIEknbSBub3Qgc3VyZSB0aGlzIHdhcyBh IGdvb2QgaWRlYS4KPiA+ICAgCj4gPj4KPiA+PiAgCj4gPj4+ICsJfSBhZGRyOwo+ID4+PiArCj4g Pj4+ICsJc3RydWN0IHsKPiA+Pj4gKwkJdTggbmJ5dGVzOwo+ID4+PiArCQl1OCBidXN3aWR0aDsK PiA+Pj4gKwl9IGR1bW15Owo+ID4+PiArCj4gPj4+ICsJc3RydWN0IHsKPiA+Pj4gKwkJdTggYnVz d2lkdGg7Cj4gPj4+ICsJCWVudW0gc3BpX21lbV9kYXRhX2RpciBkaXI7Cj4gPj4+ICsJCXVuc2ln bmVkIGludCBuYnl0ZXM7Cj4gPj4+ICsJCS8qIGJ1Zi57aW4sb3V0fSBtdXN0IGJlIERNQS1hYmxl LiAqLwo+ID4+PiArCQl1bmlvbiB7Cj4gPj4+ICsJCQl2b2lkICppbjsKPiA+Pj4gKwkJCWNvbnN0 IHZvaWQgKm91dDsKPiA+Pj4gKwkJfSBidWY7Cj4gPj4+ICsJfSBkYXRhOyAgICAKPiA+Pgo+ID4+ IEFsc28sIHlvdSBzaG91bGQgYWRkIGFub3RoZXIgbWVtYmVyIGluIHRoaXMgc3RydWN0dXJlIHRv IHNldCB0aGUgJ3R5cGUnIG9mCj4gPj4gb3BlcmF0aW9uIGZvciB0aGUgU1BJIGZsYXNoIGNvbW1h bmQ6Cj4gPj4gLSByZWdpc3RlciByZWFkCj4gPj4gLSByZWdpc3RlciB3cml0ZQo+ID4+IC0gbWVt b3J5IHJlYWQKPiA+PiAtIG1lbW9yeSB3cml0ZQo+ID4+IC0gbWVtb3J5IGVyYXNlCj4gPj4gWy0g U0ZEUCByZWFkID8gXQo+ID4+IFstIE9UUCByZWFkL3dyaXRlID8gXSAgCj4gPiAKPiA+IE5vLCBy ZWFsbHksIHRoYXQncyBub3QgYmVsb25naW5nIGhlcmUuIEl0J3MgZW50aXJlbHkgU1BJIE5PUiBz cGVjaWZpYy4KPiA+ICAgCj4gCj4gSSBkaXNhZ3JlZSB3aXRoIHlvdSBvbiB0aGF0LiBFeGNlcHQg Zm9yIFNGRFAgb2YgY291cnNlLCB0aGlzIHdpbGwgYWxzbyBhcHBseSB0bwo+IFNQSSBOQU5EIGFz IHdlbGwuIEFuZCB0aGlzIGluZm9ybWF0aW9uIHNob3VsZCBiZSBwYXNzZWQgZG93biB0byB0aGUg U1BJIChmbGFzaCkKPiBjb250cm9sbGVyIGRyaXZlciwgaW5zdGVhZCBvZiBiZWluZyBsb3N0IGF0 IHRoZSBTUEkgTkFORC9OT1IgbGV2ZWxzLAoKSSdtIG5vdCBzYXlpbmcgd2Ugc2hvdWxkIGtlZXAg dGhlc2UgaW5mb3JtYXRpb24gYXQgdGhlIHNwaS1ub3IvbmFuZApsZXZlbCwganVzdCBzYXlpbmcg d2Ugc2hvdWxkIGZpbmQgYSB3YXkgdG8gbWFrZSBpdCBsb29rIGxpa2UgYSBnZW5lcmljCnNvbHV0 aW9uIHNvIHRoYXQgU1BJIGNvbnRyb2xsZXJzIGRvbid0IGhhdmUgdG8gZ3Vlc3Mgd2hhdCB0aGV5 IHNob3VsZApkbyBiYXNlZCBvbiB0aGUgbWVtb3J5IG9wZXJhdGlvbiB0eXBlLgoKVHlwaWNhbGx5 LCB3aHkgc2hvdWxkIGEgU1BJIGNvbnRyb2xsZXIgY2FyZSBhYm91dCB3aGV0aGVyIHRoZSBvcGVy YXRpb24KaXMgYW4gZXJhc2UsIGEgcmVnIHJlYWQgb3IgYSByZWcgd3JpdGUuIEZyb20gdGhlIGNv bnRyb2xsZXIgUG9WLCBpdCdzCmp1c3QgYW4gc3BpLW1lbSBvcGVyYXRpb24uClRoZSB1c2UgY2Fz ZXMgeW91IHdhbnQgdG8gb3B0aW1pemUgYXJlIHJlYWQvd3JpdGUgdXNlci1kYXRhLCBhbmQgdGhp cwpjYW4gYmUgZG9uZSBpbiBkaWZmZXJlbnQgd2F5cyAoZGlyZWN0IG1lbW9yeSBtYXBwaW5nIGlz IG9uZSBzb2x1dGlvbikuCgo+IHNvIHRoZSBTUEkKPiBjb250cm9sbGVyIGRyaXZlciBjb3VsZCB0 YWtlIHRoZSBwcm9wZXIgYWN0aW9ucyAoZGF0YSBjYWNoZSBmbHVzaC9pbnZhbGlkYXRpb24KPiBm b3IgbWVtb3J5IG9wZXJhdGlvbnMsCgpUaGlzIG9uZSBoYXMgdG8gZG8gd2l0aCBkaXJlY3QgbWFw cGluZywgc28gYW4gQVBJIHRvIGFsbG93IGRpcmVjdAptYXBwaW5nIHNob3VsZCBoZWxwIGFkZHJl c3MgdGhhdC4KCj4gZW5hYmxpbmcvZGlzYWJsaW5nIG9uLXRoZS1mbHkgZGF0YSBzY3JhbWJsaW5n LAoKQW5kIHdoYXQncyB0aGUgcHJvYmxlbSB3aXRoIHBhc3NpbmcgdGhlIHNjcmFtYmxlIGluZm9y bWF0aW9uIG9uIGEKcGVyLW9wZXJhdGlvbiBiYXNpcyBhbmQgbGV0dGluZyB0aGUgdXBwZXIgbGF5 ZXIgZGVjaWRlIHdoZW4gaXQncyBhIGdvb2QKaWRlYSB0byB1c2UgaXQgb3Igbm90PwoKPiBhbmQg b3RoZXIKPiBjb250cm9sbGVyIHNwZWNpZmljIGNvbnN0cmFpbnRzKS4KCkNvdWxkIHlvdSBiZSBt b3JlIHNwZWNpZmljPwoKSSByZWFsbHkgaGF2ZSB0aGUgZmVlbGluZyB5b3UncmUgcmV2aWV3aW5n IHRoYXQgd2l0aCB5b3VyIFNQSSBOT1IKbWFpbnRhaW5lciBleWUsIHdoaWxlLCBhcyBJIHNhaWQg c2V2ZXJhbCB0aW1lcywgSSdtIHRyeWluZyB0bwphZGRyZXNzIHRoZSBwcm9ibGVtIG1vcmUgZ2Vu ZXJpY2FsbHkuIE15IGludGVudCBpcyBub3QgdG8gbW92ZSBldmVyeQpiaXRzIHlvdSBoYXZlIGlu IHRoZSBzcGktbm9yIGxheWVyIHRvIHRoZSBzcGkgbGF5ZXIuIEluc3RlYWQsIHdlIGNhbgpwcm9n cmVzc2l2ZWx5IHByb3ZpZGUgYSBjb25zaXN0ZW50IEFQSSB0aGF0IGhlbHBzIHlvdSBkZWFsIHdp dGggbWVtb3J5CmRldmljZXMgKEkgZ3Vlc3Mgc3VwcG9ydGluZyBkaXJlY3QgbWVtb3J5IG1hcHBp bmcgaXMgdGhlIG5leHQgc3RlcCBpZgp3ZSB3YW50IHRvIGdldCB0aGUgYmVzdCBwZXJmcyBvdXQg b2YgdGhlc2UgYWR2YW5jZWQgY29udHJvbGxlcnMpIGluIGEKZGV2aWNlIGFnbm9zdGljIGZhc2hp b24uCgpSZWdhcmRzLAoKQm9yaXMKCi0tIApCb3JpcyBCcmV6aWxsb24sIEJvb3RsaW4gKGZvcm1l cmx5IEZyZWUgRWxlY3Ryb25zKQpFbWJlZGRlZCBMaW51eCBhbmQgS2VybmVsIGVuZ2luZWVyaW5n Cmh0dHBzOi8vYm9vdGxpbi5jb20KCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fXwpMaW51eCBNVEQgZGlzY3Vzc2lvbiBtYWlsaW5nIGxpc3QKaHR0 cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1tdGQvCg==