OpenCores
URL https://opencores.org/ocsvn/adv_debug_sys/adv_debug_sys/trunk

Subversion Repositories adv_debug_sys

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /adv_debug_sys/tags
    from Rev 26 to Rev 27
    Reverse comparison

Rev 26 → Rev 27

/ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/src/ajb_block_diagram.odg Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/src/ajb_block_diagram.odg Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt (nonexistent)
ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/gpl-2.0.txt =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/gpl-2.0.txt (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/gpl-2.0.txt (nonexistent) @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_parallel.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_parallel.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_parallel.h (nonexistent) @@ -1,19 +0,0 @@ - -#ifndef _CABLE_PARALLEL_H_ -#define _CABLE_PARALLEL_H_ - -#include - -int cable_parallel_init(); -int cable_parallel_opt(int c, char *str); -void cable_parallel_phys_wait(); - -int cable_xpc3_inout(uint8_t value, uint8_t *inval); -int cable_xpc3_out(uint8_t value); - -int cable_xess_inout(uint8_t value, uint8_t *inval); -int cable_xess_out(uint8_t value); - - - -#endif Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/spr-defs.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/spr-defs.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/spr-defs.h (nonexistent) @@ -1,581 +0,0 @@ -/* spr-defs.h -- Defines OR1K architecture specific special-purpose registers - - Copyright (C) 1999 Damjan Lampret, lampret@opencores.org - Copyright (C) 2008 Embecosm Limited - - Contributor Jeremy Bennett - - This file is part of OpenRISC 1000 Architectural Simulator. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along - with this program. If not, see . */ - -/* This program is commented throughout in a fashion suitable for processing - with Doxygen. */ - - -#ifndef SPR_DEFS__H -#define SPR_DEFS__H - -/* Definition of special-purpose registers (SPRs). */ - -#define MAX_GRPS (32) -#define MAX_SPRS_PER_GRP_BITS (11) -#define MAX_SPRS_PER_GRP (1 << MAX_SPRS_PER_GRP_BITS) -#define MAX_SPRS (0x10000) - -/* Base addresses for the groups */ -#define SPRGROUP_SYS (0<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_DMMU (1<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_IMMU (2<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_DC (3<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_IC (4<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_MAC (5<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_D (6<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_PC (7<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_PM (8<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_PIC (9<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_TT (10<< MAX_SPRS_PER_GRP_BITS) - -/* System control and status group */ -#define SPR_VR (SPRGROUP_SYS + 0) -#define SPR_UPR (SPRGROUP_SYS + 1) -#define SPR_CPUCFGR (SPRGROUP_SYS + 2) -#define SPR_DMMUCFGR (SPRGROUP_SYS + 3) -#define SPR_IMMUCFGR (SPRGROUP_SYS + 4) -#define SPR_DCCFGR (SPRGROUP_SYS + 5) -#define SPR_ICCFGR (SPRGROUP_SYS + 6) -#define SPR_DCFGR (SPRGROUP_SYS + 7) -#define SPR_PCCFGR (SPRGROUP_SYS + 8) -#define SPR_NPC (SPRGROUP_SYS + 16) /* CZ 21/06/01 */ -#define SPR_SR (SPRGROUP_SYS + 17) /* CZ 21/06/01 */ -#define SPR_PPC (SPRGROUP_SYS + 18) /* CZ 21/06/01 */ -#define SPR_EPCR_BASE (SPRGROUP_SYS + 32) /* CZ 21/06/01 */ -#define SPR_EPCR_LAST (SPRGROUP_SYS + 47) /* CZ 21/06/01 */ -#define SPR_EEAR_BASE (SPRGROUP_SYS + 48) -#define SPR_EEAR_LAST (SPRGROUP_SYS + 63) -#define SPR_ESR_BASE (SPRGROUP_SYS + 64) -#define SPR_ESR_LAST (SPRGROUP_SYS + 79) -#define SPR_GPR_BASE (SPRGROUP_SYS + 1024) -#define SPR_GPR_LAST (SPRGROUP_SYS + 1535) -#define MAX_GPRS 32 // Does this really belong here? No. --NAY - -/* Data MMU group */ -#define SPR_DMMUCR (SPRGROUP_DMMU + 0) -#define SPR_DTLBMR_BASE(WAY) (SPRGROUP_DMMU + 0x200 + (WAY) * 0x100) -#define SPR_DTLBMR_LAST(WAY) (SPRGROUP_DMMU + 0x27f + (WAY) * 0x100) -#define SPR_DTLBTR_BASE(WAY) (SPRGROUP_DMMU + 0x280 + (WAY) * 0x100) -#define SPR_DTLBTR_LAST(WAY) (SPRGROUP_DMMU + 0x2ff + (WAY) * 0x100) - -/* Instruction MMU group */ -#define SPR_IMMUCR (SPRGROUP_IMMU + 0) -#define SPR_ITLBMR_BASE(WAY) (SPRGROUP_IMMU + 0x200 + (WAY) * 0x100) -#define SPR_ITLBMR_LAST(WAY) (SPRGROUP_IMMU + 0x27f + (WAY) * 0x100) -#define SPR_ITLBTR_BASE(WAY) (SPRGROUP_IMMU + 0x280 + (WAY) * 0x100) -#define SPR_ITLBTR_LAST(WAY) (SPRGROUP_IMMU + 0x2ff + (WAY) * 0x100) - -/* Data cache group */ -#define SPR_DCCR (SPRGROUP_DC + 0) -#define SPR_DCBPR (SPRGROUP_DC + 1) -#define SPR_DCBFR (SPRGROUP_DC + 2) -#define SPR_DCBIR (SPRGROUP_DC + 3) -#define SPR_DCBWR (SPRGROUP_DC + 4) -#define SPR_DCBLR (SPRGROUP_DC + 5) -#define SPR_DCR_BASE(WAY) (SPRGROUP_DC + 0x200 + (WAY) * 0x200) -#define SPR_DCR_LAST(WAY) (SPRGROUP_DC + 0x3ff + (WAY) * 0x200) - -/* Instruction cache group */ -#define SPR_ICCR (SPRGROUP_IC + 0) -#define SPR_ICBPR (SPRGROUP_IC + 1) -#define SPR_ICBIR (SPRGROUP_IC + 2) -#define SPR_ICBLR (SPRGROUP_IC + 3) -#define SPR_ICR_BASE(WAY) (SPRGROUP_IC + 0x200 + (WAY) * 0x200) -#define SPR_ICR_LAST(WAY) (SPRGROUP_IC + 0x3ff + (WAY) * 0x200) - -/* MAC group */ -#define SPR_MACLO (SPRGROUP_MAC + 1) -#define SPR_MACHI (SPRGROUP_MAC + 2) - -/* Debug group */ -#define SPR_DVR(N) (SPRGROUP_D + (N)) -#define SPR_DCR(N) (SPRGROUP_D + 8 + (N)) -#define SPR_DMR1 (SPRGROUP_D + 16) -#define SPR_DMR2 (SPRGROUP_D + 17) -#define SPR_DWCR0 (SPRGROUP_D + 18) -#define SPR_DWCR1 (SPRGROUP_D + 19) -#define SPR_DSR (SPRGROUP_D + 20) -#define SPR_DRR (SPRGROUP_D + 21) - -/* Performance counters group */ -#define SPR_PCCR(N) (SPRGROUP_PC + (N)) -#define SPR_PCMR(N) (SPRGROUP_PC + 8 + (N)) - -/* Power management group */ -#define SPR_PMR (SPRGROUP_PM + 0) - -/* PIC group */ -#define SPR_PICMR (SPRGROUP_PIC + 0) -#define SPR_PICPR (SPRGROUP_PIC + 1) -#define SPR_PICSR (SPRGROUP_PIC + 2) - -/* Tick Timer group */ -#define SPR_TTMR (SPRGROUP_TT + 0) -#define SPR_TTCR (SPRGROUP_TT + 1) - -/* - * Bit definitions for the Version Register - * - */ -#define SPR_VR_VER 0xff000000 /* Processor version */ -#define SPR_VR_CFG 0x00ff0000 /* Processor configuration */ -#define SPR_VR_RES 0x00ff0000 /* Reserved */ -#define SPR_VR_REV 0x0000003f /* Processor revision */ - -#define SPR_VR_VER_OFF 24 -#define SPR_VR_CFG_OFF 16 -#define SPR_VR_REV_OFF 0 - -/* - * Bit definitions for the Unit Present Register - * - */ -#define SPR_UPR_UP 0x00000001 /* UPR present */ -#define SPR_UPR_DCP 0x00000002 /* Data cache present */ -#define SPR_UPR_ICP 0x00000004 /* Instruction cache present */ -#define SPR_UPR_DMP 0x00000008 /* Data MMU present */ -#define SPR_UPR_IMP 0x00000010 /* Instruction MMU present */ -#define SPR_UPR_MP 0x00000020 /* MAC present */ -#define SPR_UPR_DUP 0x00000040 /* Debug unit present */ -#define SPR_UPR_PCUP 0x00000080 /* Performance counters unit present */ -#define SPR_UPR_PMP 0x00000100 /* Power management present */ -#define SPR_UPR_PICP 0x00000200 /* PIC present */ -#define SPR_UPR_TTP 0x00000400 /* Tick timer present */ -#define SPR_UPR_RES 0x00fe0000 /* Reserved */ -#define SPR_UPR_CUP 0xff000000 /* Context units present */ - -/* - * JPB: Bit definitions for the CPU configuration register - * - */ -#define SPR_CPUCFGR_NSGF 0x0000000f /* Number of shadow GPR files */ -#define SPR_CPUCFGR_CGF 0x00000010 /* Custom GPR file */ -#define SPR_CPUCFGR_OB32S 0x00000020 /* ORBIS32 supported */ -#define SPR_CPUCFGR_OB64S 0x00000040 /* ORBIS64 supported */ -#define SPR_CPUCFGR_OF32S 0x00000080 /* ORFPX32 supported */ -#define SPR_CPUCFGR_OF64S 0x00000100 /* ORFPX64 supported */ -#define SPR_CPUCFGR_OV64S 0x00000200 /* ORVDX64 supported */ -#define SPR_CPUCFGR_RES 0xfffffc00 /* Reserved */ - -/* - * JPB: Bit definitions for the Debug configuration register and other - * constants. - * - */ - -#define SPR_DCFGR_NDP 0x00000007 /* Number of matchpoints mask */ -#define SPR_DCFGR_NDP1 0x00000000 /* One matchpoint supported */ -#define SPR_DCFGR_NDP2 0x00000001 /* Two matchpoints supported */ -#define SPR_DCFGR_NDP3 0x00000002 /* Three matchpoints supported */ -#define SPR_DCFGR_NDP4 0x00000003 /* Four matchpoints supported */ -#define SPR_DCFGR_NDP5 0x00000004 /* Five matchpoints supported */ -#define SPR_DCFGR_NDP6 0x00000005 /* Six matchpoints supported */ -#define SPR_DCFGR_NDP7 0x00000006 /* Seven matchpoints supported */ -#define SPR_DCFGR_NDP8 0x00000007 /* Eight matchpoints supported */ -#define SPR_DCFGR_WPCI 0x00000008 /* Watchpoint counters implemented */ - -#define MATCHPOINTS_TO_NDP(n) (1 == n ? SPR_DCFGR_NDP1 : \ - 2 == n ? SPR_DCFGR_NDP2 : \ - 3 == n ? SPR_DCFGR_NDP3 : \ - 4 == n ? SPR_DCFGR_NDP4 : \ - 5 == n ? SPR_DCFGR_NDP5 : \ - 6 == n ? SPR_DCFGR_NDP6 : \ - 7 == n ? SPR_DCFGR_NDP7 : SPR_DCFGR_NDP8) -#define MAX_MATCHPOINTS 8 -#define MAX_WATCHPOINTS (MAX_MATCHPOINTS + 2) - -/* - * Bit definitions for the Supervision Register - * - */ -#define SPR_SR_SM 0x00000001 /* Supervisor Mode */ -#define SPR_SR_TEE 0x00000002 /* Tick timer Exception Enable */ -#define SPR_SR_IEE 0x00000004 /* Interrupt Exception Enable */ -#define SPR_SR_DCE 0x00000008 /* Data Cache Enable */ -#define SPR_SR_ICE 0x00000010 /* Instruction Cache Enable */ -#define SPR_SR_DME 0x00000020 /* Data MMU Enable */ -#define SPR_SR_IME 0x00000040 /* Instruction MMU Enable */ -#define SPR_SR_LEE 0x00000080 /* Little Endian Enable */ -#define SPR_SR_CE 0x00000100 /* CID Enable */ -#define SPR_SR_F 0x00000200 /* Condition Flag */ -#define SPR_SR_CY 0x00000400 /* Carry flag */ -#define SPR_SR_OV 0x00000800 /* Overflow flag */ -#define SPR_SR_OVE 0x00001000 /* Overflow flag Exception */ -#define SPR_SR_DSX 0x00002000 /* Delay Slot Exception */ -#define SPR_SR_EPH 0x00004000 /* Exception Prefix High */ -#define SPR_SR_FO 0x00008000 /* Fixed one */ -#define SPR_SR_SUMRA 0x00010000 /* Supervisor SPR read access */ -#define SPR_SR_RES 0x0ffe0000 /* Reserved */ -#define SPR_SR_CID 0xf0000000 /* Context ID */ - -/* - * Bit definitions for the Data MMU Control Register - * - */ -#define SPR_DMMUCR_P2S 0x0000003e /* Level 2 Page Size */ -#define SPR_DMMUCR_P1S 0x000007c0 /* Level 1 Page Size */ -#define SPR_DMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */ -#define SPR_DMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */ - -/* - * Bit definitions for the Instruction MMU Control Register - * - */ -#define SPR_IMMUCR_P2S 0x0000003e /* Level 2 Page Size */ -#define SPR_IMMUCR_P1S 0x000007c0 /* Level 1 Page Size */ -#define SPR_IMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */ -#define SPR_IMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */ - -/* - * Bit definitions for the Data TLB Match Register - * - */ -#define SPR_DTLBMR_V 0x00000001 /* Valid */ -#define SPR_DTLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */ -#define SPR_DTLBMR_CID 0x0000003c /* Context ID */ -#define SPR_DTLBMR_LRU 0x000000c0 /* Least Recently Used */ -#define SPR_DTLBMR_VPN 0xfffff000 /* Virtual Page Number */ - -/* - * Bit definitions for the Data TLB Translate Register - * - */ -#define SPR_DTLBTR_CC 0x00000001 /* Cache Coherency */ -#define SPR_DTLBTR_CI 0x00000002 /* Cache Inhibit */ -#define SPR_DTLBTR_WBC 0x00000004 /* Write-Back Cache */ -#define SPR_DTLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */ -#define SPR_DTLBTR_A 0x00000010 /* Accessed */ -#define SPR_DTLBTR_D 0x00000020 /* Dirty */ -#define SPR_DTLBTR_URE 0x00000040 /* User Read Enable */ -#define SPR_DTLBTR_UWE 0x00000080 /* User Write Enable */ -#define SPR_DTLBTR_SRE 0x00000100 /* Supervisor Read Enable */ -#define SPR_DTLBTR_SWE 0x00000200 /* Supervisor Write Enable */ -#define SPR_DTLBTR_PPN 0xfffff000 /* Physical Page Number */ - -/* - * Bit definitions for the Instruction TLB Match Register - * - */ -#define SPR_ITLBMR_V 0x00000001 /* Valid */ -#define SPR_ITLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */ -#define SPR_ITLBMR_CID 0x0000003c /* Context ID */ -#define SPR_ITLBMR_LRU 0x000000c0 /* Least Recently Used */ -#define SPR_ITLBMR_VPN 0xfffff000 /* Virtual Page Number */ - -/* - * Bit definitions for the Instruction TLB Translate Register - * - */ -#define SPR_ITLBTR_CC 0x00000001 /* Cache Coherency */ -#define SPR_ITLBTR_CI 0x00000002 /* Cache Inhibit */ -#define SPR_ITLBTR_WBC 0x00000004 /* Write-Back Cache */ -#define SPR_ITLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */ -#define SPR_ITLBTR_A 0x00000010 /* Accessed */ -#define SPR_ITLBTR_D 0x00000020 /* Dirty */ -#define SPR_ITLBTR_SXE 0x00000040 /* User Read Enable */ -#define SPR_ITLBTR_UXE 0x00000080 /* User Write Enable */ -#define SPR_ITLBTR_PPN 0xfffff000 /* Physical Page Number */ - -/* - * Bit definitions for Data Cache Control register - * - */ -#define SPR_DCCR_EW 0x000000ff /* Enable ways */ - -/* - * Bit definitions for Insn Cache Control register - * - */ -#define SPR_ICCR_EW 0x000000ff /* Enable ways */ - -/* - * Bit definitions for Data Cache Configuration Register - * - */ - -#define SPR_DCCFGR_NCW 0x00000007 -#define SPR_DCCFGR_NCS 0x00000078 -#define SPR_DCCFGR_CBS 0x00000080 -#define SPR_DCCFGR_CWS 0x00000100 -#define SPR_DCCFGR_CCRI 0x00000200 -#define SPR_DCCFGR_CBIRI 0x00000400 -#define SPR_DCCFGR_CBPRI 0x00000800 -#define SPR_DCCFGR_CBLRI 0x00001000 -#define SPR_DCCFGR_CBFRI 0x00002000 -#define SPR_DCCFGR_CBWBRI 0x00004000 - -#define SPR_DCCFGR_NCW_OFF 0 -#define SPR_DCCFGR_NCS_OFF 3 -#define SPR_DCCFGR_CBS_OFF 7 - -/* - * Bit definitions for Instruction Cache Configuration Register - * - */ -#define SPR_ICCFGR_NCW 0x00000007 -#define SPR_ICCFGR_NCS 0x00000078 -#define SPR_ICCFGR_CBS 0x00000080 -#define SPR_ICCFGR_CCRI 0x00000200 -#define SPR_ICCFGR_CBIRI 0x00000400 -#define SPR_ICCFGR_CBPRI 0x00000800 -#define SPR_ICCFGR_CBLRI 0x00001000 - -#define SPR_ICCFGR_NCW_OFF 0 -#define SPR_ICCFGR_NCS_OFF 3 -#define SPR_ICCFGR_CBS_OFF 7 - -/* - * Bit definitions for Data MMU Configuration Register - * - */ - -#define SPR_DMMUCFGR_NTW 0x00000003 -#define SPR_DMMUCFGR_NTS 0x0000001C -#define SPR_DMMUCFGR_NAE 0x000000E0 -#define SPR_DMMUCFGR_CRI 0x00000100 -#define SPR_DMMUCFGR_PRI 0x00000200 -#define SPR_DMMUCFGR_TEIRI 0x00000400 -#define SPR_DMMUCFGR_HTR 0x00000800 - -#define SPR_DMMUCFGR_NTW_OFF 0 -#define SPR_DMMUCFGR_NTS_OFF 2 - -/* - * Bit definitions for Instruction MMU Configuration Register - * - */ - -#define SPR_IMMUCFGR_NTW 0x00000003 -#define SPR_IMMUCFGR_NTS 0x0000001C -#define SPR_IMMUCFGR_NAE 0x000000E0 -#define SPR_IMMUCFGR_CRI 0x00000100 -#define SPR_IMMUCFGR_PRI 0x00000200 -#define SPR_IMMUCFGR_TEIRI 0x00000400 -#define SPR_IMMUCFGR_HTR 0x00000800 - -#define SPR_IMMUCFGR_NTW_OFF 0 -#define SPR_IMMUCFGR_NTS_OFF 2 - -/* - * Bit definitions for Debug Control registers - * - */ -#define SPR_DCR_DP 0x00000001 /* DVR/DCR present */ -#define SPR_DCR_CC 0x0000000e /* Compare condition */ -#define SPR_DCR_SC 0x00000010 /* Signed compare */ -#define SPR_DCR_CT 0x000000e0 /* Compare to */ - -/* Bit results with SPR_DCR_CC mask */ -#define SPR_DCR_CC_MASKED 0x00000000 -#define SPR_DCR_CC_EQUAL 0x00000002 -#define SPR_DCR_CC_LESS 0x00000004 -#define SPR_DCR_CC_LESSE 0x00000006 -#define SPR_DCR_CC_GREAT 0x00000008 -#define SPR_DCR_CC_GREATE 0x0000000a -#define SPR_DCR_CC_NEQUAL 0x0000000c - -/* Bit results with SPR_DCR_CT mask */ -#define SPR_DCR_CT_DISABLED 0x00000000 -#define SPR_DCR_CT_IFEA 0x00000020 -#define SPR_DCR_CT_LEA 0x00000040 -#define SPR_DCR_CT_SEA 0x00000060 -#define SPR_DCR_CT_LD 0x00000080 -#define SPR_DCR_CT_SD 0x000000a0 -#define SPR_DCR_CT_LSEA 0x000000c0 -#define SPR_DCR_CT_LSD 0x000000e0 -/* SPR_DCR_CT_LSD doesn't seem to be implemented anywhere in or1ksim. 2004-1-30 HP */ - -/* - * Bit definitions for Debug Mode 1 register - * - */ -#define SPR_DMR1_CW 0x000fffff /* Chain register pair data */ -#define SPR_DMR1_CW0_AND 0x00000001 -#define SPR_DMR1_CW0_OR 0x00000002 -#define SPR_DMR1_CW0 (SPR_DMR1_CW0_AND | SPR_DMR1_CW0_OR) -#define SPR_DMR1_CW1_AND 0x00000004 -#define SPR_DMR1_CW1_OR 0x00000008 -#define SPR_DMR1_CW1 (SPR_DMR1_CW1_AND | SPR_DMR1_CW1_OR) -#define SPR_DMR1_CW2_AND 0x00000010 -#define SPR_DMR1_CW2_OR 0x00000020 -#define SPR_DMR1_CW2 (SPR_DMR1_CW2_AND | SPR_DMR1_CW2_OR) -#define SPR_DMR1_CW3_AND 0x00000040 -#define SPR_DMR1_CW3_OR 0x00000080 -#define SPR_DMR1_CW3 (SPR_DMR1_CW3_AND | SPR_DMR1_CW3_OR) -#define SPR_DMR1_CW4_AND 0x00000100 -#define SPR_DMR1_CW4_OR 0x00000200 -#define SPR_DMR1_CW4 (SPR_DMR1_CW4_AND | SPR_DMR1_CW4_OR) -#define SPR_DMR1_CW5_AND 0x00000400 -#define SPR_DMR1_CW5_OR 0x00000800 -#define SPR_DMR1_CW5 (SPR_DMR1_CW5_AND | SPR_DMR1_CW5_OR) -#define SPR_DMR1_CW6_AND 0x00001000 -#define SPR_DMR1_CW6_OR 0x00002000 -#define SPR_DMR1_CW6 (SPR_DMR1_CW6_AND | SPR_DMR1_CW6_OR) -#define SPR_DMR1_CW7_AND 0x00004000 -#define SPR_DMR1_CW7_OR 0x00008000 -#define SPR_DMR1_CW7 (SPR_DMR1_CW7_AND | SPR_DMR1_CW7_OR) -#define SPR_DMR1_CW8_AND 0x00010000 -#define SPR_DMR1_CW8_OR 0x00020000 -#define SPR_DMR1_CW8 (SPR_DMR1_CW8_AND | SPR_DMR1_CW8_OR) -#define SPR_DMR1_CW9_AND 0x00040000 -#define SPR_DMR1_CW9_OR 0x00080000 -#define SPR_DMR1_CW9 (SPR_DMR1_CW9_AND | SPR_DMR1_CW9_OR) -#define SPR_DMR1_RES1 0x00300000 /* Reserved */ -#define SPR_DMR1_ST 0x00400000 /* Single-step trace*/ -#define SPR_DMR1_BT 0x00800000 /* Branch trace */ -#define SPR_DMR1_RES2 0xff000000 /* Reserved */ - -/* - * Bit definitions for Debug Mode 2 register. AWTC and WGB corrected by JPB - * - */ -#define SPR_DMR2_WCE0 0x00000001 /* Watchpoint counter 0 enable */ -#define SPR_DMR2_WCE1 0x00000002 /* Watchpoint counter 0 enable */ -#define SPR_DMR2_AWTC 0x00000ffc /* Assign watchpoints to counters */ -#define SPR_DMR2_AWTC_OFF 2 /* Bit offset to AWTC field */ -#define SPR_DMR2_WGB 0x003ff000 /* Watchpoints generating breakpoint */ -#define SPR_DMR2_WGB_OFF 12 /* Bit offset to WGB field */ -#define SPR_DMR2_WBS 0xffc00000 /* JPB: Watchpoint status */ -#define SPR_DMR2_WBS_OFF 22 /* Bit offset to WBS field */ - -/* - * Bit definitions for Debug watchpoint counter registers - * - */ -#define SPR_DWCR_COUNT 0x0000ffff /* Count */ -#define SPR_DWCR_MATCH 0xffff0000 /* Match */ -#define SPR_DWCR_MATCH_OFF 16 /* Match bit offset */ - -/* - * Bit definitions for Debug stop register - * - */ -#define SPR_DSR_RSTE 0x00000001 /* Reset exception */ -#define SPR_DSR_BUSEE 0x00000002 /* Bus error exception */ -#define SPR_DSR_DPFE 0x00000004 /* Data Page Fault exception */ -#define SPR_DSR_IPFE 0x00000008 /* Insn Page Fault exception */ -#define SPR_DSR_TTE 0x00000010 /* Tick Timer exception */ -#define SPR_DSR_AE 0x00000020 /* Alignment exception */ -#define SPR_DSR_IIE 0x00000040 /* Illegal Instruction exception */ -#define SPR_DSR_IE 0x00000080 /* Interrupt exception */ -#define SPR_DSR_DME 0x00000100 /* DTLB miss exception */ -#define SPR_DSR_IME 0x00000200 /* ITLB miss exception */ -#define SPR_DSR_RE 0x00000400 /* Range exception */ -#define SPR_DSR_SCE 0x00000800 /* System call exception */ -#define SPR_DSR_FPE 0x00001000 /* Floating point Exception */ -#define SPR_DSR_TE 0x00002000 /* Trap exception */ - -/* - * Bit definitions for Debug reason register - * - */ -#define SPR_DRR_RSTE 0x00000001 /* Reset exception */ -#define SPR_DRR_BUSEE 0x00000002 /* Bus error exception */ -#define SPR_DRR_DPFE 0x00000004 /* Data Page Fault exception */ -#define SPR_DRR_IPFE 0x00000008 /* Insn Page Fault exception */ -#define SPR_DRR_TTE 0x00000010 /* Tick Timer exception */ -#define SPR_DRR_AE 0x00000020 /* Alignment exception */ -#define SPR_DRR_IIE 0x00000040 /* Illegal Instruction exception */ -#define SPR_DRR_IE 0x00000080 /* Interrupt exception */ -#define SPR_DRR_DME 0x00000100 /* DTLB miss exception */ -#define SPR_DRR_IME 0x00000200 /* ITLB miss exception */ -#define SPR_DRR_RE 0x00000400 /* Range exception */ -#define SPR_DRR_SCE 0x00000800 /* System call exception */ -#define SPR_DRR_FPE 0x00001000 /* Floating point exception */ -#define SPR_DRR_TE 0x00002000 /* Trap exception */ - -/* - * Bit definitions for Performance counters mode registers - * - */ -#define SPR_PCMR_CP 0x00000001 /* Counter present */ -#define SPR_PCMR_UMRA 0x00000002 /* User mode read access */ -#define SPR_PCMR_CISM 0x00000004 /* Count in supervisor mode */ -#define SPR_PCMR_CIUM 0x00000008 /* Count in user mode */ -#define SPR_PCMR_LA 0x00000010 /* Load access event */ -#define SPR_PCMR_SA 0x00000020 /* Store access event */ -#define SPR_PCMR_IF 0x00000040 /* Instruction fetch event*/ -#define SPR_PCMR_DCM 0x00000080 /* Data cache miss event */ -#define SPR_PCMR_ICM 0x00000100 /* Insn cache miss event */ -#define SPR_PCMR_IFS 0x00000200 /* Insn fetch stall event */ -#define SPR_PCMR_LSUS 0x00000400 /* LSU stall event */ -#define SPR_PCMR_BS 0x00000800 /* Branch stall event */ -#define SPR_PCMR_DTLBM 0x00001000 /* DTLB miss event */ -#define SPR_PCMR_ITLBM 0x00002000 /* ITLB miss event */ -#define SPR_PCMR_DDS 0x00004000 /* Data dependency stall event */ -#define SPR_PCMR_WPE 0x03ff8000 /* Watchpoint events */ - -/* - * Bit definitions for the Power management register - * - */ -#define SPR_PMR_SDF 0x0000000f /* Slow down factor */ -#define SPR_PMR_DME 0x00000010 /* Doze mode enable */ -#define SPR_PMR_SME 0x00000020 /* Sleep mode enable */ -#define SPR_PMR_DCGE 0x00000040 /* Dynamic clock gating enable */ -#define SPR_PMR_SUME 0x00000080 /* Suspend mode enable */ - -/* - * Bit definitions for PICMR - * - */ -#define SPR_PICMR_IUM 0xfffffffc /* Interrupt unmask */ - -/* - * Bit definitions for PICPR - * - */ -#define SPR_PICPR_IPRIO 0xfffffffc /* Interrupt priority */ - -/* - * Bit definitions for PICSR - * - */ -#define SPR_PICSR_IS 0xffffffff /* Interrupt status */ - -/* - * Bit definitions for Tick Timer Control Register - * - */ -#define SPR_TTCR_PERIOD 0x0fffffff /* Time Period */ -#define SPR_TTMR_PERIOD SPR_TTCR_PERIOD -#define SPR_TTMR_IP 0x10000000 /* Interrupt Pending */ -#define SPR_TTMR_IE 0x20000000 /* Interrupt Enable */ -#define SPR_TTMR_RT 0x40000000 /* Restart tick */ -#define SPR_TTMR_SR 0x80000000 /* Single run */ -#define SPR_TTMR_CR 0xc0000000 /* Continuous run */ -#define SPR_TTMR_M 0xc0000000 /* Tick mode */ - -/* - * l.nop constants - * - */ -#define NOP_NOP 0x0000 /* Normal nop instruction */ -#define NOP_EXIT 0x0001 /* End of simulation */ -#define NOP_REPORT 0x0002 /* Simple report */ -#define NOP_PRINTF 0x0003 /* Simprintf instruction */ -#define NOP_PUTC 0x0004 /* JPB: Simputc instruction */ -#define NOP_CNT_RESET 0x0005 /* Reset statistics counters */ -#define NOP_REPORT_FIRST 0x0400 /* Report with number */ -#define NOP_REPORT_LAST 0x03ff /* Report with number */ - -#endif /* SPR_DEFS__H */ Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_jtag_bridge.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_jtag_bridge.c (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_jtag_bridge.c (nonexistent) @@ -1,532 +0,0 @@ -/* adv_jtag_bridge.c -- JTAG protocol bridge between GDB and Advanced debug module. - Copyright(C) 2001 Marko Mlinar, markom@opencores.org - Code for TCP/IP copied from gdb, by Chris Ziomkowski - Refactoring by Nathan Yawn, nyawn@opencores.org - - This file was part of the OpenRISC 1000 Architectural Simulator. - It is now also used to connect GDB to a running hardware OpenCores / OR1200 - advanced debug unit. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Establishes jtag proxy server and communicates with parallel - port directly. Requires root access. */ - -#include -#include // for exit(), atoi(), strtoul() -#include -#include -#include // for strstr() -#include - - -#include "adv_jtag_bridge.h" -#include "rsp-server.h" -#include "chain_commands.h" -#include "cable_common.h" -#include "or32_selftest.h" -#include "bsdl.h" -#include "errcodes.h" - -#define debug(...) //fprintf(stderr, __VA_ARGS__ ) - -// How many command-line IR length settings to create by default -#define IR_START_SETS 16 - -////////////////////////////////////////////////// -// Command line option flags / values - -/* Which device in the scan chain we want to target. - * 0 is the first device we find, which is nearest the data input of the cable. - */ -unsigned int target_dev_pos = 0; - -// Do test before setting up server? -unsigned char do_selftest = 0; - -// IR register length in TAP of -// Can override autoprobe, or set if IDCODE not supported -typedef struct { - int dev_index; - int ir_length; -} irset; - -#define START_IR_SETS 16 -int reallocs = 0; -int num_ir_sets = 0; -irset * cmd_line_ir_sizes = NULL; - -// DEBUG command for target device TAP -// May actually be USER1, for Xilinx devices using internal BSCAN modules -// Can override autoprobe, or set if unable to find in BSDL files -int cmd_line_cmd_debug = -1; // 0 is a valid debug command, so use -1 - -// TCP port to set up the server for GDB on -char *port; -char default_port[] = "9999"; - -// Force altera virtual jtag mode on(1) or off(-1) -int force_alt_vjtag = 0; - - -// Pointer to the command line arg used as the cable name -char * cable_name = NULL; - -//////////////////////////////////////////////////////// -// List of IDCODES of devices on the JTAG scan chain -// The array is dynamically allocated in chain_commands/jtag_enumerate_chain() - -uint32_t *idcodes = NULL; -int num_devices = 0; - - -const char *name_not_found = "(unknown)"; - -/////////////////////////////////////////////////////////// -// JTAG constants - -// Defines for Altera JTAG constants -#define ALTERA_MANUFACTURER_ID 0x6E - -// Defines for Xilinx JTAG constants -#define XILINX_MANUFACTURER_ID 0x49 - - -/////////////////////////////////////////////////// -// Prototypes for local / helper functions -int get_IR_size(int devidx); -uint32_t get_debug_cmd(int devidx); -void configure_chain(void); -void print_usage(char *func); -void parse_args(int argc, char **argv); -void get_ir_opts(char *optstr, int *idx, int *val); - - -////////////////////////////////////////////////////////////////////////////////////// -/*----------------------------------------------------------------------------------*/ -// Functions -///////////////////////////////////////////////////////////////////////////////////// - -// Resets JTAG, and sets up DEBUG scan chain -void configure_chain(void) -{ - int i; - unsigned int manuf_id; - uint32_t cmd; - const char *name; - int irlen; - int err = APP_ERR_NONE; - - err |= tap_reset(); - err |= jtag_enumerate_chain(&idcodes, &num_devices); - - if(err != APP_ERR_NONE) { - printf("Error %s enumerating JTAG chain, aborting.\n", get_err_string(err)); - exit(1); - } - - printf("\nDevices on JTAG chain:\n"); - printf("Index\tName\t\tID Code\t\tIR Length\n"); - printf("----------------------------------------------------------------\n"); - for(i = 0; i < num_devices; i++) - { - if(idcodes[i] != IDCODE_INVALID) { - name = bsdl_get_name(idcodes[i]); - irlen = bsdl_get_IR_size(idcodes[i]); - if(name == NULL) - name = name_not_found; - } else { - name = name_not_found; - irlen = -1; - } - printf("%d: \t%s \t0x%08X \t%d\n", i, name, idcodes[i], irlen); - } - printf("\n"); - -#ifdef __LEGACY__ -// The legacy debug interface cannot support multi-device chains. If there is more than -// one device on this chain, pull the cord. -if(num_devices > 1) { - fprintf(stderr, "\n*** ERROR: The legacy debug hardware cannot support JTAG chains with\n"); - fprintf(stderr, "*** more than one device. Reconnect the JTAG cable to ONLY the legacy\n"); - fprintf(stderr, "*** debug unit, or change your SoC to use the Advanced Debug Unit.\n"); - exit(0); -} -#endif - - - if(target_dev_pos >= num_devices) { - printf("ERROR: Requested target device (%i) beyond highest device index (%i).\n", target_dev_pos, num_devices-1); - exit(1); - } else { - printf("Target device %i, JTAG ID = 0x%08x\n", target_dev_pos, idcodes[target_dev_pos]); - } - - manuf_id = (idcodes[target_dev_pos] >> 1) & 0x7FF; - - // Use BSDL files to determine prefix bits, postfix bits, debug command, IR length - config_set_IR_size(get_IR_size(target_dev_pos)); - - // Set the IR prefix / postfix bits - int total = 0; - for(i = 0; i < num_devices; i++) { - if(i == target_dev_pos) { - config_set_IR_postfix_bits(total); - //debug("Postfix bits: %d\n", total); - total = 0; - continue; - } - - total += get_IR_size(i); - debug("Adding %i to total for devidx %i\n", get_IR_size(i), i); - } - config_set_IR_prefix_bits(total); - debug("Prefix bits: %d\n", total); - - - // Note that there's a little translation here, since device index 0 is actually closest to the cable data input - config_set_DR_prefix_bits(num_devices - target_dev_pos - 1); // number of devices between cable data out and target device - config_set_DR_postfix_bits(target_dev_pos); // number of devices between target device and cable data in - - // Set the DEBUG command for the IR of the target device. - // If this is a Xilinx device, use USER1 instead of DEBUG - // If we Altera Virtual JTAG mode, we don't care. - if((force_alt_vjtag == -1) || ((force_alt_vjtag == 0) && (manuf_id != ALTERA_MANUFACTURER_ID))) { - cmd = get_debug_cmd(target_dev_pos); - if(cmd == TAP_CMD_INVALID) { - printf("Unable to find DEBUG command, aborting.\n"); - exit(1); - } - config_set_debug_cmd(cmd); // This may have to be USER1 if this is a Xilinx device - } - - // Enable the kludge for Xilinx BSCAN, if necessary. - // Safe, but slower, for non-BSCAN TAPs. - if(manuf_id == XILINX_MANUFACTURER_ID) { - config_set_xilinx_bscan(1); - } - - // Set Altera Virtual JTAG mode on or off. If not forced, then enable - // if the target device has an Altera manufacturer IDCODE - if(force_alt_vjtag == 1) { - config_set_alt_vjtag(1); - } else if(force_alt_vjtag == -1) { - config_set_alt_vjtag(0); - } else { - if(manuf_id == ALTERA_MANUFACTURER_ID) { - config_set_alt_vjtag(1); - } else { - config_set_alt_vjtag(0); - } - } - - // Do a sanity test - cmd = bsdl_get_idcode_cmd(idcodes[target_dev_pos]); - if(cmd != TAP_CMD_INVALID) { - uint32_t id_read; - err |= jtag_get_idcode(cmd, &id_read); - - if(err != APP_ERR_NONE) { - printf("Error %s checking IDCODE, aborting.\n", get_err_string(err)); - exit(1); - } - - if(id_read == idcodes[target_dev_pos]) { - printf("IDCODE sanity test passed, chain OK!\n"); - } else { - printf("Warning: IDCODE sanity test failed. Read IDCODE 0x%08X, expected 0x%08X\n", id_read, idcodes[target_dev_pos]); - } - } - - if(err |= tap_enable_debug_module()) { // Select the debug unit in the TAP. - printf("Error %s enabling debug module, aborting.\n", get_err_string(err)); - exit(1); - } -} - - -void print_usage(char *func) -{ - printf("JTAG connection between GDB and the SoC debug interface.\n"); -#ifdef __LEGACY__ - printf("Compiled with support for the Legacy debug unit (debug_if).\n"); -#else - printf("Compiled with support for the Advanced Debug Interface (adv_dbg_if).\n"); -#endif - printf("Copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.org\n\n"); - printf("Usage: %s (options) [cable] (cable options)\n", func); - printf("Options:\n"); - printf("\t-g [port] : port number for GDB (default: 9999)\n"); - printf("\t-x [index] : Position of the target device in the scan chain\n"); - printf("\t-a [0 / 1] : force Altera virtual JTAG mode off (0) or on (1)\n"); - printf("\t-l [:] : Specify length of IR register for device\n"); - printf("\t , override autodetect (if any)\n"); - printf("\t-c [hex cmd] : Debug command for target TAP, override autodetect\n"); - printf("\t (ignored for Altera targets)\n"); - printf("\t-v [hex cmd] : VIR command for target TAP, override autodetect\n"); - printf("\t (Altera virtual JTAG targets only)\n"); - printf("\t-r [hex cmd] : VDR for target TAP, override autodetect\n"); - printf("\t (Altera virtual JTAG targets only)\n"); - printf("\t-b [dirname] : Add a directory to search for BSDL files\n"); - printf("\t-t : perform CPU / memory self-test before starting server\n"); - printf("\t-h : show help\n\n"); - cable_print_help(); -} - - -void parse_args(int argc, char **argv) -{ - int c; - int i; - int idx, val; - const char *valid_cable_args = NULL; - port = NULL; - force_alt_vjtag = 0; - cmd_line_cmd_debug = -1; - - /* Parse the global arguments (if-any) */ - while((c = getopt(argc, argv, "+g:x:a:l:c:v:r:b:th")) != -1) { - switch(c) { - case 'h': - print_usage(argv[0]); - exit(0); - break; - case 'g': - port = optarg; - break; - case 'x': - target_dev_pos = atoi(optarg); - break; - case 'l': - get_ir_opts(optarg, &idx, &val); // parse the option - if(num_ir_sets >= (IR_START_SETS< 0) && (retval != cmd_line_ir_sizes[i].ir_length)) - printf("Warning: overriding autoprobed IR length (%i) with command line value (%i) for device %i\n", retval, - cmd_line_ir_sizes[i].ir_length, devidx); - retval = cmd_line_ir_sizes[i].ir_length; - } - } - - if(retval < 0) { // Make sure we have a value - printf("ERROR! Unable to autoprobe IR length for device index %i; Must set IR size on command line. Aborting.\n", devidx); - exit(1); - } - - return retval; -} - - -uint32_t get_debug_cmd(int devidx) -{ - int retval = TAP_CMD_INVALID; - uint32_t manuf_id = (idcodes[devidx] >> 1) & 0x7FF; - - if(idcodes[devidx] != IDCODE_INVALID) { - if(manuf_id == XILINX_MANUFACTURER_ID) { - retval = bsdl_get_user1_cmd(idcodes[devidx]); - if(cmd_line_cmd_debug < 0) printf("Xilinx IDCODE, assuming internal BSCAN mode\n\t(using USER1 instead of DEBUG TAP command)\n"); - } else { - retval = bsdl_get_debug_cmd(idcodes[devidx]); - } - } - - if(cmd_line_cmd_debug >= 0) { - if(retval != TAP_CMD_INVALID) { - printf("Warning: overriding autoprobe debug command (0x%X) with command line value (0x%X)\n", retval, cmd_line_cmd_debug); - } else { - printf("Using command-line debug command 0x%X\n", cmd_line_cmd_debug); - } - retval = cmd_line_cmd_debug; - } - - if(retval == TAP_CMD_INVALID) { - printf("ERROR! Unable to find DEBUG command for device index %i, device ID 0x%0X\n", devidx, idcodes[devidx]); - } - - return retval; -} - - -// Extracts two values from an option string -// of the form ":", where both args -// are in base 10 -void get_ir_opts(char *optstr, int *idx, int *val) -{ - char *ptr; - - ptr = strstr(optstr, ":"); - if(ptr == NULL) { - printf("Error: badly formatted IR length option. Use format \':\', without spaces, where both args are in base 10\n"); - exit(1); - } - - *ptr = '\0'; - ptr++; // This now points to the second (value) arg string - - *idx = strtoul(optstr, NULL, 10); - *val = strtoul(ptr, NULL, 10); - // ***CHECK FOR SUCCESS -} - Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/Makefile =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/Makefile (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/Makefile (nonexistent) @@ -1,104 +0,0 @@ -prefix = /usr/local - -# Your build environment. selects libs, lib dirs, and include dirs -# Supported: linux, cygwin -BUILD_ENVIRONMENT=cygwin - -# Set this to 'true' if you want to build for the legacy debug unit ('debug_if' core), -# leave 'false' if you are building for the Advanced Debug Unit. -SUPPORT_LEGACY=false - -# Set this to 'true' to include support for cables which require libusb -# currently includes Altera USB-Blaster and Xilinx XPC DLC8 -SUPPORT_USB_CABLES=true - -# Set this to 'true' to support cables which require libFTDI -# SUPPORT_USB_CABLES must also be set to 'true' to support FTDI-based cables. -SUPPORT_FTDI_CABLES=true - - -# ---------------------------------------------------------------------------- -# Most people shouldn't have to change anything below this line - -ifeq ($(BUILD_ENVIRONMENT),linux) -# These are for native Linux. You may need to put the path to libusb into the LIBS variable -# with the -L command. -CFLAGS = -g -O2 -Wall -CC = gcc -LIBS = -lpthread -INCLUDEDIRS = -I/usr/local/include/libusb-1.0/ -I/usr/local/include/ - -else - -ifeq ($(BUILD_ENVIRONMENT),cygwin) -# These are for cygwin. It assumes libusb.a is in the current directory. -CFLAGS = -g -O2 -Wall -CC = gcc -LIBS = -L. -lioperm -lpthread -INCLUDEDIRS = -I/usr/local/include/ -endif - -endif - -ifeq ($(SUPPORT_LEGACY),true) -CFLAGS += -D__LEGACY__ -endif - - -PROGRAMS = adv_jtag_bridge - -HEADERS = adv_jtag_bridge.h chain_commands.h opencores_tap.h \ - altera_virtual_jtag.h rsp-server.h bsdl.h or32_selftest.c cable_common.h \ - cable_parallel.h cable_sim.h \ - bsdl_parse.h errcodes.h spr-defs.h except.h adv_dbg_commands.h dbg_api.h \ - legacy_dbg_commands.h - -SOURCES = adv_jtag_bridge.c rsp-server.c chain_commands.c cable_common.c bsdl.c \ - or32_selftest.c cable_parallel.c cable_sim.c \ - bsdl_parse.c errcodes.c adv_dbg_commands.c dbg_api.c legacy_dbg_commands.c - -OBJECTS = adv_jtag_bridge.o rsp-server.o chain_commands.o cable_common.o bsdl.o \ - or32_selftest.o cable_parallel.o cable_sim.o \ - bsdl_parse.o errcodes.o adv_dbg_commands.o dbg_api.o legacy_dbg_commands.o - - -ifeq ($(SUPPORT_USB_CABLES),true) -CFLAGS += -D__SUPPORT_USB_CABLES__ -HEADERS += cable_usbblaster.h cable_xpc_dlc9.h -SOURCES += cable_usbblaster.c cable_xpc_dlc9.c -OBJECTS += cable_usbblaster.o cable_xpc_dlc9.o - -ifeq ($(SUPPORT_FTDI_CABLES),true) -CFLAGS += -D__SUPPORT_FTDI_CABLES__ -LIBS += -lftdi -HEADERS += cable_ft2232.h -SOURCES += cable_ft2232.c -OBJECTS += cable_ft2232.o -endif - -# libusb must follow libftdi in the list of libraries -LIBS += -lusb -endif - - -all: $(PROGRAMS) - -default: $(PROGRAMS) - -.c.o: - $(CC) $(CFLAGS) -c $< - -adv_jtag_bridge: Makefile $(OBJECTS) $(HEADERS) - rm -f $@ - $(CC) -o $@ $(CFLAGS) $(OBJECTS) $(LIBS) $(INCLUDEDIRS) - - -install: all - [ -d $(prefix)/bin ] || mkdir -p $(prefix)/bin - for p in $(PROGRAMS) ; do \ - /bin/rm -f $(prefix)/bin/$$p; \ - /bin/cp -p $$p $(prefix)/bin/$$p; \ - done - -clean: Makefile - rm -f $(PROGRAMS) *.o *~ Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/except.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/except.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/except.h (nonexistent) @@ -1,52 +0,0 @@ -/* except.h -- OR1K architecture specific exceptions - -Copyright (C) 1999 Damjan Lampret, lampret@opencores.org -Copyright (C) 2008 Embecosm Limited - -Contributor Jeremy Bennett - -This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see . -*/ - -/* This program is commented throughout in a fashion suitable for processing - with Doxygen. */ - - -#ifndef EXCEPT__H -#define EXCEPT__H - - -/* Package includes */ -//#include "arch.h" - -/* Definition of OR1K exceptions */ -#define EXCEPT_NONE 0x0000 -#define EXCEPT_RESET 0x0100 -#define EXCEPT_BUSERR 0x0200 -#define EXCEPT_DPF 0x0300 -#define EXCEPT_IPF 0x0400 -#define EXCEPT_TICK 0x0500 -#define EXCEPT_ALIGN 0x0600 -#define EXCEPT_ILLEGAL 0x0700 -#define EXCEPT_INT 0x0800 -#define EXCEPT_DTLBMISS 0x0900 -#define EXCEPT_ITLBMISS 0x0a00 -#define EXCEPT_RANGE 0x0b00 -#define EXCEPT_SYSCALL 0x0c00 -#define EXCEPT_FPE 0x0d00 -#define EXCEPT_TRAP 0x0e00 - -#endif /* EXCEPT__H */ Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/or32_selftest.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/or32_selftest.c (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/or32_selftest.c (nonexistent) @@ -1,633 +0,0 @@ -/* or32_selftest.c -- JTAG protocol bridge between GDB and Advanced debug module. - Copyright(C) 2001 Marko Mlinar, markom@opencores.org - Code for TCP/IP copied from gdb, by Chris Ziomkowski - Refactoring and USB support by Nathan Yawn - - This file contains functions which perform high-level transactions - on a JTAG chain and debug unit, such as setting a value in the TAP IR - or doing a burst write through the wishbone module of the debug unit. - It uses the protocol for the Advanced Debug Interface (adv_dbg_if). - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - - -#include -#include // for exit() - -#include "or32_selftest.h" -#include "dbg_api.h" -#include "errcodes.h" - - -// Define your system parameters here -//#define HAS_CPU1 // stall cpu1 (as well as cpu0) -//#define HAS_MEMORY_CONTROLLER // init the SDRAM controller -#define MC_BASE_ADDR 0x93000000 -#define SDRAM_BASE 0x00000000 -//#define SDRAM_SIZE 0x04000000 -#define SDRAM_SIZE 0x400 -#define SRAM_BASE 0x00000000 -#define SRAM_SIZE 0x04000000 -#define FLASH_BASE_ADDR 0xf0000000 - -// Define the tests to be performed here -#define TEST_SRAM -//#define TEST_SDRAM -#define TEST_OR1K -//#define TEST_8051 // run a test on an 8051 on CPU1 - - -// Defines which depend on user-defined values, don't change these -#define FLASH_BAR_VAL FLASH_BASE_ADDR -#define SDRAM_BASE_ADDR SDRAM_BASE -#define SDRAM_BAR_VAL SDRAM_BASE_ADDR -#define SDRAM_AMR_VAL (~(SDRAM_SIZE -1)) - -#define CHECK(x) check(__FILE__, __LINE__, (x)) -void check(char *fn, int l, int i); - -void check(char *fn, int l, int i) { - if (i != 0) { - fprintf(stderr, "%s:%d: Jtag error %d occured; exiting.\n", fn, l, i); - exit(1); - } -} - - -//////////////////////////////////////////////////////////// -// Self-test functions -/////////////////////////////////////////////////////////// -int dbg_test() -{ - int success; - - success = stall_cpus(); - if(success == APP_ERR_NONE) { - -#ifdef HAS_MEMORY_CONTROLLER - // Init the memory contloller - init_mc(); - // Init the SRAM addresses in the MC - init_sram(); -#endif - - - -#ifdef TEST_SDRAM - success |= test_sdram(); - success |= test_sdram_2(); -#endif - -#ifdef TEST_SRAM - success |= test_sram(); -#endif - -#ifdef TEST_OR1K - success |= test_or1k_cpu0(); -#endif - -#if ((defined TEST_8051) && (defined HAS_CPU1)) - success |= test_8051_cpu1(); -#endif - - return success; - } - - return APP_ERR_TEST_FAIL; -} - - -int stall_cpus(void) -{ - unsigned char stalled; - -#ifdef HAS_CPU1 - printf("Stall 8051 - "); - CHECK(dbg_cpu1_write_reg(0, 0x01)); // stall 8051 -#endif - - printf("Stall or1k - "); - CHECK(dbg_cpu0_write_ctrl(0, 0x01)); // stall or1k - - -#ifdef HAS_CPU1 - CHECK(dbg_cpu1_read_ctrl(0, &stalled)); - if (!(stalled & 0x1)) { - printf("8051 is not stalled!\n"); // check stall 8051 - return APP_ERR_TEST_FAIL; - } -#endif - - CHECK(dbg_cpu0_read_ctrl(0, &stalled)); - if (!(stalled & 0x1)) { - printf("or1k is not stalled!\n"); // check stall or1k - return APP_ERR_TEST_FAIL; - } - - printf("CPU(s) stalled.\n"); - - return APP_ERR_NONE; -} - - -void init_mc(void) -{ - unsigned long insn; - - printf("Initialize Memory Controller (SDRAM)\n"); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_BAR_0, FLASH_BAR_VAL & 0xffff0000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_AMR_0, FLASH_AMR_VAL & 0xffff0000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_WTR_0, FLASH_WTR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RTR_0, FLASH_RTR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x40000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_BAR_4, SDRAM_BAR_VAL & 0xffff0000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_AMR_4, SDRAM_AMR_VAL & 0xffff0000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_CCR_4, 0x00bf0005)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RATR, SDRAM_RATR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RCDR, SDRAM_RCDR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RCTR, SDRAM_RCTR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_REFCTR, SDRAM_REFCTR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_PTR, SDRAM_PTR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RRDR, SDRAM_RRDR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RIR, SDRAM_RIR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x5e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x5e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x7e000033)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x7e000033)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_CCR_4, 0xc0bf0005)); - - CHECK(dbg_wb_read32(MC_BASE_ADDR+MC_CCR_4, &insn)); - printf("expected %x, read %lx\n", 0xc0bf0005, insn); -} - - -void init_sram(void) -{ - // SRAM initialized to 0x40000000 - printf("Initialize Memory Controller (SRAM)\n"); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_BAR_1, SRAM_BASE & 0xffff0000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_AMR_1, ~(SRAM_SIZE - 1) & 0xffff0000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_CCR_1, 0xc020001f)); -} - - - -int test_sdram(void) -{ - unsigned long insn; - unsigned long i; - unsigned long data4_out[0x08]; - unsigned long data4_in[0x08]; - unsigned short data2_out[0x10]; - unsigned short data2_in[0x10]; - unsigned char data1_out[0x20]; - unsigned char data1_in[0x20]; - - printf("Start SDRAM WR\n"); - for (i=0x10; i<(SDRAM_SIZE+SDRAM_BASE); i=i<<1) { - //printf("0x%x: 0x%x\n", SDRAM_BASE+i, i); - CHECK(dbg_wb_write32(SDRAM_BASE+i, i)); - } - - printf("Start SDRAM RD\n"); - for (i=0x10; i<(SDRAM_SIZE+SDRAM_BASE); i=i<<1) { - CHECK(dbg_wb_read32(SDRAM_BASE+i, &insn)); - //printf("0x%x: 0x%x\n", SDRAM_BASE+i, insn); - if (i != insn) { - printf("SDRAM test FAIL\n"); - return APP_ERR_TEST_FAIL; - } - } - - printf("32-bit block write from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20); - for (i=0; i<(0x20/4); i++) { - data4_out[i] = data4_in[i] = ((4*i+3)<<24) | ((4*i+2)<<16) | ((4*i+1)<<8) | (4*i); - //printf("data_out = %0x\n", data4_out[i]); - } - - //printf("Press a key for write\n"); getchar(); - CHECK(dbg_wb_write_block32(SDRAM_BASE, &data4_out[0], 0x20)); - - // 32-bit block read is used for checking - printf("32-bit block read from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20); - CHECK(dbg_wb_read_block32(SDRAM_BASE, &data4_out[0], 0x20)); - for (i=0; i<(0x20/4); i++) { - //printf("0x%x: 0x%x\n", SDRAM_BASE+(i*4), data_out[i]); - if (data4_in[i] != data4_out[i]) { - printf("SDRAM data differs. Expected: 0x%0lx, read: 0x%0lx\n", data4_in[i], data4_out[i]); - return APP_ERR_TEST_FAIL; - } - } - - - printf("16-bit block write from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20); - for (i=0; i<(0x20/2); i++) { - data2_out[i] = data2_in[i] = ((4*i+1)<<8) | (4*i); - //printf("data_out = %0x\n", data_out[i]); - } - CHECK(dbg_wb_write_block16(SDRAM_BASE, &data2_out[0], 0x20)); - - // 16-bit block read is used for checking - printf("16-bit block read from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20); - CHECK(dbg_wb_read_block16(SDRAM_BASE, &data2_out[0], 0x20)); - for (i=0; i<(0x20/2); i++) { - //printf("0x%x: 0x%x\n", SDRAM_BASE+(i*4), data_out[i]); - if (data2_in[i] != data2_out[i]) { - printf("SDRAM data differs. Expected: 0x%0x, read: 0x%0x\n", data2_in[i], data2_out[i]); - return APP_ERR_TEST_FAIL; - } - } - - printf("8-bit block write from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20); - for (i=0; i<(0x20/1); i++) { - data1_out[i] = data1_in[i] = (4*i); - //printf("data_out = %0x\n", data_out[i]); - } - CHECK(dbg_wb_write_block8(SDRAM_BASE, &data1_out[0], 0x20)); - - // 32-bit block read is used for checking - printf("8-bit block read from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20); - CHECK(dbg_wb_read_block8(SDRAM_BASE, &data1_out[0], 0x20)); - for (i=0; i<(0x20/1); i++) { - //printf("0x%x: 0x%x\n", SDRAM_BASE+(i*4), data_out[i]); - if (data1_in[i] != data1_out[i]) { - printf("SDRAM data differs. Expected: 0x%0x, read: 0x%0x\n", data1_in[i], data1_out[i]); - return APP_ERR_TEST_FAIL; - } - } - - printf("SDRAM OK!\n"); - return APP_ERR_NONE; -} - - -int test_sdram_2(void) -{ - unsigned long insn; - - printf("SDRAM test 2: \n"); - CHECK(dbg_wb_write32(SDRAM_BASE+0x00, 0x12345678)); - CHECK(dbg_wb_read32(SDRAM_BASE+0x00, &insn)); - printf("expected %x, read %lx\n", 0x12345678, insn); - if (insn != 0x12345678) return APP_ERR_TEST_FAIL; - - CHECK(dbg_wb_write32(SDRAM_BASE+0x0000, 0x11112222)); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0000, &insn)); - printf("expected %x, read %lx\n", 0x11112222, insn); - if (insn != 0x11112222) return APP_ERR_TEST_FAIL; - - CHECK(dbg_wb_write32(SDRAM_BASE+0x0004, 0x33334444)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x0008, 0x55556666)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x000c, 0x77778888)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x0010, 0x9999aaaa)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x0014, 0xbbbbcccc)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x0018, 0xddddeeee)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x001c, 0xffff0000)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x0020, 0xdeadbeef)); - - CHECK(dbg_wb_read32(SDRAM_BASE+0x0000, &insn)); - printf("expected %x, read %lx\n", 0x11112222, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0004, &insn)); - printf("expected %x, read %lx\n", 0x33334444, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0008, &insn)); - printf("expected %x, read %lx\n", 0x55556666, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x000c, &insn)); - printf("expected %x, read %lx\n", 0x77778888, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0010, &insn)); - printf("expected %x, read %lx\n", 0x9999aaaa, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0014, &insn)); - printf("expected %x, read %lx\n", 0xbbbbcccc, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0018, &insn)); - printf("expected %x, read %lx\n", 0xddddeeee, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x001c, &insn)); - printf("expected %x, read %lx\n", 0xffff0000, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0020, &insn)); - printf("expected %x, read %lx\n", 0xdeadbeef, insn); - - if (insn != 0xdeadbeef) { - printf("SDRAM test 2 FAILED\n"); - return APP_ERR_TEST_FAIL; - } - else - printf("SDRAM test 2 passed\n"); - - return APP_ERR_NONE; -} - - -int test_sram(void) -{ - //unsigned long insn; - unsigned long ins; - unsigned long insn[9]; - insn[0] = 0x11112222; - insn[1] = 0x33334444; - insn[2] = 0x55556666; - insn[3] = 0x77778888; - insn[4] = 0x9999aaaa; - insn[5] = 0xbbbbcccc; - insn[6] = 0xddddeeee; - insn[7] = 0xffff0000; - insn[8] = 0xdedababa; - - printf("SRAM test: \n"); - //dbg_wb_write_block32(0x0, insn, 9); - - CHECK(dbg_wb_write32(SRAM_BASE+0x0000, 0x11112222)); - CHECK(dbg_wb_write32(SRAM_BASE+0x0004, 0x33334444)); - CHECK(dbg_wb_write32(SRAM_BASE+0x0008, 0x55556666)); - CHECK(dbg_wb_write32(SRAM_BASE+0x000c, 0x77778888)); - CHECK(dbg_wb_write32(SRAM_BASE+0x0010, 0x9999aaaa)); - CHECK(dbg_wb_write32(SRAM_BASE+0x0014, 0xbbbbcccc)); - CHECK(dbg_wb_write32(SRAM_BASE+0x0018, 0xddddeeee)); - CHECK(dbg_wb_write32(SRAM_BASE+0x001c, 0xffff0000)); - CHECK(dbg_wb_write32(SRAM_BASE+0x0020, 0xdedababa)); - - - CHECK(dbg_wb_read32(SRAM_BASE+0x0000, &ins)); - printf("expected %x, read %lx\n", 0x11112222, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x0004, &ins)); - printf("expected %x, read %lx\n", 0x33334444, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x0008, &ins)); - printf("expected %x, read %lx\n", 0x55556666, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x000c, &ins)); - printf("expected %x, read %lx\n", 0x77778888, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x0010, &ins)); - printf("expected %x, read %lx\n", 0x9999aaaa, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x0014, &ins)); - printf("expected %x, read %lx\n", 0xbbbbcccc, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x0018, &ins)); - printf("expected %x, read %lx\n", 0xddddeeee, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x001c, &ins)); - printf("expected %x, read %lx\n", 0xffff0000, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x0020, &ins)); - printf("expected %x, read %lx\n", 0xdedababa, ins); - - if (ins != 0xdedababa) { - printf("SRAM test failed!!!\n"); - return APP_ERR_TEST_FAIL; - } - else - printf("SRAM test passed\n"); - - return APP_ERR_NONE; -} - - - -int test_or1k_cpu0(void) -{ - unsigned long npc, ppc, r1, insn; - unsigned char stalled; - unsigned long result; - int i; - - printf("Testing CPU0 (or1k) - writing instructions\n"); - CHECK(dbg_wb_write32(SDRAM_BASE+0x00, 0xe0000005)); /* l.xor r0,r0,r0 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x04, 0x9c200000)); /* l.addi r1,r0,0x0 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x08, 0x18400000)); /* l.movhi r2,0x4000 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x0c, 0xa8420030)); /* l.ori r2,r2,0x30 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x10, 0x9c210001)); /* l.addi r1,r1,1 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x14, 0x9c210001)); /* l.addi r1,r1,1 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x18, 0xd4020800)); /* l.sw 0(r2),r1 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x1c, 0x9c210001)); /* l.addi r1,r1,1 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x20, 0x84620000)); /* l.lwz r3,0(r2) */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x24, 0x03fffffb)); /* l.j loop2 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x28, 0xe0211800)); /* l.add r1,r1,r3 */ - - printf("Setting up CPU0\n"); - CHECK(dbg_cpu0_write((0 << 11) + 17, 0x01)); /* Enable exceptions */ - CHECK(dbg_cpu0_write((6 << 11) + 20, 0x2000)); /* Trap causes stall */ - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE)); /* Set PC */ - CHECK(dbg_cpu0_write((6 << 11) + 16, 1 << 22)); /* Set step bit */ - printf("Starting CPU0!\n"); - for(i = 0; i < 11; i++) { - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* 11x Unstall */ - //printf("Starting CPU, waiting for trap...\n"); - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - //printf("Got trap.\n"); - } - - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000010, 0x00000028, 5); - result = npc + ppc + r1; - - CHECK(dbg_cpu0_write((6 << 11) + 16, 0)); // Reset step bit - CHECK(dbg_wb_read32(SDRAM_BASE + 0x28, &insn)); // Set trap insn in delay slot - CHECK(dbg_wb_write32(SDRAM_BASE + 0x28, 0x21000001)); - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); // Unstall - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); // Read NPC - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); // Read PPC - CHECK(dbg_cpu0_read(0x401, &r1)); // Read R1 - CHECK(dbg_wb_write32(SDRAM_BASE + 0x28, insn)); // Set back original insn - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000010, 0x00000028, 8); - result = npc + ppc + r1 + result; - - CHECK(dbg_wb_read32(SDRAM_BASE + 0x24, &insn)); // Set trap insn in place of branch insn - CHECK(dbg_wb_write32(SDRAM_BASE + 0x24, 0x21000001)); - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x10)); // Set PC - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); // Unstall - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); // Read NPC - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); // Read PPC - CHECK(dbg_cpu0_read(0x401, &r1)); // Read R1 - CHECK(dbg_wb_write32(SDRAM_BASE + 0x24, insn)); // Set back original insn - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000028, 0x00000024, 11); - result = npc + ppc + r1 + result; - - CHECK(dbg_wb_read32(SDRAM_BASE + 0x20, &insn)); /* Set trap insn before branch insn */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, 0x21000001)); - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x24)); /* Set PC */ - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* Unstall */ - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, insn)); /* Set back original insn */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000024, 0x00000020, 24); - result = npc + ppc + r1 + result; - - CHECK(dbg_wb_read32(SDRAM_BASE + 0x1c, &insn)); /* Set trap insn behind lsu insn */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x1c, 0x21000001)); - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x20)); /* Set PC */ - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* Unstall */ - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x1c, insn)); /* Set back original insn */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000020, 0x0000001c, 49); - result = npc + ppc + r1 + result; - - CHECK(dbg_wb_read32(SDRAM_BASE + 0x20, &insn)); /* Set trap insn very near previous one */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, 0x21000001)); - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x1c)); /* Set PC */ - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* Unstall */ - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, insn)); /* Set back original insn */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000024, 0x00000020, 50); - result = npc + ppc + r1 + result; - - CHECK(dbg_wb_read32(SDRAM_BASE + 0x10, &insn)); /* Set trap insn to the start */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x10, 0x21000001)); - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x20) /* Set PC */); - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* Unstall */ - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x10, insn)); /* Set back original insn */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000014, 0x00000010, 99); - result = npc + ppc + r1 + result; - - CHECK(dbg_cpu0_write((6 << 11) + 16, 1 << 22)); /* Set step bit */ - for(i = 0; i < 5; i++) { - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* Unstall */ - //printf("Waiting for trap..."); - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - //printf("got trap.\n"); - } - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000028, 0x00000024, 101); - result = npc + ppc + r1 + result; - - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x24)); /* Set PC */ - for(i = 0; i < 2; i++) { - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* Unstall */ - //printf("Waiting for trap...\n"); - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - //printf("Got trap.\n"); - } - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000010, 0x00000028, 201); - result = npc + ppc + r1 + result; - printf("result = %.8lx\n", result ^ 0xdeaddae1); - - if((result ^ 0xdeaddae1) != 0xdeaddead) - return APP_ERR_TEST_FAIL; - - return APP_ERR_NONE; -} - - -// This function does not currently return a useful value -/* -unsigned char test_8051_cpu1(void) -{ - int retval = 1; - unsigned long result = 0; - unsigned long npc[3], tmp; - - printf("Testing CPU1 (8051)\n"); - - // WRITE ACC - CHECK(dbg_cpu1_write(0x20e0, 0xa6)); - - // READ ACC - CHECK(dbg_cpu1_read(0x20e0, &tmp)); // select SFR space - printf("Read 8051 ACC = %0x (expected a6)\n", tmp); - result = result + tmp; - - // set exception to single step to jump over a loop - CHECK(dbg_cpu1_write(0x3010, 0xa0)); // set single step and global enable in EER - CHECK(dbg_cpu1_write(0x3011, 0x40)); // set evec = 24'h000040 - CHECK(dbg_cpu1_write(0x3012, 0x00)); // (already reset value) - CHECK(dbg_cpu1_write(0x3013, 0x00)); // (already reset value) - - // set HW breakpoint at PC == 0x41 - CHECK(dbg_cpu1_write(0x3020, 0x41)); // DVR0 = 24'h000041 - CHECK(dbg_cpu1_write(0x3023, 0x39)); // DCR0 = valid, == PC - CHECK(dbg_cpu1_write(0x3001, 0x04)); // DSR = watchpoint - - // flush 8051 instruction cache - CHECK(dbg_cpu1_write(0x209f, 0x00)); - - // Put some instructions in ram (8-bit mode on wishbone) - CHECK(dbg_wb_write8 (0x40, 0x04)); // inc a - CHECK(dbg_wb_write8 (0x41, 0x03)); // rr a; - CHECK(dbg_wb_write8 (0x42, 0x14)); // dec a; - CHECK(dbg_wb_write8 (0x43, 0xf5)); // mov 0e5h, a; - CHECK(dbg_wb_write8 (0x44, 0xe5)); - - // unstall just 8051 - CHECK(dbg_cpu1_write_reg(0, 0)); - - // read PC - CHECK(dbg_cpu1_read(0, &npc[0])); - CHECK(dbg_cpu1_read(1, &npc[1])); - CHECK(dbg_cpu1_read(2, &npc[2])); - printf("Read 8051 npc = %02x%02x%02x (expected 41)\n", npc[2], npc[1], npc[0]); - result = result + (npc[2] << 16) + (npc[1] << 8) + npc[0]; - - // READ ACC - CHECK(dbg_cpu1_read(0x20e0, &tmp)); // select SFR space - printf("Read 8051 ACC = %0x (expected a7)\n", tmp); - result = result + tmp; - - // set sigle step to stop execution - CHECK(dbg_cpu1_write(0x3001, 0x20)); // set single step and global enable in DSR - - // clear DRR - CHECK(dbg_cpu1_write(0x3000, 0x00)); // set single step and global enable in DRR - - // unstall just 8051 - CHECK(dbg_cpu1_write_reg(0, 0)); - - // read PC - CHECK(dbg_cpu1_read(0, &npc[0])); - CHECK(dbg_cpu1_read(1, &npc[1])); - CHECK(dbg_cpu1_read(2, &npc[2])); - printf("Read 8051 npc = %02x%02x%02x (expected 42)\n", npc[2], npc[1], npc[0]); - result = result + (npc[2] << 16) + (npc[1] << 8) + npc[0]; - - // READ ACC - CHECK(dbg_cpu1_read(0x20e0, &tmp)); // select SFR space - printf("Read 8051 ACC = %0x (expected d3)\n", tmp); - result = result + tmp; - - printf("report (%x)\n", result ^ 0x6c1 ^ 0xdeaddead); - - return APP_ERR_NONE; -} -*/ Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_jtag_bridge.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_jtag_bridge.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_jtag_bridge.h (nonexistent) @@ -1,18 +0,0 @@ -#ifndef _ADV_JTAG_BRIDGE_H_ -#define _ADV_JTAG_BRIDGE_H_ - -//#ifndef Boolean -//#define Boolean int -//#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - - -#endif /* _ADV_JTAG_BRIDGE_H_ */ - Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/legacy_dbg_commands.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/legacy_dbg_commands.c (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/legacy_dbg_commands.c (nonexistent) @@ -1,393 +0,0 @@ -/* legacy_dbg_commands.c -- JTAG protocol bridge between GDB and OpenCores debug module. - Copyright(C) 2001 Marko Mlinar, markom@opencores.org - Code for TCP/IP copied from gdb, by Chris Ziomkowski - Adapted for the Advanced JTAG Bridge by Nathan Yawn, 2009 - - This file was part of the OpenRISC 1000 Architectural Simulator. - It is now also used to connect GDB to a running hardware OpenCores / OR1200 - debug unit. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // for htonl - -#include "chain_commands.h" -#include "cable_common.h" -#include "errcodes.h" -#include "legacy_dbg_commands.h" - -#define debug(...) //fprintf(stderr, __VA_ARGS__ ) - -#define LEGACY_CRC_POLY 0x04c11db7 -#define DBG_CRC_SIZE 32 - -/* Crc of current read or written data. */ -static int legacy_crc_r, legacy_crc_w = 0; - - -/*----------------------------------------------------------------------------------*/ -// Helper Functions - -/* Generates new crc, sending in new bit input_bit */ -static unsigned long legacy_crc_calc(unsigned long crc, int input_bit) { - unsigned long d = (input_bit&1) ? 0xfffffff : 0x0000000; - unsigned long crc_32 = ((crc >> 31)&1) ? 0xfffffff : 0x0000000; - crc <<= 1; - return crc ^ ((d ^ crc_32) & LEGACY_CRC_POLY); -} - -/* Writes bitstream. LS bit first if len < 0, MS bit first if len > 0. */ -static void legacy_write_stream(uint32_t stream, int len, int set_last_bit) { - int i; - uint32_t err; - uint32_t outdata = 0; - uint32_t datacpy = stream; - - // MSB needs to be transferred first, lower levels do LSB first. Reverse. - for(i = 0; i < len; i++) { - outdata |= stream & 0x1; - if(i < (len-1)) { - outdata <<= 1; - stream >>= 1; - } - } - - // Call the lower level, in case the driver has a high-speed transfer capability. - // *** This always transfers LS bit first. - err = jtag_write_stream(&outdata, len, set_last_bit); - - debug("legacy_write_stream, stream = 0x%X (0x%X), len = %d, set_last_bit = %d, ret = 0x%X\n", datacpy, outdata, len, set_last_bit, err); - - if(err != APP_ERR_NONE) { - fprintf(stderr, "Error in legacy_write_stream: %s\n", get_err_string(err)); - } - - // The low level call does not compute - // a CRC. Do so here. Remember, CRC is only calculated using data bits. - if(len < 0) { - fprintf(stderr, "Program error: legacy debug JTAG read with negative length!\n"); - /* - len = -len; - for(i = 0; i < len; i++) { - legacy_crc_w = legacy_crc_calc(legacy_crc_w, stream&1); - datacpy >>= 1; - } - */ - } - else { - for(i = len-1; i >= 0; i--) { - legacy_crc_w = legacy_crc_calc(legacy_crc_w, (datacpy>>i)&1); - } - } - -} - -/* Gets bitstream. LS bit first if len < 0, MS bit first if len > 0. */ -static uint32_t legacy_read_stream(unsigned long stream, int len, int set_last_bit) { - int i; - uint32_t data = 0, datacpy = 0; - uint32_t outdata = stream; - uint32_t indata; - uint32_t err; - - // *** WARNING: We assume that the input ("stream") will always be 0. - // If it's ever not, then we probably need to reverse the bit order (as - // is done in legacy_write_stream) before sending. - - // Call the lower level, in case the driver has a high-speed transfer capability. - // This always transfers LS bit first. - err = jtag_read_write_stream(&outdata, &indata, len, 0, set_last_bit); - - // Data comes from the legacy debug unit MSB first, so we need to - // reverse the bit order. - for(i = 0; i < len; i++) { - data |= indata & 0x1; - if(i < (len-1)) { - data <<= 1; - indata >>= 1; - } - } - - datacpy = data; - - debug("legacy_read_stream: write 0x%X, read 0x%X, len %i, set_last_bit = %d\n", outdata, data, len, set_last_bit); - - if(err != APP_ERR_NONE) { - fprintf(stderr, "Error in legacy_read_stream: %s\n", get_err_string(err)); - } - - // The low level call does not compute - // a CRC. Do so here. Remember, CRC is only calculated using data bits. - if(len < 0) { - fprintf(stderr, "Program error: legacy debug JTAG read with negative length!\n"); - /* - len = -len; - for(i = 0; i < len; i++) { - legacy_crc_w = legacy_crc_calc(legacy_crc_w, stream&1); - stream >>= 1; - legacy_crc_r = legacy_crc_calc(legacy_crc_r, datacpy&1); - datacpy >>= 1; - } - */ - } - else { - for(i = len-1; i >= 0; i--) { - legacy_crc_w = legacy_crc_calc(legacy_crc_w, (stream>>i)&1); - legacy_crc_r = legacy_crc_calc(legacy_crc_r, (datacpy>>i)&1); - } - } - - return data; -} - -////////////////////////////////////////////////////////////////////////// -// Actual operations on the legacy debug unit - -/* Sets scan chain. */ -int legacy_dbg_set_chain(int chain) { - int status, crc_generated, legacy_crc_read; - desired_chain = chain; - -try_again: - if (current_chain == chain) return APP_ERR_NONE; - current_chain = -1; - debug("\nset_chain %i\n", chain); - tap_set_shift_dr(); /* SHIFT_DR */ - - /* write data, EXIT1_DR */ - legacy_crc_w = 0xffffffff; - legacy_write_stream(((chain & 0xf) | (1<= 0 */ -int legacy_dbg_command(int type, unsigned long adr, int len) { - int status, crc_generated, legacy_crc_read; - -try_again: - legacy_dbg_set_chain(desired_chain); - debug("\ncomm %i\n", type); - - /***** WRITEx *****/ - tap_set_shift_dr(); /* SHIFT_DR */ - - /* write data, EXIT1_DR */ - legacy_crc_w = 0xffffffff; - legacy_write_stream(((DI_WRITE_CMD & 0xf) | (0< 0); - legacy_write_stream(len - 1, 16, 0); - legacy_write_stream(legacy_crc_w, DBG_CRC_SIZE, 0); - - legacy_crc_r = 0xffffffff; - status = legacy_read_stream(0, DC_STATUS_SIZE, 0); - crc_generated = legacy_crc_r; - legacy_crc_read = legacy_read_stream(0, DBG_CRC_SIZE, 1); - - /* CRCs must match, otherwise retry */ - if (legacy_crc_read != crc_generated) { - if (retry_do()) goto try_again; - else return APP_ERR_CRC; - } - /* we should read expected status value, otherwise retry */ - if (status != 0) { - if (retry_do()) goto try_again; - else return APP_ERR_BAD_PARAM; - } - - tap_exit_to_idle(); // Transition the TAP back to state IDLE - - /* reset retry counter */ - retry_ok(); - return APP_ERR_NONE; -} - -/* writes a ctrl reg */ -int legacy_dbg_ctrl(int reset, int stall) { - int status, crc_generated, legacy_crc_read; - -try_again: - legacy_dbg_set_chain(desired_chain); - debug("\nctrl\n"); - - /***** WRITEx *****/ - tap_set_shift_dr(); /* SHIFT_DR */ - - /* write data, EXIT1_DR */ - legacy_crc_w = 0xffffffff; - legacy_write_stream(((DI_WRITE_CTRL & 0xf) | (0< -#include // for malloc() -#include // for usleep() -//#include // for mutexes - -#include "chain_commands.h" // For the return error codes -#include "altera_virtual_jtag.h" // hardware-specifg defines for the Altera Virtual JTAG interface -#include "cable_common.h" // low-level JTAG IO routines -#include "adv_dbg_commands.h" // for the kludge in tap_reset() -#include "errcodes.h" - -#define debug(...) //fprintf(stderr, __VA_ARGS__ ) - -// How many tries before an abort -#define NUM_SOFT_RETRIES 5 - -// for the klugde in tap_reset() -extern int current_reg_idx[DBG_MAX_MODULES]; - -/* Currently selected scan chain in the debug unit - just to prevent unnecessary - transfers. */ -int current_chain = -1; -int desired_chain = -1; - -// wait for 100ms -#define JTAG_RETRY_WAIT() usleep(100000); - -// Retry data -int soft_retry_no = 0; -//static int hard_retry_no = 0; - -// Configuration data -int global_IR_size = 0; -int global_IR_prefix_bits = 0; -int global_IR_postfix_bits = 0; -int global_DR_prefix_bits = 0; -int global_DR_postfix_bits = 0; -unsigned int global_jtag_cmd_debug = 0; // Value to be shifted into the TAP IR to select the debug unit (unused for virtual jtag) -unsigned char global_altera_virtual_jtag = 0; // Set true to use virtual jtag mode -unsigned int vjtag_cmd_vir = ALTERA_CYCLONE_CMD_VIR; // virtual IR-shift command for altera devices, may be configured on command line -unsigned int vjtag_cmd_vdr = ALTERA_CYCLONE_CMD_VDR; // virtual DR-shift, ditto -unsigned char global_xilinx_bscan = 0; // Set true if the hardware uses a Xilinx BSCAN_* device. - - -/////////////////////////////////////////////////////////////////////// -// Configuration - -void config_set_IR_size(int size) { - global_IR_size = size; -} - -void config_set_IR_prefix_bits(int bits) { - global_IR_prefix_bits = bits; -} - -void config_set_IR_postfix_bits(int bits) { - global_IR_postfix_bits = bits; -} - -void config_set_DR_prefix_bits(int bits) { - global_DR_prefix_bits = bits; -} - -void config_set_DR_postfix_bits(int bits) { - global_DR_postfix_bits = bits; -} - -void config_set_debug_cmd(unsigned int cmd) { - global_jtag_cmd_debug = cmd; -} - -void config_set_alt_vjtag(unsigned char enable) { - global_altera_virtual_jtag = (enable) ? 1:0; -} - -// At present, all devices which support virtual JTAG use the same VIR/VDR -// commands. But, if they ever change, these can be changed on the command line. -void config_set_vjtag_cmd_vir(unsigned int cmd) { - vjtag_cmd_vir = cmd; -} - -void config_set_vjtag_cmd_vdr(unsigned int cmd) { - vjtag_cmd_vdr = cmd; -} - -void config_set_xilinx_bscan(unsigned char enable) { - global_xilinx_bscan = (enable) ? 1:0; -} - -////////////////////////////////////////////////////////////////////// -// Functions which operate on the JTAG TAP - - -/* Resets JTAG - Writes TRST=1, and TRST=0. Sends 8 TMS to put the TAP - * in test_logic_reset mode, for good measure. - */ -int tap_reset(void) { - int i; - int err = APP_ERR_NONE; - - debug("\nreset("); - err |= jtag_write_bit(0); - JTAG_RETRY_WAIT(); - /* In case we don't have TRST reset it manually */ - for(i = 0; i < 8; i++) err |= jtag_write_bit(TMS); - err |= jtag_write_bit(TRST); // if TRST not supported, this puts us in test logic/reset - JTAG_RETRY_WAIT(); - err |= jtag_write_bit(0); // run test / idle - debug(")\n"); - - // Reset data on current module/register selections - current_chain = -1; - - // (this is only for the adv. debug i/f...bit of a kludge) - for(i = 0; i < DBG_MAX_MODULES; i++) - current_reg_idx[i] = -1; - - return err; -} - - // Set the IR with the DEBUG command, one way or the other -int tap_enable_debug_module(void) -{ - uint32_t data; - int err = APP_ERR_NONE; - - if(global_altera_virtual_jtag) { - /* Set for virtual IR shift */ - err |= tap_set_ir(vjtag_cmd_vir); // This is the altera virtual IR scan command - err |= jtag_write_bit(TMS); /* SELECT_DR SCAN */ - err |= jtag_write_bit(0); /* CAPTURE_DR */ - err |= jtag_write_bit(0); /* SHIFT_DR */ - - /* Select debug scan chain in virtual IR */ - data = (0x1< 32) { // Deal with spill into the next word - ir_chain[startoffset+1] &= ir >> (32-startshift); - ir_chain[startoffset+1] |= (0xFFFFFFFF << (global_IR_size - (32-startshift))); // Put the 1's back in the MSB positions - } - - // Do the actual JTAG transaction - debug("Set IR 0x%X\n", ir); - err |= jtag_write_bit(TMS); /* SELECT_DR SCAN */ - err |= jtag_write_bit(TMS); /* SELECT_IR SCAN */ - - err |= jtag_write_bit(0); /* CAPTURE_IR */ - err |= jtag_write_bit(0); /* SHIFT_IR */ - - /* write data, EXIT1_IR */ - debug("Setting IR, size %i, IR_size = %i, pre_size = %i, post_size = %i, data 0x%X\n", chain_size, global_IR_size, global_IR_prefix_bits, global_IR_postfix_bits, ir); - err |= cable_write_stream(ir_chain, chain_size, 1); // Use cable_ call directly (not jtag_), so we don't add DR prefix bits - debug("Done setting IR\n"); - - err |= jtag_write_bit(TMS); /* UPDATE_IR */ - err |= jtag_write_bit(0); /* IDLE */ - current_chain = -1; - return err; -} - - -// This assumes we are in the IDLE state, and we want to be in the SHIFT_DR state. -int tap_set_shift_dr(void) -{ - int err = APP_ERR_NONE; - - err |= jtag_write_bit(TMS); /* SELECT_DR SCAN */ - err |= jtag_write_bit(0); /* CAPTURE_DR */ - err |= jtag_write_bit(0); /* SHIFT_DR */ - - return err; -} - -// This transitions from EXIT1 to IDLE. It should be the last thing called -// in any debug unit transaction. -int tap_exit_to_idle(void) -{ - int err = APP_ERR_NONE; - - err |= jtag_write_bit(TMS); /* UPDATE_DR */ - err |= jtag_write_bit(0); /* IDLE */ - - return err; -} - -//////////////////////////////////////////////////////////////////// -// Operations to read / write data over JTAG - - -/* Writes TCLK=0, TRST=1, TMS=bit1, TDI=bit0 - and TCLK=1, TRST=1, TMS=bit1, TDI=bit0 -*/ -int jtag_write_bit(uint8_t packet) { - debug("Wbit(%i)\n", packet); - return cable_write_bit(packet); -} - -int jtag_read_write_bit(uint8_t packet, uint8_t *in_bit) { - int retval = cable_read_write_bit(packet, in_bit); - debug("RWbit(%i,%i)", packet, *in_bit); - return retval; -} - -// This automatically adjusts for the DR length (other devices on scan chain) -// when the set_TMS flag is true. -int jtag_write_stream(uint32_t *out_data, int length_bits, unsigned char set_TMS) -{ - int i; - int err = APP_ERR_NONE; - - if(!set_TMS) - err |= cable_write_stream(out_data, length_bits, 0); - else if(global_DR_prefix_bits == 0) - err |= cable_write_stream(out_data, length_bits, 1); - else { - err |= cable_write_stream(out_data, length_bits, 0); - // It could be faster to do a cable_write_stream for all the prefix bits (if >= 8 bits), - // but we'd need a data array of unknown (and theoretically unlimited) - // size to hold the 0 bits to write. TODO: alloc/realloc one. - for(i = 0; i < (global_DR_prefix_bits-1); i++) - err |= jtag_write_bit(0); - err |= jtag_write_bit(TMS); - } - return err; -} - -// When set_TMS is true, this function insures the written data is in the desired position (past prefix bits) -// before sending TMS. When 'adjust' is true, this function insures that the data read in accounts for postfix -// bits (they are shifted through before the read starts). -int jtag_read_write_stream(uint32_t *out_data, uint32_t *in_data, int length_bits, unsigned char adjust, unsigned char set_TMS) -{ - int i; - int err = APP_ERR_NONE; - - if(adjust && (global_DR_postfix_bits > 0)) { - // It would be faster to do a cable_write_stream for all the postfix bits, - // but we'd need a data array of unknown (and theoretically unlimited) - // size to hold the '0' bits to write. - for(i = 0; i < global_DR_postfix_bits; i++) - err |= cable_write_bit(0); - } - - // If there are both prefix and postfix bits, we may shift more bits than strictly necessary. - // If we shifted out the data while burning through the postfix bits, these shifts could be subtracted - // from the number of prefix shifts. However, that way leads to madness. - if(!set_TMS) - err |= cable_read_write_stream(out_data, in_data, length_bits, 0); - else if(global_DR_prefix_bits == 0) - err |= cable_read_write_stream(out_data, in_data, length_bits, 1); - else { - err |= cable_read_write_stream(out_data, in_data, length_bits, 0); - // It would be faster to do a cable_write_stream for all the prefix bits, - // but we'd need a data array of unknown (and theoretically unlimited) - // size to hold the '0' bits to write. - for(i = 0; i < (global_DR_prefix_bits-1); i++) - err |= jtag_write_bit(0); - err |= jtag_write_bit(TMS); - } - return err; -} - - - -// This function attempts to determine the structure of the JTAG chain -// It can determine how many devices are present. -// If the devices support the IDCODE command, it will be read and stored. -// There is no way to automatically determine the length of the IR registers - -// this must be read from a BSDL file, if IDCODE is supported. -// When IDCODE is not supported, IR length of the target device must be entered on the command line. - -#define ALLOC_SIZE 64 -#define MAX_DEVICES 1024 -int jtag_enumerate_chain(uint32_t **id_array, int *num_devices) -{ - uint32_t invalid_code = 0x7f; // Shift this out, we know we're done when we get it back - const unsigned int done_code = 0x3f; // invalid_code is altered, we keep this for comparison (minus the start bit) - int devindex = 0; // which device we are currently trying to detect - uint32_t tempID; - uint32_t temp_manuf_code; - uint32_t temp_rest_code; - uint8_t start_bit = 0; - uint32_t *idcodes; - int reallocs = 0; - int err = APP_ERR_NONE; - - // Malloc a reasonable number of entries, we'll expand if we must. Linked lists are overrated. - idcodes = (uint32_t *) malloc(ALLOC_SIZE*sizeof(uint32_t)); - if(idcodes == NULL) { - printf("Failed to allocate memory for device ID codes!\n"); - return APP_ERR_MALLOC; - } - - // Put in SHIFT-DR mode - err |= jtag_write_bit(TMS); /* SELECT_DR SCAN */ - err |= jtag_write_bit(0); /* CAPTURE_DR */ - err |= jtag_write_bit(0); /* SHIFT_DR */ - - printf("Enumerating JTAG chain...\n"); - - // Putting a limit on the # of devices supported has the useful side effect - // of insuring we still exit in error cases (we never get the 0x7f manuf. id) - while(devindex < MAX_DEVICES) { - // get 1 bit. 0 = BYPASS, 1 = start of IDCODE - err |= jtag_read_write_bit(invalid_code&0x01, &start_bit); - invalid_code >>= 1; - - if(start_bit == 0) { - if(devindex >= (ALLOC_SIZE << reallocs)) { // Enlarge the memory array if necessary, double the size each time - idcodes = (uint32_t *) realloc(idcodes, (ALLOC_SIZE << ++reallocs)*sizeof(uint32_t)); - if(idcodes == NULL) { - printf("Failed to allocate memory for device ID codes during enumeration!\n"); - return APP_ERR_MALLOC; - } - } - idcodes[devindex] = -1; - devindex++; - } - else { - // get 11 bit manufacturer code - err |= jtag_read_write_stream(&invalid_code, &temp_manuf_code, 11, 0, 0); - invalid_code >>= 11; - - if(temp_manuf_code != done_code) { - // get 20 more bits, rest of ID - err |= jtag_read_write_stream(&invalid_code, &temp_rest_code, 20, 0, 0); - invalid_code >>= 20; - tempID = (temp_rest_code << 12) | (temp_manuf_code << 1) | 0x01; - if(devindex >= (ALLOC_SIZE << reallocs)) { // Enlarge the memory array if necessary, double the size each time - idcodes = (uint32_t *) realloc(idcodes, (ALLOC_SIZE << ++reallocs)*sizeof(unsigned long)); - if(idcodes == NULL) { - printf("Failed to allocate memory for device ID codes during enumeration!\n"); - return APP_ERR_MALLOC; - } - } - idcodes[devindex] = tempID; - devindex++; - } else { - break; - } - } - - if(err) // Don't try to keep probing if we get a comm. error - return err; - } - - if(devindex >= MAX_DEVICES) - printf("WARNING: maximum supported devices on JTAG chain (%i) exceeded.\n", MAX_DEVICES); - - // Put in IDLE mode - err |= jtag_write_bit(TMS); /* EXIT1_DR */ - err |= jtag_write_bit(TMS); /* UPDATE_DR */ - err |= jtag_write_bit(0); /* IDLE */ - - *id_array = idcodes; - *num_devices = devindex; - - return err; -} - - - -int jtag_get_idcode(uint32_t cmd, uint32_t *idcode) -{ - uint32_t data_out = 0; - int err = APP_ERR_NONE; - unsigned char saveconfig = global_altera_virtual_jtag; - global_altera_virtual_jtag = 0; // We want the actual IDCODE, not the virtual device IDCODE - - err |= tap_set_ir(cmd); - err |= tap_set_shift_dr(); - err |= jtag_read_write_stream(&data_out, idcode, 32, 1, 1); /* EXIT1_DR */ - - if(err) - printf("Error getting ID code!\n"); - - // Put in IDLE mode - err |= jtag_write_bit(TMS); /* UPDATE_DR */ - err |= jtag_write_bit(0); /* IDLE */ - - global_altera_virtual_jtag = saveconfig; - return err; -} - - -///////////////////////////////////////////////////////////////// -// Helper functions - -/* counts retries and returns zero if we should abort */ -/* TODO: dynamically adjust timings */ -int retry_do() { - int err = APP_ERR_NONE; - - if (soft_retry_no >= NUM_SOFT_RETRIES) { - return 0; - - // *** TODO: Add a 'hard retry', which re-initializes the cable, re-enumerates the bus, etc. - - } else { /* quick reset */ - if(err |= tap_reset()) { - printf("Error %s while resetting for retry.\n", get_err_string(err)); - return 0; - } - - // Put us back into DEBUG mode - if(err |= tap_enable_debug_module()) { - printf("Error %s enabling debug module during retry.\n", get_err_string(err)); - return 0; - } - - soft_retry_no++; - printf("Retry...\n"); - } - - return 1; -} - -/* resets retry counter */ -void retry_ok() { - soft_retry_no = 0; -} - Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/gdb-6.8-bz436037-reg-no-longer-active.patch =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/gdb-6.8-bz436037-reg-no-longer-active.patch (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/gdb-6.8-bz436037-reg-no-longer-active.patch (nonexistent) @@ -1,24 +0,0 @@ -diff -d -urpN src.0/gdb/valops.c src.1/gdb/valops.c ---- src.0/gdb/valops.c 2008-07-27 04:00:03.000000000 +0200 -+++ src.1/gdb/valops.c 2008-07-31 15:17:42.000000000 +0200 -@@ -813,10 +813,18 @@ value_assign (struct value *toval, struc - struct frame_info *frame; - int value_reg; - -- /* Figure out which frame this is in currently. */ -- frame = frame_find_by_id (VALUE_FRAME_ID (toval)); - value_reg = VALUE_REGNUM (toval); - -+ /* Figure out which frame this is in currently. */ -+ frame = frame_find_by_id (VALUE_FRAME_ID (toval)); -+ /* "set $reg+=1" should work on programs with no debug info, -+ but frame_find_by_id returns NULL here (RH bug 436037). -+ Use current frame, it represents CPU state in this case. -+ If frame_find_by_id is changed to do it internally -+ (it is contemplated there), remove this. */ -+ if (!frame) -+ frame = get_current_frame (); -+ /* Probably never happens. */ - if (!frame) - error (_("Value being assigned to is no longer active.")); - Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/legacy_dbg_commands.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/legacy_dbg_commands.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/legacy_dbg_commands.h (nonexistent) @@ -1,26 +0,0 @@ - -#ifndef _LEGACY_DBG_COMMANDS_H_ -#define _LEGACY_DBG_COMMANDS_H_ - -#define DC_SIZE 4 -#define DC_STATUS_SIZE 4 - -#define DC_WISHBONE 0 -#define DC_CPU0 1 -#define DC_CPU1 2 - -#define DI_GO 0 -#define DI_READ_CMD 1 -#define DI_WRITE_CMD 2 -#define DI_READ_CTRL 3 -#define DI_WRITE_CTRL 4 - - -// Interface to send commands to the legacy debug interface -int legacy_dbg_set_chain(int chain); -int legacy_dbg_command(int type, unsigned long adr, int len); -int legacy_dbg_ctrl(int reset, int stall); -int legacy_dbg_ctrl_read(int *reset, int *stall); -int legacy_dbg_go(unsigned char *data, unsigned short len, int read); - -#endif Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_dbg_commands.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_dbg_commands.c (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_dbg_commands.c (nonexistent) @@ -1,689 +0,0 @@ -/* adv_dbg_commands.c -- JTAG protocol bridge between GDB and Advanced debug module. - Copyright(C) Nathan Yawn, nyawn@opencores.net - - This file contains functions which perform high-level transactions - on a JTAG chain and debug unit, such as setting a value in the TAP IR - or doing a burst write through the wishbone module of the debug unit. - It uses the protocol for the Advanced Debug Interface (adv_dbg_if). - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - - - -#include -#include // for malloc() -#include // for exit() -//#include // for mutexes - -#include "chain_commands.h" -#include "adv_dbg_commands.h" // hardware-specific defines for the debug module -//#include "altera_virtual_jtag.h" // hardware-specifg defines for the Altera Virtual JTAG interface -#include "cable_common.h" // low-level JTAG IO routines -#include "errcodes.h" - -#define debug(...) //fprintf(stderr, __VA_ARGS__ ) - -// How many '0' status bits to get during a burst read -// before giving up -#define MAX_READ_STATUS_WAIT 100 - -// Currently selected internal register in each module -// - cuts down on unnecessary transfers -int current_reg_idx[DBG_MAX_MODULES]; - -// Prototypes for local functions -uint32_t adbg_compute_crc(uint32_t crc_in, uint32_t data_in, int length_bits); - - - -//////////////////////////////////////////////////////////////////////// -// Helper functions - -uint32_t adbg_compute_crc(uint32_t crc_in, uint32_t data_in, int length_bits) -{ - int i; - unsigned int d, c; - uint32_t crc_out = crc_in; - - for(i = 0; i < length_bits; i = i+1) - { - d = ((data_in >> i) & 0x1) ? 0xffffffff : 0; - c = (crc_out & 0x1) ? 0xffffffff : 0; - crc_out = crc_out >> 1; - crc_out = crc_out ^ ((d ^ c) & ADBG_CRC_POLY); - } - return crc_out; -} - -////////////////////////////////////////////////////////////////// -// Functions which operate on the advanced debug unit - -/* Selects one of the modules in the debug unit (e.g. wishbone unit, CPU0, etc.) - */ -int adbg_select_module(int chain) -{ - uint32_t data; - int err = APP_ERR_NONE; - - if (current_chain == chain) - return err; - - current_chain = -1; - desired_chain = chain; - - // MSB of the data out must be set to 1, indicating a module select command - data = chain | (1<> 16) | ((opcode & 0xf) << 16)) & ~(0x1<<20); // MSB must be 0 to access modules - - err |= tap_set_shift_dr(); /* SHIFT_DR */ - - /* write data, EXIT1_DR */ - err |= jtag_write_stream(data, 53, 1); // When TMS is set (last parameter), DR length is also adjusted; EXIT1_DR - - err |= tap_exit_to_idle(); // Go from EXIT1 to IDLE - - /* reset retry counter */ - retry_ok(); - - if(err) - printf("Error %s sending burst command to module %i\n", get_err_string(err), desired_chain); - - return err; -} - -// Set up and execute a burst read from a contiguous block of addresses. -// Note that there is a minor weakness in the CRC algorithm in case of retries: -// the CRC is only checked for the final burst read. Thus, if errors/partial retries -// break up a transfer into multiple bursts, only the last burst will be CRC protected. -#define MAX_BUS_ERRORS 10 -int adbg_wb_burst_read(int word_size_bytes, int word_count, unsigned long start_address, void *data) -{ - unsigned char opcode; - uint8_t status; - unsigned long instream; - int i, j; - uint32_t crc_calc; - uint32_t crc_read; - unsigned char word_size_bits; - uint32_t out_data = 0; - uint32_t in_data; - unsigned long addr; - uint32_t err_data[2]; - int bus_error_retries = 0; - int err = APP_ERR_NONE; - - debug("Doing burst read, word size %d, word count %d, start address 0x%lX", word_size_bytes, word_count, start_address); - - if(word_count <= 0) { - debug("Ignoring illegal read burst length (%d)\n", word_count); - return 0; - } - - instream = 0; - word_size_bits = word_size_bytes << 3; - - // Select the appropriate opcode - switch(current_chain) { - case DC_WISHBONE: - if (word_size_bytes == 1) opcode = DBG_WB_CMD_BREAD8; - else if(word_size_bytes == 2) opcode = DBG_WB_CMD_BREAD16; - else if(word_size_bytes == 4) opcode = DBG_WB_CMD_BREAD32; - else { - printf("Tried burst read with invalid word size (%0x), defaulting to 4-byte words", word_size_bytes); - opcode = DBG_WB_CMD_BREAD32; - } - break; - case DC_CPU0: - if(word_size_bytes == 4) opcode = DBG_CPU0_CMD_BREAD32; - else { - printf("Tried burst read with invalid word size (%0x), defaulting to 4-byte words", word_size_bytes); - opcode = DBG_CPU0_CMD_BREAD32; - } - break; - case DC_CPU1: - if(word_size_bytes == 4) opcode = DBG_CPU1_CMD_BREAD32; - else { - printf("Tried burst read with invalid word size (%0x), defaulting to 4-byte words", word_size_bytes); - opcode = DBG_CPU0_CMD_BREAD32; - } - break; - default: - printf("ERROR! Illegal debug chain selected while doing burst read!\n"); - return 1; - } - - wb_burst_read_retry_full: - i = 0; - addr = start_address; - wb_burst_read_retry_partial: - crc_calc = 0xffffffff; - - - // Send the BURST READ command, returns TAP to idle state - if(err |= adbg_burst_command(opcode, addr, (word_count-i))) // word_count-i in case of partial retry - return err; - - // This is a kludge to word around oddities in the Xilinx BSCAN_* devices, and the - // adv_dbg_if state machine. The debug FSM needs 1 TCK between UPDATE_DR above, and - // the CAPTURE_DR below, and the BSCAN_* won't provide it. So, we force it, by putting the TAP - // in BYPASS, which makes the debug_select line inactive, which is AND'ed with the TCK line (in the xilinx_internal_jtag module), - // which forces it low. Then we re-enable USER1/debug_select to make TCK high. One TCK - // event, the hard way. - if(global_xilinx_bscan) { - err |= tap_set_ir(0xFFFFFFFF); - err |= tap_enable_debug_module(); - } - - // Get us back to shift_dr mode to read a burst - err |= tap_set_shift_dr(); - - // We do not adjust for the DR length here. BYPASS regs are loaded with 0, - // and the debug unit waits for a '1' status bit before beginning to read data. - - // Repeat for each word: wait until ready = 1, then read word_size_bits bits. - for(; i < word_count; i++) - { - // Get 1 status bit, then word_size_bytes*8 bits - status = 0; - j = 0; - while(!status) { // Status indicates whether there is a word available to read. Wait until it returns true. - err |= jtag_read_write_bit(0, &status); - j++; - // If max count exceeded, retry starting with the failure address - if(j > MAX_READ_STATUS_WAIT) { - printf("Burst read timed out.\n"); - if(!retry_do()) { - printf("Retry count exceeded in burst read!\n"); - return err|APP_ERR_MAX_RETRY; - } - err = APP_ERR_NONE; // on retry, errors cleared - addr = start_address + (i*word_size_bytes); - goto wb_burst_read_retry_partial; - } - } - - if(j > 1) { // It's actually normal for the first read of a burst to take 2 tries, even with a fast WB clock - 3 with a Xilinx BSCAN - debug("Took %0d tries before good status bit during burst read", j); - } - - // Get one word of data - err |= jtag_read_write_stream(&out_data, &in_data, word_size_bits, 0, 0); - debug("Read 0x%0lx", in_data); - - if(err) { // Break and retry as soon as possible on error - printf("Error %s during burst read.\n", get_err_string(err)); - if(!retry_do()) { - printf("Retry count exceeded in burst read!\n"); - return err|APP_ERR_MAX_RETRY; - } - err = APP_ERR_NONE; // on retry, errors cleared - addr = start_address + (i*word_size_bytes); - goto wb_burst_read_retry_partial; - } - - crc_calc = adbg_compute_crc(crc_calc, in_data, word_size_bits); - - if(word_size_bytes == 1) ((unsigned char *)data)[i] = in_data & 0xFF; - else if(word_size_bytes == 2) ((unsigned short *)data)[i] = in_data & 0xFFFF; - else ((unsigned long *)data)[i] = in_data; - } - - // All bus data was read. Read the data CRC from the debug module. - err |= jtag_read_write_stream(&out_data, &crc_read, 32, 0, 1); - - err |= tap_exit_to_idle(); // Go from EXIT1 to IDLE - - if(crc_calc != crc_read) { - printf("CRC ERROR! Computed 0x%x, read CRC 0x%x\n", crc_calc, crc_read); - if(!retry_do()) { - printf("Retry count exceeded! Abort!\n\n"); - return err|APP_ERR_CRC; - } - goto wb_burst_read_retry_full; - } - else debug("CRC OK!"); - - - - // Now, read the error register, and retry/recompute as necessary. - if(current_chain == DC_WISHBONE) - { - err |= adbg_ctrl_read(DBG_WB_REG_ERROR, err_data, 1); // First, just get 1 bit...read address only if necessary, - if(err_data[0] & 0x1) { // Then we have a problem. - err |= adbg_ctrl_read(DBG_WB_REG_ERROR, err_data, 33); - addr = (err_data[0] >> 1) | (err_data[1] << 31); - i = (addr - start_address) / word_size_bytes; - printf("ERROR! WB bus error during burst read, address 0x%lX (index 0x%X), retrying!\n", addr, i); - bus_error_retries++; - if(bus_error_retries > MAX_BUS_ERRORS) { - printf("Max WB bus errors reached during burst read\n"); - return err|APP_ERR_MAX_BUS_ERR; - } - // Don't call retry_do(), a JTAG reset won't help a WB bus error - err_data[0] = 1; - err |= adbg_ctrl_write(DBG_WB_REG_ERROR, err_data, 1); // Write 1 bit, to reset the error register, - goto wb_burst_read_retry_partial; - } - } - - retry_ok(); - return err; -} - -// Set up and execute a burst write to a contiguous set of addresses -int adbg_wb_burst_write(void *data, int word_size_bytes, int word_count, unsigned long start_address) -{ - unsigned char opcode; - uint8_t status; - uint32_t datawords[2] = {0,0}; - uint32_t statuswords[2] = {0,0}; - int i; - uint32_t crc_calc; - uint32_t crc_match; - unsigned int word_size_bits; - unsigned long addr; - int bus_error_retries = 0; - uint32_t err_data[2]; - int loopct, successes; - int first_status_loop; - int err = APP_ERR_NONE; - - debug("Doing burst write, word size %d, word count %d, start address 0x%lx", word_size_bytes, word_count, start_address); - word_size_bits = word_size_bytes << 3; - - if(word_count <= 0) { - printf("Ignoring illegal burst write size (%d)\n", word_count); - return 0; - } - - // Select the appropriate opcode - switch(current_chain) { - case DC_WISHBONE: - if (word_size_bytes == 1) opcode = DBG_WB_CMD_BWRITE8; - else if(word_size_bytes == 2) opcode = DBG_WB_CMD_BWRITE16; - else if(word_size_bytes == 4) opcode = DBG_WB_CMD_BWRITE32; - else { - printf("Tried WB burst write with invalid word size (%0x), defaulting to 4-byte words", word_size_bytes); - opcode = DBG_WB_CMD_BWRITE32; - } - break; - case DC_CPU0: - if(word_size_bytes == 4) opcode = DBG_CPU0_CMD_BWRITE32; - else { - printf("Tried CPU0 burst write with invalid word size (%0x), defaulting to 4-byte words", word_size_bytes); - opcode = DBG_CPU0_CMD_BWRITE32; - } - break; - case DC_CPU1: - if(word_size_bytes == 4) opcode = DBG_CPU1_CMD_BWRITE32; - else { - printf("Tried CPU1 burst write with invalid word size (%0X), defaulting to 4-byte words", word_size_bytes); - opcode = DBG_CPU0_CMD_BWRITE32; - } - break; - default: - printf("ERROR! Illegal debug chain selected while doing burst WRITE!\n"); - return 1; - } - - // Compute which loop iteration in which to expect the first status bit - first_status_loop = 1 + ((global_DR_prefix_bits + global_DR_postfix_bits)/(word_size_bits+1)); - - wb_burst_write_retry_full: - i = 0; - addr = start_address; - wb_burst_write_retry_partial: - crc_calc = 0xffffffff; - successes = 0; - - - // Send burst command, return to idle state - if(err |= adbg_burst_command(opcode, addr, (word_count-i))) // word_count-i in case of partial retry - return err; - - // Get us back to shift_dr mode to write a burst - //err |= jtag_write_bit(TMS); // select_dr_scan - //err |= jtag_write_bit(0); // capture_ir - //err |= jtag_write_bit(0); // shift_ir - err |= tap_set_shift_dr(); - - // Write a start bit (a 1) so it knows when to start counting - err |= jtag_write_bit(TDO); - - // Now, repeat... - for(loopct = 0; i < word_count; i++,loopct++) // loopct only used to check status... - { - // Write word_size_bytes*8 bits, then get 1 status bit - if(word_size_bytes == 4) datawords[0] = ((unsigned long *)data)[i]; - else if(word_size_bytes == 2) datawords[0] = ((unsigned short *)data)[i]; - else datawords[0] = ((unsigned char *)data)[i]; - - crc_calc = adbg_compute_crc(crc_calc, datawords[0], word_size_bits); - - // This is an optimization - if((global_DR_prefix_bits + global_DR_postfix_bits) == 0) { - err |= jtag_write_stream(datawords, word_size_bits, 0); // Write data - err |= jtag_read_write_bit(0, &status); // Read status bit - if(!status) { - addr = start_address + (i*word_size_bytes); - printf("Write before bus ready, retrying (idx %i, addr 0x%08lX).\n", i, addr); - if(!retry_do()) { printf("Retry count exceeded! Abort!\n\n"); exit(1);} - // Don't bother going to TAP idle state, we're about to reset the TAP - goto wb_burst_write_retry_partial; - } - } - else { // This is slower (for a USB cable anyway), because a read takes 1 more USB transaction than a write. - err |= jtag_read_write_stream(datawords, statuswords, word_size_bits+1, 0, 0); - debug("St. 0x%08lX 0x%08lX\n", statuswords[0], statuswords[1]); - status = (statuswords[0] || statuswords[1]); - if(loopct > first_status_loop) { - if(status) successes++; - else { - i = successes; - addr = start_address + (i*word_size_bytes); - printf("Write before bus ready, retrying (idx %i, addr 0x%08lX).\n", i, addr); - if(!retry_do()) { printf("Retry count exceeded! Abort!\n\n"); exit(1);} - // Don't bother going to TAP idle state, we're about to reset the TAP - goto wb_burst_write_retry_partial; - } - } - } - - if(err) { - printf("Error %s getting status bit, retrying.\n", get_err_string(err)); - if(!retry_do()) { - printf("Retry count exceeded!\n"); - return err|APP_ERR_MAX_RETRY; - } - err = APP_ERR_NONE; - addr = start_address + (i*word_size_bytes); - // Don't bother going to TAP idle state, we're about to reset the TAP - goto wb_burst_write_retry_partial; - } - - debug("Wrote 0x%0lx", datawords[0]); - } - - // *** If this is a multi-device chain, at least one status bit will be lost. - // *** If we want to check for it, we'd have to look while sending the CRC, and - // *** maybe while burning bits to get the match bit. So, for now, there is a - // *** hole here. - - // Done sending data, Send the CRC we computed - err |= jtag_write_stream(&crc_calc, 32, 0); - for(i = 0; i < global_DR_prefix_bits; i++) // Push the CRC data all the way to the debug unit - err |= jtag_write_bit(0); // Can't do this with a stream command without setting TMS on the last bit - - // Read the 'CRC match' bit, and go to exit1_dr - // May need to adjust for other devices in chain! - datawords[0] = 0; - err |= jtag_read_write_stream(datawords, &crc_match, 1, 1, 0); // set 'adjust' to pull match bit all the way in - // But don't set TMS above, that would shift prefix bits (again), wasting time. - err |= jtag_write_bit(TMS); // exit1_dr - err |= tap_exit_to_idle(); // Go from EXIT1 to IDLE - - if(!crc_match) { - printf("CRC ERROR! match bit after write is %i (computed CRC 0x%x)", crc_match, crc_calc); - if(!retry_do()) { printf("Retry count exceeded! Abort!\n\n"); exit(1);} - goto wb_burst_write_retry_full; - } - else debug("CRC OK!"); - - - // Now, read the error register and retry/recompute as needed - if (current_chain == DC_WISHBONE) - { - err |= adbg_ctrl_read(DBG_WB_REG_ERROR, err_data, 1); // First, just get 1 bit...read address only if necessary - if(err_data[0] & 0x1) { // Then we have a problem. - err |= adbg_ctrl_read(DBG_WB_REG_ERROR, err_data, 33); - addr = (err_data[0] >> 1) | (err_data[1] << 31); - i = (addr - start_address) / word_size_bytes; - printf("ERROR! WB bus error during burst write, address 0x%lX (index 0x%X), retrying!\n", addr, i); - bus_error_retries++; - if(bus_error_retries > MAX_BUS_ERRORS) { - printf("Max WB bus errors reached!\n"); - return err|APP_ERR_MAX_BUS_ERR; - } - // Don't call retry_do(), a JTAG reset won't help a WB bus error - err |= adbg_ctrl_write(DBG_WB_REG_ERROR, err_data, 1); // Write 1 bit, to reset the error register. - goto wb_burst_write_retry_partial; - } - } - - retry_ok(); - return err; -} Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_ft2232.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_ft2232.c (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_ft2232.c (nonexistent) @@ -1,880 +0,0 @@ -/* cable_ft2232.c - FT2232 based cable driver for the Advanced JTAG Bridge - Copyright (C) 2008 Arnim Laeuger, arniml@opencores.org - Copyright (C) 2009 José Ignacio Villar, jose@dte.us.es - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "cable_ft2232.h" -#include "cable_common.h" -#include "errcodes.h" -int debug = 0; - -static int usbconn_ftdi_common_open( usbconn_t *conn); -static void usbconn_ftdi_free( usbconn_t *conn ); -static int seq_purge(struct ftdi_context *ftdic, int purge_rx, int purge_tx); -static int seq_reset(struct ftdi_context *ftdic); -static int usbconn_ftdi_flush( ftdi_param_t *params ); -static int usbconn_ftdi_read( usbconn_t *conn, uint8_t *buf, int len ); -static int usbconn_ftdi_write( usbconn_t *conn, uint8_t *buf, int len, int recv ); -static int usbconn_ftdi_mpsse_open( usbconn_t *conn ); -static int usbconn_ftdi_close(usbconn_t *conn); - -usbconn_driver_t usbconn_ft2232_mpsse_driver = { - "ftdi-mpsse", - usbconn_ftdi_connect, - usbconn_ftdi_free, - usbconn_ftdi_mpsse_open, - usbconn_ftdi_close, - usbconn_ftdi_read, - usbconn_ftdi_write -}; - -usbconn_cable_t usbconn_ft2232_mpsse_CableID2= { - "CableID2", /* cable name */ - "CableID2", /* string pattern, not used */ - "ftdi-mpsse", /* default usbconn driver */ - 0x0403, /* VID */ - 0x6010 /* PID */ -}; - -static usbconn_t *ft2232_device; - - - -/// ---------------------------------------------------------------------------------------------- -/// libftdi wrappers for debugging purposes. -/// ---------------------------------------------------------------------------------------------- - -void print_buffer(unsigned char *buf, int size) { - int i=0; - for(i=0; i 1) print_buffer(buf, size); - return ftdi_write_data(ftdi, buf, size); -} - -char *my_ftdi_get_error_string (struct ftdi_context *ftdi) { - debug("[MYDBG] ftdi_get_error_string(ftdi);\n"); - return ftdi_get_error_string (ftdi); -} - -int my_ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size) { - int ret = 0; - debug("[MYDBG] ftdi_read_data(ftdi, buf=BUFFER[%d], size=%d);\n", size, size); - ret = ftdi_read_data(ftdi, buf, size); - if(debug) print_buffer(buf, size); - return ret; -} - -int my_ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, const char* description, const char* serial) { - debug("[MYDBG] ftdi_usb_open_desc(ftdi, vendor=%d, product=%d, description=DESCRIPTION, serial=SERIAL);\n", vendor, product); - return ftdi_usb_open_desc(ftdi, vendor, product, description, serial); -} - -void my_ftdi_deinit(struct ftdi_context *ftdi) { - debug("[MYDBG] ftdi_deinit(ftdi);\n"); - ftdi_deinit(ftdi); -} - -int my_ftdi_usb_purge_buffers(struct ftdi_context *ftdi) { - debug("[MYDBG] ftdi_usb_purge_buffers(ftdi);\n"); - return ftdi_usb_purge_buffers(ftdi); -} - -int my_ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi) { - debug("[MYDBG] ftdi_usb_purge_rx_buffer(ftdi);\n"); - return ftdi_usb_purge_rx_buffer(ftdi); -} - -int my_ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi) { - debug("[MYDBG] ftdi_usb_purge_tx_buffer(ftdi);\n"); - return ftdi_usb_purge_tx_buffer(ftdi); -} - -int my_ftdi_usb_reset(struct ftdi_context *ftdi) { - debug("[MYDBG] ftdi_usb_reset(ftdi);\n"); - return ftdi_usb_reset(ftdi); -} - -int my_ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency) { - debug("[MYDBG] ftdi_set_latency_timer(ftdi, latency=0x%02x);\n", latency); - return ftdi_set_latency_timer(ftdi, latency); -} - -int my_ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate) { - debug("[MYDBG] ftdi_set_baudrate(ftdi, baudrate=%d);\n", baudrate); - return ftdi_set_baudrate(ftdi, baudrate); -} - -int my_ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) { - debug("[MYDBG] ftdi_read_data_set_chunksize(ftdi, chunksize=%u);\n", chunksize); - return ftdi_read_data_set_chunksize(ftdi, chunksize); -} - -int my_ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) { - debug("[MYDBG] ftdi_write_data_set_chunksize(ftdi, chunksize=%u);\n", chunksize); - return ftdi_write_data_set_chunksize(ftdi, chunksize); -} - -int my_ftdi_set_event_char(struct ftdi_context *ftdi, unsigned char eventch, unsigned char enable) { - debug("[MYDBG] ftdi_set_event_char(ftdi, eventch=0x%02x, enable=0x%02x);\n", eventch, enable); - return ftdi_set_event_char(ftdi, eventch, enable); -} - -int my_ftdi_set_error_char(struct ftdi_context *ftdi, unsigned char errorch, unsigned char enable) { - debug("[MYDBG] ftdi_set_error_char(ftdi, errorch=0x%02x, enable=0x%02x);\n", errorch, enable); - return ftdi_set_error_char(ftdi, errorch, enable); -} - -int my_ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode) { - debug("[MYDBG] ftdi_set_bitmode(ftdi, bitmask=0x%02x, mode=0x%02x);\n", bitmask, mode); - return ftdi_set_bitmode(ftdi, bitmask, mode); -} - -int my_ftdi_usb_close(struct ftdi_context *ftdi) { - debug("[MYDBG] ftdi_usb_close(ftdi);\n"); - return ftdi_usb_close(ftdi); -} - - - -/// ---------------------------------------------------------------------------------------------- -/// USBconn FTDI MPSSE subsystem -/// ---------------------------------------------------------------------------------------------- - - -static int usbconn_ftdi_common_open(usbconn_t *conn) { - ftdi_param_t *params = conn->params; - struct ftdi_context * ftdic = params->ftdic; - int error; - - printf("Initializing USB device\n"); - - if ((error = my_ftdi_usb_open_desc(ftdic, conn->cable->vid, conn->cable->pid, NULL, NULL))) { - if (error == -1) printf("usb_find_busses() failed\n"); - else if (error == -2) printf("usb_find_devices() failed\n"); - else if (error == -3) printf("usb device not found\n"); - else if (error == -4) printf("unable to open device\n"); - else if (error == -5) printf("unable to claim device\n"); - else if (error == -6) printf("reset failed\n"); - else if (error == -7) printf("set baudrate failed\n"); - else if (error == -8) printf("get product description failed\n"); - else if (error == -9) printf("get serial number failed\n"); - else if (error == -10) printf("unable to close device\n"); - - my_ftdi_deinit(ftdic); - ftdic = NULL; - - printf("Can't open FTDI usb device\n"); - return(-1); - } - - return 0; -} - -static int seq_purge(struct ftdi_context *ftdic, int purge_rx, int purge_tx) { - int r = 0; - unsigned char buf; - - if ((r = my_ftdi_usb_purge_buffers( ftdic )) < 0) - printf("my_ftdi_usb_purge_buffers() failed\n"); - if (r >= 0) if ((r = my_ftdi_read_data( ftdic, &buf, 1 )) < 0) - printf("my_ftdi_read_data() failed\n"); - - return r < 0 ? -1 : 0; -} - -static int seq_reset(struct ftdi_context *ftdic) { - - if (my_ftdi_usb_reset( ftdic ) < 0) { - printf("my_ftdi_usb_reset() failed\n"); - return -1; - } - - if(seq_purge(ftdic, 1, 1) < 0) - return -1; - - return 0; -} - -static int usbconn_ftdi_flush( ftdi_param_t *params ) - { - int xferred; - int recvd = 0; - - if (!params->ftdic) - return -1; - - if (params->send_buffered == 0) - return 0; - - if ((xferred = my_ftdi_write_data( params->ftdic, params->send_buf, params->send_buffered )) < 0) - printf("my_ftdi_write_data() failed\n"); - - if (xferred < params->send_buffered) { - printf("Written fewer bytes than requested.\n"); - return -1; - } - - params->send_buffered = 0; - - /* now read all scheduled receive bytes */ - if (params->to_recv) { - if (params->recv_write_idx + params->to_recv > params->recv_buf_len) { - /* extend receive buffer */ - params->recv_buf_len = params->recv_write_idx + params->to_recv; - if (params->recv_buf) - params->recv_buf = (uint8_t *)realloc( params->recv_buf, params->recv_buf_len ); - } - - if (!params->recv_buf) { - printf("Receive buffer does not exist.\n"); - return -1; - } - - while (recvd == 0) - if ((recvd = my_ftdi_read_data( params->ftdic, &(params->recv_buf[params->recv_write_idx]), params->to_recv )) < 0) - printf("Error from my_ftdi_read_data()\n"); - - if (recvd < params->to_recv) - printf("Received less bytes than requested.\n"); - - params->to_recv -= recvd; - params->recv_write_idx += recvd; - } - - debug("[MYDBG] FLUSHING xferred=%u\n", xferred); - return xferred < 0 ? -1 : xferred; -} - -static int usbconn_ftdi_read( usbconn_t *conn, uint8_t *buf, int len ) { - ftdi_param_t *params = conn->params; - int cpy_len; - int recvd = 0; - - if (!params->ftdic) - return -1; - - /* flush send buffer to get all scheduled receive bytes */ - if (usbconn_ftdi_flush( params ) < 0) - return -1; - - if (len == 0) - return 0; - - /* check for number of remaining bytes in receive buffer */ - cpy_len = params->recv_write_idx - params->recv_read_idx; - if (cpy_len > len) - cpy_len = len; - len -= cpy_len; - - if (cpy_len > 0) { - /* get data from the receive buffer */ - memcpy( buf, &(params->recv_buf[params->recv_read_idx]), cpy_len ); - params->recv_read_idx += cpy_len; - if (params->recv_read_idx == params->recv_write_idx) - params->recv_read_idx = params->recv_write_idx = 0; - } - - if (len > 0) { - /* need to get more data directly from the device */ - while (recvd == 0) - if ((recvd = my_ftdi_read_data( params->ftdic, &(buf[cpy_len]), len )) < 0) - printf("Error from my_ftdi_read_data()\n"); - } - debug("[MYDBG] READ cpy_len=%u ; len=%u\n", cpy_len, len); - return recvd < 0 ? -1 : cpy_len + len; -} - -static int usbconn_ftdi_write( usbconn_t *conn, uint8_t *buf, int len, int recv ) { - - ftdi_param_t *params = conn->params; - int xferred = 0; - - if (!params->ftdic) - return -1; - - /* this write function will try to buffer write data - buffering will be ceased and a flush triggered in two cases. */ - - /* Case A: max number of scheduled receive bytes will be exceeded - with this write - Case B: max number of scheduled send bytes has been reached */ - if ((params->to_recv + recv > FTDI_MAXRECV) || ((params->send_buffered > FTDX_MAXSEND) && (params->to_recv == 0))) - xferred = usbconn_ftdi_flush(params); - - if (xferred < 0) - return -1; - - /* now buffer this write */ - if (params->send_buffered + len > params->send_buf_len) { - params->send_buf_len = params->send_buffered + len; - if (params->send_buf) - params->send_buf = (uint8_t *)realloc( params->send_buf, params->send_buf_len); - } - - if (params->send_buf) { - memcpy( &(params->send_buf[params->send_buffered]), buf, len ); - params->send_buffered += len; - if (recv > 0) - params->to_recv += recv; - - if (recv < 0) { - /* immediate write requested, so flush the buffered data */ - xferred = usbconn_ftdi_flush( params ); - } - - debug("[MYDBG] WRITE inmediate=%s ; xferred=%u ; len=%u\n", ((recv < 0) ? "TRUE" : "FALSE"), xferred, len); - return xferred < 0 ? -1 : len; - } - else { - printf("Send buffer does not exist.\n"); - return -1; - } -} - -static int usbconn_ftdi_mpsse_open( usbconn_t *conn ) { - ftdi_param_t *params = conn->params; - struct ftdi_context *ftdic = params->ftdic; - - int r = 0; - - if (usbconn_ftdi_common_open(conn) < 0) { - printf("Connection failed\n"); - return -1; - } - - /* This sequence might seem weird and containing superfluous stuff. - However, it's built after the description of JTAG_InitDevice - Ref. FTCJTAGPG10.pdf - Intermittent problems will occur when certain steps are skipped. */ - - r = seq_reset( ftdic ); - if (r >= 0) - r = seq_purge( ftdic, 1, 0 ); - - if (r >= 0) - if ((r = my_ftdi_write_data_set_chunksize( ftdic, FTDX_MAXSEND_MPSSE )) < 0) - puts( my_ftdi_get_error_string( ftdic ) ); - - if (r >= 0) - if ((r = my_ftdi_read_data_set_chunksize( ftdic, FTDX_MAXSEND_MPSSE )) < 0) - puts( my_ftdi_get_error_string( ftdic ) ); - - /* set a reasonable latency timer value - if this value is too low then the chip will send intermediate result data - in short packets (suboptimal performance) */ - if (r >= 0) - if ((r = my_ftdi_set_latency_timer( ftdic, 16 )) < 0) - printf("my_ftdi_set_latency_timer() failed\n"); - - if (r >= 0) - if ((r = my_ftdi_set_bitmode( ftdic, 0x0b, BITMODE_MPSSE )) < 0) - printf("my_ftdi_set_bitmode() failed\n"); - - if (r >= 0) - if ((r = my_ftdi_usb_reset( ftdic )) < 0) - printf("my_ftdi_usb_reset() failed\n"); - - if (r >= 0) - r = seq_purge( ftdic, 1, 0 ); - - /* set TCK Divisor */ - if (r >= 0) { - uint8_t buf[3] = {TCK_DIVISOR, 0x00, 0x00}; - r = usbconn_ftdi_write( conn, buf, 3, 0 ); - } - - /* switch off loopback */ - if (r >= 0) { - uint8_t buf[1] = {LOOPBACK_END}; - r = usbconn_ftdi_write( conn, buf, 1, 0 ); - } - - if (r >= 0) - r = usbconn_ftdi_read( conn, NULL, 0 ); - - if (r >= 0) - if ((r = my_ftdi_usb_reset( ftdic )) < 0) - printf("my_ftdi_usb_reset() failed\n"); - - if (r >= 0) - r = seq_purge( ftdic, 1, 0 ); - - if (r < 0) { - ftdi_usb_close( ftdic ); - ftdi_deinit( ftdic ); - /* mark ftdi layer as not initialized */ - params->ftdic = NULL; - } - - return r < 0 ? -1 : 0; -} - -static int usbconn_ftdi_close(usbconn_t *conn) { - ftdi_param_t *params = conn->params; - - if (params->ftdic) { - my_ftdi_usb_close(params->ftdic); - my_ftdi_deinit(params->ftdic); - params->ftdic = NULL; - } - - return 0; -} - -static void usbconn_ftdi_free( usbconn_t *conn ) -{ - ftdi_param_t *params = conn->params; - - if (params->send_buf) free( params->send_buf ); - if (params->recv_buf) free( params->recv_buf ); - if (params->ftdic) free( params->ftdic ); - if (params->serial) free( params->serial ); - - free( conn->params ); - free( conn ); -} - -usbconn_t * usbconn_ftdi_connect() { - - usbconn_t *conn = malloc( sizeof( usbconn_t ) ); - ftdi_param_t *params = malloc( sizeof( ftdi_param_t ) ); - struct ftdi_context *ftdic = malloc( sizeof( struct ftdi_context ) ); - - if (params) { - params->send_buf_len = FTDX_MAXSEND; - params->send_buffered = 0; - params->send_buf = (uint8_t *) malloc( params->send_buf_len ); - params->recv_buf_len = FTDI_MAXRECV; - params->to_recv = 0; - params->recv_write_idx = 0; - params->recv_read_idx = 0; - params->recv_buf = (uint8_t *) malloc( params->recv_buf_len ); - } - - if (!conn || !params || !ftdic || !params->send_buf || !params->recv_buf) { - printf("Can't allocate memory for ftdi context structures\n"); - - if (conn) free( conn ); - if (params) free( params ); - if (ftdic) free( ftdic ); - if (params->send_buf) free( params->send_buf ); - if (params->recv_buf) free( params->recv_buf ); - return NULL; - } - - conn->driver = &usbconn_ft2232_mpsse_driver; - conn->cable = &usbconn_ft2232_mpsse_CableID2; - - ftdi_init( ftdic ); - params->ftdic = ftdic; - params->pid = conn->cable->pid; - params->vid = conn->cable->vid; - params->serial = NULL; - - conn->params = params; - - printf("Structs successfully initialized\n"); - - /* do a test open with the specified cable paramters, - alternatively we could use libusb to detect the presence of the - specified USB device */ - if (usbconn_ftdi_common_open(conn) != 0) { - printf("Connection failed\n"); - usbconn_ftdi_free(conn); - printf("Freeing structures.\n"); - return NULL; - } - - my_ftdi_usb_close( ftdic ); - - printf("Connected to libftdi driver.\n"); - - return conn; -} - - - -/// ---------------------------------------------------------------------------------------------- -/// High level functions to generate Tx/Rx commands -/// ---------------------------------------------------------------------------------------------- - -int cable_ft2232_write_bytes(usbconn_t *conn, unsigned char *buf, int len, int postread) { - - int cur_command_size; - int max_command_size; - int cur_chunk_len; - int recv; - int xferred; - int i; - unsigned char *mybuf; - - if(len == 0) - return 0; - debug("write_bytes(length=%d, postread=%s)\n", len, ((postread > 0) ? "TRUE" : "FALSE")); - recv = 0; - max_command_size = min(len, 65536)+3; - mybuf = (unsigned char *) malloc( max_command_size ); - - /// Command OPCODE: write bytes - mybuf[0] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG; - if(postread) // if postread is enabled it will buffer incoming bytes - mybuf[0] = mybuf[0] | MPSSE_DO_READ; - - // We divide the transmitting stream of bytes in chunks with a maximun length of 65536 bytes each. - while(len > 0) { - cur_chunk_len = min(len, 65536); - len = len - cur_chunk_len; - cur_command_size = cur_chunk_len + 3; - - /// Low and High bytes of the length field - mybuf[1] = (unsigned char) ( cur_chunk_len - 1); - mybuf[2] = (unsigned char) ((cur_chunk_len - 1) >> 8); - - debug("\tOPCODE: 0x%x\n", mybuf[0]); - debug("\tLENGTL: 0x%02x\n", mybuf[1]); - debug("\tLENGTH: 0x%02x\n", mybuf[2]); - - /// The rest of the command is filled with the bytes that will be transferred - memcpy(&(mybuf[3]), buf, cur_chunk_len ); - buf = buf + cur_chunk_len; - for(i = 0; i< cur_chunk_len; i++) - if(debug>1) debug("\tBYTE%3d: 0x%02x\n", i, mybuf[3+i]); - - /// Finally we can ransmit the command - xferred = usbconn_ftdi_write( conn, mybuf, cur_command_size, (postread ? cur_chunk_len : 0) ); - if(xferred != cur_command_size) - return -1; - - // If OK, the update the number of incoming bytes that are being buffered for a posterior read - if(postread) - recv = recv + cur_chunk_len; - } - debug("\tPOSTREAD: %u bytes\n", recv); - - // Returns the number of buffered incoming bytes - return recv; -} - -int cable_ft2232_write_bits(usbconn_t *conn, unsigned char *buf, int len, int postread, int with_tms) -{ - int max_command_size; - int max_chunk_len; - int cur_chunk_len; - int recv; - int xferred; - int i; - unsigned char *mybuf; - - if(len == 0) - return 0; - - max_command_size = 3; - mybuf = (unsigned char *) malloc( max_command_size ); - - if(!with_tms) { - /// Command OPCODE: write bits (can write up to 8 bits in a single command) - max_chunk_len = 8; - mybuf[0] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG | MPSSE_BITMODE; - } - else { - /// Command OPCODE: 0x4B write bit with tms (can write up to 1 bits in a single command) - max_chunk_len = 1; - mybuf[0] = MPSSE_WRITE_TMS|MPSSE_LSB|MPSSE_BITMODE|MPSSE_WRITE_NEG; - } - - if(postread) // (OPCODE += 0x20) if postread is enabled it will buffer incoming bits - mybuf[0] = mybuf[0] | MPSSE_DO_READ; - - // We divide the transmitting stream of bytes in chunks with a maximun length of max_chunk_len bits each. - i=0; - recv = 0; - while(len > 0) { - cur_chunk_len = min(len, max_chunk_len); - len = len - cur_chunk_len; - - /// Bits length field - mybuf[1] = (unsigned char) ( cur_chunk_len - 1); - - debug("\tOPCODE: 0x%x\n", mybuf[0]); - debug("\tLENGTH: 0x%02x\n", mybuf[1]); - - if(!with_tms) { - /// The last byte of the command is filled with the bits that will be transferred - debug("\tDATA[%d] 0x%02x\n", (i/8), buf[i/8]); - mybuf[2] = buf[i/8]; - i=i+8; - } - else { - //TODO: seleccionar el bit a transmitir - mybuf[2] = 0x01 | ((buf[(i/8)] >> (i%8)) << 7); - i++; - } - - debug("\tBYTE%3d: 0x%02x\n", i, mybuf[2]); - - /// Finally we can transmmit the command - xferred = usbconn_ftdi_write( conn, mybuf, max_command_size, (postread ? 1 : 0) ); - if(xferred != max_command_size) - return -1; - - // If OK, the update the number of incoming bytes that are being buffered for a posterior read - if(postread) - recv = recv + 1; - } - debug("\tPOSTREAD: %u bytes\n", recv); - - return recv; -} - -int cable_ft2232_read_packed_bits(usbconn_t *conn, uint8_t *buf, int packet_len, int bits_per_packet, int offset) -{ - unsigned char *mybuf; - unsigned char dst_mask; - unsigned char src_mask; - int row_offset; - int dst_row; - int dst_col; - int src_row; - int src_col; - int i; - int r; - - if(packet_len == 0 || bits_per_packet == 0) - return 0; - - mybuf = (unsigned char *) malloc( packet_len ); - if((r=usbconn_ftdi_read( conn, mybuf, packet_len )) < 0) { - debug("Read failed\n"); - return -1; - } - - if(bits_per_packet < 8) { - for(i=0; i < packet_len; i++){ // rotate bits to the left side -// debug("[MYDBG] unaligned bits[%d]=%02x\n", i, mybuf[i]); - mybuf[i] = (mybuf[i] >> (8-bits_per_packet)); -// debug("[MYDBG] aligned bits[%d]=%02x\n", i, mybuf[i]); - } - for(i=offset; i < (packet_len*bits_per_packet+offset); i++) { - dst_row = i / 8; - dst_col = i % 8; - src_row = (i-offset) / bits_per_packet; - src_col = (i-offset) % bits_per_packet; - dst_mask = ~(1 << dst_col); - src_mask = (1 << src_col); -// debug("[MYDBG] i=%4d dst[%3d][%3d] dst_mask=%02x dst_val=%02x dst_masked=%02x\n", i, dst_row, dst_col, dst_mask, buf[dst_row], (buf[dst_row] & dst_mask)); -// debug("[MYDBG] i=%4d src[%3d][%3d] src_mask=%02x src_val=%02x src_masked=%02x\n", i, src_row, src_col, src_mask, mybuf[src_row], (mybuf[src_row] & src_mask)); - if(dst_col >= src_col) - buf[dst_row] = (buf[dst_row] & dst_mask) | ((mybuf[src_row] & src_mask) << (dst_col - src_col)); - else - buf[dst_row] = (buf[dst_row] & dst_mask) | ((mybuf[src_row] & src_mask) >> (dst_col - src_col)); - } - - } - else if(bits_per_packet == 8){ - row_offset = offset / 8; -// debug("[MYDBG] Row offset=%d\n", row_offset); - memcpy( &(buf[row_offset]), mybuf, packet_len); - } - else { - return -1; - } - -// debug("read_bits()-> %x\n", *buf); - return ((r < 1) ? -1 : 0); -} - -int cable_ft2232_write_stream(usbconn_t *conn, unsigned char *buf, int len, int postread, int with_tms) { - int len_bytes; - int len_bits; - int len_tms_bits; - unsigned char mybuf; - - len_tms_bits = ((with_tms) ? 1 : 0); - len_bytes = ((len -len_tms_bits) / 8); - len_bits = ((len -len_tms_bits) % 8); - - debug("[MYDBG] cable_ft2232_write_stream(len=%d postread=%d tms=%d) = %d bytes %dbits %dtms_bits\n", len, postread, with_tms, len_bytes, len_bits, len_tms_bits); - - if(len_bytes > 0) - cable_ft2232_write_bytes(conn, buf, len_bytes, postread); - - if(len_bits > 0) - cable_ft2232_write_bits(conn, &(buf[len_bytes]), len_bits, postread, 0); - - if(len_tms_bits > 0) { - mybuf = (buf[len_bytes] >> len_bits); - cable_ft2232_write_bits(conn, &mybuf, 1, postread, 1); - } - - return 0; -} - -int cable_ft2232_read_stream(usbconn_t *conn, unsigned char *buf, int len, int with_tms) { - int len_bytes; - int len_bits; - int len_tms_bits; - - len_tms_bits = ((with_tms) ? 1 : 0); - len_bytes = ((len -len_tms_bits) / 8); - len_bits = ((len -len_tms_bits) % 8); - - debug("[MYDBG] cable_ft2232_read_stream(len=%d tms=%d) = %d bytes %dbits %dtms_bits\n", len, with_tms, len_bytes, len_bits, len_tms_bits); - - if(len_bytes > 0) - cable_ft2232_read_packed_bits(conn, buf, len_bytes, 8, 0); - - if(len_bits > 0) - cable_ft2232_read_packed_bits(conn, buf, 1, len_bits, (len_bytes * 8)); - - if(len_tms_bits > 0) - cable_ft2232_read_packed_bits(conn, buf, 1, 1, (len_bits + (len_bytes * 8))); - - return 0; -} - - - -/// ---------------------------------------------------------------------------------------------- -/// Advanced Jtag debugger driver interface. -/// ---------------------------------------------------------------------------------------------- - -int cable_ftdi_init() { - int err = APP_ERR_NONE; - int res = 0; - unsigned char *buf = malloc(10); - - ft2232_device = usbconn_ftdi_connect(); - - if((res = usbconn_ftdi_mpsse_open(ft2232_device)) != 0) - err |= APP_ERR_USB; - printf("Open MPSSE mode returned: %s\n", ((res != 0) ? "FAIL" : "OK") ); - - ftdi_param_t *params = ft2232_device->params; - //struct ftdi_context * ftdic = params->ftdic; - - buf[0]= SET_BITS_LOW; - buf[1]= 0x00; - buf[2]= 0x0b; - buf[3]= TCK_DIVISOR; - buf[4]= 0x01; - buf[5]= 0x00; - buf[6]= SET_BITS_HIGH; - buf[7]= ~0x04; - buf[8]= 0x04; - buf[9]= SEND_IMMEDIATE; - if(usbconn_ftdi_write( ft2232_device , buf, 10, 0) != 10) { - err |= APP_ERR_USB; - printf("Initial write failed\n"); - } - - usbconn_ftdi_flush( params ); - - return err; -} - -int cable_ftdi_close() { - usbconn_ftdi_close(ft2232_device); - usbconn_ftdi_free(ft2232_device); - - return APP_ERR_NONE; -} - -int cable_ftdi_flush() { - ftdi_param_t *params = ft2232_device->params; - usbconn_ftdi_flush( params ); - - return APP_ERR_NONE; -} - -int cable_ftdi_write_bit(uint8_t packet) { - int err = APP_ERR_NONE; - unsigned char buf; - int tms; - - buf = ((packet & TDO) ? 0x01 : 0x00); - tms = ((packet & TMS) ? 1 : 0); - - if(cable_ft2232_write_stream(ft2232_device, &buf, 1, 0, tms) < 0) - err |= APP_ERR_COMM; - - cable_ftdi_flush(); - - return err; - -} - -int cable_ftdi_read_write_bit(uint8_t packet_out, uint8_t *bit_in) { - - int err = APP_ERR_NONE; - unsigned char buf; - int tms; - - buf = ((packet_out & TDO) ? 0x01 : 0x00); - tms = ((packet_out & TMS) ? 1 : 0); - - if(cable_ft2232_write_stream(ft2232_device, &buf, 1, 1, tms) < 0) - err = APP_ERR_COMM; - - if(cable_ft2232_read_stream(ft2232_device, ((unsigned char *)bit_in), 1, tms) < 0) - err = APP_ERR_COMM; - - return err; -} - -int cable_ftdi_write_stream(uint32_t *stream, int len_bits, int set_last_bit) { - int err = APP_ERR_NONE; - - if(cable_ft2232_write_stream(ft2232_device, ((unsigned char *)stream), len_bits, 0, set_last_bit) < 0) - err |= APP_ERR_COMM; - - cable_ftdi_flush(); - - return err; -} - -int cable_ftdi_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) { - int err = APP_ERR_NONE; - if(cable_ft2232_write_stream(ft2232_device, ((unsigned char *)outstream), len_bits, 1, set_last_bit) < 0) - err |= APP_ERR_COMM; - if(cable_ft2232_read_stream(ft2232_device, ((unsigned char *)instream), len_bits, set_last_bit) < 0) - err |= APP_ERR_COMM; - - return err; -} - -int cable_ftdi_opt(int c, char *str) { - fprintf(stderr, "Unknown parameter '%c'\n", c); - return APP_ERR_BAD_PARAM; -} - -/// ---------------------------------------------------------------------------------------------- - Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/chain_commands.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/chain_commands.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/chain_commands.h (nonexistent) @@ -1,49 +0,0 @@ -#ifndef _CHAIN_COMMANDS_H_ -#define _CHAIN_COMMANDS_H_ - -#include - -// These two are used by both debug modules -extern int current_chain; -extern int desired_chain; - -// These are needed by the advanced debug module -extern int global_DR_prefix_bits; -extern int global_DR_postfix_bits; -extern unsigned char global_xilinx_bscan; - -// Discover devices on JTAG chain -int jtag_enumerate_chain(uint32_t **id_array, int *num_devices); -int jtag_get_idcode(uint32_t cmd, uint32_t *idcode); - -// Functions to set configuration for the JTAG chain -void config_set_IR_size(int size); -void config_set_IR_prefix_bits(int bits); -void config_set_IR_postfix_bits(int bits); -void config_set_DR_prefix_bits(int bits); -void config_set_DR_postfix_bits(int bits); -void config_set_debug_cmd(unsigned int cmd); -void config_set_alt_vjtag(unsigned char enable); -void config_set_vjtag_cmd_vir(unsigned int cmd); -void config_set_vjtag_cmd_vdr(unsigned int cmd); -void config_set_xilinx_bscan(unsigned char enable); - -// Operations on the JTAG TAP -int tap_reset(void); -int tap_enable_debug_module(void); -int tap_set_ir(int ir); -int tap_set_shift_dr(void); -int tap_exit_to_idle(void); - -// Functions to Send/receive bitstreams via JTAG -// These functions are aware of other devices in the chain, and may adjust for them. -int jtag_write_bit(uint8_t packet); -int jtag_read_write_bit(uint8_t packet, uint8_t *in_bit); -int jtag_write_stream(uint32_t *out_data, int length_bits, unsigned char set_TMS); -int jtag_read_write_stream(uint32_t *out_data, uint32_t *in_data, int length_bits, - unsigned char adjust, unsigned char set_TMS); - -int retry_do(void); -void retry_ok(void); - -#endif Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/rsp-server.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/rsp-server.c (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/rsp-server.c (nonexistent) @@ -1,2968 +0,0 @@ -/* rsp-server.c -- Remote Serial Protocol server for GDB - -Copyright (C) 2008 Embecosm Limited - -Contributor Jeremy Bennett - -This file was part of Or1ksim, the OpenRISC 1000 Architectural Simulator. -Adapted for adv_jtag_bridge by Nathan Yawn - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see . -*/ - -/* This program is commented throughout in a fashion suitable for processing - with Doxygen. */ - -/* System includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Package includes */ -#include "except.h" -#include "spr-defs.h" -#include "dbg_api.h" -#include "errcodes.h" - -/* Define to log each packet */ -#define RSP_TRACE 0 - -/*! Name of the RSP service */ -#define OR1KSIM_RSP_SERVICE "jtag-rsp" - -/*! Protocol used by Or1ksim */ -#define OR1KSIM_RSP_PROTOCOL "tcp" - -/* Indices of GDB registers that are not GPRs. Must match GDB settings! */ -#define PPC_REGNUM (MAX_GPRS + 0) /*!< Previous PC */ -#define NPC_REGNUM (MAX_GPRS + 1) /*!< Next PC */ -#define SR_REGNUM (MAX_GPRS + 2) /*!< Supervision Register */ -#define NUM_REGS (MAX_GRPS + 3) /*!< Total GDB registers */ - -/*! Trap instruction for OR32 */ -#define OR1K_TRAP_INSTR 0x21000001 - -/*! Definition of GDB target signals. Data taken from the GDB 6.8 - source. Only those we use defined here. */ -enum target_signal { - TARGET_SIGNAL_NONE = 0, - TARGET_SIGNAL_INT = 2, - TARGET_SIGNAL_ILL = 4, - TARGET_SIGNAL_TRAP = 5, - TARGET_SIGNAL_FPE = 8, - TARGET_SIGNAL_BUS = 10, - TARGET_SIGNAL_SEGV = 11, - TARGET_SIGNAL_ALRM = 14, - TARGET_SIGNAL_USR2 = 31, - TARGET_SIGNAL_PWR = 32 -}; - -/*! The maximum number of characters in inbound/outbound buffers. The largest - packets are the 'G' packet, which must hold the 'G' and all the registers - with two hex digits per byte and the 'g' reply, which must hold all the - registers, and (in our implementation) an end-of-string (0) - character. Adding the EOS allows us to print out the packet as a - string. So at least NUMREGBYTES*2 + 1 (for the 'G' or the EOS) are needed - for register packets */ -#define GDB_BUF_MAX ((NUM_REGS) * 8 + 1) - -/*! Size of the matchpoint hash table. Largest prime < 2^10 */ -#define MP_HASH_SIZE 1021 - -/*! String to map hex digits to chars */ -static const char hexchars[]="0123456789abcdef"; - -/*! Data structure for RSP buffers. Can't be null terminated, since it may - include zero bytes */ -struct rsp_buf -{ - char data[GDB_BUF_MAX]; - int len; -}; - -/*! Enumeration of different types of matchpoint. These have explicit values - matching the second digit of 'z' and 'Z' packets. */ -enum mp_type { - BP_MEMORY = 0, - BP_HARDWARE = 1, - WP_WRITE = 2, - WP_READ = 3, - WP_ACCESS = 4 -}; - -/*! Data structure for a matchpoint hash table entry */ -struct mp_entry -{ - enum mp_type type; /*!< Type of matchpoint */ - unsigned long int addr; /*!< Address with the matchpoint */ - unsigned long int instr; /*!< Substituted instruction */ - struct mp_entry *next; /*!< Next entry with this hash */ -}; - -/* Data to interface the GDB handler thread with the target handler thread */ -pthread_mutex_t rsp_mutex = PTHREAD_MUTEX_INITIALIZER; /*!< Mutex to protect the "target_running" member of the rsp struct */ -pthread_mutex_t target_handler_mutex = PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t target_handler_cond = PTHREAD_COND_INITIALIZER; - -int target_handler_state = 0; -pthread_t target_handler_thread; -void *target_handler(void *arg); - -int pipe_fds[2]; // Descriptors for the pipe from the poller thread to the GDB interface thread - -// Work-around for the current OR1200 implementation; After setting the NPC, -// it always reads back 0 until the next instruction is executed. This -// is a problem with the way we handle memory breakpoints (resetting the NPC), -// so we cache the last value we set the NPC to, incase we need it. -unsigned char use_cached_npc = 0; -unsigned int cached_npc = 0; - -/*! Central data for the RSP connection */ -static struct -{ - int client_waiting; /*!< Is client waiting a response? */ - int target_running; /*!< Is target hardware running? --NAY */ - int single_step_mode; - int proto_num; /*!< Number of the protocol used */ - int server_fd; /*!< FD for new connections */ - int client_fd; /*!< FD for talking to GDB */ - int sigval; /*!< GDB signal for any exception */ - unsigned long int start_addr; /*!< Start of last run */ - struct mp_entry *mp_hash[MP_HASH_SIZE]; /*!< Matchpoint hash table */ -} rsp; - -/* Forward declarations of static functions */ -void rsp_exception (unsigned long int except); -static void rsp_server_request (); -static void rsp_client_request (); -static void rsp_server_close (); -static void rsp_client_close (); -static void put_packet (struct rsp_buf *buf); -static void put_str_packet (const char *str); -static struct rsp_buf *get_packet (); -static void put_rsp_char (char c); -static int get_rsp_char (); -static int rsp_unescape (char *data, - int len); -static void mp_hash_init (); -static void mp_hash_add (enum mp_type type, - unsigned long int addr, - unsigned long int instr); -static struct mp_entry *mp_hash_lookup (enum mp_type type, - unsigned long int addr); -static struct mp_entry *mp_hash_delete (enum mp_type type, - unsigned long int addr); -static int hex (int c); -static void reg2hex (unsigned long int val, - char *buf); -static unsigned long int hex2reg (char *buf); -static void ascii2hex (char *dest, - char *src); -static void hex2ascii (char *dest, - char *src); -static unsigned int set_npc (unsigned long int addr); -static void rsp_report_exception (); -static void rsp_continue (struct rsp_buf *buf); -static void rsp_continue_with_signal (struct rsp_buf *buf); -static void rsp_continue_generic (unsigned long int except); -static void rsp_read_all_regs (); -static void rsp_write_all_regs (struct rsp_buf *buf); -static void rsp_read_mem (struct rsp_buf *buf); -static void rsp_write_mem (struct rsp_buf *buf); -static void rsp_read_reg (struct rsp_buf *buf); -static void rsp_write_reg (struct rsp_buf *buf); -static void rsp_query (struct rsp_buf *buf); -static void rsp_command (struct rsp_buf *buf); -static void rsp_set (struct rsp_buf *buf); -static void rsp_restart (); -static void rsp_step (struct rsp_buf *buf); -static void rsp_step_with_signal (struct rsp_buf *buf); -static void rsp_step_generic (unsigned long int except); -static void rsp_vpkt (struct rsp_buf *buf); -static void rsp_write_mem_bin (struct rsp_buf *buf); -static void rsp_remove_matchpoint (struct rsp_buf *buf); -static void rsp_insert_matchpoint (struct rsp_buf *buf); - -void set_stall_state(int stall); - -/*---------------------------------------------------------------------------*/ -/*!Initialize the Remote Serial Protocol connection - - This involves setting up a socket to listen on a socket for attempted - connections from a single GDB instance (we couldn't be talking to multiple - GDBs at once!). - - The service is specified either as a port number in the Or1ksim configuration - (parameter rsp_port in section debug, default 51000) or as a service name - in the constant OR1KSIM_RSP_SERVICE. - - The protocol used for communication is specified in OR1KSIM_RSP_PROTOCOL. */ -/*---------------------------------------------------------------------------*/ -void -rsp_init (int portNum) -{ - struct protoent *protocol; /* Protocol number */ - struct hostent *host_entry; /* Our host entry */ - struct sockaddr_in sock_addr; /* Socket address */ - - int optval; /* Socket options */ - int flags; /* Socket flags */ - char name[256]; /* Our name */ - unsigned long tmp; - - - /* Clear out the central data structure */ - rsp.client_waiting = 0; /* GDB client is not waiting for us */ - rsp.proto_num = -1; /* i.e. invalid */ - rsp.server_fd = -1; /* i.e. invalid */ - rsp.client_fd = -1; /* i.e. invalid */ - rsp.sigval = 0; /* No exception */ - rsp.start_addr = EXCEPT_RESET; /* Default restart point */ - - /* Set up the matchpoint hash table */ - mp_hash_init (); - - /* Get the protocol number of TCP and save it for future use */ - protocol = getprotobyname (OR1KSIM_RSP_PROTOCOL); - if (NULL == protocol) - { - fprintf (stderr, "Warning: RSP unable to load protocol \"%s\": %s\n", - OR1KSIM_RSP_PROTOCOL, strerror (errno)); - return; - } - - rsp.proto_num = protocol->p_proto; /* Saved for future client use */ - - /* 0 is used as the RSP port number to indicate that we should use the - service name instead. */ - if (0 == portNum) - { - struct servent *service = - getservbyname (OR1KSIM_RSP_SERVICE, protocol->p_name); - - if (NULL == service) - { - fprintf (stderr, "Warning: RSP unable to find service \"%s\": %s\n", - OR1KSIM_RSP_SERVICE, strerror (errno)); - return; - } - - portNum = ntohs (service->s_port); - } - - /* Create the socket using the TCP protocol */ - rsp.server_fd = socket (PF_INET, SOCK_STREAM, protocol->p_proto); - if (rsp.server_fd < 0) - { - fprintf (stderr, "Warning: RSP could not create server socket: %s\n", - strerror (errno)); - return; - } - - /* Set this socket to reuse its address. This allows the server to keep - trying before a GDB session has got going. */ - optval = 1; - if (setsockopt(rsp.server_fd, SOL_SOCKET, - SO_REUSEADDR, &optval, sizeof (optval)) < 0) - { - fprintf (stderr, "Cannot set SO_REUSEADDR option on server socket %d: " - "%s\n", rsp.server_fd, strerror (errno)); - rsp_server_close(); - return; - } - - /* The server should be non-blocking. Get the current flags and then set the - non-blocking flags */ - flags = fcntl (rsp.server_fd, F_GETFL); - if (flags < 0) - { - fprintf (stderr, "Warning: Unable to get flags for RSP server socket " - "%d: %s\n", rsp.server_fd, strerror (errno)); - rsp_server_close(); - return; - } - - flags |= O_NONBLOCK; - if (fcntl (rsp.server_fd, F_SETFL, flags) < 0) - { - fprintf (stderr, "Warning: Unable to set flags for RSP server socket " - "%d to 0x%08x: %s\n", rsp.server_fd, flags, strerror (errno)); - rsp_server_close(); - return; - } - - /* Find out what our name is */ - if (gethostname (name, sizeof (name)) < 0) - { - fprintf (stderr, "Warning: Unable to get hostname for RSP server: %s\n", - strerror (errno)); - rsp_server_close(); - return; - } - - /* Find out what our address is */ - host_entry = gethostbyname (name); - if (NULL == host_entry) - { - fprintf (stderr, "Warning: Unable to get host entry for RSP server: " - "%s\n", strerror (errno)); - rsp_server_close(); - return; - } - - /* Bind our socket to the appropriate address */ - memset (&sock_addr, 0, sizeof (sock_addr)); - sock_addr.sin_family = host_entry->h_addrtype; - sock_addr.sin_port = htons (portNum); - - if (bind (rsp.server_fd, - (struct sockaddr *)&sock_addr, sizeof (sock_addr)) < 0) - { - fprintf (stderr, "Warning: Unable to bind RSP server socket %d to port " - "%d: %s\n", rsp.server_fd, portNum, - strerror (errno)); - rsp_server_close(); - return; - } - - /* Mark us as a passive port, with a maximum backlog of 1 connection (we - never connect simultaneously to more than one RSP client!) */ - if (listen (rsp.server_fd, 1) < 0) - { - fprintf (stderr, "Warning: Unable to set RSP backlog on server socket " - "%d to %d: %s\n", rsp.server_fd, 1, strerror (errno)); - rsp_server_close(); - return; - } - - // Stall the CPU...it starts off running. - set_stall_state(1); - rsp.target_running = 0; - target_handler_state = 0; // Don't start the polling thread until we have a client - rsp.single_step_mode = 0; - - // Set up the CPU to break to the debug unit on exceptions. - dbg_cpu0_read(SPR_DSR, &tmp); - dbg_cpu0_write(SPR_DSR, tmp|SPR_DSR_TE|SPR_DSR_FPE|SPR_DSR_RE|SPR_DSR_IIE|SPR_DSR_AE|SPR_DSR_BUSEE); - - // Enable TRAP exception, but don't otherwise change the SR - dbg_cpu0_read(SPR_SR, &tmp); - dbg_cpu0_write(SPR_SR, tmp|SPR_SR_SM); // We set 'supervisor mode', which also enables TRAP exceptions - - if(0 > pipe(pipe_fds)) { // pipe_fds[0] is for reading, [1] is for writing - perror("Error creating sockets: "); - rsp_server_close(); - return; - } - - // Create the harware target polling thread - if(pthread_create(&target_handler_thread, NULL, target_handler, NULL)) - { - fprintf(stderr, "Failed to create target handler thread!\n"); - rsp_server_close(); - return; - } - -} /* rsp_init () */ - - -/*---------------------------------------------------------------------------*/ -/*!Look for action on RSP - - This function is called when the processor has stalled, which, except for - initialization, must be due to an interrupt. - - If we have no RSP client, we poll the RSP server for a client requesting to - join. We can make no progress until the client is available. - - Then if the cause is an interrupt, and the interrupt not been notified to - GDB, a packet reporting the cause of the interrupt is sent. - - The function then polls the RSP client port (if open) - for available input. It then processes the GDB RSP request and return. - - If an error occurs when polling the RSP server, other than an interrupt, a - warning message is printed out and the RSP server and client (if open) - connections are closed. - - If an error occurs when polling the RSP client, other than an interrupt, a - warning message is printed out and the RSP client connection is closed. - - Polling is always blocking (i.e. timeout -1). */ -/*---------------------------------------------------------------------------*/ -int handle_rsp (void) -{ - struct pollfd fds[2]; /* The FD to poll for */ - char bitbucket; - - /* Give up if no RSP server port (this should not occur) */ - if (-1 == rsp.server_fd) - { - fprintf (stderr, "Warning: No RSP server port open\n"); - return 0; - } - - /* If we have no RSP client, poll the server until we get one. */ - while (-1 == rsp.client_fd) - { - /* Poll for a client on the RSP server socket */ - fds[0].fd = rsp.server_fd; /* FD for the server socket */ - fds[0].events = POLLIN; /* Poll for input activity */ - - /* Poll is always blocking. We can't do anything more until something - happens here. */ - switch (poll (fds, 1, -1)) - { - case -1: - /* Error. Only one we ignore is an interrupt */ - if (EINTR != errno) - { - fprintf (stderr, "Warning: poll for RSP failed: closing " - "server connection: %s\n", strerror (errno)); - rsp_client_close(); - rsp_server_close(); - return 0; - } - break; - - case 0: - /* Timeout. This can't occur! */ - fprintf (stderr, "Warning: Unexpected RSP server poll timeout\n"); - break; - - default: - /* Is the poll due to input available? If we succeed ignore any - outstanding reports of exceptions. */ - if (POLLIN == (fds[0].revents & POLLIN)) - { - rsp_server_request (); - rsp.client_waiting = 0; /* No longer waiting */ - } - else - { - /* Error leads to closing the client and server */ - fprintf (stderr, "Warning: RSP server received flags " - "0x%08x: closing server connection\n", fds[0].revents); - rsp_client_close(); - rsp_server_close(); - return 0; - } - } - } - - - /* Poll the RSP client socket for a message from GDB */ - /* Also watch for a message from the hardware poller thread. - This might be easier if we used ppoll() and sent a Signal, instead - of using a pipe? */ - - fds[0].fd = rsp.client_fd; /* FD for the client socket */ - fds[0].events = POLLIN; /* Poll for input activity */ - - fds[1].fd = pipe_fds[0]; - fds[1].events = POLLIN; - - /* Poll is always blocking. We can't do anything more until something - happens here. */ - //fprintf(stderr, "Polling...\n"); - switch (poll (fds, 2, -1)) - { - case -1: - /* Error. Only one we ignore is an interrupt */ - if (EINTR != errno) - { - fprintf (stderr, "Warning: poll for RSP failed: closing " - "server connection: %s\n", strerror (errno)); - rsp_client_close(); - rsp_server_close(); - return 0; - } - - return 1; - - case 0: - /* Timeout. This can't occur! */ - fprintf (stderr, "Warning: Unexpected RSP client poll timeout\n"); - return 1; - - default: - /* Is the client activity due to input available? */ - if (POLLIN == (fds[0].revents & POLLIN)) - { - rsp_client_request (); - } - else if(POLLIN == (fds[1].revents & POLLIN)) - { - //fprintf(stderr, "Got pipe event from monitor thread\n"); - bitbucket = read(pipe_fds[0], &bitbucket, 1); // Clear the byte out and discard - /* If we have an unacknowledged exception and a client is available, tell - GDB. If this exception was a trap due to a memory breakpoint, then - adjust the NPC. */ - if (rsp.client_waiting) - { - // Read the PPC - unsigned long ppcval; - dbg_cpu0_read(SPR_PPC, &ppcval); - - if ((TARGET_SIGNAL_TRAP == rsp.sigval) && - (NULL != mp_hash_lookup (BP_MEMORY, ppcval))) // We also get TRAP from a single-step, don't change npc unless it's really a BP - { - set_npc (ppcval); - } - - rsp_report_exception(); - rsp.client_waiting = 0; /* No longer waiting */ - } - } - else - { - /* Error leads to closing the client, but not the server. */ - fprintf (stderr, "Warning: RSP client received flags " - "0x%08x: closing client connection\n", fds[0].revents); - rsp_client_close(); - } - } - - return 1; -} /* handle_rsp () */ - - -//--------------------------------------------------------------------------- -//!Note an exception for future processing -// -// The simulator has encountered an exception. Record it here, so that a -// future call to handle_exception will report it back to the client. The -// signal is supplied in Or1ksim form and recorded in GDB form. - -// We flag up a warning if an exception is already pending, and ignore the -// earlier exception. - -// @param[in] except The exception -//--------------------------------------------------------------------------- - -void rsp_exception (unsigned long int except) -{ - int sigval; // GDB signal equivalent to exception - - switch (except) - { - case SPR_DRR_RSTE: sigval = TARGET_SIGNAL_PWR; break; - case SPR_DRR_BUSEE: sigval = TARGET_SIGNAL_BUS; break; - case SPR_DRR_DPFE: sigval = TARGET_SIGNAL_SEGV; break; - case SPR_DRR_IPFE: sigval = TARGET_SIGNAL_SEGV; break; - case SPR_DRR_TTE: sigval = TARGET_SIGNAL_ALRM; break; - case SPR_DRR_AE: sigval = TARGET_SIGNAL_BUS; break; - case SPR_DRR_IIE: sigval = TARGET_SIGNAL_ILL; break; - case SPR_DRR_IE: sigval = TARGET_SIGNAL_INT; break; - case SPR_DRR_DME: sigval = TARGET_SIGNAL_SEGV; break; - case SPR_DRR_IME: sigval = TARGET_SIGNAL_SEGV; break; - case SPR_DRR_RE: sigval = TARGET_SIGNAL_FPE; break; - case SPR_DRR_SCE: sigval = TARGET_SIGNAL_USR2; break; - case SPR_DRR_FPE: sigval = TARGET_SIGNAL_FPE; break; - case SPR_DRR_TE: sigval = TARGET_SIGNAL_TRAP; break; - - // In the current OR1200 hardware implementation, a single-step does not create a TRAP, - // the DSR reads back 0. GDB expects a TRAP, so... - case 0: sigval = TARGET_SIGNAL_TRAP; break; - - default: - fprintf (stderr, "Warning: Unknown RSP exception %lu: Ignored\n", except); - return; - } - - if ((0 != rsp.sigval) && (sigval != rsp.sigval)) - { - fprintf (stderr, "Warning: RSP signal %d received while signal " - "%d pending: Pending exception replaced\n", sigval, rsp.sigval); - } - - rsp.sigval = sigval; // Save the signal value - -} // rsp_exception () - - - -/*---------------------------------------------------------------------------*/ -/*!Handle a request to the server for a new client - - We may already have a client. If we do, we will accept an immediately close - the new client. */ -/*---------------------------------------------------------------------------*/ -static void -rsp_server_request () -{ - struct sockaddr_in sock_addr; /* The socket address */ - socklen_t len; /* Size of the socket address */ - int fd; /* The client FD */ - int flags; /* fcntl () flags */ - int optval; /* Option value for setsockopt () */ - - /* Get the client FD */ - len = sizeof (sock_addr); - fd = accept (rsp.server_fd, (struct sockaddr *)&sock_addr, &len); - if (fd < 0) - { - /* This is can happen, because a connection could have started, and then - terminated due to a protocol error or user initiation before the - accept could take place. - - Two of the errors we can ignore (a retry is permissible). All other - errors, we assume the server port has gone tits up and close. */ - - if ((errno != EWOULDBLOCK) && (errno != EAGAIN)) - { - fprintf (stderr, "Warning: RSP server error creating client: " - "closing connection %s\n", strerror (errno)); - rsp_client_close (); - rsp_server_close (); - } - - return; - } - - /* If we already have a client, then immediately close the new one */ - if (-1 != rsp.client_fd) - { - fprintf (stderr, "Warning: Additional RSP client request refused\n"); - close (fd); - return; - } - - /* We have a new client, which should be non-blocking. Get the current flags - and then set the non-blocking flags */ - flags = fcntl (fd, F_GETFL); - if (flags < 0) - { - fprintf (stderr, "Warning: Unable to get flags for RSP client socket " - "%d: %s\n", fd, strerror (errno)); - close (fd); - return; - } - - flags |= O_NONBLOCK; - if (fcntl (fd, F_SETFL, flags) < 0) - { - fprintf (stderr, "Warning: Unable to set flags for RSP client socket " - "%d to 0x%08x: %s\n", fd, flags, strerror (errno)); - close (fd); - return; - } - - /* Turn of Nagel's algorithm for the client socket. This means the client - sends stuff immediately, it doesn't wait to fill up a packet. */ - optval = 0; - len = sizeof (optval); - if (setsockopt (fd, rsp.proto_num, TCP_NODELAY, &optval, len) < 0) - { - fprintf (stderr, "Warning: Unable to disable Nagel's algorithm for " - "RSP client socket %d: %s\n", fd, strerror (errno)); - close (fd); - return; - } - - /* We have a new client socket */ - rsp.client_fd = fd; - - // Set the hardware polling thread to run - // This will cause the poll() to be interrupted next time - pthread_mutex_lock(&target_handler_mutex); - target_handler_state = 1; - pthread_mutex_unlock(&target_handler_mutex); - -} /* rsp_server_request () */ - - -/*---------------------------------------------------------------------------*/ -/*!Deal with a request from the GDB client session - - In general, apart from the simplest requests, this function replies on - other functions to implement the functionality. */ -/*---------------------------------------------------------------------------*/ -static void -rsp_client_request () -{ - struct rsp_buf *buf = get_packet (); /* Message sent to us */ - - // Null packet means we hit EOF or the link was closed for some other - // reason. Close the client and return - if (NULL == buf) - { - rsp_client_close (); - return; - } - -#if RSP_TRACE - printf ("Packet received %s: %d chars\n", buf->data, buf->len ); - fflush (stdout); -#endif - - // Check if target is running. - int running = 0; - pthread_mutex_lock(&rsp_mutex); - running = rsp.target_running; - pthread_mutex_unlock(&rsp_mutex); - - // If running, only process async BREAK command - if(running) - { - if(buf->data[0] == 0x03) // 0x03 is the ctrl-C "break" command from GDB - { - // Send the STALL command to the target - set_stall_state (1); - } - else - { - // Send a response to GDB indicating the target is not stalled: "Target not stopped" - put_str_packet("O6154677274656e20746f73206f74707064650a0d"); // Need to hex-encode warning string (I think...) - fprintf(stderr, "WARNING: Received GDB command 0x%X (%c) while target running!\n", buf->data[0], buf->data[0]); - } - return; - } - - switch (buf->data[0]) - { - case 0x03: - fprintf(stderr, "Warning: asynchronous BREAK received while target stopped.\n"); - return; - - case '!': - /* Request for extended remote mode */ - put_str_packet ("OK"); - return; - - case '?': - /* Return last signal ID */ - rsp_report_exception(); - return; - - case 'A': - /* Initialization of argv not supported */ - fprintf (stderr, "Warning: RSP 'A' packet not supported: ignored\n"); - put_str_packet ("E01"); - return; - - case 'b': - /* Setting baud rate is deprecated */ - fprintf (stderr, "Warning: RSP 'b' packet is deprecated and not " - "supported: ignored\n"); - return; - - case 'B': - /* Breakpoints should be set using Z packets */ - fprintf (stderr, "Warning: RSP 'B' packet is deprecated (use 'Z'/'z' " - "packets instead): ignored\n"); - return; - - case 'c': - /* Continue */ - rsp_continue (buf); - return; - - case 'C': - /* Continue with signal */ - rsp_continue_with_signal (buf); - return; - - case 'd': - /* Disable debug using a general query */ - fprintf (stderr, "Warning: RSP 'd' packet is deprecated (define a 'Q' " - "packet instead: ignored\n"); - return; - - case 'D': - /* Detach GDB. Do this by closing the client. The rules say that - execution should continue. TODO. Is this really then intended - meaning? Or does it just mean that only vAttach will be recognized - after this? */ - put_str_packet ("OK"); - rsp_client_close (); - set_stall_state (0); - return; - - case 'F': - /* File I/O is not currently supported */ - fprintf (stderr, "Warning: RSP file I/O not currently supported: 'F' " - "packet ignored\n"); - return; - - case 'g': - rsp_read_all_regs (); - return; - - case 'G': - rsp_write_all_regs (buf); - return; - - case 'H': - /* Set the thread number of subsequent operations. For now ignore - silently and just reply "OK" */ - put_str_packet ("OK"); - return; - - case 'i': - /* Single instruction step */ - rsp_step (buf); - return; - - case 'I': - /* Single instruction step with signal */ - rsp_step_with_signal (buf); - return; - - case 'k': - /* Kill request. Do nothing for now. */ - return; - - case 'm': - /* Read memory (symbolic) */ - rsp_read_mem (buf); - return; - - case 'M': - /* Write memory (symbolic) */ - rsp_write_mem (buf); - return; - - case 'p': - /* Read a register */ - rsp_read_reg (buf); - return; - - case 'P': - /* Write a register */ - rsp_write_reg (buf); - return; - - case 'q': - /* Any one of a number of query packets */ - rsp_query (buf); - return; - - case 'Q': - /* Any one of a number of set packets */ - rsp_set (buf); - return; - - case 'r': - /* Reset the system. Deprecated (use 'R' instead) */ - fprintf (stderr, "Warning: RSP 'r' packet is deprecated (use 'R' " - "packet instead): ignored\n"); - return; - - case 'R': - /* Restart the program being debugged. */ - rsp_restart (); - return; - - case 's': - /* Single step (one high level instruction). This could be hard without - DWARF2 info */ - rsp_step (buf); - return; - - case 'S': - /* Single step (one high level instruction) with signal. This could be - hard without DWARF2 info */ - rsp_step_with_signal (buf); - return; - - case 't': - /* Search. This is not well defined in the manual and for now we don't - support it. No response is defined. */ - fprintf (stderr, "Warning: RSP 't' packet not supported: ignored\n"); - return; - - case 'T': - /* Is the thread alive. We are bare metal, so don't have a thread - context. The answer is always "OK". */ - put_str_packet ("OK"); - return; - - case 'v': - /* Any one of a number of packets to control execution */ - rsp_vpkt (buf); - return; - - case 'X': - /* Write memory (binary) */ - rsp_write_mem_bin (buf); - return; - - case 'z': - /* Remove a breakpoint/watchpoint. */ - rsp_remove_matchpoint (buf); - return; - - case 'Z': - /* Insert a breakpoint/watchpoint. */ - rsp_insert_matchpoint (buf); - return; - - default: - /* Unknown commands are ignored */ - fprintf (stderr, "Warning: Unknown RSP request %s\n", buf->data); - return; - } -} /* rsp_client_request () */ - - -/*---------------------------------------------------------------------------*/ -/*!Close the server if it is open */ -/*---------------------------------------------------------------------------*/ -static void -rsp_server_close () -{ - // Stop the target handler thread - pthread_mutex_lock(&target_handler_mutex); - target_handler_state = 2; - pthread_mutex_unlock(&target_handler_mutex); - - if (-1 != rsp.server_fd) - { - close (rsp.server_fd); - rsp.server_fd = -1; - } -} /* rsp_server_close () */ - - -/*---------------------------------------------------------------------------*/ -/*!Close the client if it is open */ -/*---------------------------------------------------------------------------*/ -static void -rsp_client_close () -{ - unsigned char was_running = 0; - - // If target is running, stop it so we can modify SPRs - pthread_mutex_lock(&rsp_mutex); - was_running = rsp.target_running; - pthread_mutex_unlock(&rsp_mutex); - if(was_running) { - set_stall_state(1); - } - - // Clear the DSR: don't transfer control to the debug unit for any reason - dbg_cpu0_write(SPR_DSR, 0); - - // If target was running, restart it. - if(was_running) { - set_stall_state(0); - } - - // Stop the target handler thread. MUST BE DONE AFTER THE LAST set_stall_state()! - pthread_mutex_lock(&target_handler_mutex); - target_handler_state = 0; - pthread_mutex_unlock(&target_handler_mutex); - - if (-1 != rsp.client_fd) - { - close (rsp.client_fd); - rsp.client_fd = -1; - } -} /* rsp_client_close () */ - - -/*---------------------------------------------------------------------------*/ -/*!Send a packet to the GDB client - - Modeled on the stub version supplied with GDB. Put out the data preceded by - a '$', followed by a '#' and a one byte checksum. '$', '#', '*' and '}' are - escaped by preceding them with '}' and then XORing the character with - 0x20. - - @param[in] buf The data to send */ -/*---------------------------------------------------------------------------*/ -static void -put_packet (struct rsp_buf *buf) -{ - int ch; /* Ack char */ - - /* Construct $#. Repeat until the GDB client - acknowledges satisfactory receipt. */ - do - { - unsigned char checksum = 0; /* Computed checksum */ - int count = 0; /* Index into the buffer */ - -#if RSP_TRACE - printf ("Putting %s\n", buf->data); - fflush (stdout); -#endif - - put_rsp_char ('$'); /* Start char */ - - /* Body of the packet */ - for (count = 0; count < buf->len; count++) - { - unsigned char ch = buf->data[count]; - - /* Check for escaped chars */ - if (('$' == ch) || ('#' == ch) || ('*' == ch) || ('}' == ch)) - { - ch ^= 0x20; - checksum += (unsigned char)'}'; - put_rsp_char ('}'); - } - - checksum += ch; - put_rsp_char (ch); - } - - put_rsp_char ('#'); /* End char */ - - /* Computed checksum */ - put_rsp_char (hexchars[checksum >> 4]); - put_rsp_char (hexchars[checksum % 16]); - - /* Check for ack of connection failure */ - ch = get_rsp_char (); - if (-1 == ch) - { - return; /* Fail the put silently. */ - } - } - while ('+' != ch); - -} /* put_packet () */ - - -/*---------------------------------------------------------------------------*/ -/*!Convenience to put a constant string packet - - param[in] str The text of the packet */ -/*---------------------------------------------------------------------------*/ -static void -put_str_packet (const char *str) -{ - struct rsp_buf buf; - int len = strlen (str); - - /* Construct the packet to send, so long as string is not too big, - otherwise truncate. Add EOS at the end for convenient debug printout */ - - if (len >= GDB_BUF_MAX) - { - fprintf (stderr, "Warning: String %s too large for RSP packet: " - "truncated\n", str); - len = GDB_BUF_MAX - 1; - } - - strncpy (buf.data, str, len); - buf.data[len] = 0; - buf.len = len; - - put_packet (&buf); - -} /* put_str_packet () */ - - -/*---------------------------------------------------------------------------*/ -/*!Get a packet from the GDB client - - Modeled on the stub version supplied with GDB. The data is in a static - buffer. The data should be copied elsewhere if it is to be preserved across - a subsequent call to get_packet(). - - Unlike the reference implementation, we don't deal with sequence - numbers. GDB has never used them, and this implementation is only intended - for use with GDB 6.8 or later. Sequence numbers were removed from the RSP - standard at GDB 5.0. - - @return A pointer to the static buffer containing the data */ -/*---------------------------------------------------------------------------*/ -static struct rsp_buf * -get_packet () -{ - static struct rsp_buf buf; /* Survives the return */ - - /* Keep getting packets, until one is found with a valid checksum */ - while (1) - { - unsigned char checksum; /* The checksum we have computed */ - int count; /* Index into the buffer */ - int ch; /* Current character */ - - /* Wait around for the start character ('$'). Ignore all other - characters */ - ch = get_rsp_char (); - while (ch != '$') - { - if (-1 == ch) - { - return NULL; /* Connection failed */ - } - - // 0x03 is a special case, an out-of-band break when running - if(ch == 0x03) - { - buf.data[0] = ch; - buf.len = 1; - return &buf; - } - - ch = get_rsp_char (); - } - - /* Read until a '#' or end of buffer is found */ - checksum = 0; - count = 0; - while (count < GDB_BUF_MAX - 1) - { - ch = get_rsp_char (); - - /* Check for connection failure */ - if (-1 == ch) - { - return NULL; - } - - /* If we hit a start of line char begin all over again */ - if ('$' == ch) - { - checksum = 0; - count = 0; - - continue; - } - - /* Break out if we get the end of line char */ - if ('#' == ch) - { - break; - } - - /* Update the checksum and add the char to the buffer */ - - checksum = checksum + (unsigned char)ch; - buf.data[count] = (char)ch; - count = count + 1; - } - - /* Mark the end of the buffer with EOS - it's convenient for non-binary - data to be valid strings. */ - buf.data[count] = 0; - buf.len = count; - - /* If we have a valid end of packet char, validate the checksum */ - if ('#' == ch) - { - unsigned char xmitcsum; /* The checksum in the packet */ - - ch = get_rsp_char (); - if (-1 == ch) - { - return NULL; /* Connection failed */ - } - xmitcsum = hex (ch) << 4; - - ch = get_rsp_char (); - if (-1 == ch) - { - return NULL; /* Connection failed */ - } - - xmitcsum += hex (ch); - - /* If the checksums don't match print a warning, and put the - negative ack back to the client. Otherwise put a positive ack. */ - if (checksum != xmitcsum) - { - fprintf (stderr, "Warning: Bad RSP checksum: Computed " - "0x%02x, received 0x%02x\n", checksum, xmitcsum); - - put_rsp_char ('-'); /* Failed checksum */ - } - else - { - put_rsp_char ('+'); /* successful transfer */ - break; - } - } - else - { - fprintf (stderr, "Warning: RSP packet overran buffer\n"); - } - } - - return &buf; /* Success */ - -} /* get_packet () */ - - -/*---------------------------------------------------------------------------*/ -/*!Put a single character out onto the client socket - - This should only be called if the client is open, but we check for safety. - - @param[in] c The character to put out */ -/*---------------------------------------------------------------------------*/ -static void -put_rsp_char (char c) -{ - if (-1 == rsp.client_fd) - { - fprintf (stderr, "Warning: Attempt to write '%c' to unopened RSP " - "client: Ignored\n", c); - return; - } - - /* Write until successful (we retry after interrupts) or catastrophic - failure. */ - while (1) - { - switch (write (rsp.client_fd, &c, sizeof (c))) - { - case -1: - /* Error: only allow interrupts or would block */ - if ((EAGAIN != errno) && (EINTR != errno)) - { - fprintf (stderr, "Warning: Failed to write to RSP client: " - "Closing client connection: %s\n", - strerror (errno)); - rsp_client_close (); - return; - } - - break; - - case 0: - break; /* Nothing written! Try again */ - - default: - return; /* Success, we can return */ - } - } -} /* put_rsp_char () */ - - -/*---------------------------------------------------------------------------*/ -/*!Get a single character from the client socket - - This should only be called if the client is open, but we check for safety. - - @return The character read, or -1 on failure */ -/*---------------------------------------------------------------------------*/ -static int -get_rsp_char () -{ - unsigned char c; /* The character read */ - - if (-1 == rsp.client_fd) - { - fprintf (stderr, "Warning: Attempt to read from unopened RSP " - "client: Ignored\n"); - return -1; - } - - /* Read until successful (we retry after interrupts) or catastrophic - failure. */ - while (1) - { - switch (read (rsp.client_fd, &c, sizeof (c))) - { - case -1: - /* Error: only allow interrupts or would block */ - if ((EAGAIN != errno) && (EINTR != errno)) - { - fprintf (stderr, "Warning: Failed to read from RSP client: " - "Closing client connection: %s\n", - strerror (errno)); - rsp_client_close (); - return -1; - } - - break; - - case 0: - // EOF - rsp_client_close (); - return -1; - - default: - return c & 0xff; /* Success, we can return (no sign extend!) */ - } - } -} /* get_rsp_char () */ - - -/*---------------------------------------------------------------------------*/ -/*!"Unescape" RSP binary data - - '#', '$' and '}' are escaped by preceding them by '}' and oring with 0x20. - - This function reverses that, modifying the data in place. - - @param[in] data The array of bytes to convert - @para[in] len The number of bytes to be converted - - @return The number of bytes AFTER conversion */ -/*---------------------------------------------------------------------------*/ -static int -rsp_unescape (char *data, - int len) -{ - int from_off = 0; /* Offset to source char */ - int to_off = 0; /* Offset to dest char */ - - while (from_off < len) - { - /* Is it escaped */ - if ( '}' == data[from_off]) - { - from_off++; - data[to_off] = data[from_off] ^ 0x20; - } - else - { - data[to_off] = data[from_off]; - } - - from_off++; - to_off++; - } - - return to_off; - -} /* rsp_unescape () */ - - -/*---------------------------------------------------------------------------*/ -/*!Initialize the matchpoint hash table - - This is an open hash table, so this function clears all the links to - NULL. */ -/*---------------------------------------------------------------------------*/ -static void -mp_hash_init () -{ - int i; - - for (i = 0; i < MP_HASH_SIZE; i++) - { - rsp.mp_hash[i] = NULL; - } -} /* mp_hash_init () */ - - -/*---------------------------------------------------------------------------*/ -/*!Add an entry to the matchpoint hash table - - Add the entry if it wasn't already there. If it was there do nothing. The - match just be on type and addr. The instr need not match, since if this is - a duplicate insertion (perhaps due to a lost packet) they will be - different. - - @param[in] type The type of matchpoint - @param[in] addr The address of the matchpoint - @para[in] instr The instruction to associate with the address */ -/*---------------------------------------------------------------------------*/ -static void -mp_hash_add (enum mp_type type, - unsigned long int addr, - unsigned long int instr) -{ - int hv = addr % MP_HASH_SIZE; - struct mp_entry *curr; - - /* See if we already have the entry */ - for(curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next) - { - if ((type == curr->type) && (addr == curr->addr)) - { - return; /* We already have the entry */ - } - } - - /* Insert the new entry at the head of the chain */ - curr = malloc (sizeof (*curr)); - - curr->type = type; - curr->addr = addr; - curr->instr = instr; - curr->next = rsp.mp_hash[hv]; - - rsp.mp_hash[hv] = curr; - -} /* mp_hash_add () */ - - -/*---------------------------------------------------------------------------*/ -/*!Look up an entry in the matchpoint hash table - - The match must be on type AND addr. - - @param[in] type The type of matchpoint - @param[in] addr The address of the matchpoint - - @return The entry deleted, or NULL if the entry was not found */ -/*---------------------------------------------------------------------------*/ -static struct mp_entry * -mp_hash_lookup (enum mp_type type, - unsigned long int addr) -{ - int hv = addr % MP_HASH_SIZE; - struct mp_entry *curr; - - /* Search */ - for (curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next) - { - if ((type == curr->type) && (addr == curr->addr)) - { - return curr; /* The entry found */ - } - } - - /* Not found */ - return NULL; - -} /* mp_hash_lookup () */ - - -/*---------------------------------------------------------------------------*/ -/*!Delete an entry from the matchpoint hash table - - If it is there the entry is deleted from the hash table. If it is not - there, no action is taken. The match must be on type AND addr. - - The usual fun and games tracking the previous entry, so we can delete - things. - - @note The deletion DOES NOT free the memory associated with the entry, - since that is returned. The caller should free the memory when they - have used the information. - - @param[in] type The type of matchpoint - @param[in] addr The address of the matchpoint - - @return The entry deleted, or NULL if the entry was not found */ -/*---------------------------------------------------------------------------*/ -static struct mp_entry * -mp_hash_delete (enum mp_type type, - unsigned long int addr) -{ - int hv = addr % MP_HASH_SIZE; - struct mp_entry *prev = NULL; - struct mp_entry *curr; - - /* Search */ - for (curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next) - { - if ((type == curr->type) && (addr == curr->addr)) - { - /* Found - delete. Method depends on whether we are the head of - chain. */ - if (NULL == prev) - { - rsp.mp_hash[hv] = curr->next; - } - else - { - prev->next = curr->next; - } - - return curr; /* The entry deleted */ - } - - prev = curr; - } - - /* Not found */ - return NULL; - -} /* mp_hash_delete () */ - - -/*---------------------------------------------------------------------------*/ -/*!Utility to give the value of a hex char - - @param[in] ch A character representing a hexadecimal digit. Done as -1, - for consistency with other character routines, which can use - -1 as EOF. - - @return The value of the hex character, or -1 if the character is - invalid. */ -/*---------------------------------------------------------------------------*/ -static int -hex (int c) -{ - return ((c >= 'a') && (c <= 'f')) ? c - 'a' + 10 : - ((c >= '0') && (c <= '9')) ? c - '0' : - ((c >= 'A') && (c <= 'F')) ? c - 'A' + 10 : -1; - -} /* hex () */ - - -/*---------------------------------------------------------------------------*/ -/*!Convert a register to a hex digit string - - The supplied 32-bit value is converted to an 8 digit hex string according - the target endianism. It is null terminated for convenient printing. - - @param[in] val The value to convert - @param[out] buf The buffer for the text string */ -/*---------------------------------------------------------------------------*/ -static void -reg2hex (unsigned long int val, - char *buf) -{ - int n; /* Counter for digits */ - - for (n = 0; n < 8; n++) - { -#ifdef WORDSBIGENDIAN - int nyb_shift = n * 4; -#else - int nyb_shift = 28 - (n * 4); -#endif - buf[n] = hexchars[(val >> nyb_shift) & 0xf]; - } - - buf[8] = 0; /* Useful to terminate as string */ - -} /* reg2hex () */ - - -/*---------------------------------------------------------------------------*/ -/*!Convert a hex digit string to a register value - - The supplied 8 digit hex string is converted to a 32-bit value according - the target endianism - - @param[in] buf The buffer with the hex string - - @return The value to convert */ -/*---------------------------------------------------------------------------*/ -static unsigned long int -hex2reg (char *buf) -{ - int n; /* Counter for digits */ - unsigned long int val = 0; /* The result */ - - for (n = 0; n < 8; n++) - { -#ifdef WORDSBIGENDIAN - int nyb_shift = n * 4; -#else - int nyb_shift = 28 - (n * 4); -#endif - val |= hex (buf[n]) << nyb_shift; - } - - return val; - -} /* hex2reg () */ - - -/*---------------------------------------------------------------------------*/ -/*!Convert an ASCII character string to pairs of hex digits - - Both source and destination are null terminated. - - @param[out] dest Buffer to store the hex digit pairs (null terminated) - @param[in] src The ASCII string (null terminated) */ -/*---------------------------------------------------------------------------*/ -static void ascii2hex (char *dest, - char *src) -{ - int i; - - /* Step through converting the source string */ - for (i = 0; src[i] != '\0'; i++) - { - char ch = src[i]; - - dest[i * 2] = hexchars[ch >> 4 & 0xf]; - dest[i * 2 + 1] = hexchars[ch & 0xf]; - } - - dest[i * 2] = '\0'; - -} /* ascii2hex () */ - - -/*---------------------------------------------------------------------------*/ -/*!Convert pairs of hex digits to an ASCII character string - - Both source and destination are null terminated. - - @param[out] dest The ASCII string (null terminated) - @param[in] src Buffer holding the hex digit pairs (null terminated) */ -/*---------------------------------------------------------------------------*/ -static void hex2ascii (char *dest, - char *src) -{ - int i; - - /* Step through convering the source hex digit pairs */ - for (i = 0; src[i * 2] != '\0' && src[i * 2 + 1] != '\0'; i++) - { - dest[i] = ((hex (src[i * 2]) & 0xf) << 4) | (hex (src[i * 2 + 1]) & 0xf); - } - - dest[i] = '\0'; - -} /* hex2ascii () */ - - -/*---------------------------------------------------------------------------*/ -/*!Set the program counter - - This sets the value in the NPC SPR. Not completely trivial, since this is - actually cached in cpu_state.pc. Any reset of the NPC also involves - clearing the delay state and setting the pcnext global. - - Only actually do this if the requested address is different to the current - NPC (avoids clearing the delay pipe). - - @param[in] addr The address to use */ -/*---------------------------------------------------------------------------*/ -static unsigned int set_npc (unsigned long int addr) -{ - int errcode; - - errcode = dbg_cpu0_write(SPR_NPC, addr); - cached_npc = addr; - use_cached_npc = 1; - - /* This was done in the simulator. Is any of this necessary on the hardware? --NAY - if (cpu_state.pc != addr) - { - cpu_state.pc = addr; - cpu_state.delay_insn = 0; - pcnext = addr + 4; - } - */ - return errcode; -} /* set_npc () */ - - -/*---------------------------------------------------------------------------*/ -/*!Send a packet acknowledging an exception has occurred - - This is only called if there is a client FD to talk to */ -/*---------------------------------------------------------------------------*/ -static void -rsp_report_exception () -{ - struct rsp_buf buf; - - /* Construct a signal received packet */ - buf.data[0] = 'S'; - buf.data[1] = hexchars[rsp.sigval >> 4]; - buf.data[2] = hexchars[rsp.sigval % 16]; - buf.data[3] = 0; - buf.len = strlen (buf.data); - - put_packet (&buf); - -} /* rsp_report_exception () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP continue request - - Parse the command to see if there is an address. Uses the underlying - generic continue function, with EXCEPT_NONE. - - @param[in] buf The full continue packet */ -/*---------------------------------------------------------------------------*/ -static void -rsp_continue (struct rsp_buf *buf) -{ - unsigned long int addr; /* Address to continue from, if any */ - - if (strncmp(buf->data, "c", 2)) - { - if(1 != sscanf (buf->data, "c%lx", &addr)) - { - fprintf (stderr, - "Warning: RSP continue address %s not recognized: ignored\n", - buf->data); - } - else - { - /* Set the address as the value of the next program counter */ - // TODO Is support for this really that simple? --NAY - set_npc (addr); - } - } - - rsp_continue_generic (EXCEPT_NONE); - -} /* rsp_continue () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP continue with signal request - - Currently null. Will use the underlying generic continue function. - - @param[in] buf The full continue with signal packet */ -/*---------------------------------------------------------------------------*/ -static void -rsp_continue_with_signal (struct rsp_buf *buf) -{ - printf ("RSP continue with signal '%s' received\n", buf->data); - -} /* rsp_continue_with_signal () */ - - -/*---------------------------------------------------------------------------*/ -/*!Generic processing of a continue request - - The signal may be EXCEPT_NONE if there is no exception to be - handled. Currently the exception is ignored. - - The single step flag is cleared in the debug registers and then the - processor is unstalled. - - @param[in] addr Address from which to step - @param[in] except The exception to use (if any) */ -/*---------------------------------------------------------------------------*/ -static void -rsp_continue_generic (unsigned long int except) -{ - unsigned long tmp; - - /* Clear Debug Reason Register and watchpoint break generation in Debug Mode - Register 2 */ - dbg_cpu0_write(SPR_DRR, 0); - dbg_cpu0_read(SPR_DMR2, &tmp); - tmp &= ~SPR_DMR2_WGB; - dbg_cpu0_write(SPR_DMR2, tmp); - - /* Clear the single step trigger in Debug Mode Register 1 and set traps to be - handled by the debug unit in the Debug Stop Register */ - dbg_cpu0_read(SPR_DMR1, &tmp); - tmp &= ~(SPR_DMR1_ST|SPR_DMR1_BT); // clear single-step and trap-on-branch - dbg_cpu0_write(SPR_DMR1, tmp); - - // *** TODO Is there ever a situation where the DSR will not be set to give us control on a TRAP? --NAY - - /* Unstall the processor (also starts the target handler thread) */ - set_stall_state (0); - - /* Note the GDB client is now waiting for a reply. */ - rsp.client_waiting = 1; - rsp.single_step_mode = 0; - -} /* rsp_continue_generic () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP read all registers request - - The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PPC - (i.e. SPR PPC), NPC (i.e. SPR NPC) and SR (i.e. SPR SR). Each register is - returned as a sequence of bytes in target endian order. - - Each byte is packed as a pair of hex digits. */ -/*---------------------------------------------------------------------------*/ -static void -rsp_read_all_regs () -{ - struct rsp_buf buf; /* Buffer for the reply */ - int r; /* Register index */ - unsigned long regbuf[MAX_GPRS]; - unsigned int errcode = APP_ERR_NONE; - - // Read all the GPRs in a single burst, for efficiency - errcode = dbg_cpu0_read_block(SPR_GPR_BASE, regbuf, MAX_GPRS); - - /* Format the GPR data for output */ - for (r = 0; r < MAX_GPRS; r++) - { - reg2hex(regbuf[r], &(buf.data[r * 8])); - } - - /* PPC, NPC and SR have consecutive addresses, read in one burst */ - errcode |= dbg_cpu0_read_block(SPR_NPC, regbuf, 3); - - // Note that reg2hex adds a NULL terminator; as such, they must be - // put in buf.data in numerical order: PPC, NPC, SR - reg2hex(regbuf[2], &(buf.data[PPC_REGNUM * 8])); - - if(use_cached_npc == 1) { // Hackery to work around CPU hardware quirk - reg2hex(cached_npc, &(buf.data[NPC_REGNUM * 8])); - } - else { - reg2hex(regbuf[0], &(buf.data[NPC_REGNUM * 8])); - } - - reg2hex(regbuf[1], &(buf.data[SR_REGNUM * 8])); - - //fprintf(stderr, "Read SPRs: 0x%08X, 0x%08X, 0x%08X\n", regbuf[0], regbuf[1], regbuf[2]); - - /* - dbg_cpu0_read(SPR_PPC, &tmp); - reg2hex(tmp, &(buf.data[PPC_REGNUM * 8])); - - if(use_cached_npc == 1) { // Hackery to work around CPU hardware quirk - tmp = cached_npc; - } - else { - dbg_cpu0_read(SPR_NPC, &tmp); - } - reg2hex(tmp, &(buf.data[NPC_REGNUM * 8])); - - dbg_cpu0_read(SPR_SR, &tmp); - reg2hex(tmp, &(buf.data[SR_REGNUM * 8])); - */ - - if(errcode == APP_ERR_NONE) { - /* Finalize the packet and send it */ - buf.data[NUM_REGS * 8] = 0; - buf.len = NUM_REGS * 8; - put_packet (&buf); - } - else { - fprintf(stderr, "Error while reading all registers: %s\n", get_err_string(errcode)); - put_str_packet("E01"); - } - -} /* rsp_read_all_regs () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP write all registers request - - The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PPC - (i.e. SPR PPC), NPC (i.e. SPR NPC) and SR (i.e. SPR SR). Each register is - supplied as a sequence of bytes in target endian order. - - Each byte is packed as a pair of hex digits. - - @todo There is no error checking at present. Non-hex chars will generate a - warning message, but there is no other check that the right amount - of data is present. The result is always "OK". - - @param[in] buf The original packet request. */ -/*---------------------------------------------------------------------------*/ -static void -rsp_write_all_regs (struct rsp_buf *buf) -{ - int r; /* Register index */ - unsigned long regbuf[MAX_GPRS]; - unsigned int errcode; - - /* The GPRs */ - for (r = 0; r < MAX_GPRS; r++) - { - // Set up the data for a burst access - regbuf[r] = hex2reg (&(buf->data[r * 8])); - } - - errcode = dbg_cpu0_write_block(SPR_GPR_BASE, regbuf, MAX_GPRS); - - /* PPC, NPC and SR */ - regbuf[0] = hex2reg (&(buf->data[NPC_REGNUM * 8])); - regbuf[1] = hex2reg (&(buf->data[SR_REGNUM * 8])); - regbuf[2] = hex2reg (&(buf->data[PPC_REGNUM * 8])); - - errcode |= dbg_cpu0_write_block(SPR_NPC, regbuf, 3); - - /* - tmp = hex2reg (&(buf->data[PPC_REGNUM * 8])); - dbg_cpu0_write(SPR_PPC, tmp); - - tmp = hex2reg (&(buf->data[SR_REGNUM * 8])); - dbg_cpu0_write(SPR_SR, tmp); - - tmp = hex2reg (&(buf->data[NPC_REGNUM * 8])); - dbg_cpu0_write(SPR_NPC, tmp); - */ - - if(errcode == APP_ERR_NONE) - put_str_packet ("OK"); - else { - fprintf(stderr, "Error while writing all registers: %s\n", get_err_string(errcode)); - put_str_packet("E01"); - } - -} /* rsp_write_all_regs () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP read memory (symbolic) request - - Syntax is: - - m,: - - The response is the bytes, lowest address first, encoded as pairs of hex - digits. - - The length given is the number of bytes to be read. - - @note This function reuses buf, so trashes the original command. - - @param[in] buf The command received */ -/*---------------------------------------------------------------------------*/ -static void -rsp_read_mem (struct rsp_buf *buf) -{ - unsigned int addr; /* Where to read the memory */ - int len; /* Number of bytes to read */ - int off; /* Offset into the memory */ - unsigned int errcode = APP_ERR_NONE; - - if (2 != sscanf (buf->data, "m%x,%x:", &addr, &len)) - { - fprintf (stderr, "Warning: Failed to recognize RSP read memory " - "command: %s\n", buf->data); - put_str_packet ("E01"); - return; - } - - /* Make sure we won't overflow the buffer (2 chars per byte) */ - if ((len * 2) >= GDB_BUF_MAX) - { - fprintf (stderr, "Warning: Memory read %s too large for RSP packet: " - "truncated\n", buf->data); - len = (GDB_BUF_MAX - 1) / 2; - } - - // Do the memory read into a temporary buffer - unsigned char *tmpbuf = (unsigned char *) malloc(len); // *** TODO check return, don't always malloc (use realloc) - errcode = dbg_wb_read_block8(addr, tmpbuf, len); - - - /* Refill the buffer with the reply */ - for (off = 0; off < len; off++) - { - unsigned char ch; /* The byte at the address */ - - /* Check memory area is valid. Not really possible without knowing hardware configuration. */ - - // Get the memory direct - no translation. - ch = tmpbuf[off]; - buf->data[off * 2] = hexchars[ch >> 4]; - buf->data[off * 2 + 1] = hexchars[ch & 0xf]; - } - - free(tmpbuf); - - if(errcode == APP_ERR_NONE) { - buf->data[off * 2] = 0; /* End of string */ - buf->len = strlen (buf->data); - put_packet (buf); - } - else { - fprintf(stderr, "Error reading memory: %s\n", get_err_string(errcode)); - put_str_packet("E01"); - } - -} /* rsp_read_mem () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP write memory (symbolic) request - - Syntax is: - - m,: - - The data is the bytes, lowest address first, encoded as pairs of hex - digits. - - The length given is the number of bytes to be written. - - @note This function reuses buf, so trashes the original command. - - @param[in] buf The command received */ -/*---------------------------------------------------------------------------*/ -static void -rsp_write_mem (struct rsp_buf *buf) -{ - unsigned int addr; /* Where to write the memory */ - int len; /* Number of bytes to write */ - char *symdat; /* Pointer to the symboli data */ - int datlen; /* Number of digits in symbolic data */ - int off; /* Offset into the memory */ - unsigned int errcode; - - if (2 != sscanf (buf->data, "M%x,%x:", &addr, &len)) - { - fprintf (stderr, "Warning: Failed to recognize RSP write memory " - "command: %s\n", buf->data); - put_str_packet ("E01"); - return; - } - - /* Find the start of the data and check there is the amount we expect. */ - symdat = memchr ((const void *)buf->data, ':', GDB_BUF_MAX) + 1; - datlen = buf->len - (symdat - buf->data); - - /* Sanity check */ - if (len * 2 != datlen) - { - fprintf (stderr, "Warning: Write of %d digits requested, but %d digits " - "supplied: packet ignored\n", len * 2, datlen ); - put_str_packet ("E01"); - return; - } - - /* Write the bytes to memory */ - // Put all the data into a single buffer, so it can be burst-written via JTAG. - // One burst is much faster than many single-byte transactions. - unsigned char *tmpbuf = (unsigned char *) malloc(len); - for (off = 0; off < len; off++) - { - unsigned char nyb1 = hex (symdat[off * 2]); - unsigned char nyb2 = hex (symdat[off * 2 + 1]); - tmpbuf[off] = (nyb1 << 4) | nyb2; - } - - errcode = dbg_wb_write_block8(addr, tmpbuf, len); - free(tmpbuf); - - /* Can't really check if the memory addresses are valid on hardware. */ - if(errcode == APP_ERR_NONE) { - put_str_packet ("OK"); - } - else { - fprintf(stderr, "Error writing memory: %s\n", get_err_string(errcode)); - put_str_packet("E01"); - } - -} /* rsp_write_mem () */ - - -/*---------------------------------------------------------------------------*/ -/*!Read a single register - - The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC - (i.e. SPR NPC) and SR (i.e. SPR SR). The register is returned as a - sequence of bytes in target endian order. - - Each byte is packed as a pair of hex digits. - - @param[in] buf The original packet request. Reused for the reply. */ -/*---------------------------------------------------------------------------*/ -static void -rsp_read_reg (struct rsp_buf *buf) -{ - unsigned int regnum; - unsigned long tmp; - unsigned int errcode = APP_ERR_NONE; - - /* Break out the fields from the data */ - if (1 != sscanf (buf->data, "p%x", ®num)) - { - fprintf (stderr, "Warning: Failed to recognize RSP read register " - "command: \'%s\'\n", buf->data); - put_str_packet ("E01"); - return; - } - - /* Get the relevant register */ - if (regnum < MAX_GPRS) - { - errcode = dbg_cpu0_read(SPR_GPR_BASE+regnum, &tmp); - } - else if (PPC_REGNUM == regnum) - { - errcode = dbg_cpu0_read(SPR_PPC, &tmp); - } - else if (NPC_REGNUM == regnum) - { - if(use_cached_npc) { - tmp = cached_npc; - } else { - errcode = dbg_cpu0_read(SPR_NPC, &tmp); - } - } - else if (SR_REGNUM == regnum) - { - errcode = dbg_cpu0_read(SPR_SR, &tmp); - } - else - { - /* Error response if we don't know the register */ - fprintf (stderr, "Warning: Attempt to read unknown register 0x%x: " - "ignored\n", regnum); - put_str_packet ("E01"); - return; - } - - if(errcode == APP_ERR_NONE) { - reg2hex(tmp, buf->data); - buf->len = strlen (buf->data); - put_packet (buf); - } - else { - fprintf(stderr, "Error reading register: %s\n", get_err_string(errcode)); - put_str_packet("E01"); - } - -} /* rsp_read_reg () */ - - -/*---------------------------------------------------------------------------*/ -/*!Write a single register - - The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC - (i.e. SPR NPC) and SR (i.e. SPR SR). The register is specified as a - sequence of bytes in target endian order. - - Each byte is packed as a pair of hex digits. - - @param[in] buf The original packet request. */ -/*---------------------------------------------------------------------------*/ -static void -rsp_write_reg (struct rsp_buf *buf) -{ - unsigned int regnum; - char valstr[9]; /* Allow for EOS on the string */ - unsigned int errcode = APP_ERR_NONE; - - /* Break out the fields from the data */ - if (2 != sscanf (buf->data, "P%x=%8s", ®num, valstr)) - { - fprintf (stderr, "Warning: Failed to recognize RSP write register " - "command: %s\n", buf->data); - put_str_packet ("E01"); - return; - } - - /* Set the relevant register. Must translate between GDB register numbering and hardware reg. numbers. */ - if (regnum < MAX_GPRS) - { - errcode = dbg_cpu0_write(SPR_GPR_BASE+regnum, hex2reg(valstr)); - } - else if (PPC_REGNUM == regnum) - { - errcode = dbg_cpu0_write(SPR_PPC, hex2reg(valstr)); - } - else if (NPC_REGNUM == regnum) - { - errcode = set_npc (hex2reg (valstr)); - } - else if (SR_REGNUM == regnum) - { - errcode = dbg_cpu0_write(SPR_SR, hex2reg(valstr)); - } - else - { - /* Error response if we don't know the register */ - fprintf (stderr, "Warning: Attempt to write unknown register 0x%x: " - "ignored\n", regnum); - put_str_packet ("E01"); - return; - } - - if(errcode == APP_ERR_NONE) { - put_str_packet ("OK"); - } - else { - fprintf(stderr, "Error writing register: %s\n", get_err_string(errcode)); - put_str_packet("E01"); - } - -} /* rsp_write_reg () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP query request - - @param[in] buf The request */ -/*---------------------------------------------------------------------------*/ -static void -rsp_query (struct rsp_buf *buf) -{ - if (0 == strcmp ("qC", buf->data)) - { - /* Return the current thread ID (unsigned hex). A null response - indicates to use the previously selected thread. Since we do not - support a thread concept, this is the appropriate response. */ - put_str_packet (""); - } - else if (0 == strncmp ("qCRC", buf->data, strlen ("qCRC"))) - { - /* Return CRC of memory area */ - fprintf (stderr, "Warning: RSP CRC query not supported\n"); - put_str_packet ("E01"); - } - else if (0 == strcmp ("qfThreadInfo", buf->data)) - { - /* Return info about active threads. We return just '-1' */ - put_str_packet ("m-1"); - } - else if (0 == strcmp ("qsThreadInfo", buf->data)) - { - /* Return info about more active threads. We have no more, so return the - end of list marker, 'l' */ - put_str_packet ("l"); - } - else if (0 == strncmp ("qGetTLSAddr:", buf->data, strlen ("qGetTLSAddr:"))) - { - /* We don't support this feature */ - put_str_packet (""); - } - else if (0 == strncmp ("qL", buf->data, strlen ("qL"))) - { - /* Deprecated and replaced by 'qfThreadInfo' */ - fprintf (stderr, "Warning: RSP qL deprecated: no info returned\n"); - put_str_packet ("qM001"); - } - else if (0 == strcmp ("qOffsets", buf->data)) - { - /* Report any relocation */ - put_str_packet ("Text=0;Data=0;Bss=0"); - } - else if (0 == strncmp ("qP", buf->data, strlen ("qP"))) - { - /* Deprecated and replaced by 'qThreadExtraInfo' */ - fprintf (stderr, "Warning: RSP qP deprecated: no info returned\n"); - put_str_packet (""); - } - else if (0 == strncmp ("qRcmd,", buf->data, strlen ("qRcmd,"))) - { - /* This is used to interface to commands to do "stuff" */ - rsp_command (buf); - } - else if (0 == strncmp ("qSupported", buf->data, strlen ("qSupported"))) - { - /* Report a list of the features we support. For now we just ignore any - supplied specific feature queries, but in the future these may be - supported as well. Note that the packet size allows for 'G' + all the - registers sent to us, or a reply to 'g' with all the registers and an - EOS so the buffer is a well formed string. */ - - char reply[GDB_BUF_MAX]; - - sprintf (reply, "PacketSize=%x", GDB_BUF_MAX); - put_str_packet (reply); - } - else if (0 == strncmp ("qSymbol:", buf->data, strlen ("qSymbol:"))) - { - /* Offer to look up symbols. Nothing we want (for now). TODO. This just - ignores any replies to symbols we looked up, but we didn't want to - do that anyway! */ - put_str_packet ("OK"); - } - else if (0 == strncmp ("qThreadExtraInfo,", buf->data, - strlen ("qThreadExtraInfo,"))) - { - /* Report that we are runnable, but the text must be hex ASCI - digits. For now do this by steam, reusing the original packet */ - sprintf (buf->data, "%02x%02x%02x%02x%02x%02x%02x%02x%02x", - 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0); - buf->len = strlen (buf->data); - put_packet (buf); - } - else if (0 == strncmp ("qXfer:", buf->data, strlen ("qXfer:"))) - { - /* For now we support no 'qXfer' requests, but these should not be - expected, since they were not reported by 'qSupported' */ - fprintf (stderr, "Warning: RSP 'qXfer' not supported: ignored\n"); - put_str_packet (""); - } - else - { - fprintf (stderr, "Unrecognized RSP query: ignored\n"); - } -} /* rsp_query () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP qRcmd request - - The actual command follows the "qRcmd," in ASCII encoded to hex - - @param[in] buf The request in full */ -/*---------------------------------------------------------------------------*/ -static void -rsp_command (struct rsp_buf *buf) -{ - char cmd[GDB_BUF_MAX]; - unsigned long tmp; - - hex2ascii (cmd, &(buf->data[strlen ("qRcmd,")])); - - /* Work out which command it is */ - if (0 == strncmp ("readspr ", cmd, strlen ("readspr"))) - { - unsigned int regno; - - /* Parse and return error if we fail */ - if( 1 != sscanf (cmd, "readspr %4x", ®no)) - { - fprintf (stderr, "Warning: qRcmd %s not recognized: ignored\n", - cmd); - put_str_packet ("E01"); - return; - } - - /* SPR out of range */ - if (regno > MAX_SPRS) - { - fprintf (stderr, "Warning: qRcmd readspr %x too large: ignored\n", - regno); - put_str_packet ("E01"); - return; - } - - /* Construct the reply */ - dbg_cpu0_read(regno, &tmp); // TODO Check return value of all hardware accesses - sprintf (cmd, "%8lx", tmp); - ascii2hex (buf->data, cmd); - buf->len = strlen (buf->data); - put_packet (buf); - } - else if (0 == strncmp ("writespr ", cmd, strlen ("writespr"))) - { - unsigned int regno; - unsigned long int val; - - /* Parse and return error if we fail */ - if( 2 != sscanf (cmd, "writespr %4x %8lx", ®no, &val)) - { - fprintf (stderr, "Warning: qRcmd %s not recognized: ignored\n", - cmd); - put_str_packet ("E01"); - return; - } - - /* SPR out of range */ - if (regno > MAX_SPRS) - { - fprintf (stderr, "Warning: qRcmd writespr %x too large: ignored\n", - regno); - put_str_packet ("E01"); - return; - } - - /* Update the SPR and reply "OK" */ - dbg_cpu0_write(regno, val); - put_str_packet ("OK"); - } - -} /* rsp_command () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP set request - - @param[in] buf The request */ -/*---------------------------------------------------------------------------*/ -static void -rsp_set (struct rsp_buf *buf) -{ - if (0 == strncmp ("QPassSignals:", buf->data, strlen ("QPassSignals:"))) - { - /* Passing signals not supported */ - put_str_packet (""); - } - else if ((0 == strncmp ("QTDP", buf->data, strlen ("QTDP"))) || - (0 == strncmp ("QFrame", buf->data, strlen ("QFrame"))) || - (0 == strcmp ("QTStart", buf->data)) || - (0 == strcmp ("QTStop", buf->data)) || - (0 == strcmp ("QTinit", buf->data)) || - (0 == strncmp ("QTro", buf->data, strlen ("QTro")))) - { - /* All tracepoint features are not supported. This reply is really only - needed to 'QTDP', since with that the others should not be - generated. */ - put_str_packet (""); - } - else - { - fprintf (stderr, "Unrecognized RSP set request: ignored\n"); - } -} /* rsp_set () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP restart request - - For now we just put the program counter back to the one used with the last - vRun request. */ -/*---------------------------------------------------------------------------*/ -static void -rsp_restart () -{ - set_npc (rsp.start_addr); - -} /* rsp_restart () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP step request - - Parse the command to see if there is an address. Uses the underlying - generic step function, with EXCEPT_NONE. - - @param[in] buf The full step packet */ -/*---------------------------------------------------------------------------*/ -static void -rsp_step (struct rsp_buf *buf) -{ - unsigned long int addr; /* The address to step from, if any */ - - if(strncmp(buf->data, "s", 2)) - { - if(1 != sscanf (buf->data, "s%lx", &addr)) - { - fprintf (stderr, - "Warning: RSP step address %s not recognized: ignored\n", - buf->data); - } - else - { - /* Set the address as the value of the next program counter */ - // TODO Is implementing this really just this simple? - //set_npc (addr); - } - } - - rsp_step_generic (EXCEPT_NONE); - -} /* rsp_step () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP step with signal request - - Currently null. Will use the underlying generic step function. - - @param[in] buf The full step with signal packet */ -/*---------------------------------------------------------------------------*/ -static void -rsp_step_with_signal (struct rsp_buf *buf) -{ - int val; - printf ("RSP step with signal '%s' received\n", buf->data); - val = strtoul(&buf->data[1], NULL, 10); - rsp_step_generic(val); -} /* rsp_step_with_signal () */ - - -/*---------------------------------------------------------------------------*/ -/*!Generic processing of a step request - - The signal may be EXCEPT_NONE if there is no exception to be - handled. Currently the exception is ignored. - - The single step flag is set in the debug registers and then the processor - is unstalled. - - @param[in] addr Address from which to step - @param[in] except The exception to use (if any) */ -/*---------------------------------------------------------------------------*/ -static void -rsp_step_generic (unsigned long int except) -{ - unsigned long tmp; - - /* Clear Debug Reason Register and watchpoint break generation in Debug Mode - Register 2 */ - tmp = 0; - dbg_cpu0_write(SPR_DRR, tmp); // *** TODO Check return value of all hardware accesses - dbg_cpu0_read(SPR_DMR2, &tmp); - if(tmp & SPR_DMR2_WGB) { - tmp &= ~SPR_DMR2_WGB; - dbg_cpu0_write(SPR_DMR2, tmp); - } - - /* Set the single step trigger in Debug Mode Register 1 and set traps to be - handled by the debug unit in the Debug Stop Register */ - if(!rsp.single_step_mode) - { - dbg_cpu0_read(SPR_DMR1, &tmp); - tmp |= SPR_DMR1_ST|SPR_DMR1_BT; - dbg_cpu0_write(SPR_DMR1, tmp); - dbg_cpu0_read(SPR_DSR, &tmp); - if(!(tmp & SPR_DSR_TE)) { - tmp |= SPR_DSR_TE; - dbg_cpu0_write(SPR_DSR, tmp); - } - rsp.single_step_mode = 1; - } - - /* Unstall the processor */ - set_stall_state (0); - - /* Note the GDB client is now waiting for a reply. */ - rsp.client_waiting = 1; - -} /* rsp_step_generic () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP 'v' packet - - These are commands associated with executing the code on the target - - @param[in] buf The request */ -/*---------------------------------------------------------------------------*/ -static void -rsp_vpkt (struct rsp_buf *buf) -{ - if (0 == strncmp ("vAttach;", buf->data, strlen ("vAttach;"))) - { - /* Attaching is a null action, since we have no other process. We just - return a stop packet (using TRAP) to indicate we are stopped. */ - put_str_packet ("S05"); - return; - } - else if (0 == strcmp ("vCont?", buf->data)) - { - /* For now we don't support this. */ - put_str_packet (""); - return; - } - else if (0 == strncmp ("vCont", buf->data, strlen ("vCont"))) - { - /* This shouldn't happen, because we've reported non-support via vCont? - above */ - fprintf (stderr, "Warning: RSP vCont not supported: ignored\n" ); - return; - } - else if (0 == strncmp ("vFile:", buf->data, strlen ("vFile:"))) - { - /* For now we don't support this. */ - fprintf (stderr, "Warning: RSP vFile not supported: ignored\n" ); - put_str_packet (""); - return; - } - else if (0 == strncmp ("vFlashErase:", buf->data, strlen ("vFlashErase:"))) - { - /* For now we don't support this. */ - fprintf (stderr, "Warning: RSP vFlashErase not supported: ignored\n" ); - put_str_packet ("E01"); - return; - } - else if (0 == strncmp ("vFlashWrite:", buf->data, strlen ("vFlashWrite:"))) - { - /* For now we don't support this. */ - fprintf (stderr, "Warning: RSP vFlashWrite not supported: ignored\n" ); - put_str_packet ("E01"); - return; - } - else if (0 == strcmp ("vFlashDone", buf->data)) - { - /* For now we don't support this. */ - fprintf (stderr, "Warning: RSP vFlashDone not supported: ignored\n" ); - put_str_packet ("E01"); - return; - } - else if (0 == strncmp ("vRun;", buf->data, strlen ("vRun;"))) - { - /* We shouldn't be given any args, but check for this */ - if (buf->len > strlen ("vRun;")) - { - fprintf (stderr, "Warning: Unexpected arguments to RSP vRun " - "command: ignored\n"); - } - - /* Restart the current program. However unlike a "R" packet, "vRun" - should behave as though it has just stopped. We use signal - 5 (TRAP). */ - rsp_restart (); - put_str_packet ("S05"); - } - else - { - fprintf (stderr, "Warning: Unknown RSP 'v' packet type %s: ignored\n", - buf->data); - put_str_packet ("E01"); - return; - } -} /* rsp_vpkt () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP write memory (binary) request - - Syntax is: - - X,: - - Followed by the specified number of bytes as raw binary. Response should be - "OK" if all copied OK, E if error has occurred. - - The length given is the number of bytes to be written. However the number - of data bytes may be greater, since '#', '$' and '}' are escaped by - preceding them by '}' and oring with 0x20. - - @param[in] buf The command received */ -/*---------------------------------------------------------------------------*/ -static void -rsp_write_mem_bin (struct rsp_buf *buf) -{ - unsigned int addr; /* Where to write the memory */ - int len; /* Number of bytes to write */ - char *bindat; /* Pointer to the binary data */ - int off; /* Offset to start of binary data */ - int newlen; /* Number of bytes in bin data */ - unsigned int errcode; - - if (2 != sscanf (buf->data, "X%x,%x:", &addr, &len)) - { - fprintf (stderr, "Warning: Failed to recognize RSP write memory " - "command: %s\n", buf->data); - put_str_packet ("E01"); - return; - } - - /* Find the start of the data and "unescape" it */ - bindat = memchr ((const void *)buf->data, ':', GDB_BUF_MAX) + 1; - off = bindat - buf->data; - newlen = rsp_unescape (bindat, buf->len - off); - - /* Sanity check */ - if (newlen != len) - { - int minlen = len < newlen ? len : newlen; - - fprintf (stderr, "Warning: Write of %d bytes requested, but %d bytes " - "supplied. %d will be written\n", len, newlen, minlen); - len = minlen; - } - - /* Write the bytes to memory */ - errcode = dbg_wb_write_block8(addr, (uint8_t *) bindat, len); - - // We can't really verify if the memory target address exists or not. - // Don't write to non-existant memory unless your system wishbone implementation - // has a hardware bus timeout. - if(errcode == APP_ERR_NONE) { - put_str_packet ("OK"); - } - else { - fprintf(stderr, "Error writing memory: %s\n", get_err_string(errcode)); - put_str_packet("E01"); - } - -} /* rsp_write_mem_bin () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP remove breakpoint or matchpoint request - - For now only memory breakpoints are implemented, which are implemented by - substituting a breakpoint at the specified address. The implementation must - cope with the possibility of duplicate packets. - - @todo This doesn't work with icache/immu yet - - @param[in] buf The command received */ -/*---------------------------------------------------------------------------*/ -static void -rsp_remove_matchpoint (struct rsp_buf *buf) -{ - enum mp_type type; /* What sort of matchpoint */ - unsigned long int addr; /* Address specified */ - int len; /* Matchpoint length (not used) */ - struct mp_entry *mpe; /* Info about the replaced instr */ - unsigned long instbuf[1]; - - /* Break out the instruction */ - if (3 != sscanf (buf->data, "z%1d,%lx,%1d", (int *)&type, &addr, &len)) - { - fprintf (stderr, "Warning: RSP matchpoint deletion request not " - "recognized: ignored\n"); - put_str_packet ("E01"); - return; - } - - /* Sanity check that the length is 4 */ - if (4 != len) - { - fprintf (stderr, "Warning: RSP matchpoint deletion length %d not " - "valid: 4 assumed\n", len); - len = 4; - } - - /* Sort out the type of matchpoint */ - switch (type) - { - case BP_MEMORY: - /* Memory breakpoint - replace the original instruction. */ - mpe = mp_hash_delete (type, addr); - - /* If the BP hasn't yet been deleted, put the original instruction - back. Don't forget to free the hash table entry afterwards. */ - if (NULL != mpe) - { - instbuf[0] = mpe->instr; - dbg_wb_write_block32(addr, instbuf, 1); // *** TODO Check return value - free (mpe); - } - - put_str_packet ("OK"); - - return; - - case BP_HARDWARE: - put_str_packet (""); /* Not supported */ - return; - - case WP_WRITE: - put_str_packet (""); /* Not supported */ - return; - - case WP_READ: - put_str_packet (""); /* Not supported */ - return; - - case WP_ACCESS: - put_str_packet (""); /* Not supported */ - return; - - default: - fprintf (stderr, "Warning: RSP matchpoint type %d not " - "recognized: ignored\n", type); - put_str_packet ("E01"); - return; - - } -} /* rsp_remove_matchpoint () */ - - -/*---------------------------------------------------------------------------*/ -/*!Handle a RSP insert breakpoint or matchpoint request - - For now only memory breakpoints are implemented, which are implemented by - substituting a breakpoint at the specified address. The implementation must - cope with the possibility of duplicate packets. - - @todo This doesn't work with icache/immu yet - - @param[in] buf The command received */ -/*---------------------------------------------------------------------------*/ -static void -rsp_insert_matchpoint (struct rsp_buf *buf) -{ - enum mp_type type; /* What sort of matchpoint */ - unsigned long int addr; /* Address specified */ - int len; /* Matchpoint length (not used) */ - unsigned long instbuf[1]; - - /* Break out the instruction */ - if (3 != sscanf (buf->data, "Z%1d,%lx,%1d", (int *)&type, &addr, &len)) - { - fprintf (stderr, "Warning: RSP matchpoint insertion request not " - "recognized: ignored\n"); - put_str_packet ("E01"); - return; - } - - /* Sanity check that the length is 4 */ - if (4 != len) - { - fprintf (stderr, "Warning: RSP matchpoint insertion length %d not " - "valid: 4 assumed\n", len); - len = 4; - } - - /* Sort out the type of matchpoint */ - switch (type) - { - case BP_MEMORY: - /* Memory breakpoint - substitute a TRAP instruction */ - dbg_wb_read_block32(addr, instbuf, 1); // Get the old instruction. *** TODO Check return value - mp_hash_add (type, addr, instbuf[0]); - instbuf[0] = OR1K_TRAP_INSTR; // Set the TRAP instruction - dbg_wb_write_block32(addr, instbuf, 1); // *** TODO Check return value - put_str_packet ("OK"); - - return; - - case BP_HARDWARE: - put_str_packet (""); /* Not supported */ - return; - - case WP_WRITE: - put_str_packet (""); /* Not supported */ - return; - - case WP_READ: - put_str_packet (""); /* Not supported */ - return; - - case WP_ACCESS: - put_str_packet (""); /* Not supported */ - return; - - default: - fprintf (stderr, "Warning: RSP matchpoint type %d not " - "recognized: ignored\n", type); - put_str_packet ("E01"); - return; - - } - -} /* rsp_insert_matchpoint () */ - - -// Additions from this point on were added solely to handle hardware, -// and did not come from simulator interface code. -/////////////////////////////////////////////////////////////////////////// -// -// Thread to poll for break on remote processor. -/////////////////////////////////////////////////////////////////////////// - -void *target_handler(void *arg) -{ - unsigned char target_status = 0; - int retval = APP_ERR_NONE; - char string[] = "a"; // We send this through the pipe. Content is unimportant. - unsigned int local_state = 0; - - while(1) - { - // Block on condition for GO or DETACH signal - pthread_mutex_lock(&target_handler_mutex); - if(target_handler_state == 0) - { - pthread_cond_wait(&target_handler_cond, &target_handler_mutex); - } - - // if detach, exit thread - if(target_handler_state == 2) // 2 = DETACH - { - target_handler_state = 0; - pthread_mutex_unlock(&target_handler_mutex); - return arg; - } - - local_state = target_handler_state; - pthread_mutex_unlock(&target_handler_mutex); - - - - if(local_state == 1) // Then start target polling loop, but keep checking for DETACH. State 1 == GO - { - while(1) - { - // non-blocking check for DETACH signal - pthread_mutex_lock(&target_handler_mutex); - if(target_handler_state == 2) // state 2 == DETACH - { - pthread_mutex_unlock(&target_handler_mutex); - return arg; - } - pthread_mutex_unlock(&target_handler_mutex); - - // Poll target hardware - retval = dbg_cpu0_read_ctrl(0, &target_status); - if(retval != APP_ERR_NONE) - fprintf(stderr, "ERROR 0x%X while polling target CPU status\n", retval); - else { - if(target_status & 0x01) // Did we get the stall bit? Bit 0 is STALL bit. - { - // clear the RUNNING flag - pthread_mutex_lock(&rsp_mutex); - rsp.target_running = 0; - pthread_mutex_unlock(&rsp_mutex); - - // Log the exception so it can be sent back to GDB - unsigned long drrval; - dbg_cpu0_read(SPR_DRR, &drrval); // Read the DRR, find out why we stopped - rsp_exception(drrval); // Send it to be translated and stored - - // Send message to GDB handler thread via socket (so it can break out of its poll()) - int ret = write(pipe_fds[1], string, 1); - if(!ret) { - fprintf(stderr, "Warning: target monitor write() to pipe returned 0\n"); - } - else if(ret < 0) { - perror("Error in target monitor write to pipe: "); - } - - // Set our own state back to STOP - pthread_mutex_lock(&target_handler_mutex); - target_handler_state = 0; - pthread_mutex_unlock(&target_handler_mutex); - - break; // Stop polling, block on the next GO/DETACH - } - } - - usleep(250000); // wait 1/4 second before polling again. - } - } - - else - { - fprintf(stderr, "Unknown command 0x%X received by target handler thread\n", local_state); - pthread_mutex_lock(&target_handler_mutex); // Set our own state back to STOP - target_handler_state = 0; - pthread_mutex_unlock(&target_handler_mutex); - } - } - - return arg; -} - - - - -void set_stall_state(int stall) -{ - int retval = 0; - unsigned char data = (stall>0)? 1:0; - unsigned char stalled = 0; - - // Set the 'running' variable, if necessary. Do this before actually starting the CPU. - // The 'running' variable prevents us from responding to most GDB requests while the - // CPU is running. - // We don't ever set the 'running' bit to 0 here. Instead, we stall the CPU hardware, and let - // the target handler thread detect the stall, then signal us to send a message up to - // GDB and clear the 'running' bit. - if(stall == 0) - { - use_cached_npc = 0; - pthread_mutex_lock(&rsp_mutex); - rsp.target_running = 1; - pthread_mutex_unlock(&rsp_mutex); - } - - // Actually start or stop the CPU hardware - retval = dbg_cpu0_write_ctrl(0, data); // 0x01 is the STALL command bit - if(retval != APP_ERR_NONE) - fprintf(stderr, "ERROR 0x%X sending async STALL to target.\n", retval); - - dbg_cpu0_read_ctrl(0, &stalled); - /* - if (!(stalled & 0x1)) { - printf("or1k is not stalled!\n"); - } - - fprintf(stderr, "Set STALL to %i\n", data); - */ - - // Wake up the target handler thread to poll for a new STALL - if(stall == 0) - { - pthread_mutex_lock(&target_handler_mutex); - target_handler_state = 1; - pthread_cond_signal(&target_handler_cond); - pthread_mutex_unlock(&target_handler_mutex); - } - - return; -} Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/README =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/README (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/README (nonexistent) @@ -1,54 +0,0 @@ -These are the notes for building the Advanced JTAG Bridge program. -Nathan Yawn, nathan.yawn@opencores.org - -BUILDING - -This program doesn't use automake. It has been developed using the cygwin -environment under winXP, and should also compile under various GNU/Linux -distributions. It has been tested and in known to work with Ubuntu 9.04. -There are two sets of build flags defined in the Makefile, -one for cygwin and one for Linux - one set is used, one is commented out. -Edit the Makefile for your system, type "make," and see what happens... - -The program may be built with support for the Advanced Debug Interface -(the default), or the legacy "debug_if" interface. To compile for the -legacy interface, __LEGACY__ should be added to CFLAGS in the Makefile -(the line is present but commented out by default). Note that support -for the two different debug hardware units is mutually exclusive; both -cannot be supported in the same build. - -DEPENDENCIES - -Adv_jtag_bridge has three dependencies: - -- The pthreads library (probably already installed) -- Cygwin only: libioperm (for parallel port device access permissions) -- libusb - -Since adv_jtag_bridge was written, a newer version of libusb has been -released (1.0), which used a different interface. We still use the old -interface (0.1), so be sure you install the "compatibility layer" if you -install the latest libusb. As of December 2008, libUSB-Win32 still used -v0.1, so cygwin users may not need to install any additional compatibility -layer. - -BUGS - -GDB 6.8 has a bug which prevents it from working when no stack frame is -present (such as at start-up on a bare-metal debugger, such as this one). -A simple patch applied to GDB 6.8 will work around the problem (a general -solution is not yet available). This patch can be found in the source -directory of adv_jtag_bridge as "gdb-6.8-bz436037-reg-no-longer-active.patch". - -LICENSE - -This code is based on "jp2", which was distributed under the GNU Public -License, version 2. Adv_jtag_bridge is therefore also distributed under -this license. - -WARRANTY - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_dbg_commands.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_dbg_commands.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_dbg_commands.h (nonexistent) @@ -1,73 +0,0 @@ - -#ifndef _ADV_DBG_COMMANDS_H_ -#define _ADV_DBG_COMMANDS_H_ - - -// Definitions for the top-level debug unit. This really just consists -// of a single register, used to select the active debug module ("chain"). -#define DBG_MODULE_SELECT_REG_SIZE 2 -#define DBG_MAX_MODULES 4 // used to size an array - -#define DC_WISHBONE 0 -#define DC_CPU0 1 -#define DC_CPU1 2 - -// Polynomial for the CRC calculation -// Yes, it's backwards. Yes, this is on purpose. -// The hardware is designed this way to save on logic and routing, -// and it's really all the same to us here. -#define ADBG_CRC_POLY 0xedb88320 - -// These are for the internal registers in the Wishbone module -// The first is the length of the index register, -// the indexes of the various registers are defined after that -#define DBG_WB_REG_SEL_LEN 1 -#define DBG_WB_REG_ERROR 0 - -// Opcode definitions for the Wishbone module -#define DBG_WB_OPCODE_LEN 4 -#define DBG_WB_CMD_NOP 0x0 -#define DBG_WB_CMD_BWRITE8 0x1 -#define DBG_WB_CMD_BWRITE16 0x2 -#define DBG_WB_CMD_BWRITE32 0x3 -#define DBG_WB_CMD_BREAD8 0x5 -#define DBG_WB_CMD_BREAD16 0x6 -#define DBG_WB_CMD_BREAD32 0x7 -#define DBG_WB_CMD_IREG_WR 0x9 // This is both a select and a write -#define DBG_WB_CMD_IREG_SEL 0xd // There is no 'read', the current register is always read. Use a NOP to read. - - -// Internal register definitions for the CPU0 module -#define DBG_CPU0_REG_SEL_LEN 1 -#define DBG_CPU0_REG_STATUS 0 - -// Opcode definitions for the first CPU module -#define DBG_CPU0_OPCODE_LEN 4 -#define DBG_CPU0_CMD_NOP 0x0 -#define DBG_CPU0_CMD_BWRITE32 0x3 -#define DBG_CPU0_CMD_BREAD32 0x7 -#define DBG_CPU0_CMD_IREG_WR 0x9 // This is both a select and a write -#define DBG_CPU0_CMD_IREG_SEL 0xd // There is no 'read', the current register is always read. Use a NOP to read. - -// Internal register definitions for the CPU1 module -#define DBG_CPU1_REG_SEL_LEN 1 -#define DBG_CPU1_REG_STATUS 0 - -// Opcode definitions for the second CPU module -#define DBG_CPU1_OPCODE_LEN 4 -#define DBG_CPU1_CMD_NOP 0x0 -#define DBG_CPU1_CMD_BWRITE32 0x3 -#define DBG_CPU1_CMD_BREAD32 0x7 -#define DBG_CPU1_CMD_IREG_WR 0x9 // This is both a select and a write -#define DBG_CPU1_CMD_IREG_SEL 0xd // There is no 'read', the current register is always read. Use a NOP to read. - -// API to do transactions on the advanced debug interface -int adbg_select_module(int chain); -int adbg_select_ctrl_reg(unsigned long regidx); -int adbg_ctrl_write(unsigned long regidx, uint32_t *cmd_data, int length_bits); -int adbg_ctrl_read(unsigned long regidx, uint32_t *data, int databits); -int adbg_burst_command(unsigned int opcode, unsigned long address, int length_words); -int adbg_wb_burst_read(int word_size_bytes, int word_count, unsigned long start_address, void *data); -int adbg_wb_burst_write(void *data, int word_size_bytes, int word_count, unsigned long start_address); - -#endif Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_ft2232.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_ft2232.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_ft2232.h (nonexistent) @@ -1,107 +0,0 @@ - -#ifndef _CABLE_FT2232_H_ -#define _CABLE_FT2232_H_ - -#define debug(...) //fprintf(stderr, __VA_ARGS__ ) -#ifndef min -#define min(X,Y) ((X) < (Y) ? (X) : (Y)) -#endif - -#define FTDX_MAXSEND 4096 -#define FTDX_MAXSEND_MPSSE (64 * 1024) -#define FTDI_MAXRECV ( 4 * 64) - -#define BIT_CABLEID2_TCK 0 /* ADBUS0 */ -#define BIT_CABLEID2_TDIDO 1 /* ADBUS1 */ -#define BIT_CABLEID2_TDODI 2 /* ADBUS2 */ -#define BIT_CABLEID2_TMS 3 /* ADBUS3 */ -#define BITMASK_CABLEID2_TCK (1 << BIT_CABLEID2_TCK) -#define BITMASK_CABLEID2_TDIDO (1 << BIT_CABLEID2_TDIDO) -#define BITMASK_CABLEID2_TDODI (1 << BIT_CABLEID2_TDODI) -#define BITMASK_CABLEID2_TMS (1 << BIT_CABLEID2_TMS) - -#define BIT_CABLEID2_OE 1 /* ACBUS1 */ -#define BIT_CABLEID2_RXLED 2 /* ACBUS2 */ -#define BIT_CABLEID2_TXLED 3 /* ACBUS3 */ -#define BITMASK_CABLEID2_OE (1 << BIT_CABLEID2_OE) -#define BITMASK_CABLEID2_RXLED (1 << BIT_CABLEID2_RXLED) -#define BITMASK_CABLEID2_TXLED (1 << BIT_CABLEID2_TXLED) - -typedef struct usbconn_t usbconn_t; - -typedef struct { - char *name; - char *desc; - char *driver; - int32_t vid; - int32_t pid; -} usbconn_cable_t; - -typedef struct { - const char *type; - usbconn_t *(*connect)( const char **, int, usbconn_cable_t *); - void (*free)( usbconn_t * ); - int (*open)( usbconn_t * ); - int (*close)( usbconn_t * ); - int (*read)( usbconn_t *, uint8_t *, int ); - int (*write)( usbconn_t *, uint8_t *, int, int ); -} usbconn_driver_t; - -struct usbconn_t { - usbconn_driver_t *driver; - void *params; - usbconn_cable_t *cable; -}; - -typedef struct { - /* USB device information */ - unsigned int vid; - unsigned int pid; - struct ftdi_context *ftdic; - char *serial; - /* send and receive buffer handling */ - uint32_t send_buf_len; - uint32_t send_buffered; - uint8_t *send_buf; - uint32_t recv_buf_len; - uint32_t to_recv; - uint32_t recv_write_idx; - uint32_t recv_read_idx; - uint8_t *recv_buf; -} ftdi_param_t; - - -usbconn_t * usbconn_ftdi_connect(); -int my_ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size); -char *my_ftdi_get_error_string (struct ftdi_context *ftdi); -int my_ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size); -int my_ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, const char* description, const char* serial); -void my_ftdi_deinit(struct ftdi_context *ftdi); -int my_ftdi_usb_purge_buffers(struct ftdi_context *ftdi); -int my_ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi); -int my_ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi); -int my_ftdi_usb_reset(struct ftdi_context *ftdi); -int my_ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency); -int my_ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate); -int my_ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize); -int my_ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize); -int my_ftdi_set_event_char(struct ftdi_context *ftdi, unsigned char eventch, unsigned char enable); -int my_ftdi_set_error_char(struct ftdi_context *ftdi, unsigned char errorch, unsigned char enable); -int my_ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode); -int my_ftdi_usb_close(struct ftdi_context *ftdi); -int cable_common_write_bit(uint8_t packet); -int cable_common_read_write_bit(uint8_t packet_out, uint8_t *bit_in); -int cable_common_write_stream(uint32_t *stream, int len_bits, int set_last_bit); -int cable_common_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit); -int cable_ftdi_init(); -int cable_ftdi_write_bit(uint8_t packet); -int cable_ftdi_read_write_bit(uint8_t packet_out, uint8_t *bit_in); -int cable_ftdi_write_stream(uint32_t *stream, int len_bits, int set_last_bit); -int cable_ftdi_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit); -int cable_ftdi_opt(int c, char *str); -int cable_ftdi_flush(); -int cable_ftdi_close(); - -#endif - - Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/rsp-server.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/rsp-server.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/rsp-server.h (nonexistent) @@ -1,36 +0,0 @@ -/* rsp-server.c -- Remote Serial Protocol server for GDB - -Copyright (C) 2008 Embecosm Limited - -Contributor Jeremy Bennett - -This file was part of Or1ksim, the OpenRISC 1000 Architectural Simulator. -Was actually purchased by Mom when I decided it was nice, but not affordable after two other recent pen purchases. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see . -*/ - -/* This program is commented throughout in a fashion suitable for processing - with Doxygen. */ - - -#ifndef RSP_SERVER__H -#define RSP_SERVER__H - - -/* Function prototypes for external use */ -void rsp_init (int portNum); -int handle_rsp (void); // returns 1 normally, 0 for an unrecoverable error - -#endif /* RSP_SERVER__H */ Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/bsdl.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/bsdl.c (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/bsdl.c (nonexistent) @@ -1,238 +0,0 @@ -/* bsdl.c - BSDL file handler for the advanced JTAG bridge - Copyright(C) 2008 Nathan Yawn - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include -#include -#include -#include -#include "bsdl.h" -#include "bsdl_parse.h" - - -#define debug(...) //fprintf(stderr, __VA_ARGS__ ) - -// Globals to deal with directory names -#define MAX_BSDL_DIRS 64 // Any more than this would take a looooong time... -static char *bsdl_dirs[MAX_BSDL_DIRS]; -static int bsdl_current_dir = 0; // We try them in reverse order - -// Globals to hold the current, open directory -DIR *bsdl_open_dir = NULL; - -// Globals to hold BSDL info -static bsdlinfo *bsdl_head = NULL; -static bsdlinfo *bsdl_tail = NULL; -static bsdlinfo *bsdl_last = NULL; // optimization: pointer to the last struct we used (not necessarily the last in the linked list) - -// Prototypes for local functions -bsdlinfo *get_bsdl_info(uint32_t idcode); - - - -////////////////////////////////////////////////////////////////////// -// API for init and config - -void bsdl_init(void) -{ - bsdl_dirs[0] = strdup("/opt/bsdl"); - bsdl_dirs[1] = strdup("/usr/share/bsdl"); - bsdl_dirs[2] = strdup("~/.bsdl"); - bsdl_dirs[3] = strdup("."); - bsdl_current_dir = 3; -} - -void bsdl_add_directory(const char *dirname) -{ - if(bsdl_current_dir >= (MAX_BSDL_DIRS-1)) { - printf("Max BSDL dirs (%d) exceeded; failed to add directory %s\n", MAX_BSDL_DIRS, dirname); - return; - } - - bsdl_current_dir++; - bsdl_dirs[bsdl_current_dir] = strdup(dirname); -} - - -/////////////////////////////////////////////////////////////////// -// API to get device info from BSDL files, if available - - -const char * bsdl_get_name(uint32_t idcode) -{ - bsdlinfo *info; - info = get_bsdl_info(idcode); - if(info != NULL) - return info->name; - - return NULL; - - -} - -// Return the IR length of the device with the given IDCODE, -// if its BSDL file is available. Returns -1 on -// error, which is an invalid size. - -int bsdl_get_IR_size(uint32_t idcode) -{ - bsdlinfo *info; - info = get_bsdl_info(idcode); - if(info != NULL) - return info->IR_size; - - return -1; -} - - -// Returns the DEBUG command for the device with the gived IDCODE, -// if its BSDL file is available. Returns 0xFFFFFFFF on error, -// which is as invalid command (because it's the BYPASS command) -uint32_t bsdl_get_debug_cmd(uint32_t idcode) -{ - bsdlinfo *info; - info = get_bsdl_info(idcode); - if(info != NULL) - return info->cmd_debug; - return TAP_CMD_INVALID; -} - -// Returns the USER1 command for the device with the gived IDCODE, -// if its BSDL file is available. Returns 0xFFFFFFFF on error, -// which is as invalid command (because it's the BYPASS command) -uint32_t bsdl_get_user1_cmd(uint32_t idcode) -{ - bsdlinfo *info; - info = get_bsdl_info(idcode); - if(info != NULL) - return info->cmd_user1; - return TAP_CMD_INVALID; -} - -// Returns the IDCODE command for the device with the gived IDCODE, -// if its BSDL file is available. Returns 0xFFFFFFFF on error, -// which is as invalid command (because it's the BYPASS command) -uint32_t bsdl_get_idcode_cmd(uint32_t idcode) -{ - bsdlinfo *info; - info = get_bsdl_info(idcode); - if(info != NULL) - return info->cmd_idcode; - return TAP_CMD_INVALID; -} - -///////////////////////////////////////////////////////////////////////////// -// Internal routines - - -// This uses a lazy algorithm...first, search data we already have. -// Then, parse new files (storing all data) only until we find -// the data we want. -bsdlinfo *get_bsdl_info(uint32_t idcode) -{ - struct dirent *direntry = NULL; - bsdlinfo *ptr = bsdl_head; - char *c; - - // Check the last place we looked - if(bsdl_last != NULL) - if((bsdl_last->idcode & bsdl_last->idcode_mask) == (idcode & bsdl_last->idcode_mask)) - return bsdl_last; - - // First, search through the info already parsed - while(ptr != NULL) - { - if((ptr->idcode & ptr->idcode_mask) == (idcode & ptr->idcode_mask)) - { - bsdl_last = ptr; - return ptr; - } - ptr = ptr->next; - } - - // Parse files until we get the IDCODE we want - while(1) - { - // Find and open a valid directory - while(bsdl_open_dir == NULL) - { - if(bsdl_current_dir < 0) - return NULL; // There are no more directories to check - debug("Trying BSDL dir \'%s\'\n", bsdl_dirs[bsdl_current_dir]); - bsdl_open_dir = opendir(bsdl_dirs[bsdl_current_dir]); - if((bsdl_open_dir == NULL) && (bsdl_current_dir > 2)) // Don't warn if default dirs not found - printf("Warning: unable to open BSDL directory \'%s\'\n", bsdl_dirs[bsdl_current_dir]); - bsdl_current_dir--; - direntry = NULL; - } - - // Find a BSDL file - do - { - direntry = readdir(bsdl_open_dir); - if(direntry == NULL) - { // We've exhausted this directory - closedir(bsdl_open_dir); - bsdl_open_dir = NULL; - break; - } - - // *** If a subdirectory, continue!! - - // Check if it's a BSDL file: .bsd, .bsdl, .BSD, .BSDL - debug("Checking file \'%s\'\n", direntry->d_name); - c = strrchr(direntry->d_name, '.'); - debug("File extension is \'%s\'\n", c); - if(c == NULL) - continue; - if(!strcmp(c, ".bsd") || !strcmp(c, ".bsdl") || !strcmp(c, ".BSD") || !strcmp(c, ".BSDL")) - break; - - } - while(1); - - if(direntry == NULL) // We need a new directory - continue; - - // Parse the BSDL file we found - debug("Parsing file \'%s\'\n", direntry->d_name); - ptr = parse_extract_values(direntry->d_name); - - // If we got good data... - if(ptr != NULL) - { - // Store the values... - if(bsdl_head == NULL) { - bsdl_head = ptr; - bsdl_tail = ptr; - } else { - bsdl_tail->next = ptr; - bsdl_tail = ptr; - } - - // ...and return if we got an IDCODE match - if((ptr->idcode & ptr->idcode_mask) == (idcode & ptr->idcode_mask)) { - bsdl_last = ptr; - return ptr; - } - } - } // while(1), parse files until we find a match or run out of dirs / files - - - // If no more files to parse and not found, return NULL - return NULL; -} Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/dbg_api.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/dbg_api.c (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/dbg_api.c (nonexistent) @@ -1,669 +0,0 @@ -/* dbg_api.c -- JTAG protocol bridge between GDB and Advanced debug module. - Copyright(C) Nathan Yawn, nyawn@opencores.net - based on code from jp2 by Marko Mlinar, markom@opencores.org - - This file contains API functions which may be called from the GDB - interface server. These functions call the appropriate hardware- - specific functions for the advanced debug interface or the legacy - debug interface, depending on which is selected. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - - - -#include -#include // for mutexes -#include // for ntohl() - -#include "adv_dbg_commands.h" -#include "legacy_dbg_commands.h" -#include "cable_common.h" -#include "errcodes.h" - -#define debug(...) //fprintf(stderr, __VA_ARGS__ ) - -#define DBG_HW_ADVANCED 1 -#define DBG_HW_LEGACY 2 -#ifdef __LEGACY__ -#warning Compiling for LEGACY debug hardware! -#define DEBUG_HARDWARE DBG_HW_LEGACY -#else -#warning Compiling for ADVANCED debug unit! -#define DEBUG_HARDWARE DBG_HW_ADVANCED -#endif - -pthread_mutex_t dbg_access_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* read a word from wishbone */ -int dbg_wb_read32(unsigned long adr, unsigned long *data) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(4, 1, adr, (void *)data); // All WB reads / writes are bursts - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x6, adr, 4))) - err = legacy_dbg_go((unsigned char*)data, 4, 1); - *data = ntohl(*data); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -/* write a word to wishbone */ -int dbg_wb_write32(unsigned long adr, unsigned long data) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)&data, 4, 1, adr); - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - data = ntohl(data); - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x2, adr, 4))) - err = legacy_dbg_go((unsigned char*)&data, 4, 0); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -// write a word to wishbone -// Never actually called from the GDB interface -int dbg_wb_write16(unsigned long adr, uint16_t data) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)&data, 2, 1, adr); - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - data = ntohs(data); - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x1, adr, 2))) - err = legacy_dbg_go((unsigned char*)&data, 2, 0); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -// write a word to wishbone -// Never actually called from the GDB interface -int dbg_wb_write8(unsigned long adr, uint8_t data) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)&data, 1, 1, adr); - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x0, adr, 1))) - err = legacy_dbg_go((unsigned char*)&data, 1, 0); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -int dbg_wb_read_block32(unsigned long adr, unsigned long *data, int len) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(!len) - return APP_ERR_NONE; // GDB may issue a 0-length transaction to test if a feature is supported - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(4, len, adr, (void *)data); // 'len' is words. - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int i; - int bytelen = len<<2; - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x6, adr, bytelen))) - if (APP_ERR_NONE == (err = legacy_dbg_go((unsigned char*)data, bytelen, 1))) // 'len' is words, call wants bytes - for (i = 0; i < len; i ++) data[i] = ntohl(data[i]); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -// Never actually called from the GDB interface -int dbg_wb_read_block16(unsigned long adr, uint16_t *data, int len) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(!len) - return APP_ERR_NONE; // GDB may issue a 0-length transaction to test if a feature is supported - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(2, len, adr, (void *)data); // 'len' is 16-bit halfwords - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int i; - int bytelen = len<<1; - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x5, adr, bytelen))) - if (APP_ERR_NONE == (err = legacy_dbg_go((unsigned char*)data, bytelen, 1))) // 'len' is halfwords, call wants bytes - for (i = 0; i < len; i ++) data[i] = ntohs(data[i]); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -// Never actually called from the GDB interface -int dbg_wb_read_block8(unsigned long adr, uint8_t *data, int len) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(!len) - return APP_ERR_NONE; // GDB may issue a 0-length transaction to test if a feature is supported - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(1, len, adr, (void *)data); // *** is 'len' bits or words?? Call wants words... - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x4, adr, len))) - err = legacy_dbg_go((unsigned char*)data, len, 1); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - - -// write a block to wishbone -int dbg_wb_write_block32(unsigned long adr, unsigned long *data, int len) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(!len) - return APP_ERR_NONE; // GDB may issue a 0-length transaction to test if a feature is supported - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)data, 4, len, adr); // 'len' is words. - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int i; - int bytelen = len << 2; - for (i = 0; i < len; i ++) data[i] = ntohl(data[i]); - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x2, adr, bytelen))) - err = legacy_dbg_go((unsigned char*)data, bytelen, 0); // 'len' is words, call wants bytes - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -// write a block to wishbone -// Never actually called from the GDB interface -int dbg_wb_write_block16(unsigned long adr, uint16_t *data, int len) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(!len) - return APP_ERR_NONE; // GDB may issue a 0-length transaction to test if a feature is supported - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)data, 2, len, adr); // 'len' is (half)words - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int i; - int bytelen = len<<1; - for (i = 0; i < len; i ++) data[i] = ntohs(data[i]); - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x1, adr, bytelen))) - err = legacy_dbg_go((unsigned char*)data, bytelen, 0); // 'len' is 16-bit halfwords, call wants bytes - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -// write a block to wishbone -int dbg_wb_write_block8(unsigned long adr, uint8_t *data, int len) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(!len) - return APP_ERR_NONE; // GDB may issue a 0-length transaction to test if a feature is supported - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)data, 1, len, adr); // 'len' is in words... - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x0, adr, len))) - err = legacy_dbg_go((unsigned char*)data, len, 0); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -/* read a register from cpu0. This is assumed to be an OR32 CPU, with 32-bit regs. */ -int dbg_cpu0_read(unsigned long adr, unsigned long *data) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(4, 1, adr, (void *) data); // All CPU register reads / writes are bursts - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU0))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x6, adr, 4))) - if (APP_ERR_NONE == (err = legacy_dbg_go((unsigned char*)data, 4, 1))) - *data = ntohl(*data); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - debug("dbg_cpu_read(), addr 0x%X, data[0] = 0x%X\n", adr, data[0]); - return err; -} - -/* read multiple registers from cpu0. This is assumed to be an OR32 CPU, with 32-bit regs. */ -int dbg_cpu0_read_block(unsigned long adr, unsigned long *data, int count) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(4, count, adr, (void *) data); // All CPU register reads / writes are bursts - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int i; - unsigned long readaddr = adr; - err = APP_ERR_NONE; - for(i = 0; i < count; i++) { - err |= dbg_cpu0_read(readaddr++, &data[i]); - } - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - debug("dbg_cpu_read_block(), addr 0x%X, count %i, data[0] = 0x%X\n", adr, count, data[0]); - return err; -} - -/* write a cpu register to cpu0. This is assumed to be an OR32 CPU, with 32-bit regs. */ -int dbg_cpu0_write(unsigned long adr, unsigned long data) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)&data, 4, 1, adr); - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - data = ntohl(data); - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU0))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x2, adr, 4))) - err = legacy_dbg_go((unsigned char*)&data, 4, 0); - } - debug("cpu0_write, adr 0x%X, data 0x%X, ret %i\n", adr, data, err); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -/* write multiple cpu registers to cpu0. This is assumed to be an OR32 CPU, with 32-bit regs. */ -int dbg_cpu0_write_block(unsigned long adr, unsigned long *data, int count) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)data, 4, count, adr); - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int i; - unsigned long writeaddr = adr; - err = APP_ERR_NONE; - for(i = 0; i < count; i++) { - err |= dbg_cpu0_write(writeaddr++, data[i]); - } - } - debug("cpu0_write_block, adr 0x%X, data[0] 0x%X, count %i, ret %i\n", adr, data[0], count, err); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -/* write a debug unit cpu module register - * Since OR32 debug module has only 1 register, - * adr is ignored (for now) */ -int dbg_cpu0_write_ctrl(unsigned long adr, unsigned char data) { - int err = APP_ERR_NONE; - uint32_t dataword = data; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) { - printf("Failed to set chain to 0x%X\n", DC_CPU0); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - if((err = adbg_ctrl_write(DBG_CPU0_REG_STATUS, &dataword, 2))) { - printf("Failed to write chain to 0x%X control reg 0x%X\n", DC_CPU0,DBG_CPU0_REG_STATUS ); // Only 2 bits: Reset, Stall - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU0))) - err = legacy_dbg_ctrl(data & 2, data &1); - } - debug("cpu0_write_ctrl(): set reg to 0x%X\n", data); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -/* read a register from cpu module of the debug unit. - * Currently, there is only 1 register, so we do not need to select it, adr is ignored - */ -int dbg_cpu0_read_ctrl(unsigned long adr, unsigned char *data) { - int err = APP_ERR_NONE; - uint32_t dataword; - pthread_mutex_lock(&dbg_access_mutex); - - // reset is bit 1, stall is bit 0 in *data - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) { - printf("Failed to set chain to 0x%X\n", DC_CPU0); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - if ((err = adbg_ctrl_read(DBG_CPU0_REG_STATUS, &dataword, 2))) { - printf("Failed to read chain 0x%X control reg 0x%X\n", DC_CPU0, DBG_CPU0_REG_STATUS); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - *data = dataword; - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int r, s; - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU0))) - err = legacy_dbg_ctrl_read(&r, &s); - *data = (r << 1) | s; - debug("api cpu0 read ctrl: r = %i, s = %i, data = %i\n", r, s, *data); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -// CPU1 Functions. Note that 2 CPUs are not currently supported by GDB, so these are never actually -// called from the GDB interface. They are included for completeness and future use. -// read a register from cpu1 -int dbg_cpu1_read(unsigned long adr, unsigned long *data) - { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU1))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(4, 1, adr, (void *) data); // All CPU register reads / writes are bursts - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU1))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x6, adr, 4))) - err = legacy_dbg_go((unsigned char*)data, 4, 1); - *data = ntohl(*data); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -// write a cpu register -int dbg_cpu1_write(unsigned long adr, unsigned long data) -{ - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)&data, 4, 1, adr); - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - data = ntohl(data); - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU1))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x2, adr, 4))) - err = legacy_dbg_go((unsigned char*)&data, 4, 0); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -// write a debug unit cpu module register -int dbg_cpu1_write_ctrl(unsigned long adr, unsigned char data) { - int err; - uint32_t dataword = data; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU1))) { - printf("Failed to set chain to 0x%X\n", DC_CPU1); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - if((err = adbg_ctrl_write(DBG_CPU1_REG_STATUS, &dataword, 2))) { - printf("Failed to write chain to 0x%X control reg 0x%X\n", DC_CPU1,DBG_CPU0_REG_STATUS ); // Only 2 bits: Reset, Stall - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU1))) - err = legacy_dbg_ctrl(data & 2, data & 1); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -// read a debug unit cpu module register -int dbg_cpu1_read_ctrl(unsigned long adr, unsigned char *data) { - int err; - uint32_t dataword; - pthread_mutex_lock(&dbg_access_mutex); - - // reset is bit 1, stall is bit 0 in *data - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU1))) { - printf("Failed to set chain to 0x%X\n", DC_CPU1); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - if ((err = adbg_ctrl_read(DBG_CPU1_REG_STATUS, &dataword, 2))) { - printf("Failed to read chain 0x%X control reg 0x%X\n", DC_CPU0, DBG_CPU1_REG_STATUS); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - *data = dataword; - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int r, s; - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU1))) - err = legacy_dbg_ctrl_read(&r, &s); - *data = (r << 1) | s; - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - - Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_rtl/dbg_comm_vpi.v =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_rtl/dbg_comm_vpi.v (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_rtl/dbg_comm_vpi.v (nonexistent) @@ -1,178 +0,0 @@ -////////////////////////////////////////////////////////////////////// -//// //// -//// dbg_comm_vpi.v //// -//// //// -//// //// -//// This file is part of the SoC/OpenRISC Development Interface //// -//// http://www.opencores.org/cores/DebugInterface/ //// -//// //// -//// //// -//// Author(s): //// -//// Igor Mohor (igorm@opencores.org) //// -//// Gyorgy Jeney (nog@sdf.lonestar.net) //// -//// Nathan Yawn (nathan.yawn@opencores.org) //// -//// //// -//// //// -////////////////////////////////////////////////////////////////////// -//// //// -//// Copyright (C) 2000-2008 Authors //// -//// //// -//// This source file may be used and distributed without //// -//// restriction provided that this copyright statement is not //// -//// removed from the file and that any derivative work contains //// -//// the original copyright notice and the associated disclaimer. //// -//// //// -//// This source file is free software; you can redistribute it //// -//// and/or modify it under the terms of the GNU Lesser General //// -//// Public License as published by the Free Software Foundation; //// -//// either version 2.1 of the License, or (at your option) any //// -//// later version. //// -//// //// -//// This source is distributed in the hope that it will be //// -//// useful, but WITHOUT ANY WARRANTY; without even the implied //// -//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// -//// PURPOSE. See the GNU Lesser General Public License for more //// -//// details. //// -//// //// -//// You should have received a copy of the GNU Lesser General //// -//// Public License along with this source; if not, download it //// -//// from http://www.opencores.org/lgpl.shtml //// -//// //// -////////////////////////////////////////////////////////////////////// -// -// CVS Revision History -// -// $Log: dbg_comm_vpi.v,v $ -// Revision 1.2 2009/05/17 20:55:57 Nathan -// Changed email address to opencores.org -// -// Revision 1.1 2008/07/26 17:33:20 Nathan -// Added debug comm module for use with VPI / network communication. -// -// Revision 1.1 2002/03/28 19:59:54 lampret -// Added bench directory -// -// Revision 1.1.1.1 2001/11/04 18:51:07 lampret -// First import. -// -// Revision 1.3 2001/09/24 14:06:13 mohor -// Changes connected to the OpenRISC access (SPR read, SPR write). -// -// Revision 1.2 2001/09/20 10:10:30 mohor -// Working version. Few bugs fixed, comments added. -// -// Revision 1.1.1.1 2001/09/13 13:49:19 mohor -// Initial official release. -// -// -// -// -// - - -`define JP_PORT "4567" -`define TIMEOUT_COUNT 6'd20 // 1/2 of a TCK clock will be this many SYS_CLK ticks. Must be less than 6 bits. - - module dbg_comm_vpi ( - SYS_CLK, - SYS_RSTN, - P_TMS, - P_TCK, - P_TRST, - P_TDI, - P_TDO - ); - - //parameter Tp = 20; - - output SYS_CLK; - output SYS_RSTN; - output P_TMS; - output P_TCK; - output P_TRST; - output P_TDI; - input P_TDO; - - reg SYS_CLK; - reg SYS_RSTN; - - - reg [4:0] memory; // [0:0]; - - - wire P_TCK; - wire P_TRST; - wire P_TDI; - wire P_TMS; - wire P_TDO; - - reg [3:0] in_word_r; - reg [5:0] clk_count; - - - // Provide the wishbone / CPU / system clock - initial - begin - SYS_CLK = 1'b0; - clk_count[5:0] <= `TIMEOUT_COUNT + 1; // Start with the timeout clock stopped - forever #5 SYS_CLK = ~SYS_CLK; - end - - // Provide the system reset - initial - begin - SYS_RSTN = 1'b1; - #200 SYS_RSTN = 1'b0; - #5000 SYS_RSTN = 1'b1; - end - - - // Handle commands from the upper level - initial - begin - in_word_r = 5'b0; - memory = 5'b0; - $jp_init(`JP_PORT); - #5500; // Wait until reset is complete - - while(1) - begin - #1; - $jp_in(memory); // This will not change memory[][] if no command has been sent from jp - if(memory[4]) // was memory[0][4] - begin - in_word_r = memory[3:0]; - memory = memory & 4'b1111; - clk_count = 6'b000000; // Reset the timeout clock in case jp wants to wait for a timeout / half TCK period - end - end - end - - - - // Send the output bit to the upper layer - always @ (P_TDO) - begin - $jp_out(P_TDO); - end - - - assign P_TCK = in_word_r[0]; - assign P_TRST = in_word_r[1]; - assign P_TDI = in_word_r[2]; - assign P_TMS = in_word_r[3]; - - - // Send timeouts / wait periods to the upper layer - always @ (posedge SYS_CLK) - begin - if(clk_count < `TIMEOUT_COUNT) clk_count[5:0] = clk_count[5:0] + 1; - else if(clk_count == `TIMEOUT_COUNT) begin - $jp_wait_time(); - clk_count[5:0] = clk_count[5:0] + 1; - end - // else it's already timed out, don't do anything - end - -endmodule - Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_rtl/dbg_comm.v =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_rtl/dbg_comm.v (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_rtl/dbg_comm.v (nonexistent) @@ -1,174 +0,0 @@ -////////////////////////////////////////////////////////////////////// -//// //// -//// dbg_comm.v //// -//// //// -//// //// -//// This file is part of the SoC/OpenRISC Development Interface //// -//// http://www.opencores.org/cores/DebugInterface/ //// -//// //// -//// //// -//// Author(s): //// -//// Igor Mohor (igorm@opencores.org) //// -//// Nathan Yawn (nathan.yawn@opencores.org) //// -//// //// -//// //// -//// //// -////////////////////////////////////////////////////////////////////// -//// //// -//// Copyright (C) 2000-2008 Authors //// -//// //// -//// This source file may be used and distributed without //// -//// restriction provided that this copyright statement is not //// -//// removed from the file and that any derivative work contains //// -//// the original copyright notice and the associated disclaimer. //// -//// //// -//// This source file is free software; you can redistribute it //// -//// and/or modify it under the terms of the GNU Lesser General //// -//// Public License as published by the Free Software Foundation; //// -//// either version 2.1 of the License, or (at your option) any //// -//// later version. //// -//// //// -//// This source is distributed in the hope that it will be //// -//// useful, but WITHOUT ANY WARRANTY; without even the implied //// -//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// -//// PURPOSE. See the GNU Lesser General Public License for more //// -//// details. //// -//// //// -//// You should have received a copy of the GNU Lesser General //// -//// Public License along with this source; if not, download it //// -//// from http://www.opencores.org/lgpl.shtml //// -//// //// -////////////////////////////////////////////////////////////////////// -// -// CVS Revision History -// -// $Log: dbg_comm.v,v $ -// Revision 1.3 2009/05/17 20:55:57 Nathan -// Changed email address to opencores.org -// -// Revision 1.2 2008/07/22 18:23:25 Nathan -// Added clock and reset outputs to make simulation system simpler. Fixed P_TRST signal name. Added fflush calls to make file IO work as quickly as possible. Write the data out bit on falling clock edge. Cleanup. -// -// Revision 1.1 2002/03/28 19:59:54 lampret -// Added bench directory -// -// Revision 1.1.1.1 2001/11/04 18:51:07 lampret -// First import. -// -// Revision 1.3 2001/09/24 14:06:13 mohor -// Changes connected to the OpenRISC access (SPR read, SPR write). -// -// Revision 1.2 2001/09/20 10:10:30 mohor -// Working version. Few bugs fixed, comments added. -// -// Revision 1.1.1.1 2001/09/13 13:49:19 mohor -// Initial official release. -// -// -// -// -// - - - -`define GDB_IN "e:/tmp/gdb_in.dat" -`define GDB_OUT "e:/tmp/gdb_out.dat" - - -module dbg_comm( - SYS_CLK, - SYS_RSTN, - P_TMS, - P_TCK, - P_TRST, - P_TDI, - P_TDO - ); - -parameter Tp = 20; - -output SYS_CLK; -output SYS_RSTN; -output P_TMS; -output P_TCK; -output P_TRST; -output P_TDI; -input P_TDO; - -// Signal for the whole system -reg SYS_CLK; -reg SYS_RSTN; - -// For handling data from the input file -integer handle1, handle2; -reg [4:0] memory[0:0]; - -wire P_TCK; -wire P_TRST; -wire P_TDI; -wire P_TMS; -wire P_TDO; - -// Temp. signal -reg [3:0] in_word_r; - - - -// Provide the wishbone / CPU / system clock -initial -begin - SYS_CLK = 1'b0; - forever #5 SYS_CLK = ~SYS_CLK; -end - -// Provide the system reset -initial -begin - SYS_RSTN = 1'b1; - #200 SYS_RSTN = 1'b0; - #5000 SYS_RSTN = 1'b1; -end - -// Set the initial state of the JTAG pins -initial -begin - in_word_r = 4'h0; // This sets the TRSTN output active... -end - -// Handle input from a file for the JTAG pins -initial -begin - #5500; // Wait until reset is complete - while(1) - begin - #Tp; - $readmemh(`GDB_OUT, memory); - if(!(memory[0] & 5'b10000)) - begin - in_word_r = memory[0][3:0]; - handle1 = $fopen(`GDB_OUT); - $fwrite(handle1, "%h", 5'b10000 | memory[0]); // To ack that we read dgb_out.dat - $fflush(handle1); - $fclose(handle1); - end - end -end - -// Send the current state of the JTAG output to a file -always @ (P_TDO or negedge P_TCK) -begin - handle2 = $fopen(`GDB_IN); - $fdisplay(handle2, "%b", P_TDO); - $fflush(handle2); - $fclose(handle2); -end - -// Note these must match the bit definitions in the JTAG bridge program (adv_jtag_bridge) -assign P_TCK = in_word_r[0]; -assign P_TRST = in_word_r[1]; -assign P_TDI = in_word_r[2]; -assign P_TMS = in_word_r[3]; - - -endmodule // TAP - Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/altera_virtual_jtag.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/altera_virtual_jtag.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/altera_virtual_jtag.h (nonexistent) @@ -1,19 +0,0 @@ -#ifndef _ALTERA_VIRTUAL_JTAG_H_ -#define _ALTERA_VIRTUAL_JTAG_H_ - -// Contains constants relevant to the Altera Virtual JTAG -// device, which are not included in the BSDL. -// As of this writing, these are constant across every -// device which supports virtual JTAG. - -// These are commands for the FPGA's IR -#define ALTERA_CYCLONE_CMD_VIR 0x0E -#define ALTERA_CYCLONE_CMD_VDR 0x0C - -// These defines are for the virtual IR (not the FPGA's) -// The virtual TAP was defined in hardware to match the OpenCores native -// TAP in both IR size and DEBUG command. -#define ALT_VJTAG_IR_SIZE 4 -#define ALT_VJTAG_CMD_DEBUG 0x8 - -#endif Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/bsdl.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/bsdl.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/bsdl.h (nonexistent) @@ -1,36 +0,0 @@ -#ifndef _BSDL_H_ -#define _BSDL_H_ - -#include - -// Used by lower levels. -// should not be used by higher levels (i.e. anything that calls -// the API functions). -struct bsdlinfo_node { - char *name; - uint32_t idcode; - uint32_t idcode_mask; - int IR_size; - uint32_t cmd_debug; - uint32_t cmd_user1; - uint32_t cmd_idcode; - struct bsdlinfo_node *next; -}; - -typedef struct bsdlinfo_node bsdlinfo; - - -#define IDCODE_INVALID 0xFFFFFFFF -#define TAP_CMD_INVALID 0XFFFFFFFF - - -void bsdl_init(void); -void bsdl_add_directory(const char *dirname); - -const char * bsdl_get_name(uint32_t idcode); -int bsdl_get_IR_size(uint32_t idcode); -uint32_t bsdl_get_debug_cmd(uint32_t idcode); -uint32_t bsdl_get_user1_cmd(uint32_t idcode); -uint32_t bsdl_get_idcode_cmd(uint32_t idcode); - -#endif Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/dbg_api.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/dbg_api.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/dbg_api.h (nonexistent) @@ -1,31 +0,0 @@ -#ifndef _DBG_API_H_ -#define _DBG_API_H_ - -#include -#include - - - -// API for GDB -int dbg_wb_read32(unsigned long adr, unsigned long *data); -int dbg_wb_write32(unsigned long adr, unsigned long data); -int dbg_wb_write16(unsigned long adr, uint16_t data); -int dbg_wb_write8(unsigned long adr, uint8_t data); -int dbg_wb_read_block32(unsigned long adr, unsigned long *data, int len); -int dbg_wb_read_block16(unsigned long adr, uint16_t *data, int len); -int dbg_wb_read_block8(unsigned long adr, uint8_t *data, int len); -int dbg_wb_write_block32(unsigned long adr, unsigned long *data, int len); -int dbg_wb_write_block16(unsigned long adr, uint16_t *data, int len); -int dbg_wb_write_block8(unsigned long adr, uint8_t *data, int len); -int dbg_cpu0_read(unsigned long adr, unsigned long *data); -int dbg_cpu0_read_block(unsigned long adr, unsigned long *data, int count); -int dbg_cpu0_write(unsigned long adr, unsigned long data); -int dbg_cpu0_write_block(unsigned long adr, unsigned long *data, int count); -int dbg_cpu0_write_ctrl(unsigned long adr, unsigned char data); -int dbg_cpu0_read_ctrl(unsigned long adr, unsigned char *data); -//int dbg_cpu1_read(unsigned long adr, unsigned long *data); -//int dbg_cpu1_write(unsigned long adr, unsigned long data); -//int dbg_cpu1_write_reg(unsigned long adr, unsigned char data); -//int dbg_cpu1_read_ctrl(unsigned long adr, unsigned char *data); - -#endif Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_xpc_dlc9.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_xpc_dlc9.c (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_xpc_dlc9.c (nonexistent) @@ -1,415 +0,0 @@ -/* cable_xpc_dlc9.c - Xilinx Platform Cable (DLC9) driver for the Advanced JTAG Bridge - Copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.org - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#include -#include -#include // for usleep() -#include // for sleep() - - -#include "usb.h" // libusb header -#include "cable_common.h" -#include "errcodes.h" - -#define USB_TIMEOUT 500 - -// Note that this is based on the UrJTAG driver for the XPC-USB, -// which was 'experimental' at the time. -// It only supports bit-bang mode, and therefore will not be fast. - -// USB constants for the DLC9 -#define XPCUSB_VID 0x3fd -#define XPCUSB_PID 0x08 - -// Bit meanings in the command byte sent to the DLC9 -// DLC9 has no TRST bit -#define XPCUSB_CMD_TDI 0x01 -#define XPCUSB_CMD_TDO 0x01 -#define XPCUSB_CMD_TMS 0x02 -#define XPCUSB_CMD_TCK 0x04 -#define XPCUSB_CMD_PROG 0x08 - - -static struct usb_device *device; - - -/////////////////////////////////////////////////////////////////////////////// -/*----- Functions for the Xilinx Platform Cable USB (Model DLC9) */ -///////////////////////////////////////////////////////////////////////////// - - -static int xpcu_request_28(struct usb_dev_handle *xpcu, int value) -{ - // Maybe clock speed setting? - if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0028, value, NULL, 0, USB_TIMEOUT)<0) - { - fprintf(stderr, "Error sending usb_control_msg(0x28.x)\n"); - return APP_ERR_USB; - } - - return APP_ERR_NONE; -} - - -static int xpcu_raise_ioa5(struct usb_dev_handle *xpcu) -{ - if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0018, 0x0000, NULL, 0, USB_TIMEOUT)<0) - { - fprintf(stderr, "Error sending usb_control_msg(0x18.0x00) (raise IOA.5{\n"); - return APP_ERR_USB; - } - - return APP_ERR_NONE; -} - -static int xpcu_select_gpio(struct usb_dev_handle *xpcu, int chain) -{ - if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0052, chain, NULL, 0, USB_TIMEOUT)<0) - { - fprintf(stderr, "Error sending usb_control_msg(0x52.x) (select gpio)\n"); - return APP_ERR_USB; - } - - return APP_ERR_NONE; -} - -static int xpcu_read_firmware_version(struct usb_dev_handle *xpcu, uint16_t *buf) -{ - if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0000, (char*)buf, 2, USB_TIMEOUT)<0) - { - fprintf(stderr,"Error sending usb_control_msg(0x50.0) (read_firmware_version)\n"); - return APP_ERR_USB; - } - return APP_ERR_NONE; -} - -static int xpcu_read_cpld_version(struct usb_dev_handle *xpcu, uint16_t *buf) -{ - if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0001, (char*)buf, 2, USB_TIMEOUT)<0) - { - fprintf(stderr, "Error sending usb_control_msg(0x50.1) (read_cpld_version)\n"); - return APP_ERR_USB; - } - return APP_ERR_NONE; -} - - -static int xpcusb_enumerate_bus(void) -{ - int flag; // for USB bus scanning stop condition - struct usb_bus *bus; // pointer on the USB bus - - // board detection - usb_init(); - usb_find_busses(); - usb_find_devices(); - - flag = 0; - - for (bus = usb_get_busses(); bus; bus = bus->next) - { - for (device = bus->devices; device; device = device->next) - { - if (device->descriptor.idVendor == XPCUSB_VID && - device->descriptor.idProduct == XPCUSB_PID) - { - flag = 1; - fprintf(stderr, "Found Xilinx Platform Cable USB (DLC9)\n"); - return APP_ERR_NONE; - } - } - if (flag) - break; - } - - fprintf(stderr, "Failed to find Xilinx Platform Cable USB\n"); - return APP_ERR_CABLENOTFOUND; -} - - -int cable_xpcusb_init() -{ - int err = APP_ERR_NONE; - - // Process to reset the XPC USB (DLC9) - if(err |= xpcusb_enumerate_bus()) { - return err; - } - - usb_dev_handle *h_device = usb_open(device); - - if(h_device == NULL) - { - fprintf(stderr, "Init failed to open USB device for reset\n"); - return APP_ERR_USB; - } - - if(usb_reset(h_device) != APP_ERR_NONE) - fprintf(stderr, "Failed to reset XPC-USB\n"); - - usb_close(h_device); - - // Wait for reset!!! - sleep(1); - - // Do device initialization - if(err |= xpcusb_enumerate_bus()) - return err; - - h_device = usb_open(device); - if(h_device == NULL) - { - fprintf(stderr, "Init failed to open USB device for initialization\n"); - return APP_ERR_USB; - } - - // set the configuration - if (usb_set_configuration(h_device, device->config->bConfigurationValue)) - { - usb_close(h_device); - fprintf(stderr, "USB-reset failed to set configuration\n"); - return APP_ERR_USB; - } - - while (usb_claim_interface(h_device, device->config->interface->altsetting->bInterfaceNumber)); - - // DO DEVICE-SPECIFIC INIT HERE - // Don't mess with the order here, it's easy to break. - - // Maybe set the clock speed? - if(xpcu_request_28(h_device, 0x11) != APP_ERR_NONE) { - fprintf(stderr, "Request 28 (set clock speed?) failed.\n"); - } - - // Set internal TCK,TMS,TDO to 0 - if(usb_control_msg(h_device, 0x40, 0xB0, 0x0030, 0x08, NULL, 0, USB_TIMEOUT)!= APP_ERR_NONE) { - fprintf(stderr, "usb_control_msg(0x30.0x00) (write port E) failed\n"); - } - - // Read firmware version (constant embedded in firmware) - uint16_t buf; - - if(xpcu_read_firmware_version(h_device, &buf) != APP_ERR_NONE) { - fprintf(stderr, "Failed to read firmware version.\n"); - } - else { - printf("firmware version = 0x%04X (%u)\n", buf, buf); - } - - // Read CPLD version (uses the internal GPIF interface) - if(xpcu_read_cpld_version(h_device, &buf) != APP_ERR_NONE) { - fprintf(stderr, "Failed to read CPLD version.\n"); - } - else - { - printf("cable CPLD version = 0x%04X (%u)\n", buf, buf); - if(buf == 0) { - printf("Warning: version '0' can't be correct. Please try resetting the cable\n"); - } - } - - // Set IOA bit 5, which enables output buffers - if(xpcu_raise_ioa5(h_device) != APP_ERR_NONE) { - fprintf(stderr, "Failed to enable XPC output buffers\n"); - } - - // access external chain for normal operation - if(xpcu_select_gpio(h_device, 0) != APP_ERR_NONE) { - fprintf(stderr, "Failed to select external JTAG chain\n"); - } - - // Init all done, release cable - if (usb_release_interface(h_device, device->config->interface->altsetting->bInterfaceNumber)){ - usb_close(h_device); - fprintf(stderr, "USB-out failed to release interface\n"); - return APP_ERR_USB; - } - - usb_close(h_device); - - return APP_ERR_NONE; -} - - -int cable_xpcusb_out(uint8_t value) -{ - int rv; // to catch return values of functions - usb_dev_handle *h_device; // handle on the ubs device - uint8_t out; - - // open the device - h_device = usb_open(device); - if (h_device == NULL){ - usb_close(h_device); - fprintf(stderr, "USB-out failed to open device\n"); - return APP_ERR_USB; - } - - // set the configuration - if (usb_set_configuration(h_device, device->config->bConfigurationValue)) - { - usb_close(h_device); - fprintf(stderr, "USB-out failed to set configuration\n"); - return APP_ERR_USB; - } - - // wait until device is ready - while (usb_claim_interface(h_device, device->config->interface->altsetting->bInterfaceNumber)); - - // send the buffer - // Translate to USB blaster protocol - out = 0; - if(value & TCLK_BIT) - out |= XPCUSB_CMD_TCK; - if(value & TDI_BIT) - out |= XPCUSB_CMD_TDI; - if(value & TMS_BIT) - out |= XPCUSB_CMD_TMS; - - out |= XPCUSB_CMD_PROG; // Set output PROG (always necessary) - - /* debug - if(value & TDI_BIT) - printf("Write 1\n"); - else - printf("Write 0\n"); - */ - - rv = usb_control_msg(h_device, 0x40, 0xB0, 0x0030, out, NULL, 0, USB_TIMEOUT); - if (rv < 0){ - fprintf(stderr, "\nFailed to send a write control message (rv = %d):\n%s\n", rv, usb_strerror()); - } - - // release the interface cleanly - if (usb_release_interface(h_device, device->config->interface->altsetting->bInterfaceNumber)){ - fprintf(stderr, "Warning: failed to release usb interface after write\n"); - } - - // close the device - usb_close(h_device); - return APP_ERR_NONE; -} - - -int cable_xpcusb_inout(uint8_t value, uint8_t *inval) -{ - int rv; // to catch return values of functions - usb_dev_handle *h_device; // handle on the usb device - char ret = 0; - uint8_t out; - - // Translate to USB blaster protocol - out = 0; - if(value & TCLK_BIT) - out |= XPCUSB_CMD_TCK; - if(value & TDI_BIT) - out |= XPCUSB_CMD_TDI; - if(value & TMS_BIT) - out |= XPCUSB_CMD_TMS; - - out |= XPCUSB_CMD_PROG; // Set output PROG (always necessary) - - // open the device - h_device = usb_open(device); - if (h_device == NULL){ - usb_close(h_device); - return APP_ERR_USB; - } - - // set the configuration - if (usb_set_configuration(h_device, device->config->bConfigurationValue)){ - usb_close(h_device); - return APP_ERR_USB; - } - - // wait until device is ready - while (usb_claim_interface(h_device, device->config->interface->altsetting->bInterfaceNumber)); - - // Send the output - rv = usb_control_msg(h_device, 0x40, 0xB0, 0x0030, out, NULL, 0, USB_TIMEOUT); - if (rv < 0){ - fprintf(stderr, "\nFailed to send a write control message (rv = %x):\n%s\n", rv, usb_strerror()); - goto usbblaster_in_fail; - } - - - // receive the response - rv = usb_control_msg(h_device, 0xC0, 0xB0, 0x0038, 0, (char*)&ret, 1, USB_TIMEOUT); - if (rv < 0){ - fprintf(stderr, "\nFailed to execute a read control message:\n%s\n", usb_strerror()); - goto usbblaster_in_fail; - } - - - // release the interface cleanly - if (usb_release_interface(h_device, device->config->interface->altsetting->bInterfaceNumber)){ - fprintf(stderr, "Warning: failed to release USB interface after read\n"); - usb_close(h_device); - return APP_ERR_USB; - } - - // close the device - usb_close(h_device); - - /* debug - if(value & TDI_BIT) - printf("Write 1, "); - else - printf("Write 0, "); - */ - - if(ret & XPCUSB_CMD_TDO) - *inval = 1; - else - *inval = 0; - - //printf("Read 0\n"); - return APP_ERR_NONE; - -usbblaster_in_fail: - usb_release_interface(h_device, device->config->interface->altsetting->bInterfaceNumber); - usb_close(h_device); - return APP_ERR_USB; -} - - -// Xilinx couldn't be like everyone else. Oh, no. -// For some reason, "set data/drop TCK" then "read data/raise TCK" won't work. -// So we have our very own bit read/write function. @whee. -int cable_xpcusb_read_write_bit(uint8_t packet_out, uint8_t *bit_in) { - uint8_t data = TRST_BIT; // TRST is active low, don't clear unless /set/ in 'packet' - int err = APP_ERR_NONE; - - /* Write data, drop clock */ - if(packet_out & TDO) data |= TDI_BIT; - if(packet_out & TMS) data |= TMS_BIT; - if(packet_out & TRST) data &= ~TRST_BIT; - - err |= cable_xpcusb_inout(data, bit_in); // read in bit, set data, drop clock - err |= cable_xpcusb_out(data|TCLK_BIT); // clk hi - - return err; -} - - -int cable_xpcusb_opt(int c, char *str) -{ - fprintf(stderr, "Unknown parameter '%c'\n", c); - return APP_ERR_BAD_PARAM; -} - Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_usbblaster.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_usbblaster.c (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_usbblaster.c (nonexistent) @@ -1,639 +0,0 @@ -/* cable_usbblaster.c - Altera USB Blaster driver for the Advanced JTAG Bridge - Copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.org - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#include -#include -#include // for usleep() -#include // for sleep() -#include // for htons() - -#include "usb.h" // libusb header -#include "cable_common.h" -#include "errcodes.h" - -#define debug(...) //fprintf(stderr, __VA_ARGS__ ) - -// USB constants for the USB Blaster -// Valid endpoints: 0x81, 0x02, 0x06, 0x88 -#define EP2 0x02 -#define EP1 0x81 -#define ALTERA_VID 0x09FB -#define ALTERA_PID 0x6001 - -//#define USB_TIMEOUT 500 -#define USB_TIMEOUT 10000 - - -// Bit meanings in the command byte sent to the USB-Blaster -#define USBBLASTER_CMD_TCK 0x01 -#define USBBLASTER_CMD_TMS 0x02 -#define USBBLASTER_CMD_nCE 0x04 /* should be left low */ -#define USBBLASTER_CMD_nCS 0x08 /* must be set for byte-shift mode reads to work */ -#define USBBLASTER_CMD_TDI 0x10 -#define USBBLASTER_CMD_OE 0x20 /* appears necessary to set it to make everything work */ -#define USBBLASTER_CMD_READ 0x40 -#define USBBLASTER_CMD_BYTESHIFT 0x80 - - -static struct usb_device *usbblaster_device; - -static char *data_out_scratchpad = NULL; -static int data_out_scratchpad_size = 0; -static char *data_in_scratchpad = NULL; -static int data_in_scratchpad_size = 0; - -/////////////////////////////////////////////////////////////////////////////// -/*-------------------------------------[ USB Blaster specific functions ]---*/ -///////////////////////////////////////////////////////////////////////////// - - -static int usbblaster_start_interface(struct usb_dev_handle *xpcu) -{ - // Need to send a VENDOR request OUT, request = GET_STATUS - // Other parameters are ignored - if(usb_control_msg(xpcu, (USB_ENDPOINT_OUT | USB_TYPE_VENDOR), USB_REQ_GET_STATUS, - 0, 0, NULL, 0, 1000)<0) - { - perror("usb_control_msg(start interface)"); - return APP_ERR_USB; - } - - return APP_ERR_NONE; -} - - -static int usbblaster_read_firmware_version(struct usb_dev_handle *xpcu, uint16_t *buf) -{ - if(usb_control_msg(xpcu, 0xC0, 0x90, 0, 3, (char*)buf, 2, USB_TIMEOUT)<0) - { - perror("usb_control_msg(0x90.0) (read_firmware_version)"); - return APP_ERR_USB; - } - - // Swap endian - *buf = htons(*buf); - //*buf = (*buf << 8) | (*buf >> 8); - - return APP_ERR_NONE; -} - - - -static int usbblaster_enumerate_bus(void) -{ - int flag; // for USB bus scanning stop condition - struct usb_bus *bus; // pointer on the USB bus - - // board detection - usb_init(); - usb_find_busses(); - usb_find_devices(); - - flag = 0; - - for (bus = usb_get_busses(); bus; bus = bus->next) - { - for (usbblaster_device = bus->devices; usbblaster_device; usbblaster_device = usbblaster_device->next) - { - if (usbblaster_device->descriptor.idVendor == ALTERA_VID && - usbblaster_device->descriptor.idProduct == ALTERA_PID) - { - flag = 1; - fprintf(stderr, "Found Altera USB-Blaster\n"); - return APP_ERR_NONE; - } - } - if (flag) - break; - } - - fprintf(stderr, "Failed to find USB-Blaster\n"); - return APP_ERR_CABLENOTFOUND; -} - - -int cable_usbblaster_init(){ - int err = APP_ERR_NONE; - - // Process to reset the usb blaster - if(err |= usbblaster_enumerate_bus()) { - return err; - } - - usb_dev_handle *h_device = usb_open(usbblaster_device); - - if(h_device == NULL) - { - fprintf(stderr, "Init failed to open USB device for reset\n"); - return APP_ERR_USB; - } - - if(usb_reset(h_device) != APP_ERR_NONE) - fprintf(stderr, "Failed to reset USB Blaster\n"); - - usb_close(h_device); - - // Wait for reset!!! - sleep(1); - - // Do device initialization - if(err |= usbblaster_enumerate_bus()) - return err; - - h_device = usb_open(usbblaster_device); - if(h_device == NULL) - { - fprintf(stderr, "Init failed to open USB device for initialization\n"); - return APP_ERR_USB; - } - - // set the configuration - if (usb_set_configuration(h_device, usbblaster_device->config->bConfigurationValue)) - { - usb_close(h_device); - fprintf(stderr, "USB-reset failed to set configuration\n"); - return APP_ERR_NONE; - } - - while (usb_claim_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)); - - //usb_clear_halt(h_device, EP1); - //usb_clear_halt(h_device, EP2); - - // IMPORTANT: DO NOT SEND A REQUEST TYPE "CLASS" OR TYPE "RESERVED". This may stall the EP. - - // Some clones need this before they will start processing IN/OUT requests - if(usbblaster_start_interface(h_device) != APP_ERR_NONE) - fprintf(stderr, "Failed to start remote interface\n"); - - uint16_t buf; - if(err |= usbblaster_read_firmware_version(h_device, &buf)) - { - usb_close(h_device); - fprintf(stderr, "Failed to read firmware version\n"); - return err; - } - else - { - printf("firmware version = 0x%04X (%u)\n", buf, buf); - } - - - // USB blaster is expecting us to read 2 bytes, which are useless to us... - char ret[2]; - int rv = usb_bulk_read(h_device, EP1, ret, 2, USB_TIMEOUT); - if (rv < 0){ // But if we fail, who cares? - fprintf(stderr, "\nWarning: Failed to read post-init bytes from the EP1 FIFO (%i):\n%s", rv, usb_strerror()); - } - - if (usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)){ - usb_close(h_device); - fprintf(stderr, "USB-out failed to release interface\n"); - return APP_ERR_USB; - } - - usb_close(h_device); - - data_out_scratchpad = (char *) malloc(64); - data_out_scratchpad_size = 64; - data_in_scratchpad = (char *) malloc(64); - data_in_scratchpad_size = 64; - - return APP_ERR_NONE; -} - - -int cable_usbblaster_out(uint8_t value) -{ - int rv; // to catch return values of functions - usb_dev_handle *h_device; // handle on the ubs device - char out; - int err = APP_ERR_NONE; - - // open the device - h_device = usb_open(usbblaster_device); - if (h_device == NULL){ - usb_close(h_device); - fprintf(stderr, "USB-out failed to open device\n"); - return APP_ERR_USB; - } - - // set the configuration - if (usb_set_configuration(h_device, usbblaster_device->config->bConfigurationValue)) - { - usb_close(h_device); - fprintf(stderr, "USB-out failed to set configuration\n"); - return APP_ERR_USB; - } - - // wait until device is ready - while (usb_claim_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)); - - out = (USBBLASTER_CMD_OE | USBBLASTER_CMD_nCS); // Set output enable (appears necessary) and nCS (necessary for byte-shift reads) - - // Translate to USB blaster protocol - // USB-Blaster has no TRST pin - if(value & TCLK_BIT) - out |= USBBLASTER_CMD_TCK; - if(value & TDI_BIT) - out |= USBBLASTER_CMD_TDI; - if(value & TMS_BIT) - out |= USBBLASTER_CMD_TMS; - - - rv = usb_bulk_write(h_device, EP2, &out, 1, USB_TIMEOUT); - if (rv != 1){ - fprintf(stderr, "\nFailed to write to the FIFO (rv = %d):\n%s", rv, usb_strerror()); - err |= APP_ERR_USB; - } - - // release the interface cleanly - if (usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)){ - fprintf(stderr, "Warning: failed to release usb interface after write\n"); - err |= APP_ERR_USB; - } - - // close the device - usb_close(h_device); - return err; -} - - -int cable_usbblaster_inout(uint8_t value, uint8_t *in_bit) -{ - int rv; // to catch return values of functions - usb_dev_handle *h_device; // handle on the usb device - char ret[3] = {0,0,0}; // Two useless bytes (0x31,0x60) always precede the useful byte - char out; - - out = (USBBLASTER_CMD_OE | USBBLASTER_CMD_nCS); // Set output enable (?) and nCS (necessary for byte-shift reads) - out |= USBBLASTER_CMD_READ; - - // Translate to USB blaster protocol - // USB-Blaster has no TRST pin - if(value & TCLK_BIT) - out |= USBBLASTER_CMD_TCK; - if(value & TDI_BIT) - out |= USBBLASTER_CMD_TDI; - if(value & TMS_BIT) - out |= USBBLASTER_CMD_TMS; - - - // open the device - h_device = usb_open(usbblaster_device); - if (h_device == NULL){ - return APP_ERR_USB; - } - - // set the configuration - if (usb_set_configuration(h_device, usbblaster_device->config->bConfigurationValue)){ - usb_close(h_device); - return APP_ERR_USB; - } - - // wait until device is ready - while (usb_claim_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)); - - // Send a read request - rv = usb_bulk_write(h_device, EP2, &out, 1, USB_TIMEOUT); - if (rv != 1){ - fprintf(stderr, "\nFailed to write a read request to the EP2 FIFO:\n%s", usb_strerror()); - usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber); - usb_close(h_device); - return APP_ERR_USB; - } - - - // receive the response - // Sometimes, we do a read but just get the useless 0x31,0x60 chars... - // retry until we get a 3rd byte (with real data), for a reasonable number of retries. - int retries = 0; - do { - rv = usb_bulk_read(h_device, EP1, ret, 3, USB_TIMEOUT); - if (rv < 0){ - fprintf(stderr, "\nFailed to read from the EP1 FIFO (%i):\n%s", rv, usb_strerror()); - usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber); - usb_close(h_device); - return APP_ERR_USB; - } - - // fprintf(stderr, "Read %i bytes: 0x%X, 0x%X, 0x%X\n", rv, ret[0], ret[1], ret[2]); - retries++; - } - while((rv < 3) && (retries < 20)); - - - // release the interface cleanly - if (usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)){ - fprintf(stderr, "Warning: failed to release USB interface after read\n"); - usb_close(h_device); - return APP_ERR_USB; - } - - // close the device - usb_close(h_device); - - *in_bit = (ret[2] & 0x01); /* TDO is bit 0. USB-Blaster may also set bit 1. */ - return APP_ERR_NONE; -} - - -// The usbblaster transfers the bits in the stream in the following order: -// bit 0 of the first byte received ... bit 7 of the first byte received -// bit 0 of second byte received ... etc. -int cable_usbblaster_write_stream(uint32_t *stream, int len_bits, int set_last_bit) { - int rv; // to catch return values of functions - usb_dev_handle *h_device; // handle on the ubs device - unsigned int bytes_to_transfer, leftover_bit_length; - uint32_t leftover_bits; - unsigned char i; - int err = APP_ERR_NONE; - - //printf("cable_usbblaster_write_stream(0x%X, %d, %i)\n", stream, len, set_last_bit); - - // This routine must transfer at least 8 bits. Additionally, TMS (the last bit) - // cannot be set by 'byte shift mode'. So we need at least 8 bits to transfer, - // plus one bit to send along with TMS. - bytes_to_transfer = len_bits / 8; - leftover_bit_length = len_bits - (bytes_to_transfer * 8); - - if((!leftover_bit_length) && set_last_bit) { - bytes_to_transfer -= 1; - leftover_bit_length += 8; - } - - //printf("bytes_to_transfer: %d. leftover_bit_length: %d\n", bytes_to_transfer, leftover_bit_length); - - // Not enough bits for high-speed transfer. bit-bang. - if(bytes_to_transfer == 0) { - return cable_common_write_stream(stream, len_bits, set_last_bit); - } - - // Bitbang functions leave clock high. USBBlaster assumes clock low at the start of a burst. - // Lower the clock. - err |= cable_usbblaster_out(0); - - // Set leftover bits - leftover_bits = (stream[bytes_to_transfer>>2] >> ((bytes_to_transfer & 0x3) * 8)) & 0xFF; - - //printf("leftover_bits: 0x%X, LSB_first_xfer = %d\n", leftover_bits, LSB_first_xfer); - - // open the device - h_device = usb_open(usbblaster_device); - if (h_device == NULL){ - usb_close(h_device); - fprintf(stderr, "USBBlaster_write_stream failed to open device\n"); - return APP_ERR_USB; - } - - // set the configuration - if (usb_set_configuration(h_device, usbblaster_device->config->bConfigurationValue)) - { - usb_close(h_device); - fprintf(stderr, "USBBlaster_write_stream failed to set configuration\n"); - return APP_ERR_USB; - } - - // wait until device is ready - while (usb_claim_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)); - - - // Copy stream into out. Not pretty, but better than changing the interface to the upper layers; - // 32 bits are easier to work with than 8 bits in upper layers. - if(data_out_scratchpad_size < (bytes_to_transfer+1)) { - free(data_out_scratchpad); - data_out_scratchpad = (char *) malloc(bytes_to_transfer+1); // free/malloc instead of realloc will save copy time - if(data_out_scratchpad == NULL) { - usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber); - usb_close(h_device); - return APP_ERR_MALLOC; - } - data_out_scratchpad_size = bytes_to_transfer+1; - } - - data_out_scratchpad[0] = USBBLASTER_CMD_BYTESHIFT | (bytes_to_transfer & 0x3F); - for(i = 0; i < bytes_to_transfer; i++) { - data_out_scratchpad[i+1] = (stream[i>>2] >> (8*(i&0x3))) & 0xFF; - } - - - /* - printf("Data packet: "); - for(i = 0; i <= bytes_to_transfer; i++) - printf("0x%X ", out[i]); - printf("\n"); - */ - - rv = usb_bulk_write(h_device, EP2, data_out_scratchpad, bytes_to_transfer+1, USB_TIMEOUT); - if (rv != (bytes_to_transfer+1)){ - fprintf(stderr, "\nFailed to write to the FIFO (rv = %d):\n%s", rv, usb_strerror()); - err |= APP_ERR_USB; - } - - // release the interface cleanly - if (usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)){ - fprintf(stderr, "Warning: failed to release usb interface after stream write\n"); - } - - // close the device - usb_close(h_device); - - // if we have a number of bits not divisible by 8, or we need to set TMS... - if(leftover_bit_length != 0) { - //printf("Doing leftovers: (0x%X, %d, %d)\n", leftover_bits, leftover_bit_length, set_last_bit); - return cable_common_write_stream(&leftover_bits, leftover_bit_length, set_last_bit); - } - - return err; -} - - -int cable_usbblaster_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) { - int rv; // to catch return values of functions - usb_dev_handle *h_device; // handle on the ubs device - unsigned int bytes_received = 0; - unsigned int bytes_to_transfer, leftover_bit_length; - uint32_t leftover_bits, leftovers_received = 0; - unsigned char i; - int retval = APP_ERR_NONE; - - debug("cable_usbblaster_read_stream(0x%X, %d, %i)\n", outstream[0], len_bits, set_last_bit); - - // This routine must transfer at least 8 bits. Additionally, TMS (the last bit) - // cannot be set by 'byte shift mode'. So we need at least 8 bits to transfer, - // plus one bit to send along with TMS. - bytes_to_transfer = len_bits / 8; - leftover_bit_length = len_bits - (bytes_to_transfer * 8); - - if((!leftover_bit_length) && set_last_bit) { - bytes_to_transfer -= 1; - leftover_bit_length += 8; - } - - //printf("RD bytes_to_transfer: %d. leftover_bit_length: %d\n", bytes_to_transfer, leftover_bit_length); - - // Not enough bits for high-speed transfer. bit-bang. - if(bytes_to_transfer == 0) { - return cable_common_read_stream(outstream, instream, len_bits, set_last_bit); - //retval |= cable_common_read_stream(&leftover_bits, &leftovers_received, leftover_bit_length, set_last_bit); - } - - // Bitbang functions leave clock high. USBBlaster assumes clock low at the start of a burst. - // Lower the clock. - retval |= cable_usbblaster_out(0); - - // Zero the input, since we add new data by logical-OR - for(i = 0; i < (len_bits/32); i++) - instream[i] = 0; - if(len_bits % 32) - instream[i] = 0; - - // Set leftover bits - leftover_bits = (outstream[bytes_to_transfer>>2] >> ((bytes_to_transfer & 0x3) * 8)) & 0xFF; - debug("leftover_bits: 0x%X\n", leftover_bits); - - // open the device - h_device = usb_open(usbblaster_device); - if (h_device == NULL){ - usb_close(h_device); - fprintf(stderr, "USBBlaster_read_stream failed to open device\n"); - return APP_ERR_USB; - } - - // set the configuration - if (usb_set_configuration(h_device, usbblaster_device->config->bConfigurationValue)) - { - usb_close(h_device); - fprintf(stderr, "USBBlaster_read_stream failed to set configuration\n"); - return APP_ERR_USB; - } - - // wait until device is ready - while (usb_claim_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)); - - - - // Copy stream into out. Not pretty, but better than changing the interface to the upper layers; - // 32 bits are easier to work with than 8 bits in upper layers. - if(data_out_scratchpad_size < (bytes_to_transfer+1)) { - free(data_out_scratchpad); - data_out_scratchpad = (char *) malloc(bytes_to_transfer+1); // free/malloc instead of realloc will save copy time - if(data_out_scratchpad == NULL) { - usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber); - usb_close(h_device); - return APP_ERR_MALLOC; - } - data_out_scratchpad_size = bytes_to_transfer+1; - } - - data_out_scratchpad[0] = USBBLASTER_CMD_BYTESHIFT | USBBLASTER_CMD_READ | (bytes_to_transfer & 0x3F); // Set command byte - for(i = 0; i < bytes_to_transfer; i++) { - data_out_scratchpad[i+1] = (outstream[i>>2] >> (8*(i&0x3))) & 0xFF; - } - - /* - debug("Data packet: "); - for(i = 0; i <= bytes_to_transfer; i++) - debug("0x%X ", data_out_scratchpad[i]); - debug("\n"); - */ - - rv = usb_bulk_write(h_device, EP2, data_out_scratchpad, bytes_to_transfer+1, USB_TIMEOUT); - if (rv != (bytes_to_transfer+1)){ - fprintf(stderr, "\nFailed to write to the EP2 FIFO (rv = %d):\n%s", rv, usb_strerror()); - usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber); - usb_close(h_device); - return APP_ERR_USB; - } - - - // Make sure we have a big-enough buffer to hold the incoming data - if(data_in_scratchpad_size < (bytes_to_transfer+2)) { - free(data_in_scratchpad); - data_in_scratchpad = (char *) malloc(bytes_to_transfer+2); // free/malloc instead of realloc will save copy time - if(data_in_scratchpad == NULL) { - usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber); - usb_close(h_device); - return APP_ERR_MALLOC; - } - data_in_scratchpad_size = (bytes_to_transfer+2); - } - - // receive the response - // Sometimes, we do a read but just get the useless 0x31,0x60 chars... - // retry until we get at least 3 bytes (with real data), for a reasonable number of retries. - int retries = 0; - bytes_received = 0; - do { - rv = usb_bulk_read(h_device, EP1, data_in_scratchpad, (bytes_to_transfer-bytes_received)+2, USB_TIMEOUT); - if (rv < 0){ - fprintf(stderr, "\nFailed to read stream from the EP1 FIFO (%i):\n%s", rv, usb_strerror()); - usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber); - usb_close(h_device); - return APP_ERR_USB; - } - - /* - debug("Read %i bytes: ", rv); - for(i = 0; i < rv; i++) - debug("0x%X ", data_in_scratchpad[i]); - debug("\n"); - */ - - if(rv > 2) retries = 0; - else retries++; - - /* Put the received bytes into the return stream. */ - for(i = 0; i < (rv-2); i++) { - // Do size/type promotion before shift. Must cast to unsigned, else the value may be - // sign-extended through the upper 16 bits of the uint32_t. - uint32_t tmp = (unsigned char) data_in_scratchpad[2+i]; - instream[(bytes_received+i)>>2] |= (tmp << ((i & 0x3)*8)); - } - - bytes_received += (rv-2); - } - while((bytes_received < bytes_to_transfer) && (retries < 15)); - - - // release the interface cleanly - if (usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)){ - fprintf(stderr, "Warning: failed to release usb interface after stream read\n"); - } - - // close the device - usb_close(h_device); - - // if we have a number of bits not divisible by 8 - if(leftover_bit_length != 0) { - debug("Doing leftovers: (0x%X, %d, %d)\n", leftover_bits, leftover_bit_length, set_last_bit); - retval |= cable_common_read_stream(&leftover_bits, &leftovers_received, leftover_bit_length, set_last_bit); - instream[bytes_to_transfer>>2] |= (leftovers_received & 0xFF) << (8*(bytes_to_transfer & 0x3)); - } - - return retval; -} - - -int cable_usbblaster_opt(int c, char *str) -{ - fprintf(stderr, "Unknown parameter '%c'\n", c); - return APP_ERR_BAD_PARAM; -} - - Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/icarus/Makefile =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/icarus/Makefile (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/icarus/Makefile (nonexistent) @@ -1,12 +0,0 @@ - -SRCDIR=../src/ - - - -default: vpi - -# This is for the Icarus simulator. -jp-io-vpi.vpi: $(SRCDIR)jp-io-vpi.c - iverilog-vpi $(SRCDIR)jp-io-vpi.c - -vpi: jp-io-vpi.vpi Makefile \ No newline at end of file Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/src/jp-io-vpi.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/src/jp-io-vpi.c (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/src/jp-io-vpi.c (nonexistent) @@ -1,371 +0,0 @@ -/* jp-io-vpi.c -- JTAG communications vpi plugin - Copyright (C) 2004 Gyrgy Jeney, nog@sdf.lonestar.org - Modifications copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.org - - This file is part of OpenRISC 1000 Architectural Simulator. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* This plugs into an rtl simulator via vpi */ - -#include -#include -#include -#include -#include - -#ifdef WIN32 -#include -#else -#include -#include -#include -#include -#include -#endif - -#include - -/* The vpi<->jp connection is `mastered' by jp1. Therefore we just sit doing - * `nothing', waiting for jp1 to request or send us some data */ -static uint8_t vpi_out; /* data that the sim gives to us */ - -#ifdef WIN32 -SOCKET jp_comm_m; -SOCKET jp_comm; -char msgbuf[64]; -char * get_ws_error(void); -#define GET_ERR_MSG get_ws_error() -#ifndef EAGAIN -#define EAGAIN WSAEWOULDBLOCK -#endif -#ifndef EWOULDBLOCK -#define EWOULDBLOCK WSAEWOULDBLOCK -#endif -#else -static int jp_comm_m; /* The listening socket */ -static int jp_comm; /* The socket for communitateing with jp1 */ -#define GET_ERR_MSG strerror(errno) -#endif - -#ifndef SOCKET_ERROR -#define SOCKET_ERROR -1 -#endif - - -static int jp_got_con; /* Have we got a connection ? */ - -static int count_comp; /* Has the predetermined cycle-count been reached ? */ -static int jp_waiting; /* Is jp-waiting for count_comp ? */ - -int jp_check_con(); - -/*---------------------------------------------[ VPI interface to the sim ]---*/ -/* Sends a byte from the sim */ -int vpi_jp_out(char *xx) -{ - vpiHandle sys = vpi_handle(vpiSysTfCall, 0); - vpiHandle argv = vpi_iterate(vpiArgument, sys); - s_vpi_value value; - - if(!argv) { - vpi_printf("$jp_out: missing destination argument\n"); - vpi_free_object(argv); - return 0; - } - vpiHandle dat_to = vpi_scan(argv); - if(vpi_get(vpiType, dat_to) != vpiNet) { - vpi_printf("$jp_out: Must have a net as argument!!\n"); - vpi_free_object(argv); - return 0; - } - - value.format = vpiVectorVal; - vpi_get_value(dat_to, &value); - - if((value.value.vector->bval & 1)) { - vpi_free_object(argv); - return 0; - } - vpi_out = value.value.vector->aval & 1; - - vpi_free_object(argv); - - return 0; -} - -/* Sends a byte to the sim */ -int vpi_jp_in(char *xx) -{ - int ret; - uint8_t dat; - s_vpi_vecval vec; - - s_vpi_value value; - vpiHandle sys = vpi_handle(vpiSysTfCall, 0); - vpiHandle argv; - vpiHandle dat_to; - - vpiHandle dat_to_index; - - if(!jp_got_con) { - if(!jp_check_con()) - return 0; - } - - ret = recv(jp_comm, &dat, 1, 0); - if(!ret) - return 0; - if(ret == SOCKET_ERROR) - { -#ifdef WIN32 - if(WSAGetLastError() == WSAEWOULDBLOCK) -#else - if(errno == EAGAIN) -#endif - { - return 0; - } - else { - vpi_printf("Socket recv error: %s\n", GET_ERR_MSG); - return 0; - } - -} - - - if(dat & 0x80) { - switch(dat & 0x7f) { - case 0: - /* jp1 wants the TDO */ - send(jp_comm, &vpi_out, 1, 0); - return 0; - case 1: - /* jp wants a time-out */ - if(count_comp) { - dat = 0xFF; /* A value of 0xFF is expected, but not required */ - send(jp_comm, &dat, 1, 0); - } - else { - jp_waiting = 1; - } - return 0; - } - } - - argv = vpi_iterate(vpiArgument, sys); - - /* We got the data, acknowledge it and send it on to the sim */ - if(!argv) { - vpi_printf("$jp_in: missing destination argument\n"); - vpi_free_object(argv); - return 0; - } - dat_to = vpi_scan(argv); - if(vpi_get(vpiType, dat_to) != vpiReg) { - vpi_printf("$jp_in: Must have a register (vpiReg) as argument (type is %d)!!\n", vpi_get(vpiType, dat_to)); - vpi_free_object(argv); - return 0; - } - - value.format = vpiVectorVal; - - vec.aval = (dat & 0xf) | 0x10; - vec.bval = 0; - value.value.vector = &vec; - vpi_put_value(dat_to, &value, 0, vpiNoDelay); - - vpi_free_object(argv); - - dat |= 0x10; - ret = send(jp_comm, &dat, 1, 0); - - count_comp = 0; - - return 0; -} - -/* tells us that we reached a predetermined cycle count */ -int jp_wait_time(char *xx) -{ - uint8_t dat = 0xFF; - if(jp_waiting) { - send(jp_comm, &dat, 1, 0); - jp_waiting = 0; - } - - count_comp = 1; - return 0; -} - -/*---------------------------------------------------[ VPI<->jp functions ]---*/ -int init_sock(char *xx) -{ - - struct sockaddr_in addr; - int ret; - vpiHandle sys = vpi_handle(vpiSysTfCall, 0); - vpiHandle argv = vpi_iterate(vpiArgument, sys); - s_vpi_value value; - - if(!argv) { - vpi_printf("$jp_init: missing port argument\n"); - return 0; - } - vpiHandle sock = vpi_scan(argv); -/* orig - if(vpi_get(vpiConstType, sock) != vpiStringConst) { - vpi_printf("$jp_init: Must have a string as argument!!\n"); - vpi_free_object(argv); - return 0; - } -*/ - -#ifdef WIN32 - WSADATA wsaData; - ret = WSAStartup(MAKEWORD(2,2), &wsaData); // must be called before all socket operations - if(ret != 0) { - vpi_printf("$jp_init: Winsock startup failed."); - return 0; - } -#endif - - value.format = vpiStringVal; - vpi_get_value(sock, &value); - - addr.sin_family = AF_INET; - addr.sin_port = atoi(value.value.str); - addr.sin_addr.s_addr = INADDR_ANY; - memset(addr.sin_zero, '\0', sizeof(addr.sin_zero)); - - jp_comm_m = socket(PF_INET, SOCK_STREAM, 0); -#ifdef WIN32 - if(jp_comm_m == INVALID_SOCKET) -#else - if(jp_comm_m < 0) -#endif - { - fprintf(stderr, "Unable to create comm socket: %s\n", GET_ERR_MSG); - return 0; - } - - if(bind(jp_comm_m, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) { - fprintf(stderr, "Unable to bind the socket: %s\n", GET_ERR_MSG); - return 0; - } - - if(listen(jp_comm_m, 1) == SOCKET_ERROR) { - fprintf(stderr, "Unable to listen: %s\n", GET_ERR_MSG); - return 0; - } - -#ifdef WIN32 - u_long arg = 1; - ioctlsocket(jp_comm_m, FIONBIO, &arg); -#else - ret = fcntl(jp_comm_m, F_GETFL); - ret |= O_NONBLOCK; - fcntl(jp_comm_m, F_SETFL, ret); -#endif - - jp_got_con = 0; - jp_waiting = 0; - return 0; -} - -/* Checks to see if we got a connection */ -int jp_check_con() -{ - int ret; - - if((jp_comm = accept(jp_comm_m, NULL, NULL)) == SOCKET_ERROR) { -#ifdef WIN32 - if(WSAGetLastError() == WSAEWOULDBLOCK) -#else - if(errno == EAGAIN) -#endif - return 0; - fprintf(stderr, "Unable to accept connection: %s\n", GET_ERR_MSG); - return 0; - } - - - // Set the comm socket to non-blocking. - // Close the server socket, so that the port can be taken again - // if the simulator is reset. -#ifdef WIN32 - u_long arg = 1; - ioctlsocket(jp_comm, FIONBIO, &arg); - closesocket(jp_comm_m); -#else - ret = fcntl(jp_comm, F_GETFL); - ret |= O_NONBLOCK; - fcntl(jp_comm, F_SETFL, ret); - close(jp_comm_m); -#endif - - vpi_printf("JTAG communication connected!\n"); - jp_got_con = 1; - return 1; -} - -/*------------------------------------------------------------[ VPI stuff ]---*/ -static void jtag_register() -{ - s_vpi_systf_data tf_data; - - tf_data.type = vpiSysTask; - tf_data.tfname = "$jp_in"; - tf_data.calltf = vpi_jp_in; - tf_data.compiletf = 0; - tf_data.sizetf = 0; - vpi_register_systf(&tf_data); - - tf_data.type = vpiSysTask; - tf_data.tfname = "$jp_out"; - tf_data.calltf = vpi_jp_out; - tf_data.compiletf = 0; - tf_data.sizetf = 0; - vpi_register_systf(&tf_data); - - tf_data.type = vpiSysTask; - tf_data.tfname = "$jp_init"; - tf_data.calltf = init_sock; - tf_data.compiletf = 0; - tf_data.sizetf = 0; - vpi_register_systf(&tf_data); - - tf_data.type = vpiSysTask; - tf_data.tfname = "$jp_wait_time"; - tf_data.calltf = jp_wait_time; - tf_data.compiletf = 0; - tf_data.sizetf = 0; - vpi_register_systf(&tf_data); -} - -void (*vlog_startup_routines[])() = { - jtag_register, - 0 -}; - - -#ifdef WIN32 -char *get_ws_error(void) -{ - snprintf(msgbuf, 64, "%d", WSAGetLastError()); - return msgbuf; -} -#endif - Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_win32/jp-io-vpi.dll =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_win32/jp-io-vpi.dll =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_win32/jp-io-vpi.dll (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_win32/jp-io-vpi.dll (nonexistent)
ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_win32/jp-io-vpi.dll Property changes : Deleted: svn:executable Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_win32/Makefile =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_win32/Makefile (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_win32/Makefile (nonexistent) @@ -1,27 +0,0 @@ - -SRCDIR=../src/ - -# The location of the ModelSim installation, used -# to build the C lib for VPI. Used by MinGW, so use windows dir name, not /cygdrive/... -MODEL=c:/altera/70/modelsim_ae - -# Different installs of Modelsim keep their libraries in different -# directories (e.g. the version that comes with the Altera web version). -# This directory must contain mtipli.dll -MODEL_LIB=$(MODEL)/win32aloem - -# If building under windows, Modelsim requires that the VPI -# library be compiled with MinGW, NOT cygwin GCC. The location -# here is the default used by the auto-installer. -MINGW_CC = c:/MinGW/bin/mingw32-gcc.exe - - -default: vpi - -# This is for ModelSim under cygwin. Modelsim requires the shared lib -# to be compiled with MinGW, not cygwin GCC. -jp-io-vpi.dll: $(SRCDIR)jp-io-vpi.c Makefile - $(MINGW_CC) -DWIN32 -c -I$(MODEL)/include $(SRCDIR)jp-io-vpi.c -o jp-io-vpi.o - $(MINGW_CC) -DWIN32 -shared -Bsymbolic -o jp-io-vpi.dll jp-io-vpi.o -L$(MODEL_LIB) -lmtipli -lws2_32 - -vpi: jp-io-vpi.dll Makefile \ No newline at end of file Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_linux_x86/Makefile =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_linux_x86/Makefile (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_linux_x86/Makefile (nonexistent) @@ -1,20 +0,0 @@ - -SRCDIR=../src/ -CC = gcc - -# The location of the ModelSim installation, used -# to build the C lib for VPI. Must contain a subdir with -# vpi_user.h. -MODEL=/opt/modelsim - - - -default: vpi - -# This is for ModelSim under Linux (x86/32) -# If RH v7.1 or lower, add -noinhibit-exec -jp-io-vpi.so: $(SRCDIR)jp-io-vpi.c Makefile - $(CC) -c -I$(MODEL)/modeltech/include $(SRCDIR)jp-io-vpi.c -o jp-io-vpi.o - $(CC) -shared -Bsymbolic -o jp-io-vpi.so jp-io-vpi.o -lc - -vpi: jp-io-vpi.so Makefile \ No newline at end of file Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_xpc_dlc9.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_xpc_dlc9.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_xpc_dlc9.h (nonexistent) @@ -1,14 +0,0 @@ - -#ifndef _CABLE_XPC_DLC9_H_ -#define _CABLE_XPC_DLC9_H_ - -#include - -int cable_xpcusb_init(); -int cable_xpcusb_out(uint8_t value); -int cable_xpcusb_inout(uint8_t value, uint8_t *inval); -int cable_xpcusb_opt(int c, char *str); -int cable_xpcusb_read_write_bit(uint8_t packet_out, uint8_t *bit_in); - - -#endif Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_usbblaster.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_usbblaster.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_usbblaster.h (nonexistent) @@ -1,15 +0,0 @@ - -#ifndef _CABLE_USBBLASTER_H_ -#define _CABLE_USBBLASTER_H_ - -#include - -int cable_usbblaster_init(); -int cable_usbblaster_out(uint8_t value); -int cable_usbblaster_inout(uint8_t value, uint8_t *in_bit); -int cable_usbblaster_write_stream(uint32_t *stream, int len_bits, int set_last_bit); -int cable_usbblaster_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit); -int cable_usbblaster_opt(int c, char *str); -void cable_usbblaster_wait(); - -#endif Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/errcodes.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/errcodes.c (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/errcodes.c (nonexistent) @@ -1,54 +0,0 @@ -/* errcodes.c - Error code to plaintext translator for the advanced JTAG bridge - Copyright(C) 2008 Nathan Yawn - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include -#include "errcodes.h" - -// We can declare the error string with a fixed size, because it can't -// have more than ALL of the error strings in it. Be sure to expand it -// as more errors are added. Also, put a space at the end of each -// error string, as there may be multiple errors. -char errstr[256]; -char *get_err_string(int err) -{ - errstr[0] = '\0'; - - if(err & APP_ERR_COMM) - strcat(errstr, "\'JTAG comm error\' "); - if(err & APP_ERR_MALLOC) - strcat(errstr, "\'malloc failed\' "); - if(err & APP_ERR_MAX_RETRY) - strcat(errstr, "\'max retries\' "); - if(err & APP_ERR_CRC) - strcat(errstr, "\'CRC mismatch\' "); - if(err & APP_ERR_MAX_BUS_ERR) - strcat(errstr, "\'max WishBone bus errors\' "); - if(err & APP_ERR_CABLE_INVALID) - strcat(errstr, "\'Invalid cable\' "); - if(err & APP_ERR_INIT_FAILED) - strcat(errstr, "\'init failed\' "); - if(err & APP_ERR_BAD_PARAM) - strcat(errstr, "\'bad command line parameter\' "); - if(err & APP_ERR_CONNECT) - strcat(errstr, "\'connection failed\' "); - if(err & APP_ERR_USB) - strcat(errstr, "\'USB\' "); - if(err & APP_ERR_CABLENOTFOUND) - strcat(errstr, "\'cable not found\' "); - return errstr; -} Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/opencores_tap.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/opencores_tap.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/opencores_tap.h (nonexistent) @@ -1,24 +0,0 @@ -#ifndef _OPENCORES_TAP_H_ -#define _OPENCODER_TAP_H_ - - -// Information on the OpenCores JTAG TAP -// Included as a default, in place of a BSDL file -// with the data. - -#define JI_SIZE (4) -enum jtag_instr - { - JI_EXTEST = 0x0, - JI_SAMPLE_PRELOAD = 0x1, - JI_IDCODE = 0x2, - JI_CHAIN_SELECT = 0x3, - JI_INTEST = 0x4, - JI_CLAMP = 0x5, - JI_CLAMPZ = 0x6, - JI_HIGHZ = 0x7, - JI_DEBUG = 0x8, - JI_BYPASS = 0xF - }; - -#endif Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/errcodes.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/errcodes.h (revision 26) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/errcodes.h (nonexistent) @@ -1,22 +0,0 @@ -#ifndef _ERRCODES_H_ -#define _ERRCODES_H_ - -// Errors in high-level chain transactions -// An error is a 32-bit bit-encoded value -#define APP_ERR_NONE 0x0 -#define APP_ERR_COMM 0x1 -#define APP_ERR_MALLOC 0x2 -#define APP_ERR_MAX_RETRY 0x4 -#define APP_ERR_CRC 0x08 -#define APP_ERR_MAX_BUS_ERR 0x10 -#define APP_ERR_CABLE_INVALID 0x20 -#define APP_ERR_INIT_FAILED 0x40 -#define APP_ERR_BAD_PARAM 0x080 -#define APP_ERR_CONNECT 0x100 -#define APP_ERR_USB 0x200 -#define APP_ERR_CABLENOTFOUND 0x400 -#define APP_ERR_TEST_FAIL 0x0800 - -char *get_err_string(int errval); - -#endif Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_parallel.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_parallel.c (nonexistent) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_parallel.c (revision 27) @@ -0,0 +1,191 @@ +/* cable_parallel.c - Parallel cable drivers (XPC3 and XESS) for the Advanced JTAG Bridge + Copyright (C) 2001 Marko Mlinar, markom@opencores.org + Copyright (C) 2004 Gyrgy Jeney, nog@sdf.lonestar.org + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + +#include +#include // for inb(), outb() +#include +#include + +#include "cable_common.h" +#include "errcodes.h" + + +#define LPT_READ (base+1) +#define LPT_WRITE base + +// Common functions used by both cable types +static int cable_parallel_out(uint8_t value); +static int cable_parallel_inout(uint8_t value, uint8_t *inval); + + +static int base = 0x378; + + + +///////////////////////////////////////////////////////////////////////////////// +/*-------------------------------------[ Parallel port specific functions ]---*/ +/////////////////////////////////////////////////////////////////////////////// + +int cable_parallel_init() +{ + + //#ifndef WIN32 + if (ioperm(base, 3, 1)) { + fprintf(stderr, "Couldn't get the port at %x\n", base); + perror("Root privileges are required.\n"); + return APP_ERR_INIT_FAILED; + } + printf("Connected to parallel port at %x\n", base); + printf("Dropping root privileges.\n"); + setreuid(getuid(), getuid()); + //#endif + + return APP_ERR_NONE; +} + + +int cable_parallel_opt(int c, char *str) +{ + switch(c) { + case 'p': + if(!sscanf(str, "%x", &base)) { + fprintf(stderr, "p parameter must have a hex number as parameter\n"); + return APP_ERR_BAD_PARAM; + } + break; + default: + fprintf(stderr, "Unknown parameter '%c'\n", c); + return APP_ERR_BAD_PARAM; + } + return APP_ERR_NONE; +} + +/*-----------------------------------------[ Physical board wait function ]---*/ +void cable_parallel_phys_wait() +{ + usleep(10); +} + +/*----------------------------------------------[ xpc3 specific functions ]---*/ +int cable_xpc3_out(uint8_t value) +{ + uint8_t out = 0; + + /* First convert the bits in value byte to the ones that the cable wants */ + if(value & TCLK_BIT) + out |= 0x02; /* D1 pin 3 */ + if(value & TRST_BIT) + out |= 0x10; /* Not used */ + if(value & TDI_BIT) + out |= 0x01; /* D0 pin 2 */ + if(value & TMS_BIT) + out |= 0x04; /* D2 pin 4 */ + + return cable_parallel_out(out); +} + +int cable_xpc3_inout(uint8_t value, uint8_t *inval) +{ + uint8_t in; + int retval; + uint8_t out = 0; + + /* First convert the bits in value byte to the ones that the cable wants */ + if(value & TCLK_BIT) + out |= 0x02; /* D1 pin 3 */ + if(value & TRST_BIT) + out |= 0x10; /* Not used */ + if(value & TDI_BIT) + out |= 0x01; /* D0 pin 2 */ + if(value & TMS_BIT) + out |= 0x04; /* D2 pin 4 */ + + retval = cable_parallel_inout(out, &in); + + if(in & 0x10) /* S6 pin 13 */ + *inval = 1; + else + *inval = 0; + + return retval; +} + +/*----------------------------------------------[ xess specific functions ]---*/ +int cable_xess_out(uint8_t value) +{ + uint8_t out = 0; + + /* First convert the bits in value byte to the ones that the cable wants */ + if(value & TCLK_BIT) + out |= 0x04; /* D2 pin 4 */ + if(value & TRST_BIT) + out |= 0x08; /* D3 pin 5 */ + if(value & TDI_BIT) + out |= 0x10; /* D4 pin 6 */ + if(value & TMS_BIT) + out |= 0x20; /* D3 pin 5 */ + + return cable_parallel_out(out); +} + +uint8_t cable_xess_inout(uint8_t value, uint8_t *inval) +{ + uint8_t in; + int retval; + uint8_t out = 0; + + /* First convert the bits in value byte to the ones that the cable wants */ + if(value & TCLK_BIT) + out |= 0x04; /* D2 pin 4 */ + if(value & TRST_BIT) + out |= 0x08; /* D3 pin 5 */ + if(value & TDI_BIT) + out |= 0x10; /* D4 pin 6 */ + if(value & TMS_BIT) + out |= 0x20; /* D3 pin 5 */ + + retval = cable_parallel_inout(out, &in); + + if(in & 0x20) /* S5 pin 12*/ + *inval = 1; + else + *inval = 0; + + return retval; +} + + +/*----------------------------------------------[ common helper functions ]---*/ +// 'static' for internal access only + +static int cable_parallel_out(uint8_t value) +{ + outb(value, LPT_WRITE); + return APP_ERR_NONE; +} + +static int cable_parallel_inout(uint8_t value, uint8_t *inval) +{ + *inval = inb(LPT_READ); + outb(value, LPT_WRITE); + + return APP_ERR_NONE; +} Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_common.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_common.c (nonexistent) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_common.c (revision 27) @@ -0,0 +1,358 @@ +/* cable_common.c -- Interface to the low-level cable drivers + Copyright (C) 2001 Marko Mlinar, markom@opencores.org + Copyright (C) 2004 Gyrgy Jeney, nog@sdf.lonestar.org + Copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + +#include +#include + + +#include "cable_common.h" +#include "cable_parallel.h" +#include "cable_sim.h" +#include "cable_usbblaster.h" +#include "cable_ft2232.h" +#include "cable_xpc_dlc9.h" +#include "errcodes.h" + +#define debug(...) //fprintf(stderr, __VA_ARGS__ ) + +static struct jtag_cable { + const char *name; + int (*inout_func)(uint8_t, uint8_t *); + int (*out_func)(uint8_t); + int (*init_func)(); + void (*wait_func)(); + int (*opt_func)(int, char *); + int (*bit_out_func)(uint8_t); + int (*bit_inout_func)(uint8_t, uint8_t *); + int (*stream_out_func)(uint32_t *, int, int); + int (*stream_inout_func)(uint32_t *, uint32_t *, int, int); + int (*flush_func)(); + const char *opts; + const char *help; +} jtag_cables[] = { + { "rtl_sim", + cable_rtl_sim_inout, + cable_rtl_sim_out, + cable_rtl_sim_init, + NULL, + cable_rtl_sim_opt, + cable_common_write_bit, + cable_common_read_write_bit, + cable_common_write_stream, + cable_common_read_stream, + NULL, + "d:", + "-d [directory] Directory in which gdb_in.dat/gdb_out.dat may be found\n" }, + { "vpi", + cable_vpi_inout, + cable_vpi_out, + cable_vpi_init, + cable_vpi_wait, + cable_vpi_opt, + cable_common_write_bit, + cable_common_read_write_bit, + cable_common_write_stream, + cable_common_read_stream, + NULL, + "s:p:", + "-p [port] Port number that the VPI module is listening on\n\t-s [server] Server that the VPI module is running on\n" }, + { "xpc3", + cable_xpc3_inout, + cable_xpc3_out, + cable_parallel_init, + cable_parallel_phys_wait, + cable_parallel_opt, + cable_common_write_bit, + cable_common_read_write_bit, + cable_common_write_stream, + cable_common_read_stream, + NULL, + "p:", + "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n" }, + { "xess", + cable_xess_inout, + cable_xess_out, + cable_parallel_init, + cable_parallel_phys_wait, + cable_parallel_opt, + cable_common_write_bit, + cable_common_read_write_bit, + cable_common_write_stream, + cable_common_read_stream, + NULL, + "p:", + "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n" }, +#ifdef __SUPPORT_USB_CABLES__ + { "usbblaster", + cable_usbblaster_inout, + cable_usbblaster_out, + cable_usbblaster_init, + NULL, + cable_usbblaster_opt, + cable_common_write_bit, + cable_common_read_write_bit, + cable_usbblaster_write_stream, + cable_usbblaster_read_stream, + NULL, + "", + "no options\n" }, + { "xpc_usb", + cable_xpcusb_inout, + cable_xpcusb_out, + cable_xpcusb_init, + NULL, + cable_xpcusb_opt, + cable_common_write_bit, + cable_xpcusb_read_write_bit, + cable_common_write_stream, + cable_common_read_stream, + NULL, + "", + "no options\n" }, +#ifdef __SUPPORT_FTDI_CABLES__ + { "ft2232", + NULL, + NULL, + cable_ftdi_init, + NULL, + cable_ftdi_opt, + cable_ftdi_write_bit, + cable_ftdi_read_write_bit, + cable_ftdi_write_stream, + cable_ftdi_read_stream, + cable_ftdi_flush, + "", + "no options\n" }, +#endif // __SUPPORT_FTDI_CABLES__ +#endif // __SUPPORT_USB_CABLES__ + { NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL } }; + +static struct jtag_cable *jtag_cable_in_use = NULL; /* The currently selected cable */ + + +///////////////////////////////////////////////////////////////////////////////////// +// Cable subsystem / init functions + + +/* Selects a cable for use */ +int cable_select(const char *cable) +{ + int i; + + for(i = 0; jtag_cables[i].name; i++) { + if(!strcmp(cable, jtag_cables[i].name)) { + jtag_cable_in_use = &jtag_cables[i]; + return APP_ERR_NONE; + } + } + + return APP_ERR_CABLE_INVALID; +} + +/* Calls the init function of the cable + */ +int cable_init() +{ + return jtag_cable_in_use->init_func(); +} + +/* Parses command-line options specific to the selected cable */ +int cable_parse_opt(int c, char *str) +{ + return jtag_cable_in_use->opt_func(c, str); +} + +const char *cable_get_args() +{ + if(jtag_cable_in_use != NULL) + return jtag_cable_in_use->opts; + else + return NULL; +} + +/* Prints a (short) useage message for each available cable */ +void cable_print_help() +{ + int i; + printf("Available cables: "); + + for(i = 0; jtag_cables[i].name; i++) { + if(i) + printf(", "); + printf("%s", jtag_cables[i].name); + } + + printf("\n\nOptions availible for the cables:\n"); + for(i = 0; jtag_cables[i].name; i++) { + if(!jtag_cables[i].help) + continue; + printf(" %s:\n %s", jtag_cables[i].name, jtag_cables[i].help); + } +} + + +///////////////////////////////////////////////////////////////////////////////// +// Cable API Functions + +int cable_write_stream(uint32_t *stream, int len_bits, int set_last_bit) { + return jtag_cable_in_use->stream_out_func(stream, len_bits, set_last_bit); +} + +int cable_read_write_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) { + return jtag_cable_in_use->stream_inout_func(outstream, instream, len_bits, set_last_bit); +} + +int cable_write_bit(uint8_t packet) { + return jtag_cable_in_use->bit_out_func(packet); +} + +int cable_read_write_bit(uint8_t packet_out, uint8_t *bit_in) { + return jtag_cable_in_use->bit_inout_func(packet_out, bit_in); +} + +int cable_flush(void) { + if(jtag_cable_in_use->flush_func != NULL) + return jtag_cable_in_use->flush_func(); + return APP_ERR_NONE; +} + + +///////////////////////////////////////////////////////////////////////////////////// +// Common functions which may or may not be used by individual drivers + + +/* Note that these make no assumption as to the starting state of the clock, + * and they leave the clock HIGH. But, these need to interface with other routines (like + * the byte-shift mode in the USB-Blaster), which begin by assuming that a new + * data bit is available at TDO, which only happens after a FALLING edge of TCK. + * So, routines which assume new data is available will need to start by dropping + * the clock. + */ +int cable_common_write_bit(uint8_t packet) { + uint8_t data = TRST_BIT; // TRST is active low, don't clear unless /set/ in 'packet' + int err = APP_ERR_NONE; + + /* Write data, drop clock */ + if(packet & TDO) data |= TDI_BIT; + if(packet & TMS) data |= TMS_BIT; + if(packet & TRST) data &= ~TRST_BIT; + + err |= jtag_cable_in_use->out_func(data); + if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func(); + + /* raise clock, to do write */ + err |= jtag_cable_in_use->out_func(data | TCLK_BIT); + if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func(); + + return err; +} + +int cable_common_read_write_bit(uint8_t packet_out, uint8_t *bit_in) { + uint8_t data = TRST_BIT; // TRST is active low, don't clear unless /set/ in 'packet' + int err = APP_ERR_NONE; + + /* Write data, drop clock */ + if(packet_out & TDO) data |= TDI_BIT; + if(packet_out & TMS) data |= TMS_BIT; + if(packet_out & TRST) data &= ~TRST_BIT; + + err |= jtag_cable_in_use->out_func(data); // drop the clock to make data available, set the out data + if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func(); + err |= jtag_cable_in_use->inout_func((data | TCLK_BIT), bit_in); // read in bit, clock high for out bit. + if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func(); + + return err; +} + + +/* Writes bitstream via bit-bang. Can be used by any driver which does not have a high-speed transfer function. + * Transfers LSB to MSB of stream[0], then LSB to MSB of stream[1], etc. + */ +int cable_common_write_stream(uint32_t *stream, int len_bits, int set_last_bit) { + int i; + int index = 0; + int bits_this_index = 0; + uint8_t out; + int err = APP_ERR_NONE; + + debug("writeSrrm%d(", len_bits); + for(i = 0; i < len_bits - 1; i++) { + out = (stream[index] >> bits_this_index) & 1; + err |= cable_write_bit(out); + debug("%i", out); + bits_this_index++; + if(bits_this_index >= 32) { + index++; + bits_this_index = 0; + } + } + + out = (stream[index] >>(len_bits - 1)) & 0x1; + if(set_last_bit) out |= TMS; + err |= cable_write_bit(out); + debug("%i)\n", out); + return err; +} + +/* Gets bitstream via bit-bang. Can be used by any driver which does not have a high-speed transfer function. + * Transfers LSB to MSB of stream[0], then LSB to MSB of stream[1], etc. + */ +int cable_common_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) { + int i; + int index = 0; + int bits_this_index = 0; + uint8_t inval, outval; + int err = APP_ERR_NONE; + + instream[0] = 0; + + debug("readStrm%d(", len_bits); + for(i = 0; i < (len_bits - 1); i++) { + outval = (outstream[index] >> bits_this_index) & 0x1; + err |= cable_read_write_bit(outval, &inval); + debug("%i", inval); + instream[index] |= (inval << bits_this_index); + bits_this_index++; + if(bits_this_index >= 32) { + index++; + bits_this_index = 0; + instream[index] = 0; // It's safe to do this, because there's always at least one more bit + } + } + + if (set_last_bit) + outval = ((outstream[index] >> (len_bits - 1)) & 1) | TMS; + else + outval = (outstream[index] >> (len_bits - 1)) & 1; + + err |= cable_read_write_bit(outval, &inval); + debug("%i", inval); + instream[index] |= (inval << bits_this_index); + + debug(") = 0x%lX\n", instream[0]); + + return err; +} + + + Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_common.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_common.h (nonexistent) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_common.h (revision 27) @@ -0,0 +1,44 @@ + +#ifndef _CABLE_COMMON_H_ +#define _CABLE_COMMON_H_ + +#include + +// Defines to use in the 'packet' args of cable_write_bit() +// and cable_read_write_bit(). Note that while TRST is +// active low for JTAG hardware, here the TRST bit +// should be set when you want the TRST wire active +// (JTAG TAP to be reset). +#define TRST (0x04) +#define TMS (0x02) +#define TDO (0x01) + +// These should only be used in the cable_* files. +#define TCLK_BIT (0x01) +#define TRST_BIT (0x02) +#define TDI_BIT (0x04) +#define TMS_BIT (0x08) +#define TDO_BIT (0x20) + +// Cable subsystem / init routines +int cable_select(const char *cable); +int cable_init(); +int cable_parse_opt(int c, char *str); +const char *cable_get_args(); +void cable_print_help(); + + +// Cable API routines +int cable_write_bit(uint8_t packet); +int cable_read_write_bit(uint8_t packet_out, uint8_t *bit_in); +int cable_write_stream(uint32_t *stream, int len_bits, int set_last_bit); +int cable_read_write_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit); +int cable_flush(void); + +// Common functions for lower-level drivers to use as desired +int cable_common_write_bit(uint8_t packet); +int cable_common_read_write_bit(uint8_t packet_out, uint8_t *bit_in); +int cable_common_write_stream(uint32_t *stream, int len_bits, int set_last_bit); +int cable_common_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit); + +#endif Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/adv_jtag_bridge.pdf =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/adv_jtag_bridge.pdf (nonexistent) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/adv_jtag_bridge.pdf (revision 27) @@ -0,0 +1,2502 @@ +%PDF-1.4 +%äüöß +2 0 obj +<> +stream +xmN0 E +8F"y a>[`Jch :03v^>؞ÛF-CzrK$z}(H\;.k *وJTs\i8 #zUZEjB?7f3݂lpB&.qܬ| +"h9} z3rX"Y(ר#Dž:.q3+^$j<尐;##8Ezod u.sz9i11y +BF0<;T} +endstream +endobj + +3 0 obj +290 +endobj + +5 0 obj +<> +stream +xVF ty3޶ +Pz J{#p<I;CqM5ҳd<]}q6Gr ]2\n}tܦ%4}O;`!~Y{n!.!p%Dހ(~"j0m +5 &5~̈́mY&0<*dd# q Y!!?:faE,XQ, W)d'PHk!2*&g J!N (ݖͤgHI4/XZ +SZфFUdZ""rd4{* +ͻCcoQ9m(Vhjs"C+9B=7hJ6%L㸃]ryBFBCJ˭P+yѽUBly*;BQ?R.LwkEl9g!D'x{92W +VE+]< +sƌ:y,,XDI5ȸT49}r +r A^ #+}oB>]X_z +endstream +endobj + +6 0 obj +1105 +endobj + +8 0 obj +<> +stream +xV +8F,%RoF^JK0 fNe3y#[%6w!AUOIiۯ d +-Э^o=AVCȶ#8 +*P2P^*ow>GA>[|<bnyrH`" f#h6F49\d{Ed GZd*+{F^8C|:~z0 ;_?5kҼ3YT0\ ǵ|gor:|~ƘXH2)N +)a\P^FJ(h"EeRR¸L)\P"DRˤ8)q2RBd)D:LD&3iƸl iFt iFiABbTr]QQ4W꽊W +s_A^פt~(}mh]m޳fbټ"O6tm~ +BCW&s}^F(W7&ޏ܏Ksbw̻h.Y,DO.ѡ0U./Nhyih9)8`.Jk[)I5kQ0х-CC`n?eFVU84%pՏʏ^zGEx\;g0BjpINf6@ ԭC +.%N +`?ՠFఇBY1T¹Oj-ll[F¦`: \ySδDtNg +-صp`iCZQ'گ2E5?*DwR^*dK*F +4+n1iy,9.%|Ti³QasSNL;YY+6˅ P +endstream +endobj + +9 0 obj +854 +endobj + +11 0 obj +<> +stream +xK6:K_"@X[z(zk%_3${yĔBX{)z?΋d}}XgRstw/ݿM|/;}gz~/S^:fK_n>dGe qr,@1Ξ( wF?%>ͪra^̔~|DF6"THS\ %qs' +JMe@{0/ +/^!1΋iS?OL(8yŌ O{n +_{IfZ_d`KR +~V?.uAV8yb,|szpS*AQWk6B]nkpgDEG?,i"FO޲)5{%nuĊ/[kѾ[N";.I¢)D({BF,F +O%Bsj٫ڲrpȃ.g܏̐2#6E潎N:JT aFGur2r 'mAݬ<9?Oy0W-U(cKpA<5 +O\]ĦkD0 j CWbu)1CZIOzVn!3ps=?s^gSkHWnٮgpfc1 +|G>Mv[ޭcbGǚ٦d'7yTc<=yJoϤ7ǶwQk=%XHwkݵP&N8CPhfbw,NZ&`Eo&ߒ`?wP9GQYyޔp(;\k6{/ufqI/ Qq{b\K%#Zk&v,+9H6u rSypŃsc6s\^ȉ)/daE+ja.""dJݤ1խ +Fs[">(eճk/N¨yz9Wwаl'Mmh(7tk~WNK kJ$iqk0qB!|FCS螊HKNAL iYvY $ܜ[aJ0c% bsϾpQ>2n r]&]52z뉚KCiMO{D-10BJlW,dø9VunPȟ32jÓPU#+q=@sD2 +endstream +endobj + +12 0 obj +1258 +endobj + +14 0 obj +<> +stream +x\I#ϯ0\k!.=|0]K3`ZReeKzӗ~E]v&{|?e?}旷-.tU}ܾ۫:no~.]>~W/{|L+wsU&h /`Y} +,o%lݖrk>ކ 7{Y}shWc/agjy8Vxtz})ct8vZC>^FǫSo`K.0Kxtpyg\ݥkzʫx\K\s~fL*kioQd|vKC7776g*jAWXUӁ (+Xx7`DT{E= I8m`d-[ojkF7*2R8Mn3(t0ծ7c4_PAh?n5.~G@*Fw ah|x`ligFNd7G.#Hwe;a Q $^k,'pcw:P6n~* Y=Fx`#^G-] + *@(t& +;LւD uINDCPY z.IA#f1z<2\k;==j*,~\ + m|}ϧa`u54$X,B+$I${u~~01%)p`Z8<Z@2@!m.gf9K76$2yMJx׷ڙZ >,uRe9ȃ_Y\AsHek&T6#gÈHsǥN3`7k`}{SIUax) (f5O 旋_©:'`3ꂿ@zzWK +5:t4p :&p;ay3CrC^Q͸kkEFʃ ̭/lAXɂLWO)+,MϋKl\ x!o[5̐"O)$8jV<Q{ċn$$ٵI-WhHf ˸*y~V-? +U'xsK#U5,\灟1r2钩9q)8R^qN*6@R #e)1! +^ I fjJrrX_6/hIα2JJ!A=K+C!)IVV+d!yJ I>XI;0U{SmNCD.gW*mgFŀ ZXT2Yj'#FaۢlA~9I3Wx,uI'~8 +sǺC´GtBsT ;NAS +>.a +endstream +endobj + +15 0 obj +3576 +endobj + +17 0 obj +<> +stream +x[ˎ߯:@w,mw/,2 E~ /} +KYij/b./>.uK?]_~׏qy^V\.]q9> vYnZ 7uf>,xΙYzƛyM7mﶎDn`,L[ L(M+]/qË8ȃm <" Ơ@+p -?`~ICė0rzzQpZ4C: E߿/-f1h0'ek^}2[k1)fhZs`-} gaQm`;!wɜ.,V~8 +J&%' +"K+;']yХ3+V@9T&.҈3}|]@ lkl;כ+>ZD|ɂ?$1JF(E˿~71c&Xq.,,54ND"_~T̞%N7eD1QRCv +?\ʈ:hXk(+y=ϼh K@x}H%K0٣ c8? +-N' Y&eGWɦ&ŧ\Fwh+U6q] +ReLӦUɆBl6yɞ,̌w/5TL&}srHQKO~Wѫ+f[6wqʞ9@AX|B&iUBT,iPs0s(rm`Dr [d"iUH$$e fzW_TؔL#$0zS):I`@ kC FuE ZJ2-#|GP-pFkw$Y6͎B6Ԧ>쟄 R*u?I(Ͼ:go='-vTlj#]@) `4 +JQu0^X.6z,Ɵg<:m_ͼ#89gM+ +L`a ]e(AyI06@jj˃#AscdZ"̨CF͡[Պ$Ӑ#"n6-E}GXfSz*%G.ʔAYʊCvwewX1_ gFg+Eۀˈ;kOW#Bu__w74M:RãB5+p}J56rJ%~2х'~s&@rWRqC*6EwnQ,{"34ϲ-z֢6 +J0К!<=' HnϒQyGTXnm5 ;A$Ve: +Y_mgҪiSb.t"~ %ȧΩ ],LaF+ܥ˅(ĔriL_ώ. YI;RJ\Fv`zI4dK_q00(7 aԦb\6{"V(n%/^䫶Q&:?iEiĭYWU[9 0Y@M]9Sݚdm . *}xyTkNVFI2R]*J~={^[SH|[}Ǟl Ƣ$m90oQv> վ 0i[H[*^ڻhNmn6=\gz7>pfnUZ*0CXqW1gw{mƓjy@-꽯;0fWE#>2Cy=YS8Kl)8Z(^û|Hj6tUvD"%~yWN{ژ+#+d~jcv Y6oG٨!yץUKm.Dp~rQҢy<L?a$)?4(նZUG}Ć_e +N8]]cL;Ss]w2p ;KQ{9u&|Tr*֒JQq] ldA@8p-헕7?=FH4G7?#&d7NJBHB;jYd"*h (:Rgef#으g;:dɭキ`oҩsy<|+rd|)o?[ٜd3S!:8"jAc鸋ġ`si[;i-6l)!~iB;$3<8dXWwsϑ)|?muܬv:MBsv\Y=~N_փ[͖I0*G涖r2"v#[r/lWL +endstream +endobj + +18 0 obj +3267 +endobj + +20 0 obj +<> +stream +xZI4Zs";@7/߱i2x4TWe*"!㗋\|y_~.?M_p^f.|6nfʩj2F+ W̓h]W>]+5)Z_gnj7.?4/Fom<9OF匟Cq]min]yiuaej^;>`3VvNrȻaQ< +مY|x~TY˛c,\uO2k6.o2lI=ݵu07 L`xXًn<⺩^,/, +1s`ALC5n?kՃ& +;9d8Nn/تڱىu0,#1i=¢da3508A:o2MS])" +aIAwZ/8N +8"ɊةU'lb†-֯Afe+"`nSN lʣ,"[P +gwO)X13YYUe@Q,WN$ 0@(9]hRY?2l e "]R!8OGwy wfJɌ +ń9S/0I̲vL3m^:S4z a(;i΂iP+- "/c)!8Q:ۄ1+2cCFpʖ1Ai: `?ZEĻ5ƙܤ|0Ucy iJ=x$23Tutݙ$B uIU\1%$1tnc3i$uy'FR6YY, +yFahjČ +@rgBE$Q# Q +,?[mf+N؊Z +BWT>"ӥLhG%t< +=oFInA_CEsn`AK0$0BfLF*>{`JZNxiK-_B& pErs&*3LT*,!IGF+xkTqnnKEox5iz.W!BMg=~W뫽ȵPjSΣlԿn6H^WH27+̊-=$X=k^{ć 33` R$Dts+`Uv */Gܪm[@uX> +stream +x[j+fg?`{Ƌ.&E wOR%u{|C0nTԩƼ^}1WN뼦~||,]f._3\|/Wq{uWnOw?/]ޖhp|͚5i ~x0oMWɀlLi~fr|=f+o&bhYc˸45]t6MЅr!k- p| o]pxAOqޠ{ΥGׄ•k2 +;NgÅ pr+7 +">}`B0rg V[H&6>Vu[Z{/x(ie[5azS^VM,fcBou!x/rݫi<&.}Oe0_vDdt 87F>n>^a>R#|\3.Us@8#'dF}5,5f08 -t$v2G8͊;{f.i4)ajV$)^dlm umNu|IQԷ]UYfoQyPƧ%3U-{X3aT{UUJMx} S&);{jUX>-B*-'Ӵ2/(l1q"} + Vdu$]0!RZT֊G=mt;Tep]Ok3# " ijn$%F)]]R2xOˁZCYl8Rz0:b).JYDP^qL +gļ4XgF4"B*JNt;Awrjc0"{IreU7SRɂxӰwhN*ݑvILWtHD+i<{$v$̽V7@fА iG/Gmg=\56Wu\-BqAUp.YG˚jhjK> M+qS=?xBvG +V +\n:8AkWPVFԑH>_.o͗iU4$)[uh:[u8# +d,RMcʧ +tp?`sl +0'Huiʼi{֬2Q}]SyMɰ9S[&uk1lZu'9bbFAT'`מ&(^ KhaH KѲy +zuOFpZ0rǯLlk0o +%TW==gہ ٶ;ŽV^Mäɑݟt# yfzq`lm7̛L`hnG68D΂L%6Fюkоl!ŽCϻDw X[;yN6zVݯ{I|=}v7׋vmwGӓ&P֦**VSF +VboVuRj.(xs6IGqZhN\m{Q5!LNL^q0oJ&oO zB$XuHkF8S pjlը|q +endstream +endobj + +24 0 obj +3242 +endobj + +26 0 obj +<> +stream +xZɊWlh9Z@Ko +>߼3#3"2#*uiRUV/^D~˻69^˯>'{qhsnm||k[<5cN9>ݔ ީSipmhɘx_&\u{P+&tQp՛V7ą_Q$5 9M*Lnozf-:qIX=d  +Dv3m<} +XEr}om=(Ba53 +L.I"K{U.\$?UnHAAN{ɕ')\W}R'7j:ωCuʡEjɁd%Mnh +Άl׃3YJ&f|ȤA)M TTn4Ћ uʙs+/@8!]*/w$JC`CgT)RLzƽøh=jOYHFr|NpHh(YÃ^%·9NgZ)Ǟf1A=V;2㯞Mc +(75sҦ)54H3\#9[":JO'Z(u[>*Tɓ9uҙWoHNHtE:/MBuiCȔ0.z +& +8Pуw 7 +dh +ڂ˟r(uu5 5о:s, xdqUL{Tb.Zyh ?yѭQ$3|[ԪpuVPV~gvpޕGr5҆ BL+ +Yܮ|^ŭ4AuPTx)a>ԪGpgX0룰&c"bPTҞmT&:Er3N c'DSaסE}MPб9=|RO7hA할f^.Զ=f7mXi?͝)CbN np!'.JAu`{ {}y{pS^![ib-]ijӍvx1GL)# +l)L!Ot< 3q)gn:/dKy$LMAMatߋj&^vz8SNi"fK%F2n/9b$pqlV|Gwl`z{<,'~#)KXfp`֥g1MU2|B-@8o r +)u +wL3hK&׺kn'Dj*i0`x-<2ɬna6TdǕ,0ֱc+Q,Nn5Tz汹- OHbX+pؠw6li6qR&~'\27\#pcSPqzPc7 +^,8~yCˍRM&bL SX,VbW5!0 + +3Ga"CD Xw E@lF"-1gl_k1CڙОa +ߜ^ük,ݰZڱ䑉9\dA)p:#HImshM|dnXSO 8|}/Rq+Z_ҵBڭߪ[ir"%HlSƭ:ͭǒϿ[ѝR7@O?5y<(![לrZ}JR߅*r(10hiut D\Stվ{j^?bN@oJ+*/+7 +endstream +endobj + +27 0 obj +2804 +endobj + +29 0 obj +<> +stream +xY=#7 WH}xvRr "@%K.]pow~Gͺt(wk:>~]fÍ~20+V^?~{~}j6{9N?-u}wr¢etyQD(MOwkpYpE~^h+^xF-Yt͘#$K|U=6ADxŪ g#X}ħ23P0G/PP-[P|`sn`]ߢEhDaD +D\ z<9*Mm9`";Vi KWt&v:vPL!jwN7= MVDPraF -`:jԊŞL̗−4RߍBIz@@\<թNGS&xu#^K܍J9ze6b3>簀EI%MpiG$>`Dzy dx;G $dG{;-c VsוC5RK +Hq@y&eW_Hym7i 9ȴ̚bKk @le6;*QG+XLa퓲IEp%)Ae\^V{ozmz/ݸZ5S׺]M(L@{G7U%g)JZ5se~*zP ZIT8iMa([ pVt8y!!׵W96`u -&ݡN/텏Lb@.Ym;-.uشdэë(3npoDd RaFj:rQԗsx_1sW;X9-sf44e@Ã&ȷUK!ŷK%T}.!J #kr E@q@kM}f?$y]UL6]qJ2S<1}z-קpk0$r'v*0<ωW,OUεK*7[b)VJIknq  +n٫&v>lU[h}FYߠf/z"Tje.V-av9,TLHShzJcVܫ࣢cD +wg-э0ZS}Β,6#; +Ġ.êvfJN5w-cZf` +m&Q%C?_nR;<_=2 (`jὉk ^`#ovP#;W{&~n3gC睞"Sd-3@J>[ +/*7n}ЙzR(PT-} *mfK4eaQ(+/ ߗH0xբ].i;Kq*ѵ< n"۱4!OYtZ*(kCڳ]ό}to$k>м^a 1o{ڼV> /`$'I ++o@- ږ5=i>Nf21 +endstream +endobj + +30 0 obj +1943 +endobj + +32 0 obj +<> +stream +xXˎ6 Wx] Hl0΢ Ew}]ˇd#vN0NlsxH\4C? co4?~!7׶诶y5ƚDL;6}{8-.>p==mF0p O?MJ&DSMi` 7\ھeZc `-qADOȧiM--hUOKy]Bp~yE tNY>!JH27@Ɛ=9#7|H}CVA;tc2kp&*:Ngc<2jE廇) sdž~D?:Nl[ϑfB@oPDYBhTןXab +b8c {+ 玸htEjjID8wa@ +kk6uj |^TKه&Fy>M|6ҙqrNfhbv[\e,o wRKcaTW[ֲآ;KO?R>c{Z#4Edc&MA&?jo`f{Jb]<<n[!Q\IT$RZ[T(nSS&X{x̛ݿQϥ֖z Oq > +stream +xUM@ W\+i><`{Co Joz(t/}ؙHޓF? +5Gcde]_Q?b65p_zi?N?k+88]{l +=`Եfj2"Kx5,$r@LDzF& |/!~0]_ze 3v\LzTw±R>e;(7NW%ߥJuMbx{(p͌"'aɐB>K8U{:( RvGCBIĢNCZBWcJ'٠5yxMKPqX9m "tӱ<0 al0bUעnm@P`*P(QQG'rBgdҀȁ)l]t%"HnVJHu ) KŭњJ`o^tD%Bnw/Ux%djXEӪ(QPބk(G5dv +ukw]}# 8b*z3D!=ء}~滈WzMJuw*ocۂz-Og/BhNTB +S>6MF) 22e y"8ʶ.>6M +endstream +endobj + +36 0 obj +706 +endobj + +38 0 obj +<> +stream +x[Ikݿ_u;c辶}АE.dȷOIUJA?^Iuj8u$<&॓ +?/up\ \vUo~}qRʿ^;McW/&|H? +?=Ia#|O~ +VGKUBau%kUJݍ000ge2RwD)vݤT>>]w9ěvxi񶇿p-\Eӫ387ݻ #EYu SUhu S# _ó:\+'p5|0&=AVGWR +LT)& S;UP*Z^9|,_aMh:OjqP0~dNhJ nљdvEO'|= +ad&xi7x-RZa!Vv!Yahm%1n676{)G4)£"^]7GV̅]L2"7Xfl)+"Sz`KGja.|Fr a38s_CvAyJNmMS3MN'U`~u59$_F\#-=ۖE_Un9.& LCU yJ*؍2}R۰ri&!T"2̢Cl9-FcUzPhG$ 0Ҁ[ڼ[tf%@R=clcH +8L ధUBJ S Ś4^TQOVZUY2Rݦ#kӜ#yyFZ/CJJ A%{3 N=ĘhH-n+]5L2njYJaċyP󘟷B9۱!wb_ʮ2ECl.|ћT +lۑZ8 +~r ҙKtù>JڸΨs懏H0Ntd#*fVm <$Ym#-IefHnǛ|ed8l+z3hV/[YXJ,kƓ"|]:or񡒺s%1*Ya]XJV`|@N̄JɱqKu# +G>Y[4_`΂^mӇ־&BF79ۻ9]bF'|F3YNI4MhQR?תէ㹃ƇCmtA3cFہ{D{wՌ\q^2j]%o kLju=j'b V9 +H&j},=b *k&nj?i`.ˆuU=5X< 'R)fN+K[͕Bߕ$%E#="hScHDfuu J;;'_ Q),;Q +GGUSYѴT5=^l}ZM!͏ݵ_DD'$ݲ^"u +o鹆|r6:lOynB-l1\n^3N[V1A/yeWnM] %,^/b@{Ƨg1nQiԦmSky@äS)Hr;fv4VA!9l`ؑURo +%*&;**T-/3eDx, Hv^ZI]ԛD [HC UAHQ? T_het qy]z}bGy'w.nehB> +f?c .=ZB HϝӀO7w/l⺈c.Q(KͥhUma Ƴ,#0kzNـ4,> +stream +x[ˎ߯:@;|J6`pKEv4E]&0Y_,T:UU_E]Tx;i^{|r1~v |s˛~,o>R~hqE?"Zu>=\MjZT6eVSeu[/nBH7b*BRwٺ(bAe&V-HqT狲gd$J&Q7i:io,&z-X"iJM@ 13||܂ +&T^9FE^ɨh׾ihF#PoNV4,VH#Je ^IO}Ҩw4|n7,.m֑:E~FzzLL u`z/-ы_EDdYٞ83mA_X uXQ dmԺӪ]B6Jw_R +p,LH)|+żjQ"/z0 װgueDD|7Re827'*n+ }1^=h +ϖUwu咳2 mVsLzU~2)"WRd_ +~_D)]>;dLֆ elxOauhGZFXH֘/*vLRQ*N[*=6,.5/wMYβ4{$KLBwA@xv(xܽVu P8 5=0r5'7zfX׊@9>Vq==s +$yZ  I݋ +!BmzKgGs-Z9jQZົkdٽS0fSEm1I[wSTL4b!q4dALa@hEv}95'r*b6Zfdi; ;n2m='Luf!Z2e8󭶷b,X {?kʷZuÀa{3H$tFvShT{C^4=)0Ps Q:m"㰆EFLCΩ<,9zHEqFO삥MZw[˩$2EnDY8 +nH!EMO`f8l\>okk}3^M3ÌΊ[ ǟav"5Z*uZWᜪUL %,bvp0ST,Z6%lfIggiWpKFqn5r#SE3ǻʺV^'W15Ix\*0KcTaOBđJ {BG0woM]gDp(;<~c^1zK*՗ϯUTmA\a,A:ZfqbL|YH:c &zJ$h$jϐ6*A [Lskyhg[AXR`݅+7~lFÃ&m1V FW(8>b +<_C3b3rE# ==52>.5bp{#S_lqQ1侎ꨧ50:׾rTl;Ϸ y*բ6ٵ?e>'b:kH[?8G&%iϜHQͣ+LrW9ɑL.Q&vm[ݾDBY @Ϙ\(j;ckS<{zL·:+diݙvΫDI'iLCyTTS/bR]mĜ=X/ +endstream +endobj + +42 0 obj +3126 +endobj + +44 0 obj +<> +stream +xZKo#7W9n@` 1 l6K֋f$g,#wUEz̳~`h?Ǚ>?KOoO!>Oh&dxeןv:aafG?䘐Vȟô7^<ǧӗp{nd0X( C7vqo}Mo-xo,lJsz܃UYM@[Q艖^YZ{,P:O2BVQ-=Ob?HBe+waI'Ңs/"owuʾRy )z@ǷWW=K9X 0#;(Wi ql]=s]/*DJ"+:(= bX`ktq9kz :5zgahg]t|g{C؃xV +m݌:hɲSDqӑ\ +g,MhJHC+ +ءCzKIdKQBtYb&-}L +sݳ J=4TƑj~-}LmX2voAQꮧ%%$RW5> +s QPK=z^tˣrd'kS<^mHc靶!I'QM491lhRu=z,T F"[ìePjC%- +{(x+t"еb mwn}M]KJEJ7enV}`& ԧNdh1m, [ +ا%AmZ̝E`s VW'|_ɗ髽M5ՖZM +&BjGa3H2TrInYIȭ +jHo!U^pn9*B5UM5sJD<U{(|u[10Q[Mb=U$G}֝eA rz8#"} + 'yYtsƤP$9Y1h+mO&XtL8'7@r +Cua)CrX\ѫGRu}clK׹?mndsħZš%qfR)!5f3l+v ɉo,h@`HV4mxo#ݪB0 0_)a^,/KYx@&SZp +QG(`:Բ _y:Aa \ǦR 3Hcqf,ݒ.S䎏ǹRH<*x8eRro_K-<}D%s#/xO`a]n(lַ]t'|ltuͥ5acA3k)6PQ +vj-}Zao38ܱpCPoCULi/Zj;3dQ3`..̨>dk3|x?xj)_W߅-(cbF;| +̀9\Tיў +r}Y;ج +b/Tŷ*s\;U윅;+U5]_׵To^mَ42p~]R!:A +<ѓ[iD쉳RӶ>L zn:h^gcVTI&6'CmҸM}ˋ8eѩ\gyy=;/q=b4ӟF)jn?TIPi"fpјn_h@2048+2mj8ҧdhvxWv4Cܗ, +endstream +endobj + +45 0 obj +2460 +endobj + +47 0 obj +<> +stream +xYK$7 ϯs;n( +f- r&C {ߏd.?f]jᇬO'ɣ.˿'u:+|5sӯ? ?_/o/_ ,xNN6+_5rpǏ羜⮳̠3F+rÔeh-*5 +TpjJo7}S_7^!O镄xXu^ +9b٪)tzL/^NF48@MS:!ot(a_wQ@x=\n5-IjHځ@kÜdٵE +B7s{ak$}gD!vX NX|@dq;`A0t0 K3=€{ +S#:FqL# I27/):V)g3,̈́P \Ҭ֕JSzR +\I\?HT#fC%39BNCrЂ>W[䱌E? +5٠&8k\:w#Ʊ?Ȃ)y/RD{p+qxK|yQ\]J)-ɹQ22#Ih`y$YR,t18*i2bA0؆M`ypP8߯eJ3 8ꐓkVvNN(Kre]Hb@DՂ ˾po_V +2IqڻDTGǤP[<".cG+A% qOkwCGa A["Oǥ?>IvQ[=Jek/;ݚY|<ȏ7gD6 +@i?E5T)+mG,,Q:銮 Q+r;ux"ٷ 颃 }e?BFRF&|PR5NNW޴RVFQ(ꤡ] CMn3T)qOLG +endstream +endobj + +48 0 obj +1622 +endobj + +52 0 obj +<> +stream +xSKkQf2ZSkS&jI.Кm0u2<`af" +B۸rƅ;ADpQut!W".jIOȝ9 BPuKk$ 4?rA"vu*GuC|jӀ!_Sx~|?BA>SC);ck1\KlNNښed=x~ ['LmvW*=RhɌZlj|[O]l[e\7j-Ss k8JCcDI2DE`C{.xhÀŧHUlhsLOTj`BQd)FOQY{3|ݐa +endstream +endobj + +53 0 obj +573 +endobj + +54 0 obj +<> +endobj + +55 0 obj +<> +stream +x]AO 96&f&=?´؁L)VM<@x7kQ13.qe0H|pPewMJ oKƹ16ү-78=8Y;{@ޯ~Mg j[8=O6=u.;"_mKd USU-4[? }Xd-ISSNc2K2{?'ŴSe}~my +endstream +endobj + +56 0 obj +<> +endobj + +57 0 obj +<> +stream +x}y|TEpUݭݝ;k&Kl$$ [D1 ICZ/ #eF}qE& Aq)Π2*8.tSuo޼{}?[V:uYݝ=!dAԆw"G;t+On0B+W̹- !$|y'xB ʻ)TOf*U&(>Yep}9&gR-p?;!1)9ūƥ? Jd^gDNCҺhл}`Vυ؏=v8=FQroIRDAY,j?ڎy~,=m ao|; TzqFx_̑+rZ^bTt;z _d52{HP;zdR3ԂzG,r3뇲P+r.DB aZt1 FB#JBh6jP (~;}h)90Zuq8/^oO] hGϠaݜ8d9wwN8O$I-i"{%Bn%ς$Qrq\.7%4n:{;nv%_+O ҄,BJ/`s1Cl//$^Km錄b m0L ?vpgj/VWD;\vr )XGhݏ0ܯ +h t9_J?AЭ>.JfbP n< ܚ'Yh.yp܍$_Sz y ]~w +*Bp]-|/ȋ0$g/ ;ȐI*sx\ŭ 0Oea' +d5 Ea|~א%2f<\?~hiK?rL_Oчp%H&.ҍ8$Y2L ncoѿP=w[܃ѳɣ(M8MDgA9z й.9$_;Cw?~Xp +tAV^} +{>eҿ'H5A\ zY:6 +#m}z+A/8 +owoAoہO0A`3l _=6s=!ĩ1a4UH-zfS'O**X?!/7';+HOKS)I w\l6l2$Q98nLjEO.BɧS&J-%u+cԦ-$l|} ʕ-"eI;cЖU%쬝CN],ֱ@hA B F؉)Es@ "J,KLda2CH#,C8bQEBi.*[N Xc^R DA*#p$T.@Tv_f,ImȀ}j4 <^5pp2^A+:Z&v10\3Ҽ.a_F #riJDuHXZqeJ:N'*>85'$ne 3Sua׌e\" ȱ@l,оt}ceXfkjm$ØFCi+6ӧ(|ESsTzjBnISGpl#6De3Q'3 KS3Sf$fΗǧW_mrn;2n^n;f]g &㈏uyJE}̸ +? +Y29e,y9EyJ (w>*34f8dzk+g1$} :69R*&N1x):i$ +*L$󆁡iƧL2JF٠8El|I qJavt]w}㗰=uvv||?F`aR-Ou/^jbcTOVa +Uh~:(ܒS5tq@l9;пLF:ؠeΨ;i+FASM +tMyMW[җuzۅğ{*[zpb=8_󫫯ǃ6lkMLk\yʟ wԚtnhGKSg޲$03>] vXR(\qQ؉# xx]a|? ^cQޚʧ +"HZ",7oorV1pEHOs!S)g ̘$,bhI/pGe?U*3Ʉ$DʷTJ Ȟ/ho`N;FG9G$4!S +NbR$|9EI޷o{yN}6B$brJ1&A$C,orȿ2 )ixx?KgLOY$o +mǏH{M{fJvtpxy(/MyO9|tʸȴ9bdsI(!͢ؤ T_.Isͪm2K&F6 fpY"/pc`/Cj(#'a0XnZІØϿm¦jmFb|q]6 NT+OE\5 QW~{G'+`}\>d4MT&.y\\LȌ,Ȋ\| ;sr{^)WTV-u77wzsnܻ/\'Ny6նvÁEXZdtd @vrjM_' +J2CajH[ ZhG +71B~uڎԀK[CaI4fFc a9)|GIZf2ٴ +vZ&Ycz30bDT2hRnHrq_} Έ~4[|ĥ3Vr +<[.QW9ѯؾΜNO$nv/פD| \ yZ"wIn+UqǗ[.GW`NWUgJ+JY lzZ5 +l0b{^M.crDh]C*,q?þIɋ1.(/+.|"C( ǩ6bՂKuo<_iY\4.ᖘno2IF#A\j(aH8Vs8b!h e +a!"xrjV q vr"[#jlӨL#>1xi*YK#c:S6xhFm'K]F?јiLxjWPrAP$>|̩ܙ?,ށˢ +_$S}4Z8jG hm$qBkڵ4-5IL Hq)aD2hn [^Pͤ +t./]&%qI CR:CT$b0l +)7.eѹ#Q +ֳ +K~lXIHѽ/) i^ g=OW?\K.,,ȋnS]P½Թ;lqFE8 S~؁ )^:!3I6S +꼏_#'INB$шC% +b?m?Ŧ~Z 1r; Ô0I,xäqꞜsYks{3܉Wе{ZEռ(3ƶGnmZl|5 A`{Sj,NL\,(9y9jNU`gY֦a}9 +qT քC93q\QzYjN +:Ƕ(*n{iڢڬ+ܖy.'JHθ kLvSipKSΤ@ 8i Iux8 +<T̞\weH;~B?ϯ92"\B;A)AS-2ˇd@<7ϞD,iXU3Z\qELCbj}0c@mTjL +hhDC$u WlDʕG~?͟4n8vq -u\F6Ko]qظSϻ ^L~._^YZ6'+%SϿs߸!gJğ gyž޺d ddԀ)/z1Ű$!&x+,&=>˘J Ok467&:܎7㰒x XY3 OcHH^FeɸfՂY!JBX׳C5X +߫/ݧ-%,@,q k·8 +چ55A4R:lMݝ:Jo.G4-m]=}W,z_jy4ZpN;^o;n_|zORx %>5UbզyvAS0fPi3SMs-7*b +?VzN5\T + +C(FنaRkVϗ3Msj2>d5*.OTAIܰwkvE!L&(UAδ|yX,,//y?~so۞͝|/y9_FexxCo&m9"oM~.bT4ߧ\ye¥W$m<'*3;g&%oJߓL oOfqn߹G|<{"ϐ?Y ;=:y ?ʴ-Ғ7+IHnO:t8IHAel=l]d$4W@fc`_%2:Cx >|T%i݇ -`9EI!)4O,H}h9y!` @J3\ֺq[utӟhAj(űoM̟MrНrB54ȅڨ2VMVS{qAW2`XuER)ߏ/<(x8һ^>9wμjNϝ}ƴ8mk~N:nrxJrFĄ3K ?sA~+jg48O9}.%&=͹ێb!.o1Nvvcm\t`n=O +Rfv +NBQ +Map%>ZzH%,ֵ]{vOkNGc#5ck<ŹauE'c^sPN%WMsq>VVUn>{[wY~/[ڳyja0WR+~§wl:qIf +|߱_.$(BM8$ RD4PϜQ+,6;i|{_rfq`F܂:H/Œƃ#cAA#`'8%ªNx@ YqK%B$b GQ z8'%i9KY4^"fr iꬿ6sq{ +[G'3++Q0Zs̳-!Vl{'x#hń! KUcXy8pj1YbL& H8U!+$yabh1;DxEk*5m5qML8d5]g yA *1ڸ>HK|=]} {5a<}$54پ# &;|tb|\5Ű! $d;=){Iw=T?\JOW㥱==udH +rXhL7a_BS9}Rǟ{׷]Ӛoڎ7FnTÿG~Y|qfad_~9x6^~;?xl?dN-.z_w/Ks9yakjKnߋmu&*=Z;NSf,3-s|LjRT6d7NgLQ3|긻Sv9ِ4v".Sű YImvՎ`ev̞)_54qsg>%!yOe\qprooeyf70N:, ۲GcpV;ԭU?@R +H.Auo"~A 0(=Q>QFs5LOKIFZeGo\Zƥ+wE[mѷ͗ *_}!cя:yϯ|3psZk.h` 5Gp:J^Pw& +K|Ʒ}ԶxvdAa|?ȿ͋|Bpz\l5f$IXU O:>{|X ~s  п|xZ}$a2dN$Vxߔ>>C{V>w?lytgmzgII֢>2ܫW̯ٸm:u274˺ǃ!؍&!{ fbcGG1lxM΀@-(^6/0pVajrB\KS,-2@UgAe<6gO"汓v F4pɦ6T.%1ţ?n3 CBf`wVvL+yIw*$PQ{.4I+w&/\4mJYJ9Жe7^4Ss6&L*=}ѳbѳo` +D\^rIQ|kŸ>Ý7`>ޞ,Eܖ +EٞWl/njbNCf!PB\h:n'ɧsD>Š|oڃ-kUԁ[ +;Itܓ|gx3 8̘rΤ r7[oz +G&db@Ԫ =eA5Vͻ$L%M_ћۋ'ok=U/n"u;_\ѱ+`^ +V^DR1Ӌ<<M X\xkw|"|O@Ta "8q$[W ( gϴNv'TXKR,,]fqV-}====3oX__skAW7 qn{70{! &gwaG-#%;GӇވ +nNT!aIϩXIũ8VceQ_A']?\֜vL YTgq<$$7$뻑gq._\1 @Πھ?.>:39>ߺ|Zч~ +ő85*.+I4Z7%fګDHQkcr1mf}hAmIx#ξw<~]˵3 +D}EK<#O-Xp8߷o~?Sn{=)R\җu\KR$9ϪZEqaqTf+*n ڊnl>[Ȑ &ZD"C1Zd>WW|c5:6FasBZ&th܊n7o6neq +X J&$pAf9j36FAMf3l3x r,DO{p +|jIY%z-~]QЎ'sSy /%(:#Sb&h, +˙mW#qLzK$^FIP^$dO7On"UvOd*L޽ DnVYvB,Uns1Rk( bڇŸh}w{bfMb ;<؇{3nE?nV\u~ѿSE1s?&H$Y$͔fsZ +1wғ@p*.d!~ߛWHٴtl!ݞLOLO"{sRbr,,Y)KKK7+̛ +{:7]~n)33O%=@@Ɠ_sJWG'}|{?eڕ`6iƄpl˲t8bTUGL $&%))1)8P();IɁ0R]GJ2 +ʲjZr C`2NKCAfLjL^qe7Hf9 s.vVD;4=%AO*Qq +Oy1M>t\Y,A!%+yXFf~}uf~lK .uNKk6E_XzљP+ĕԱeU͛'ml3(I/ǀINhA jt#'%O ]\-Gk! +_oyzr`_GK}?z%{kyd:jP7!x+=HjqPA~1$$ުcN}\k/9a7uH=[\x dF#?c?i" ]sRŨ[ 9MPv=_ } ,A  P5gCjO 8s +Pp/2Z +BrH{d4 v#Z!$ +'R Cq)ٴez,\Վ +I.ko̗ +~ݳP[*-["(#PV_UjQvX;X8la):̣qr߫"JÏ밄a 8F<&O6[J0mVaas7zqHtT[9T a9>E~BE간V3t؈KtDMp}; +bu-aqSyQQ#2XO(3"xuGrKt]E팳aO\eunjF+9#9EkaUie뿚X?tX?b0F5V[t_U|jef4*sܿrþ9!Cf{ +lU[h][cJEc~)uԸ56>W;^?vt{:E!݋3O!-~"W !֚)3ŨBǤ;pLImU +!?uq.;ֵV7EM!e^[k[7)3::mJ{sCRV] Δm=K +&e%?Gܬ,jRBkB:ۚ9ᮧ +eL͔5.:P~Nq9/ն{0AdٴR+ٮ,o wVV䤔ЪpWw3Ԩ[n@]PV2Eʕ+sF%Zh9#=;Vuַ7[R:׆[WѶa|mt=?\ߕE{ 7땅=0mݡJ[: < TC]UYƈCeK[gHiio򕆦܄` +ԭÊC +6NihRzWt=!em0 +4S˺׆Z!ns]8+Yn*ڠġF5HX oiA­=]l]Cc9Al 2ζm=i _F6ϕPs;pMY^blG+%k +7z}{{A4v)0P:J)N3%ۭ.}h"tH1n:z(= +62rS wh2u˘xmK íu!Kc4o w7ׯC֭]@4.1Eolkic4uwO]vmN.9 +m-M-͹-tӉP3X̜3cڢ9ʙYsf_XL|^EVմ :5b&@(̠q d:um=e63GXp0 +:C!*9J54k1h[A>*k8`BӝnXQ +1#`i@zWtC@f1w +<ŠTڔ5=+@@BƶQ2]7< @땮PCg[Ѷa* LagN[CTs%L'0m4!e +ւBYj@_[@P~Xu&:NcQbÀku3f]Mm=`:Ck¡)d4@㨊#kCӉTn# +}wwON#9yʤ &+0o„:`2j]}lHuG?QF= +^P\}Z{_:Z~bpǸ'}p݉n=큻1mg#??F~~6󳑟lg#??F~~6󳑟ld#}{FØgAIsà23䂖?4ǰӏcDjt@۷l(9ʏa +<۵wDZ}s21f5N~ +J*zXLiulώ?+m:%Ge{ʟɼʟWHDAYؾEI;~kux18oDWp*8a5 +pZ +5\* K/=c H~ +E7? }S m-ײPZ*1ZnۧrzHBP)\+!]iz=uqp_AT7ƌ9h+!q45Ps'h߯a` BZ\`͍i>n.Tͅq>H! +SH5BTiH۬?7W~_5MfCdzbh2͚7=Cɛ}| +(.a[%6-țHT!H!$!^H E~Rq9hK`y c`EǹaHk݈aIdC"[ŭ+%bz}Z +744f9-ttT i ( BtA2p oVo=ID2)BW!c/hf*i7ӹd|[H +&2v?7 <; <3 ~ Y/3ƾL<2Q>N3o.A|+z- ̫̀җyw'0yp(@~q+yp@~X}9s`[ }/x) ٻ?q@ߙ:5܆[ +0@1ܯkzۡ+˰[}Vm_ +.~6.}0 wKv{+`9Ao >睖zT&z4L- ᝐsě( CGx[VI%vJމRoz3t7EMb Nl,` +!a,Q+` ?_l h.rF\\X8=29X1 +-L +VD U,ۉմ4UP"'`#BtqVE=iE@i+a5z^]=c 8QܚROsxf\_zu{@I5~=E#dVGL#T0\s_ [qM5>h&A=\8#`b^=-{U6|U%z [Xye?駫 uH`aEd˗픤ZWV +e9evחUw`wOwu +^ +. + +΂ + +n +\뭂Vn`Uۦ?s[gVPP`UpT**u 5 ]|16S0cZ +V]Bʦ/ +endstream +endobj + +58 0 obj +17953 +endobj + +59 0 obj +<> +endobj + +60 0 obj +<> +stream +x]n0 O\Sվlv{WN %4c T7`ks/ +LEy`{a%׮K.5B9VGrDhXȚ +9)DGȏܟs<@>s(cpOb_cO+_bOL}?|x&5dAnԇcr@f}v?T?bPyܭu#BCISio" +endstream +endobj + +61 0 obj +<> +endobj + +62 0 obj +<> +stream +xy|U8>3g'ល=@"$@XFas!ZE[*Dh%$DjZEH[RiKVr' j~>3,,6̜tut )kڪ-DBVK}$O#$Mkl[Cم6!Uk66>$! +^l +5] AhcJd|+rNjZ۵ >5r@V3~m݆_Y,"4rK!݆PvA[kg(##fH!di< cPi(i:h2[6r{ ~9LJNIMKȜ8)+;grnՏpų)=3"3c VB,?6N2Dn9hg -0z9Pځm( b4P'ݍ~@EG[F;4/Fa>>4h+ңh!v:|cݏ~o~:Э^*A%P.>Eǰ6 (m#ѷT~1e!~6 +6 r/zEp iZZz +CbN 7D"Q}<$oΈAG`3_G}9a\;÷D> &EC?+ѷ W9F,[Kn&7so,m +B}:5:^Wb +u &A 4BOCϯױJ|=n;iG>![9":?wA>t5ڄ6mAWo"੸ ?i ђDRA$!7{W + wIuR}F~=Ȏ OAe@[@*D';T~x9zwO/0K>d: ӭ>r?:|Nwoɟ9Kpc\7ȝ>-| +O+|8+\%, +O / +"Al?nhk8cwiE@v5 IG +oit +.eK8o[w8~fs =E|Q +y"`n.er9rm^rrkn~o_W kpB~!\.DbxW$JSJNMo63`xkA>7sydgV +s؜)}߅|SY$Xb4ǿ!+Яp-{U@O5N' )"Kȣ} +~w9< +߄ f&qqT}XFnu +BQ }BBnX:2w߆ի=  F|+T 7#(Hԕ`IFD'wM*ИAJCMׁ-DQ ޽ѾoE7F[x"'"3܃w^[" +h}=8> ۅ}AGkdH@u0z 1 k7^4`SaRG؇@g_ΤZ(qЍ`'E?B0nQ=vʁ+n4@yT)ZC0ߠQ6`f%gh)jJ|8pe; [Е8?x& +?b&FGf81Q+]af0r +Ycx!J)qEiS Cys&MHOKMIN +&d8v9vb6 +zV#& +})}|JpI4q}2d]^Oek*PK5XMe&EhDyVP{mfP,3r9cvAi)ZyV_ٺmjgBs`iX7i":l;30{ִi0>_p>op&A0qh݃6lvYWWMfB3ܛxƒиtqܶYf&m* +-X64@me@E2Fn^ևo.e::Y4zO2شZ`o[Z1)GojY0W-8Ud%&Xc=`281UPQb:>^, œGx*V?O5Hsveͧ}B%(o; :5GLQɨAܗٗAED*gtɔ`Eȇ*uӲe] +Z biGJvfu%C#%Ŵgd6|m}_e4Mq8V^(X`2yֶZUbSGT^#*D8V +ByheXfWdBǁP ,YjgǞպ@_ JqHEch(e^~Yq0^>W-߶MwYYmʂrٶmuўAv!{ͪa`]q}ewW$4V<w,8;-_v;LJk>eˎ+\2KS2Mr O4(P+YKb4#yX$pS(/+ARؑG8F^(D|(WjIe}ڳ<(>iZWYCek^2ݚ;- +ݔH^rJڸ8g + oY e* Y/Slc04.9$чH 5B~ߴ Qo-ENxðkLMo6fҐq:Ndv,%Dc?!t}|!x%D%,Mp!R⧄@U2 +{ 3?lgpd&LK/DB$QD ԔYhӀhG8zgS᧚-!b2Z6O$hX[ &RY+084tW毼˧ _/#5+HYM%.zVNx[۵w:tB/k&k itG[.h$vt% RS +SP+@Zy [!=!`]L5&d Wq'diJm3jZ>E)_NƁg2]ńC!˺ҝ2|.}f4ƛJ\Bȩ!u'T<&7ۊlUjMQ8(ASbz,Μ=,V&s5-06]xCِPg;&leOX1u® s@yxc>2:8 +xk2\+&/2'.(˜)S(͟vy׿xvGZ};Hos:< "s1̳^Y\mv5mͮ<;NK>96U64iW[/7on7k:b;Қ= 9#d3֐(AjUcC0ͅ +_Ƙو\Bj&2/ˤ P͙1%U;^[p +,H"N#2W4ߴyue#^(':EU;5?znK8y]ȯ/++{ss{ҧ)+/MX}}2J |ROԧI$y|+_y4GKP%AN.aK4 LP P1B_g!@J .yl`Kߐ +vA{tOY7^[{]lg@U`.sV,3kKSh-c7H1Y +yPX!=uOyccz?F`:V|(.zCHk``JKS+D^xåTK'?ʜ^֤|ŚyyW~⥋ _C~lʒ )Ksj">\q:p(A1SaLJL +Cr]qfbizc8Ѹ)Nݺ=ƽvNkŠW5ĠcC!$ R BlC-ۅ><kğyWh1?)C4n˥_?g!rU'R5勖@jXfk@@Am3tovL,q 3'v? +^UR'( +u,i83<4U ʼ\tӌ\7XXܭ{*Q0QVФO~6;2ဋ:bٷk=^quȟkn) {w)r~Mɞ8}w|y 6;6.͉eM_ٶ7Uc{}~ba(9qnjO@9`AQ.nW$&^Hp͎k{VowiJwU) +e htD+ULwV{דn9%p"$$NN4&ѓ$%1 +ބPkҥ$Tƴ0\+0} H&<@.] ZnJ)CHsd0MT#CtMS S44c߰@oW¡ZЫ䀍Kpܸqno깁gRgv JLزcxvn>KâV%5$jzzJ oɜP)` "'1sEQY}fbp8ן,#-7'/y? +_7㤂e3gѓ?d=|#wvu|WSVo' fMҖI-$7 ) $iƌveZUۖx~նM@q!4g;i}HD· DֹML} +'X/+wR4ps;eYl5]x:s`ѳ庭 +2z"E(9pȋb-{榺;j58 {'KmnyÏi"QRYP)ON + +_6 ! UuKhůzܪ(g^lhԬc$UFmld"fo1Oa1 6q`Sa`޹yvJX<* d(5#ٍS?yc݂~pR=O͡~D$f>GԶi{۵sDB-=Lsg4WE㈇Jb&M&g{D3ҸR;DX˴=R\ڄ!b]]cn6v`d7#` m|޼o׿ו^7;W8 +vfsmHmʒ&h +#b0zK R|BC[AXG6xyPإpH/fkV&VK^Q8]%.1rГWnT ARыv< GIVf? +\w9a+s;P˽Wz\PY\FrbI +VA8jFnjjQ,Kp ī G1yѳ|;JV+NrC]d7q;*rWro&GmwFA7C+{hĮALߞm'vM`]򜅗y®ds!ߝj3 ^ಜǿ˿/OK*p/uʽBތ=չئ9Ӡ45Ɗ>hH%8vh咨һybXt}) +nGx7z村~r@S˖ot5/vmٲ:㞿c =EЅiR~Ǽj]_k6t;_]9^:x./֕Z'M׭k.Z^oeWEdmHk]Flٶb@c)?yŠ/16}1iDL!F1{ڎ<`)3͑{_s#;#{NK'Eÿs"{5QvDXg&ӆ< +8b@wV8Is8`bͮƥ="RþK] t= d)YYYmY=Y۳z4rVNr$H1Kۤ˗戽C3Dl({5WcBlW$3[#*@.44 +l{,um5A>+n^غ#F3^Z>w/a[o敋 +G}hŪg2Spݨ!K +ڥW\D6h +56jσ@ =?rn +o*h/+55lQ2U\I$ +!Dⴰ&j!+PW_ggw)^E_sm=IYUղEBKҍ{/)^ Ռ)_P"[!l_ӣg—,\N26vM_s½yW\&MThr5} > %mN+CrCNئeHF}QLa{[Og3<-ۮ\Im~"ŁNGI,lYPuuwEFa.@=7.GcE?f$h2UHZָWiJKK,;,;:qv|_()ٮ5e&l,WWǵ9.'7n(7;t~9f+}[/܇{nLJrn9/߹ّ kWx˼|G|ro%ͤT"lV0`- 9_bk̳|Pρ3D_o+!ixk즈LtȈS + +Pk2 + +0X]|2fmƸxQ [Td%d0Y@ +ƌ5Dl5ǮhrGW[i`TLd[WXd4Scu + k +!׽i&fFTSt{]޾Ao#3<{;U_Rq:֠‡7tθ"}O}ˢX +angT<JTc hp.C iBPp&4 +L_MIߕGmxN|З~2t gWBt\1{X xɗbo'IF'^Xq):ْb*k87H/.%!Zqm<ɠP<TE+S`ܩP5U)P!)5L"z{9՟ړʡT95'5ʧzX4rԪQ5M&sJm,|pܪޑI3EFJ}Ka셅1wP㎜ǯ~<-!r6!u SJ&E)>UxqՊkg>8\MV|?h];"=|bٖ/6o~߯~L]GlK%igO7NˍYqKiuc=3Uz.LOL + +m@BqkTt1F +z^ +luR@$6A})X[_D\s@l֖Uۅ4k%OVzcߣ:4ZPbJ31ZMs'"-D~Eϡ{Qcjv͹ U]E58B-)y1E/<[dНFnO"OD>Hm=ѓj J^!]v5Bq ;J]S-lxrb `9  +VKX#':\`{W`̑Arx?I8\{`yZ87^QTfь焣)/Fs//^7ٖt߾C69Rx +W)K|ƻ#݀Uyñ~{8bgq>2QTM[M;5O Oivv۟CGLփWCvkȾD_m\a]h^a!o-9&0<<6\vgq͂% Q@N`wWhӞr ;cNT +|Z? v.q\sYqDLVXbCc5آt]?k_{O3onZ8U[ՂVh¢K7`[akdO;y0ǎm=R +iœJRu*N5IZBo#Kf>sbgpryL7kiwعg" {O#>ŧ /\= Q(l(Ͳ>di]f`qf[Fx6+^e2:L&MK\%^wt&_lQFv;A/*1VVߒm!ٖbKЪڗl6fiI7V@ +q=~$.:W8Bз$(@n!#s|RW +=bqT*)r-(lb5cX7o٦ukl'g<0|OQ7&hg֭?9sy]Р@ U+ӯwkjvz{4OُYۇۍNaue9KIt Le,q2 %ᄘlPL+ړڨ2c*$l`!'%{Nz&~ өoqy]Ui +G|"n^0 _4wȅ79>pGw>{n Rz7Av#@q0JBN.ڄ#P!#FoRH£~u@Am8M[ +ڢGA[O +=aB0l pj03b5(o=̆e9D~1)lK_G"{ sȆS灆N@+瘗J71NiuFL7Tf*3K09UnF:ﺄ;wxoO.`6-2u7$da4J[ tj4Hch1qb8$yqk[ תck{1\=a_c/ӆY5tZ#KZ.;\.=e`j Uϋ/t@ouT]X_]_T1;Yhū>v۟).~:0(7?iٕs- + ~'{g>=dM϶[+4Cq399qRo8 +=<^o1F<^E9˙xyLE8݊ӓ,ҋ1 y^ȥ#Ů4Uw)V6D~\Sx#.+SIJ8n*ũN#DL#a浧_GQtQB׻^}3ba>>Wj7c_0F# aEԥSI3"QҗC"d /w?\ +iA^K <mH/',As!yUth%y@XB`U_ThLUaMHd%m +0D%?-Fd9ZtG` +( `aX4 +Uoe0Kc*L} +U +Q#C)UP+jХ֒ahEg72,f-eLFd + ys 7'MR\[k ^8` ] k! g:y%+6հfMLTi'u*c-Y:ƫtȌְ:mLb0c3/ͣE5ʙl4T6ש;kFDZƤK+RW(plQ;Pv lL60v2'1ӱK1mTlzJ2ԡM ?6jn=+X +ZmLK6bf3iyDաȈGZoc2͑e ʦ +O5f1j41]ZZZ,ՉV0q +`%s2&*vYtd1*Wk@d( p +{h2ezaƶpc]}X~Jj +Z[Z K.mhkjnmg3/ic54Sx sK.YF^ؼS^ w 7t4׭uMHXL- wtҦrry]cU`X[U +Wu5u[ήpGAnnEre]"W͓+亖93 esn]Qִq|VXQemN77H[hou4DTSsK[[k:6ʝu@E Tsl^2Qͽj5C֎Խ/7u4 \ kl#3 +&wvBwtBu~w}ܬ6E'7w512mmmaw@ꁨ#y]-]a]@w,Qu]Z ExI;| w!4vY +t:inibSڸ&<TZ;i/Ꮅ-FGjh_ +\oM5m@VyU0ľN^׆v-P- dlC'1r7Sb +05e['5]"uʰ "Ũn旅"L L# |6uɘxBrmݪM-t~bhٶn#bwյРJ 6Lumee5uuM^~}ZU`[f7u]_쵝+ijh>r e~E՜9%Us*esJg_4K.jYfͯ2ꌺ& ()O`0.FѯQ16*t+7[)f=63ӣXp0@U0,К@ ZWR5̮Cs=00.L)>7EYغ*̪0k@zWvwA0VШqJ()Ft׭  %/na2qd0'rxɝmf0:_ TlaFqLTv0r“r7]V.R2|4?6q{NQ4G{1C܃G2=4`*%T >n@P+w/ @IsP`@gʵ@ zYZ@5`wo2sB1`ɭ,qp\ +"?w3 8\X +:Nelz13J8ʅx&CqZw)OwZFn+<3=sN8/~38w'!Zn8CL% +Ydse]p-7G.([% 'e܄~w] +7_G)wDq} ej.*IPD ˇn@ۀMۀ5ۀ5`ېJ?66n=a<4 +a@RZyc@; oj)8׉* |׀ۓz`S8mZ (sFF?12s~ɫ$y;V\_S!rrzQ/i|$пŵcǰɻdCbOA#A|?3 HE'K~ܟdpǩ͕[L^$/xhm ~ DO@xtAG!>?!S&!X3dD/hHgQ,UHIA{ +~dDEP<{T 6!xZFK3܆* hf!@7BtA膰G`F`16h6hcmn0j0jF-`F-`2 :ZeQ Q0*0*aTF%`T2 0PCa +`(0PCa990r#0r#aF`0 0dCf2`Ȁ!0dCf0, aX!PӀq0Niq0Ni80Ni8MNPNI@9PNI@9 ('I@9 ('թw1b!lb +F`F>>}0z0zaF/`F/e +bυr ^ŕtoFft7,f +VoB,^RX 5_`.q B+]C8Abރ%J"o*]~$NK,V Q/\G̎iAfx~ +x3|HH?gx'hUg<}C ))32}'n ~>+nP!$,//S& +!A] U!F{FDajÓh?+%Z|R7?{3PXLD{!jS ?5/F~V"7@t2SSh (J2td+)S?~!AXD4`@x+hm3+UQbvDPʲJƕUM$-f/n҂ HN5HЋ 5P(BQ/&4 +@@?W[RWYqni'-d߳װ85J]ziv`  ki!Q7ﰟ@՟Ȍ`¾w}Fғ9}:Kf7[cgI{=ahgON__QsXbx @F⹃t쥀A4O\B0"*B\W+ \z$E\p@UF'P`urkX(M.bc Ed>,C}a1&sy\?[2hwX[Лwᦪ]TιܼsFZ]VpxfdX_waejm^ekؖ2A +*sV6A\CqmV +mUa~~ +ba6A4p3W3[1˅l7,IcrSQdwi,=e˅3x$f ^hr1Txuc5kc,߳ +;$'Τ~߀, +'t2jyNգ 4`pfPQMC%KTO0U/xwC'=D,=_1b +)Ba")RzL&L=s{fƒV.'HhӎGR#`0ÉaxF[T#u1N?vl{-w$I ?^䏖/u +endstream +endobj + +63 0 obj +19844 +endobj + +64 0 obj +<> +endobj + +65 0 obj +<> +stream +x]M0>nvv%EHpn+@8?;q)ũ?E0D/c(Q/y%Er⯇pnK|0pQO?Ǵ>_}XTU9_/%0qy<?WF֚*4>vuUj߷{..PB~ilW\kcȒšwoVFbvm){梦s5Yӿقo*0 +N⳿ԡI.<58ߡ: ӿ5FC'L\CFbH}kҿFL?//L+rVGGOl?ε_?v#C +gU1\*mL{7O3YhW +endstream +endobj + +66 0 obj +<> +endobj + +67 0 obj +<> +stream +xz{|[ŕ{d=,K%ىe[NLXp^$NjNXJz4 &8"DS! c ~ @?@s @{C'+ +Q4`d<ѵuౢA$ +:~p7Ol!);Ӕ8~"5=/ay+1l06 Ph2uZ7="^&ZDI +F9bmXԼyNM_2{"#ErܜCv |Ar|M(</ohD"VR7?_C4F$z5s~NABGP 62a{OE-M,yXE+͏JkBր2GHS✢ +Yv:'&:JDD|zހb +LLvuM:qm=8jzt޴B zsm.`Jabr ?WQ;{z}OHMc6dӜ{b4;NGa/vgQ +e  c<)bI9grkhJJ,VcpU߇TiGG *|"E0tA@Nkz.Zz ++ގ@׵(sYRJi`|+Ѥ:kG4cqKE{hOXӝW>-`W#jV[ +:S1o#|ӳ_ ([I}*@1OAfg^( +@@k;Joץœaur-.YVP_t/J((tX%rlͱݛ=CΓ|_YAq68/ +gw.D>Inкkwm)U-kZOeWA AR@O{e-Fą^h.Wu!m5Ť8N'V钖cWZZ%/bϡa+z™cf +$}lltjjKԅ]MmAv,jv~3_ō۶x( oʒMM%λSj##֤ypy݇^+"O7٬bõq-N=+wSxBڏxԤ7+R]c +oc .)ϫv-N35WM3zZ/@>-F w/ ,|''O6ӊ(MVm'/OqX/x& +JψNmM/%>^B7UmzW߷b6]XyNj~J!+݂͐^ۢF`J8Yt8ՠ[A_SCv5:γzo7}֫zkxX<_UjȽ5k1C%=]ux+7\QOboVGدK_fIމzz8.A,ʦC2Nn.BЃ=4H17k: + +47} M87R9p7yZ_$4vMy6 +VaK+~ "Z)nfV}c$hX±Fc +6nXA c8Ht|xc Aa + +4=~°Zxc yHs,X!DJ9p{0G+deS=ñ;Ss~9S2`ӯb.LxcCSp?%76"nXŨ0lvm hws,Aqa+scGAi[џFuNjg=ƗxIXa775qN ^1}4{9(1]dXfsLptcYǼc9p%n*1ac2'8QM90b{JMuuyh`tdld߸MLJF)CǔXrX2Q9o9J\w%GPR[^%W.Sh<<={#` $a?}ЍmF0>%q8J0 ,CJd:Ɨ8UCqO.X"j! C0`5YƑC4 +)v!*䬅CQ>+D%1feբyWi:rWb3qkv1am G3!6jNIqdYC,>4~l168@qB0hc,Jput9nA?JbT} |X 1+8K>¤Q3jQٌKR}UceG.l:O(Pl=<@yϠ0ߜs [] ϭ0(߼`xV0^"lˤh/cΞ1&whw%BOYY~qճ{ʏ/Y=k.ک@;v|ne[1LZ_ƗxlF +1/YZh_;1,~US݉깽xw`q&#ܧ|ҽ>nΝGz4:\Rsa^5s ]BU//в]SAy~'7駊{W*ςv*dS U&|l<|u_ǫbϜp\댲5Ϣ#uR*m=ˑcj/Xƽu[,5~[j"$KkRLjt%5/WYJ#+Qj1wr,_jIQ}_y'zRddVG݅MVGx4{3&s +~L +i<2)BS왑e|8p980(ɔqP\))2?UPHb B:+S,s`p2 OwfNl堣X+T0,33lwf@0r +**Œ眢b)T"GklA:B9se7Tfn$edjdRC,WGVPc)$ge0p`6| +@Fh,KIJ9GIk8ظQSꥲȜ 3lUsPt1`h'µ2WBĂZX26Qi}E_W=yU~\^gD=W++_~([߸ +!Z_6=@^ovg^/{ hps?mS|iSOO=1~BwO[hp4u?s_8>syѿ#l'=o} `.(_6j[;V[qkMuʵN)zfވ>jUËGHpg*^!\L=Lmw׾>1_oi\:ADdBdϝ]`m8>z\/5}&.NIL钿ɏ` +/;69UN**JY_ɲXSq_y[#{NEGw٥Yhwzd6pm~g)V i%#4*yޛq 56ci#1ɧ|H[hh'ig`ډpx(4> +endobj + +70 0 obj +<> +stream +x]Kn0Oe0$DBH)I$} @-cg3Iݜ}&ق6<ݜ~Af\i+z˱, v=駲d[؛[ꨦ+<)p |QaެUWЇ>O}FH(nT~Y_bgNIl; 3RK{i#^~v.Tݶ +ޡLwmc +e r;cut>EgsI!8~<*9GFsÉiwj')z v +endstream +endobj + +71 0 obj +<> +endobj + +72 0 obj +<> +stream +xܽ{`8|\wfo3g3& +r rQ.$ $ (\DT*XbjRhZhEE(oKi=l}}__yΙ3  +G2̬hvN,7_~#(g#hL'ɝ +w'B܈FȇFZC h6܉Cq ف +SKOPzt :؟ ݊6[eh2jBw h:ݎ hj듳$O>~Hv#+ +:8N$#o<FgAC+=Vs805 }P%:1q}x-;jy&ٞ<¨5G\e29 6VAUt gP0+|MtoHTD2x҄~Dpim|k!f@o7?bnV +nLG~O3~Lۂ, 8FCPpblIe!=q6УqSlj߆1#̣_r߈0Rt71vx +7x3?OS<3,fd5pLZM]ĬįJ%7)'`dIg_03 |3xލ;S/3wO|ApLd2-Mǘpb|,6Ζln g.ȝ䒀"~$1:AYoS%$v$':Fi@ `!CkXm W x^W&Ѿ~>ۙ0ǍL=t03_"kel^Vla/d.b\˭>>o T$t +%'Sj^g zg +h )̯_?EJ8م0pͯ3Dt`d.1J<OCAFm{nPw+y`÷0_ +6# 9;o,rO?p2.yv2p,>^bu 3$e6 q7D,3h-f~`oABt*kѧ9eB4r[7@ FW1{}D@'9}zy.Sq̀uhZ܀V3QwZ˄ UL;ȁl%s&_ a_RWCtA{;1N>N.D˒ 6'B^ oL܌QfΟ~ sle>`1;/`;pWVwhHnK;$h(cDf_r =$Of`5$I(ȣZ11}^qUÇ +RZR\4h`~yhVIϛqT۬dc +FGhv.$>5dLVCiWԡoԍzOIh娼6::){TJkp%Spf&7q6}ʆkFAuz'[6þ1adCڃQQl퓧=*YտkGkڝqZʹ #EڌHFۺSAjsfU +5j9MB宑6}b7j$uf}Y}fkU29cjOӠ5fcլvHȨGGEZ&ڰuQ +&M]?'ϢhmYPvTxm@@W>_OQ +s8Mf <-NS{0Ic!ڵ: +z2+ +cJ.CֺP 0>(.٪ #v>Gj[]2r">a5x|"H)j._F +n>4p[[5ПI|WA}YFZCB^jgjȓc'i3ȓ'=D;ns*^a?<7?e,m_2yfBcBLO)&Yv. wJ1JuƵJ_L^ o[kf7ۇůL"}El[Y0go*_ XhpyGgej# 93yl(9B:l$)gd+ +L +w/n1Qm֚zyy}kt&j +pՀ`5x˔}:2mi[`fd5U٬B:eH.$ $x Xha)G3h#gIaTyJ*u*MSUuNK7Оv$/zjf|(3+D~DbDŽg,2A #lv_HSf"ɋ("_V"HseROT.ƍr]\UVge._V}e::`VEw9akdUy9҃25+Pӡ˔,pTE^0>QvFU<$|z5o[7cB3]?sSwL|@Ȥ_~+; ++!mDxm|<k*O}(`ji]7IVKZg\A9}*s) +r + +pUGk]KUªK%Mx7ܮTEBaYDG.&TĄ9Ef(aӁH) ++|NIi'v;3 u 'VBHd`+٢_!VDVԬVf'!I&^:!}:^}n<+1*/˻cUV*#܀?-',*1-.3c@,H?K|=-xߜo}b:εL38%Jil}y.d>[l #^Ɍ P>< +˥]#EI(# 碲BsYd7pŠ +G"K${$Iȃ1tDFX ,6l˲.z%qʥ`::Wm0KY|Q6MGfqt^ep:q"/I8C'/Q*ɄW$?!J#A +f+j{kd2tjDvS:h`6$Z o,`m]f4Beb.~K8{e5(χ +L^Wq0Cٖdzojkp}?4%$ᏤO8yDbwmўF'ʏǁ CCzd`~?{~~}pڐаE[=}4۞GT,dP\CWN&<(/\o.6r-%Zo2|@2`,w]LKU|1ҶKW_Q?_S?_Q#tu|`6B8Jd"ktF80d^8 +RΕ¬_RJL0?F+#F3dAm6Bn%eӆ +eNݑbc{c|jfF3! + "yce2\#}Aj +_N +LP!06j?PI/Hg,#Ҹ0hh;˻.vŕKAS6A; +A#B#U~9$TA1k"c% +QZBž{5S MKx}+b¯lËŧ[n]_v-/LV$_Ѱo9EK>c̏7N0seZ_~xv܀U.oj(0/U^Wsäny;?| 3+`}#l˘E^E;e 4w*Y`]96-5b^.rHĝbxL<% +"τDBtBN սDnpAɼZ} zEEsJ%.00r|R5ZZQӢ^F N(;qO}1Ybc(f6q"{a'ϳgɮt5+a4-b$׆^+*04*}zN֗G.ªQ棢+uX|̇}d6 .i^2`2m9t) #INIg%N"DU0Y%}h˒LZH^ҒP^cH Z]TtU/c1w#32j;`(\VP8[-j!PKQ5hxf)D0Uڮ VLRVuٔ) x㺥J[=)”fb< FEpWʎf95(YTasy&@D1 {u"Ľb"Sb-HQQInR݈cED/!{4{wz۽I/e<`,i: ~!L'G:hBFp~mQ!J841 +a}(G +6POYM9l!l8C,@DQ!Mq˱/Xx_cs6>N*CyR7A5K +\պ͟1.S]V/tTr8$ 7aUۡ"ySގv"LIEt + +|K Z}C_oH@vN'^u ċ}{Ky%L>9]}u>YwF3% +lwcSCeOKs)5{>r1+TSE-Z`-o=蜫1k +øΛud\%s=lU&?r_&x:ͳ٥t*/G r` +~H9?O9qx.XeSMJsk>RQc͢%z0+ s+ԅRu ~ٿ?`_yлԡ:t[*]9Je҄ۂsO%&rhz" +Sz+lE̳*8B)L"ŎS*do~zŇ5OMV׵>;h]w+iMg}XY~3&Fe̪Z+#ݑv/xLJa",XHs999EE"yum#֑̍ef=[Ώke Lyb?yRr&+DS@v +322NV2]ٖXgd^гɀ dg\FxHzER\:f| +3+c<cڡ`<`Nt&=&r23O@ &…X38"z![q%V h̀F +]t27ՃS8BOPKATfn~IMѱ"h}SDճߐfy5 +@NhNjx9i)$s@#m:A']=rfAM+MJ<<^Gu#*sJ7k, +=${ +bR ++dٵ%d#BYQO\I\e(dɪq!NR\2UIˌ +len*+h'~3<ȗa9={F ౭|g GR;4 2aChJ +ʌ|^eHԗ'sqB@ABЇN?KɦJTlv5hiT\+}WYYx9b, r4lE2I4itK5mBn[zq?X'@k6rkm}.o6Y6Xm{G}$7M+$ZLH?͆"~dn`5 KB]:u +d#dCEv|vkZJӘz.b'P[5Y4#-1b0H#P4 ANMEK>y狗n;qiq;,2livP<}fr40>vO;n[o'=v酒2e;#~OquS KIv/˰+309; f]+'+=$i߾&5Zx?Ywc1NbL $e2'2AU+ [&|+怣O&<+/Ioȼ'ˍtc0J3 +bt5=-5~0{?޳큄+q{H_gGsY9N+m^:0,(Ze-0hXMxH:7y$*֬XNX뭼"ib6&H^wa\jM]rWVƜ'peZbdՠdzY}L ء1eĬC F +~FDN7I_<0L# aF* +ZF؛,so[íPJJJCi +aw K.d?<>..ϒ/: 4X$p<DzEAXIEzMzd* j 0 +U,XN&K, ,NƯK6i.VMCI`2 ɑ0FbYיg +&n ar˩sm[`.t[@fidblܑEE*H(B+U-p}B"SM82ûΜ<q//3KĘk[AJ/s1 +w Njhlӫܙ|fy`qTf<8Pp< 4-,F6PXpH?b9U6Wm[('#w/tӃ~23NAGeU/\ +P!ed(\[3K8&pduX\ +r1l Y(G̷%Tf^+beuZuTbqekFl8)\jʳ:򜹮BP4ue!Ax :$q{_@:ϝw~(|-4F`JPM.| +'BE+!ڱ-!DؙOl [՘WsS9uUUc&0Ӌj I+a/{XgQaY@Ɋ1\яN3UhrycwxvĸljA|Ob,N6"dNɞK؛?$7ɷ%O[UF%)_ϳ<>//-(Py^?#ROz"0Q=ʾSWހ+7;C)''9=cڬfӘ`dc8ShSsXUK$O1 AܳDu$!FYyj8Ը +e-T󞏾&5NCkwU + +M҈!엃ࡁa4.#aQ6]>dU&:^w\s[̲>,|Y{ i^q9A3dЫBqgܣ9==bAc ߮hv~/^#< xKS5,[Jkڗtc]Zi>*HbZRݳ G# +$ۢNBc,c Fi01'IۥRtL:#]D$eHzI3묔 1,h[@*' b'\;w; Ǹ 8;)Kq= ]P2!Ch, +$RBn!p-)QkfD[F2qwiq Ci\Dbt;\1t2 XIq8ȸgs|%N0$\ :k<2$5Q+Iq?K黬N,)] +tХ#JnE,g.#;]l +Glm 4? + +̇XòX׌Ή++bp.#"-d󲞞Q"VdcF2-CtgEKv'cp1 +nDUdxA0зQo$c6OYʥԶ),X)N3%3@[جe,^NjDmMO.2[V +3*S,4fS`G?x㍎D)#7~x~+;O<IJgP^DcGB|Vc#(=)dQg';<삝vx(QOvMA/r,+-["5;rSF.(S3cvjQ-7<^GXk8tv5d"''d)e +4l:g1qtaGMswaILly׼Ms,X9/XWov݂xOw͇/Tu>޽*YsU_23~ 7\*a?7'[_K*] UjAܚq:2A1{'vEYd x"ȴrgͮO'>iomj~W +6 NGKK k"ۂwE +~D>e/0DGE&9:#LN6Xt".CV(O W{fjZ=޻Vb.=*cj$p 0K 1\b[i][;mx+K}7y=iڿ{4eͲ 柹[~+$>J=iK%:6` iyTFxdH!?"\N' +3vd?^~]MIZyO53:#HkS-gY_Ls ^:wB* +Xd7=szF._Mӹ3~BZ'#/1hT44ՠf'E|8Ggm78XO}5>5fF~h " Q!^p259ʚ6'AYٯ9O:8N.YdgneOڼ@-oBrtr%x{dsr̹ +_ij][Z4mlÅe'?ܺYkVpJNC>'W?#79yzlS8nubS0gŎ4BÑ0ChLޠ2M9DVHH44_((Y٠bȋFvFp#CAkdaYsM[?V/grL% 9V0t=AY!mgI.uB{|bxl8-N1 +yi48(T^ẹSd{hUWEcJP>ȪȕUO(A{7@ 9}_t:nj[goy;݃7^>ӱ"f6}*x}2a~ŀf2i.{ +.*upnӜt(? O +1: c'Y,[.tYݮ;7D!&v+ךk˵ +:Vy?ޭ|I#)붆CspFhCӦ-#6qs\N89VL`M> +VLa0d*:[+\zŸ:58 Ŗ&ɶAKPGGH[ 6 s4ۯ\< ]AE!'&KtGl  y^AydM}}VOOYCT*gW}S5lEn /(ΧxkbƳ2u$vfIbn%/;ؙu?bڕ˿{M4bYpJgeK|4|=3]^:OMX{o>vg3ތx[l؞!`ØRxf}glzy}cSCiê8Q氊0kKř(T*Q׫\u2>RW{DJEJC3TMc4.%ɂ~ +5\ٯ'3bRR6F|1DTʋTʓo'D;Yq$ +cǯƲQᥦ n ?~oW,zWѮW=my[`_a\7NslSzQۜ|)?+23pq00M2;!XmrV{o .,78ye|`;;o> h|3pd~:׊MIsp4D $sX٧Xz+gJ#(V6lMXKAC9 iPZVMW׈+fsN܎/`.WI(ET?aa!*Ć7-Ei-SM࡚ wEJrq\nR +yFyISP4+e߼_=)qb;޷Z_&xm]'> D# <_JpZdhlkқeoXho\rmoNheQY[:a9ϹY-y\\rÔ18e Ū:Xo8{>%cEyitjb~3mX'S߽F 6.f2EB +Hx$e0Ha& Z֗~T7CM\3?7?;-8s{ϭ\Z%WN-3wM}}[#ğă2 xl9`H* 蝋-HDt$CC:1Ujolya亖.qc3 \7KۭBWbo$]~kF$"?&\gn~ @0='f 7l2)g_MR`Az?jNy5R^M^D荊DL2H 3 G-aG`8E3 xv낅~O%~0t1=^zclaؖ:\sŹG/W3zTmwyhxՃ?I~ +d:ke8.'- dNJGg;_w%ϙ@N +4 +@N +\&<@yX6 vDG.͌Yb]d_XqSVdlbZouޭl̾=~玴iόBc A1TBuGrsp _EKsX}ƎLi +#vح|&pd" +8'; > ./OKη5<f7?i4 +='P?܏ӏtN,1ᘋ,Gkz>.tM'TwPyEdO@'{H).2Υ!|oADeluM/L|#D1>C (b'#.9}OK|Wr+<*Q +rGl@sQcvKОgo pғ`FIڜa1qc$?[|9b523J#iķn' FBYt_T7CT&t=GP&eoHY4ss 1}eEQTA LEr*8C|aRL.-VZ+' +-:Im| +K!9|xDPp)E$bykmdF׫+CTegw}g}Џ2я{䷉9CzR@M?<L 䡛vW\ ~x[ct6 =gښ+X` +yFq'k@"۝h6O'atׅ~~8WoyEc8ލʀT*}l Uv]>_fv+ΰVX'YY+{CYԗR^ҠXkC=ztp{|k7e)IiC]򘫬g[-.ެX߂qXg̢!,9Dta +": +Y3 (X_vsydMLaj@+*]ubDtI*> +,6-ݗYLbl,R,kT3r +sBSc/ںW u[0ēH'aIFG*A||ZQ 1N0 f}-#A"|-&)L7xUk6]y,;_$_Ldcs,X(7?k i$xub"ib7S\+! 1e(v879ym hz3({3,s-^BD78IA8+vy +7LsH zF{DpAi3ktdbJNPBy^=J|}6{dз %}jRHhhrmJ&4DrN--I#ip]A{mডC#iO(SxkhPA)S"՗_̺jițKi +RZ}WgRxBzjңxouM.o6)XOqJ9]BfW4B^(OpC7Ѻp)D2Nn31RgrjwʵA+p73sVPL&:c[(FIO =oZ4[m4Gj=RC/9k&s$ +j+%w)3l)"5_GfӶ\}2M6ylH\Ɍ^ibۨWRZܡQ֙oT[B4ӹgp21Yd2)JsnrgIO?T/}K~k|ufh ++(_h902.QXEqJGT'}7{)5jrY4.EkFIui/ϧjdu(Rm/2

-D9([ߧ 駃H<O\u +9JxZᨤӑDB9rS֓o&{y?bIIѧ6zdϽ4$G5o)3[9R#l2[#{)Kh#Ͷ3)ySt7g\}OPf&?~R`O-75 yT2gRfYQ(JL\ݖSHZjBKLl2k`ߡEie ]K{L1hZ: 5mv$O1G zJ^?cn)?WMWwbJ;vhJ>lb3_}{)Q +^{%O#叱tߥ\":޴Ќ^oѠ[Z"oꡕ6 wk1F>+t4k:;SmJ}eM+ +tO⟌@'6| A^U * 4,9k%pзRIj?u1[чW7/vkʦeMmljinjmklZ5/m_ +ʴiMKVVm2xoPYp)XDڸUZZ߲~%SXRےva3[ZI*ZZ>m6v~ږZӂZKֶZ2 +ΘMmbJm҂e%75@=5x67UjqBn#6iT=iImkVVb|ihȦemKIZVkA@Rm~}ke:(U6k ++.ku +-u0 H4ֵ8jil5#X_W͑B+F*2O{qw$p0`da@-a#0 +!j 18E. +q6%Dt'T2SGIfIgҙugJLLqeM6ugICS;ĸ }o۷iG'T%E2HAV:ThG!SӍtrJMEzJ 4qh)‘t<QI KkOի#3U㣨DlBhmG\Xhgse\O""IhlJ +"#JP*b7B=29"Q`)0V07 +}$bq^D5^֐R"Cil:Ibu'zJźH +,D19y86U= bd<2͇jFL5E=d*Hu}d2 +aɄw\OĽ ?ބ6o_ Q +=w PzVֳ?x? #+Q!kG1]Dt-&&ytZNeg,HX_l GTgbxi:gxvfx:X8G:Fuq/ɣPKjAut +7QWMhy5<۔H<EE4d֍ʡ +;;hj4ε3W m6269L;.^ Nczdf&GQǴq>2Ý@,b&xY{=V51 {Q55a e-d:>=4S3s=;-nupKXE,lܭpyVG'qCuoo۽C!T6ݧӺ:nF^Z}I&?hӴ#ذ/D6&f_I Yi^yHpO +G#‘~Hp_8/ G#‘~Hpx}uݙ8NqWm.n[m u|^==ǩA"/oY^@Y`,ˀDdP/ Y5I`D-gnlXY#fq蛢8]=ZŬn4]&lhr^R|>P%U7%IP~C(%2yNT9WnYlJL|^Ҋ@ [fK_c}RſPY3RR(fOSd+i]*rsrf}!h+qD=༅8ً90+˹wt3:#_qCșg<'MhN+j^<#_t_yŝ`P=+(TE|3qhP͆5eAa<#w84p3r\N8)stܿ}kleMJGcFG(rA7y+n**?'m&r)3h¨{)B4dШb.OK?lPI +t{=} {7g)}*Z}'O`.k'hOp~Oäjr_E]^muVPa [!{Y$u~Yx𬴏~<}]p(OzDBspzMC3P\,ljzϞBGۢ\S%Bg*u}B鄊)T-)TR9rR$5SzyE2t<_vzY ۷A7w||,-""g3slS u6YU>O$o{my<@6yƍuF)n MSi3ˬ5uģ4ƺ^<&h{-h#]NH2:?<8kvOh[۴)_>oV6WJҪ"[׮7(Յ%` \qy˜F=T[CmD<]$+M+h+X}(]^ +endstream +endobj + +73 0 obj +21896 +endobj + +74 0 obj +<> +endobj + +75 0 obj +<> +stream +x]n0z +C O;|h +)~rvƐ~Z,~?EF?wnwΣϴQ/i%<]4VY#]pWa:oYFV6>]_T)|rzx\}vZwޅΟ]*Vv6s~J%S Ѫ(*FmDХ貄5=#Oܗg;z +k--++~xt!.M~&-oooo/97C_>kщM~h[$~ +KM? +k|!#dFC&K&K񐿒$~a#)ܕQk_z a6#טBqyT2ۘѻnfTq +z +endstream +endobj + +76 0 obj +<> +endobj + +77 0 obj +<> +stream +xܽw`8<{o~t'NI.2e"w[ز$[eIdbm ZlJI^R y ŴCH@w3s+Y$Oyfvvvy[R݈EBۖ־OBض}~EHv醾[;R@HCbmBHEh퟿Xh +AC; ^ /RC޶2{I%[Z/훧s-=[:jC{}C,B'Ӑ_E(p?hKIa9T&W(UjV7Mffw8]nP8Es>YnEvrCrf徔lFlgPxB;h?V+ըkh3CaT.BځbH@Ȋ[\ Ȗ{ +}ļ-t چ~+H(MmD&/Q +ɸz2\EF5-ENt9p!/Gaå9t+Nh Z6wJBtoZ4>{Ы0*F3pϝFTRա7ѝOgKScjE[yhBk7؋0 vHzW}gXKQl]nSX%x3̓~_=N3軀_b7^%eWe}7g頯KQ'A^}{mt}9,=&ɼj$TQl]n@{8Oyx2:9|e>}'"#$C8h1P +@'SE?@GB>|c̓ϸ/%)woKlPJQ5@_z]@Wяѯ?? g<vs=:{;;\IOt5{{\#moj з//&mWR|9 +ߌo1sML/brpoKvJeٕDF P +^Z޲}Yk?n}oc*l>p,V܉CmGF?s3MA?حm1lIT28%+a$.͔=*xɪl$ۜ6LnEn{nGܣ'ssgn/*iD%h+0}Ga qpOwox}ӧKp)K%^ +N-|7/35S K.#cbL%3Y,fژ<<͜f^*e \02^>>;%[s +4q.Uqkw%QSd ߓǤ?~(ʢGdGe9V)q1f5/2mQnx'bx eC@oB + 822w K$?,Qq'ׁtrDft@:rY؍Vܗ8[75Lm::(| +a)Aз=@irB[:=gng2s2} zowFܻ =}{)Pʁ?݆̽9f7W-&ìb_RE NנX3c:w`C8nj73L6ozMQbrH +|>8ߍ~*k=8qj1NQ +L*XuHx̝[LV(hRn9j5+5|Ma&5#?GE+iv`%?2F& +Ba +><;g#x_?2g{prV`VQT4b ZLV_uAr +tj]?&=aC# VYm#(0sDU,} +EFG 8G5+F֕8wmY,4n↩w]p'zG+WB,nxFD{:BOTGď(3Û=#h)ʽH+uv3^RXHB6  }tqQ揁>= -\J}>B}Z݋VܟS49͑ tO=B0Ӹd{s@  s +v)FMPt4wzkd΍+a +A3EGyՊSzl,Yq̬u3W ½xZLOre딀nz46-Oa6 g%p%CuT6lLH}"#\*aGcoV3^s\Mx +X%\J> j%ϞR?sgùJKA7 ~j~tjP]sv= 5_12RfFqoGx2ʘ6Ȃ-(G#{hqsӎcpQc@0gh8t%oh<>vnl ?[W3lil- +DJ؀-l-/,r0Ne6Z$y#Is{fPGՒɞ{O.ۃنK#8w_W~xߗx?ٜ_*.,s%ܗk ;]YDɸ*9{GuY*e* +HhJKe-ӓX-@V-8ҧo? 8dBEFeᐕ+ão$#Y;j -pb4cc]b-4N^e-zͰ9< q0ZcاOZg @(,zKBH}9my9ثsgRnRܻݟwYfPh5" ߧC uce|j@>Չ#L\[ѹxxܘ~1`WXmI\{A^2cƐr_^sVKI܂~ ͶƑƑ* /tM3ErN%NpʊJT;UVQXYQ^fUʀuTVV)Wk,[kq嚞6p,.ڲLv^лW;c .tnZ"/Y=zKP=~dCA,]X2"\L&,H*g 8ۑ^5ikkωEڽY/4gAJj5z({o.c2,[oȆH/*L44M4!'ןѼՌ!MR2#"?kd>;6hccuyFJQcӱSgM[ )l̀G0!]f$T,xy8 +wɀVlxnږay^@Gr!ScyU5 + ! +w0OL/AK +>)yUR%8޲*Zt78zhѩŨ?_[y?M52"#>c|cң0ڌyme<۴uFgQiXȚ/5,PRT}SZjO3F:)wycg}2A {]H*8&]T*%`PnGF RQ8@Dѩ$D4bZ;LZ5]XX Gm /V4̆2pc0ؽHR4PӫBv=!^LTQ̕5sKCq6N_`:B\aѰK+k5.+b].U hI"*_x-M ]XZu/NXx^ tkή3f-1 !l RjU9]Qur1T%IZpiD@la"i9ٕ^we~s[o۴a^feK7|+pamcNC[@^?A|y1)TP(7d审 Tcֺ5*(-f(`F#7D-f}4 Iö:ilC ŒL_'\of1Ǎ:36⁓% +\22b͋9cu,j*1 Mgǁ-1i 0k+}<%RBX`]p&oc{SAj>nʾUbͲ$2绯⎓C.ŦZ+#/.G!9o=nN 3:s^^D88qNu\}c<^/FGcIԄ3xKh0ჂJ,<A2IX`yhUI- )^(JBN?^ + +)c_?s"='⼭js~YMjnL*w0P&Z^?60X)-ak`Hjxx ͋}a\e9ͭB)SLcM:q|HhfMkZa=3mW2[KjXK$VB1P[OUں*m t\pR+V[޷*MƚԨO:#8ղZT¨ϣ +[G:EeFqX#S4-LTP)A7͙@Y&=7{c*w\wh# i̪]$">M罪)}6&ҁj-6Y04el~S'tx"Q'4kUձXuU+fFgTf]K9.kZUVeg]՛Ͷ΋ҥ2|Z )[0L/Oc騠S^ɬ`OroXAuANcB.a>8^`Wy c{i]N옝85ip{v~uzy@}-9]^^~!̅eH~x/*Iv(9B1h|!x> <ˏ2"eجq ܣ|8|jj΍9@PhP␛G^W$D!B`a2ȵWد54@wZ>Q(ak5m/}Ǽ]ȗ՗'jfrp}rc ֓i!XUή"*&p^b=NP2I0&sBݦr +*{ 1ƯjijA$/ +p;^0v! ϟ~//=gvO BAxeD,5g[c5i<ϵESTP)% E+$M +ҫ?yK|b[hzH6XMSw{?~줯b-B~u }Kk77[p`Qp\d>sBMNdTF =b +GJ#!@GrJtN@fÈQr?ҫ$?U$ &}d]_non7og_~4IsRbȕ(HJSU +@yQV}Q%уc CIG@TYQg19c8IC3TU)(;~bb=H K()hJpdţ'~ğfWQ{?b*+=u501W/? ̓I ԓP\do, +˭dJ16`nL3TWfzR|8aOըy[;R/\ZP;3uv ؖ;?xxs[EqJpH+soO蛾CONR%.$)|վ9B2|'5}χTVp_uGJw42ZMn#Aw Vj)no˽^bƢ6>@\hێFTƘw[81#W5/[ m_t.[]&e'<663C!S?fW#ӊ-G]*ꈉ(\3c7~y%WlPԜ|7i}ekc_9U27/B +ܾDD2{֎ԀoX|pQӥ.d>ayâXZzm,A,l0h,RL. 63ƤP#2UVRc +G\K˽.rqY +"j&S]rGyWIVcGVp-JTpKpce3iyאk6GXX~< 3NdN4!{Q,AK5y|#^bWe, :S +gN<ւ넏XQ\-Je${3bZ}驈Fe5{4WG4[_"- +JK~Px7N:`e<ؗ}ڀ6wk>`Ws8PMGR:Cg=yш3cMMCƻht:oh +L>012P8I*ı" +tfT<JcԱ&Ѕ)} ñSM?OH>:7'gEiR*<>Ҝe&(KHXѯD +KO , N7wBA  +ĤIXGmtb8J@5m}ySlnG+2qו%7+nZ9wmJ͎f}k=rΊĵ7"3S{`<²w= U63^cUƈx\o8N%d5C#OXq%EŊŞExCj +^}5Џ1%^|757T,ZEfWJ,_)i+Ԇt$T:MyLxn?jOX +{FfkڳZpL8܆om,4;ů?aAm2R늮J0h.^ۤzWhviw..]r^=:}jRK7ڋ/_/+wi(zR}X{Xg/菕L+XK5$RVBO+'㟁'sg>8 +(P~JRSG?ղ_15D^ٛ}kOMCs*Ə-0捎+Õ^fVij6@CIJ3S/\8TV,7RR}Iŝ.릢!ugѥ5{}Ejκ[{wŽŇ4T>6ppj`i'N +m4,ً{+̾VusH8\XڻD7gGq$8܄4U20C¨1Uj0(ɚ_A2%ͱXRYU孮5WWעyV5̝[]]-&cՍ +zd9%K{PLЦ~cb‡p ,B ]- +Rոz+COVg\=Ws+4 i1xfla +D*IXUl%,;ֲʧXvOs s텆,mG}W + +jĘ`d qԯp :kM]$xTqj0te&\ʉu:#:202)0U~׮JWʹ]ୋT{ +RȔVj/êԺ 8T`B5ϥ|]jAe\x4^(+]ťͮY5#{.V)3͵Do,K3z&Cz>ɡmٟ3{ր:p XW%,$[U\R7miN*fffgT;pN;Z}D})3k +A8 @;QYHZ~`z +qC6Dd?v q?56k&r^Fpc秴j"ּ +L(=j+1'M1=9kVJ#pe|l|lrb,84KZ`OKښEՉ_8.8ju~: ̵N4ddTE̦ ] TqhΦ0fa^К55^CLaN)mʢyΝ$8G]٬k.uf1~tF~դ)$`iҙ+W6A>!ʔ߃Ff= zR!gT>dz~yt}:Ӎ{e*Er2LV*+؂Lݍ)YeeԒ"fpK6nj|P/bn솅v<bwb[D-wv+ {'̻A/DFC{\JPGJWIj#}CCcAg^;#ÑG|UBE4DLaqwP) 9F_ ~O&aUUs#ݜNh4 4k5N0g nIHJ{nR/JNccucmXW[V/8RhՊg7!0d7VCүlZ&oϫga߾-႘7K(M37qWlo3kQ/6@w +;:WJ[.D.92f#dHHax1 Kg4$CN0|zFy'LH,G:%Bi|9YpD.S# +dTǼ:e#J p4ſXlͧ5t7UDG몑jD"\|˳_.vZ|- 9+5xmE,bTFO6Ԡ2Quj?d +2 Q8mJ< %U|n+W[~v!C)9 |w$)R8[5nu7'liVnȐ^с$'`naѐ +3/>|K6,w]ScWU*az|`u$?l;ҞX{컿'XaUopLtbQ1t +GYI ';ۤ?+>G 箻}-"d25SS%TԤ䢲)PVٲtʥt](QI, ,k-K˹n4T/-!};|t*OKc4VۡԧMBB @Al ænUlxUGK< *fD2(zMaD /ˌ>dNxݮUjaa e쾔jXI +R` +f Jl2! o7f%AmNw9PJ}?J w9t.81\~f qo脧1DPBN݋e"S5~?aЅmŖ)qp%#[NA1&J,H'eN*! +nMzfmhuxu䶤h"ܘSuR +͡P:u!A F!-,؅,./Sc 笩9ʦU![trjEgdeq=O>=NtlY=В^3|~W-ux)F.ToVWYu3Jy2Zh]_ܧ1h gv˫fUԛ0LNJ&ḍwhf! +!z!Y;L11ARY] 0F<5ǽ`{#:one7} +q_oEIx$N>DEe.wBpS&s0sIw 56 ^~UZ 5Yf֩p1aEJVL8N +ÑJf 7v|VWx]15?--zˏTeg\mE|G|5_<d{|11C!~XG_BYR~`vOw1VB&p p\}Bk,h py"cpxRƍ]|ۅ܈@RSXl.,,l6.|,FR`@b,4G za1S-Cc$qYbNyM4U)^Z(m6ijuG&c`r1Vw!SL¿dQH +f29 sdWLe3;{*}22wNLNjfjEcڽ/$S5KaYe.#?J 3 bڳP9h +lݝ%$ YŧYEPL +ޟ{W#fT^s&ɘ3 +AP۽' iʟG +.Pi&4<~o}@DHxeA-+/"Bw{3؆!K1=cLuЦ)9>D +M5_ /%N O6Ao2"p` /{aœwf_}VrUYxII)8 iy]m #P ٜ]\Gdُ^274#쏹>Vy+U0 )%7H̀,?JW᦬mدFOP'0wuᛢEǷj.vFM'ng|5WV5d$ƚYٍ[( wl7[62Fg64c0x]6Ty +IoE2qԨbGQŀA4aY? x1+)q9#pu!-/PX:uFE-lqV1%BuթM嗕enLP=|HTPwBl腤iYK,..v!7.*.0&JL%,O$7߄_YTF&'Hq(XO(:! ƔhRl;)zwQ`8IvҎ88 ;sgNI'vFTOwM-X,&Cȇ$5$֏4e#~)=L(`:u#ƑmV8rFsƑ8B`4G7:ߒ)28 +adN]+ >.o:?5eb '>e,~*\\5أV6~㇗ N~{=>_";WwnBPæ; C`N8b.f`}r|BHLZRiN RTUbtaVc[f\!GY̊Ћ#oF1o 0,YބZUU>#R qyK/ali +F shEƠMjԜ*.Ɋ%J4` 1G x:OEQ9t'n4Uz8#~U<8Ӟa(>u~68j>~M@u2,g4&7~l4Fd_\JƴԈ嗎'l|brǻwʿr|}HL1ԓPWx{g.qŏ[= +h"䍄YsKigՁ +P6n)Y +l[hލPV&eB H=U?F +fj|ܶV+go1M|*wO2=}n◞ +.PA*|z|HvOŤ\ Y9pV0 ^dݨV@Y΍qfw{|p(*8M5Pw(dw:hc]NqT. Խ_x963fJ +cN;HUKrQw=_n8gRn4XL֨vuvlwYp{3ཝ( Az@K\|r;ozhOAd),B`;EX%$/Q9+ +t=ad{P}V +()Wmk; me<N/B +tPko/x +-o%%5>OwWϷo _ߒOQjZ=R֏6C=y( +u[8]xȓ:bK<<ϣ0}_\7Pz:NҧtCۤ-TvV(f)X㩜uLoSm#S+}w9i6 C])|o*8{3YF46 +yQtKPjmmvrQ>;<mZyL\I|?fRud|C/x)ܽb86:;ҶHP:E,Dy:r>1@G-r]'c~Qߑ +Po@~HoMpO2O26')-pv +#FumN'mliz9koq4UnF8w:S +y0(@Sv'Zn:wJk}&Cl꧸k P +%TkLQ$h-zT~ZKK]^?OȒ'}J x-,,yJ̡ڃCI3\WtXz8hAJz;_0StAI?i%R9[o;ɈO +jىiJ!Y=b뭴Ԧ9JmD:=]ʿ_af_!Z\"K]StT- +"3|"@N.j~*&5z2Sm?b*oK_s(<`罔Vj':^&_*ȼM-t'kVڣ>.QOh΋87Ny/y{S⇢S_1MFWt&^;_=m5Z2Tq^^CnD딛yn`h򖦍R+4 +ϷLK}vі#L 'dhO/}ylG0(&k +7z{_C迭sS{!ZA=-iG*Q4 +_DxBb%ȌR(LRJ!*S( +9I;[o'%I{dcCk[o"~Vo_o`WoVnlo*%Hc|so6R27sL.e%n~q~q@G%][:;v{4 vwM_|vղʲL6unSkP_\,oWcKkfwÿ3߱k`f~a 4 6l([{Pd%V־ΡE]=ɳ]@byc5S/jw ˖tv +@_H[wwt?0ȷu}$IJ8q~oO;c@_k_Gްw]{:Kx, %tl}wn{{:H{;z-ЁmmmuӮm mcWOk7ߞo2z;tbWq_Уh@6v]K;zw ;U%]mN(a[?!c +t:ә R It'AhlBnݷɷSЮc֕Hʮ#tNޣGzzxӽ=4–7ՙƩLj sG=\dkkMͭ[Mma9iG8%]*JxL ^ws/3?&d0d`r%'pY#,&Rcq4GXw &+/ kG!px{0I,Sk㆓N$"iDɤ)&:& %%Jӥ=NH1WBp˜O|r2X} uu%0!a +VsN$zyO8TXxe(,znltT +ʆ-4!nQ]7A?8?|98՝`I +}Gd4#t HCO1,ǫ]۾CEN,]m!V_MMqT|~?- ֯۰nT_SK|xGfYD⥯s>4M$ +l aw 8&=-l*6 +JM¦RaSTT*l*6 +JM¦RaSTT?T{ݓ<홉%ɽaILLWmx7t;ҳ=_?cn/D'UOyd٘F[.?uڴd +BZ: l䉞DFњI84 61:}fu7AWD?M=Ŝ>uOwkryWH{81,PS}*u3)Bq4$ N#)x\_Rzccb}q1zz;T"fɇ1+*ϥVzԏB󠂂˄B_Oul~\#6Q'2m ݁dΌې>d"eY5 =D%!oYi +!aH:' \_z%%t8Mah9!>-d ©A+]].s; +R흫` ;E1(V2VԫWW$uVr]5=Q}w>sy4|$Cx^`W!o.|ʉU|ئ-*sRo+2WS骆2j zl-bWfwۥ\_5Vk~6`kVZι~2WU֭rPxae*$hcv} X>'aZi1 U_|ޫJγ*ށCWiTQt xTk B%!| R-N-CM)~E3aq~`HN*5;tVԨjBKhXTO]8'Q```f,F-tFDSPo"b*vEC0t[ofy!o!JZ!Dps:`|PQu>8AKpY +Ja([` + / N%zx^\KnK~~i_ZB6a,9P9m<_\&K5Y, +җd)&K,K!nѬ5<_9}pa:}*%qL0aYVX+ +@c +fRAdS0SU8+Y è3% +Jџu1?>P1qb#Ѐ9+`~Z@AXM9, .!/UZIe=yeTg +:P]}w{o@/_+7MW>|WJ;}{ط-Cjs8 +Cpe}^tKm ܪl kQY&_bﲀqrds=f;W/z,C/[%hTY*-eVkj&`%EܝlCb6an6s}*If"m;vdjݑL]~#J#Id[3KK1Sl7#Ks(q"S,> +endobj + +80 0 obj +<> +stream +x]n0E|"0CM&)RcCzVtl&^7{׍ԹӵԑΝQm׌Jͥ8ב.{w2uw5[ŷ;wV!a Q%QUNS=<%koq7!/>2PiCݐݙ2I*UvUDw%H9ڇPB$KFjl39V$d̏….`^b2w-Kua}C< j[f\Sÿד}40 v^Vz?eg +To-;\LKfgo} +3Nߟ J`< +> +endobj + +82 0 obj +<> +stream +xԼy|8>3խ}K+dI>d[qi'8% GiPRBIhUhN( +)iK)/%7PhqKgFv}zw}yF0␲++"?)Bز +Z>ee%iBHU}U/ !"ثk/]K}߅6B}ō">ʆ.7Y|+vM= {ҝi}_tK?PځlX"%tੇ>Xip?=*'/DF&lGx"YJWeں|}CciZ[mfϙ9B?n8 >^E{8OQqnp% +וNrt?y"E(Nj2Csu{,&ڋh#~(fPAȉz]$JN;lvrBcv;KG*eM8oYCN(/opCdFq}Y:` +=oG;:~{J4 +Du;*x;؉J~ct)t z &A2 Ѕh%ܽSJҌCP$;IW9Bs +5<~@:ѵhַ`DϢ#W'ql9Q-{; ܉{~{\[JR Un AxWmff:~?gߓ-J@_(EhZCףoW}Cß +|E$.sC3Bh{|haf,(xQ.~H ?q#Pj( +h-|l} +^vU0O427۹Y⟋#lõ{0 C=EpFN\kqܝܽk!7axumr +Ҩ5\t%o!tmGw܃g`/ѯ{WۿXw;% +~JRGԓF:v8%'#ǭpp<%IbB-RDD)./_|ҒFU t+!`!*_,ƻp! +_sx+*-x߂oŷ q4>a|_OpQ'YRYd>Yd=d\_I9B\VrCOY__ʿ\ +ZQeWUZZzPWꬨUM[bInc/M|`o ]a+^ 3"_ӜsWpWuϸx yWpA ݅J{rEc࿎\Q1K*|5j"yj #?I}xg +u +`;q%( Oks3q'pA4C +~GOqOyD_kp\iQ/#;&b\c@0s;SEt5P$</q +rߟ)rlac\-@9G@M@у@5((GD7]? P[:o[@^8Hπ~' @Yc(;wc +#Ah>v"G]2= =Ƨ2pAxlqz<輛 +: L|]Qz[P(=V]{]i?G[^DHuc_@=QП<xgKүfhHS+/0o1T[+up G,-]qQ3〻Hx2iMƆ|]mMu.J*x, W`z.f%Ѡi5jQ%(Gb#|,<{v͇WB +Gd(rU\S[M\S9WKr3jJay̰<]f{qw1x +BZ;SrHukτmKUiOPЈ3<;cg{>Ԉ'<}I{0EW龨}7JU#(l:v$9kF}i~pEzs۹Ks&!\>Ga,/D;WR>Xz8/-C˱/>2i[|Tͨf%XgPh4}%_<69ԗӾR90#m߮ҽ`V۷wWWe)lh;#w &@mf ;/ڧ;.9"y碞"p ZJ iFo@QfwyVG1be2Vr4UF/)QNѶ|`[E%;>T|`PsCw#y#}E~$G8)p#Z% piJI6O4_(ihF-KgR C(\Ggen"ACAO㗔lى1Qwl'UF +DDkEE +zP + +Մ¶ +[,fLHfTTo+X`-e,K9I8itLpT <-)RK^Ib9$O&IjMC\zI"+$dV+Jhy [ +":Hcxah>:,`W˒CV(b,KHv8+䳃Q*Js]<Cpls:jk|m +"X {w/ڝDxcsDvi1ii¼"gFϷ3Ͼ09qnt 9mEnQ'hQV3QNGG4+,A@wGbխ-,2d + +4W~z5-h-%@+vRᒢ9ͣx1K!Kxvl)JYȰy{/:&u:Jy:ZbYX-r0搖,;ݎoq4I--7Oj+5)-jQQܩlhksR5ioә9nu`ˊүEu͙dU؋H_;)Ӕz_,N]e| +zumqW#5+=P5\E0o\bu*\E&,|(]Q^(JRy^,GJ-T 7,rO[b +ό%=z|xfT4>2>472hT*OEqj?oE?Wum2+? +DQkD+*+j +|"vOUèQfUj|k՝ij6_܄m)2r曊݌Lo)~o$2k +^l)2tfi3W-9:0]ݝc;*V YNqDL#h&J"#. $sרI\S9êÕùݕ!{rɷ[;^)T JdHB +Db."1QsE<+&Ĝ:%P0 ItPqF11P5i0-<+,X y9+@|8+.GɃeJAHy&@&&-fLagRF0!u1[ +.$ci,Ůeb>kЕh߃N-2`',D/r.GL=ƲJ%LiP)q'Ϛ#؂5wε@v؋za^4dD)55am4NG.)vo_L)p4wB)4"M̥ѠʤB7t7չI>w@Ӝchbƛ|u4?_EIݬn.W?)I6}KdsZ/8Kl49Yr)^kNms̈;y򔝔80e7<R;Kx&?K~PGc3wo鉿omvhsJa}z Ѩኳ&s&sdNrNeC)ŇS4oh + +ޭ٫!6OF0)ƫs}QVidZ[_fLVazh;TL6&Uɡ8l. ڀ23LA@Bx8Z)M +mf &VP]9^߱ƱՈԹ-}ܥI+5_WyF#0Kk]ƱVvhڭhR6OLD[- τzφ ~SqSZj9| + +٬Fşz$c[&iMI][tjp +u<5q ątMJ,s"-<J1r(S`Q @u*{ +8HFWU?n)\M4Mא Hk)䖜@qXLX4:C4ʻBƖW~te4w7y. %="heCL wh~OYzVOr}ž"0GO'|t?aqb /w Vj3;_.%"~#ڎ>o[g̨/J=[k E {kQn!fܬnt8Gz#SW]p9X]x}ٛ*^YRh4CsD?zf\Pe\GDLEW'UҤ׷JfOp5cvlN51Mh$b3/u6#U#unhQ|s@znePcvS٭˟[eW[oxeWO^3B)'9ϦWQS^ϖZ]{xjЛPgxgTY./Ck}ZCRۘlK K4Jy>;%QX:b/v˰?8x9WQgkK4LzŠRm`6W{sSssS'赛]?+pS}[-\U PJu$vt_l>0g_`H}i pKcTy#W,h-"~K#Q_LU&#c  Ůs-?꣢ Akm=Zrjvqǵk}^Pg@Q4>\i?`` ;+(XM +_7?]r[V~YG;^M?Տ)8; +Gs@r[ +V҄1'F22Uf25Bi^kRL@qQ) oTyr@N0t.+5椾"ļHvΎ3dٲhlLzt,06ud)=HFKqiM;Vev/2JqF茎v~i?g=>R'Ο)_NZH˥mf4n֙^^g^FѼ1}qc?5ܴ޺xeΪDbdxh~4(EkLm"+q/U(;|YN׷ 9Ńw|on}Y,.(p.VzrWz{ʫn{k-vSUKj(vpzs.ևz.//tY< dC~n$.'Mӌ,12ie~# +jQc1QD > MAZO6{TZpY3,Y/rloF{hĕ;Q~DPDY9$9*F-x-qRF \ev]^(#5[;חa}R-+\}~o{ܲӡ +A+m:5c4\"QNJVf*zcskGĜF%jz>Gܥڪ.yuy /`t4/Nj9Z:TzM\DiV!ͺjG5#?3ZD")]0i#lm(ӮZ- +nvn< +װxpe@b/_DڑLޱű9ljSRz}5'5D=>Vgh+.XrFmQ2FKxNv&S0S5(J@vכ[Q?tuiʔ* el1sDx.\+UjIPMT4sɜӖsS]rܲ`Y` N}i]ЪEल:ʘ=o5[^C|ub+~JܫJtÆ7ضw7iTn{.Ȫ~QyTUI#Sfb *-(Pl_˱I%RKʪ:4,Ϻ_(,T-{=>r:a +x_O'K\}+~u!v]]'ws%cէ|`̵,çâY? NG~DC@rRC2}93)NN ǎF $[&Jԅ~,e%q h DZ@!ۃA +lXI%r*E%*ڎ5`ߩA*n`[Y)$._ǠޅAɧnXJC4*xAI*`l'&(P~$6IG9|+&nn[[P0k.m.lzlsW=2˫0`WLR8[@ 3˛R98NaHQ< e6(=XE,q.yP\(F[\)C*S0 V&XQs\^e=ʦRcRbJ&SaNwq5DZ]&Kw +k 鱾rjWªLW"s$ xX%$K<D$' @@i1>4g\@SJ +Aa _9Q8w5fEK{Uj1pkCk%9H$nz>t +𥚯ėx-×ZZ`3'vM^:Q{&*k}SB%%JB41De x:HmsBB}n-E;qԗnjBt,TVfܖN_)(!Z) 5 +ZtbT[QDBxfR+>VNQ=ұc}-1VJRvŒQttBWpzbKFMhõ*S(j0a<9uȻF>N,-U;N{þmU;3`|Di*6Zas,>ߝ<}XF%eH׮!yCSήqIuu@8Qڏ^Ȍbbt/xKft7+,HؠMqcVV#D'UE͑K~jf_C\h)7 +v8(Wq;Tcuzw%:בQUks8Ƈ0]ajh,p% eȧ>5xgA$&.7S_L|.~*}j<!z{7Mvsu4=T@xwLdGeȎÑB_/5 ]$h NoYAPq2PfL/-]ռp9Ӏ^k!۲2Yx-ӊLN2{ ӊ1@8]fv{p9jLr:0ZNW^%B/X"W .*dwB!ߣڗ,j͒E-us̬P@B% +Kt.0:.(vp6 +A-G9T%-'U^JUF`̷4_NVmomy?8^{sl'^Z)o.Tϭo"WE/vQiVF=Ŗ( +_l*:ewto(ŏI kzT#!vs(KFsTa[׫7 ͨ󪇘gZѻjnv H4\j[Z_N~@ +rx}ngnw˹X^ nx^DfvOH6E,*ÃX^ +&0]SNOH%N$LL) cXI\+/-W9^nq-!wTlr 8Ӆ2w8-`:h R9aITu#G_O1rW,[~Zv6W NIA?LjP:uCtlL|H +tZ*8@Y&gRroFߏBTtdpS +b7u.mj}~ hMumu]5j͏e%E>l3%EF->]C Rd<ËK}xR{yse97_6|_ȇ&/Q͇ `!_\RC> 5E+[yBcOﳔ8666$`r';ιdh(2)\0.B:?erȩΔ3gog_/ީ3u]3{ުg\ӚdlfY9AcX05.Wtfu:lnӣKg mڽlٛk{-^Gaa-PݿR-b~A` lR,)1c{b'c|L+zD{ѣ8q`Pk < G*"DE0J~o˩1STsn +U(6#@=@,^5\,}rkr[ʛu'l_l]?rwr7X{a~C M3ȣ ZwRI}_ŏݷrY\kr ,DžyH^:MVc@߰:yCNtu`(yF~gϔq30tL/ڻ񟅻D}iR"z@)~I\\@jWV{P8 L +1pq +F': Q,FI1s-1&(SHhTbYB`TY%g:ɛْmx +Y/.FVz3?֡Fy@՛[)ԏ*`ZI8 ؄ +SLR" +4 +zzO.اXDMjUz5 +yHOޭҨU*x|75Li4&RqKqiIЍUE({)-5w%A;j6Llͤeos4D=lCy\ z|erՏ#oˆ[EXAg"`F(Jw_WM76Zwoj5I2M-]KQQr N7ڌ6EܣejFl8:#6F"[8(TNrJ?IwI|+ sMZu'(;Ŧg/wh-oʙ Ff}LbXZ&ɺp93\*4Uh*ojQ9/uRh2ꖓ?O~kΟ^vO^^}G2ccW+2_Eɵ8g>Cqȑ[.\<뗤#~/+Qe&YMcE`on-~ϳ`rFgsUKpx1>FC7ãԈQNn1rY%kӐgٽf4٣pL,ts=D׬.{t U|Ih Եf`7:rl(9\ X^v@;rnr{WG""{"#^"T!cicS9ʕpJs%ֹd27[@hޭЋVvuQ[coKR7 +*ؾ]..}]kxw&WS)m~첣돖y ;DTۑSdiӾn-e1%&Mo4WVN+&%_$i^Wޗ8EŹ&Z+jR4;DƌVV󔱢&bض蒲2L+~lE%`WQbsKw=k> C.:ǥ+g~RnЇ a CA$JlV`'-t^TN>k{]B"嶠gHKw>R|nrw$*_ʯF?A{i Ȯ^"twAK^L#)6sħE"/痩;To0o'@\f +wj75XNMZL`i57g76onj&>(P!T%~ih̊'J,?zݱ͇/7NǫZB(|'<[.*M`mF1T7)G{j*uz%:^qϓCT ƞ6T]w|N +_xԙ4gYߩIefGCB ;ѿ +mPƒE.@ +jʚzϤ 2)\xP/|j[ؘ>׮zf07^jF\}re +v+WEmϒ^?4+ol\yͲ}o_y_7nmǎo~xمu@ 0!NE&°MP0q?ޅXfA4/ZFyD4Yʷ)Wh!&>'@O8Di|1|6skw@>u8r4[o}q)D.,~E| 3ѽǗu~Wx*yȻw|J؟P^ub(l +z0J%W4K:c8K]Yp"wh΢< + YRe$lKc7LdDcR~ƧThb]u.ڼZCתZ k}ۢnrc`:m n஢PMO0jyD2#q{Rn^[bsr!tܔG2GV$:n蘪1U(!ZuV+ʖU[ٲjptL6v6K&܆s{܆\Iۀo*88EBlMlʳ-Vhb<[sfUi؜љY +ԉ17KRnd'S,}_,5CкNEYfe",؞+K5\+˵Γ0 {mZP޿̀ + +=O M)|Λ3]%9;axK 1t.yu>Bpf̕>:q].Wc׫upýK] xW/r2%gT4$(ylz3(g8nM:PǻZT'B2Fbt֒DzNT8:rj{NP],ϗ//^%ow#⫕׷Z֙v g1Y q:tA ek;{\бANvXbyfUm-%5>1DD?C>;@ˆKx4N(%!Fe\)υ쇉e<4GܢS +jks{') 9D~6<&e2*]tFռ:Ӿ|w\+Y]O73_(_O~ +3ArJ:98}i0y +!M&{>l죸RM+Lv=IUy +Xʱ?|ݩ>TӸA([uSgwIW46MSmu5+.Gc?(Q}DE鑋K?Z~4i$ן$]N~fGިF-/OIŠ 3ـ Ģh8ʿΡmvbXˁ'w<Q +BF ʱk;3jqԶt9:zRv _ +g!WD ݆.? A630yCs2d*|. ĘdѺ|}j:U^y;KRm3eϲ_2SZ(}"158N&{Q&9#δO5f"ɉI +l2NLSqe0m23= aEKdja(9zs#f$kdj-mPlY-Ų%$ ` ; ; YpB +ln’l!p4^UHl~US]]]ի^zi ٭ך +ZbzPtNfl>7̌>xf,79sArQg1zB1<,z)Rz76]IzF,.D(e%S,ԯ&HʿSc>ƻ'$&ѱ`lj/g_Nv(bm7G4+@=ޠ7B01-x?*L]<ިn?hg혝%Dťƾ1E"6bR "0/,VCU>DBqu2I+>K +!le;tGoܶ5mqq={Q}ݶV/}0eӘrkշUj)Wz4Y9s63jX'䗞bZ vU--㥖qk#[KT91GXɢz=iXwŷۮdLe3w=ѢMvWbo;wcͭxV?uk[vDX^n>u +ӣ5t3*Fi(t +IMffE mu`sÆ,&IO\b +' +8*" }3 fbIzUFbDqD*y#j>x?C + NHdLpOOT9?U^E-KYH-G-Q!uM=7D@ l."f__5vb1;&X226郀B"޹=W3o,(7,_+ܱXx-//mX$B_N¬ 7w?;U8~(Ss[mUuޛL +k)qVX|75 v);v/Uj*jB #b_u˜3I3}ܻ5\_bBCl? حɇa9~2GVy .c#HRx +*#OF÷Kysw* +l(&XgyWD Vjg_a9t3c̳RAz옄L.P?:g;J.`q)qFQz+415"oT?ыwicM0':2#p$+;qEddq'&0 vVJv\%m :9Ca>nа6KCSb߶wC쓮SBhGi/,Nk%B<>&=Ho.5T*{dj>֔바m6Lw?`D2{:7 rCv.-U5XHLtEl$r1#k +qU;AuHK}B{DW jbIn0Sˠ*d%#,%KQ*Y}* +}FTJl{8::b]T|W \^v\AAaȨ5V¸:ID*$VG8j2*.qo4):֖IJ4Ts~bs0ښnoҊm[䧶7tSų9$2VtkTVDsoٚ]9έ N{*ʮ5,) ֈ4"r^HM9^n[V׺ꢿ!LhTy#>dmQͺVt7x9>=/yt_|4wBwRISovM0XaNr8&rȡJCI +K̠z7Zu\A_p4C/{7oql ܌MU jMRONHz*"q%z 1lG'?ի{tQ&{;+r{t/q}/"b+m"$<^@' +HwZ3'0Hxb/9J(];~Tu&P9Jk8Xj!ЋNS+=.j mg$z{E.J ݬa.Hȡ?KT;~3 8UOUO9Ak={G,.Fre +cjuC,'Vݘu}RĬ<;k1h`EDrY<ƦF/+67x6x7ImF5UÆaӰye00nn277`ٟzHP򦂩 +x6b:g2's + L jVVWAd|Ah\^Y]Wu +W7ff +jAչ播d%z=߮y.u|s2I@(1f^J{| (OIJsoU +(h45fU\GM#Iֱ$R@qZ2Xh}1 +xbm2̟33lF e~ ?X3*-<}t+JגK@ez˔-MKvPB(ړqC.-07m~<2kS &-Ꚙ +D|.ɓݔ*6H.f+XGJYy=DTQyjfSٔN-#1[ѫ{oN|O/zX̻DNkN%gѿ +[˩?{6o{_ѩ[Y}v +7;|{'%G2\% ط[<f&uƓnFBڪ1v Hn+YtA+l CBl'J!B%-'f~eSo)!\K|%$G1#o_(MZK}[Q]pjCRv7ZwPeIج PsnBh }Hs9vw{Y*eO, @LQ,tLT{t+E=~qʠ2sS\1sV= rK^'|LŎQԼgV +VAxHe? ;N%kWx cNKvN!enYv(٢$%/ +]:*.g0K(6T'$r^|SQkIx +|~PUMZ7I0V'-'-Řh!-D=A=9L4폋BG",qXeP0y.Hr^tkq$ϳ\gBuԙ}zPKqisĘ.*NNY"c^w>˽lGonց} OO,3[YlZai +6y`_,\Ř~_)"*^h];.,`M^05+UuJJcLs6f +>T]o@ k< >D52d!TN.TN.i.% .j [[0c' +x2ՁD"gt=9)iLdsP<U"fĠs H ڱ*Xo050mx_CWb +Rnx,do@NvH_-,u5[𽁝>~~-Y8e9TGZ^߰ƿx?;w:b 0>Y/>4,8 XxUA%`&5e!+b@B2ҷ-$so MYdcrAcޔ"z̚."w㜛QaAy¼sqwP],<ۢmth,.aq8K1GMUVV!Ш(OwK0A"淡R!eAOv %"AswNB$(yw* vALzN@|-sZ铫XtN%'EDqmتuՃ~59kCZ̵LQ)|{a}7ኡd"Dvґoaz'<Ĵ*<5h5@H@Iu_==?«vfj6gJ"֑-A621q"jv.76~-N1nOq@;@&-MSeFkÝUZ940pq4rK=0!rHŎ'9O-Q~_>דo}3ܲ]z3mGn&Y xQ'Ռvw?yF=쵪k7T-\Rf#GÊ8̍'Eu#5:j1aDvD#H5Tp͙UGIx$]kTO:2zcYœٞIqQQG+ +A#t6?xFc1]d&2C,o> TG5ԪvGvYw"n-آy,{}kػnWF~oOw>9l/\s{kԽ1|3G$^P^;>gݏxժ +"^ϵ + +ULkuƹcPSU3*NX OҤ**쮏?$L/8;pp9cuQEg^1&cFCgBؘlqg";WFtl ᲼w|22٥_E i& +'6hs..04g>!ٟ3vO7r;"~:(Qb2@\oQi_4 49׋pVބ MXhr0NLMtfrP(âvR ġ8)ֈ9nYO7teCWf"`eC i}E︿u9 -n_ɟl ?v-{$ \(VV䱪n~5Ӓ1)-n +*ib⌇p8ʺQM{6>n+6ytf| +RۂDe|UoRRFp@0R؉^L]7|OA $t$|$`HSO6l={~f|ϖE[Xlv RɆĶ\ۋmx8}}-Y:x"Ιm[UG3=Bd*WXm cEJP^#MqbCm~b8#fq:$fy`¶VӶV +4^JIB,X%at x&4<i8SVmy!+Rh\o+nM!B9|5ވ1|1,sbȊ(|8̄ǘˡ;.twLS?@6nu +4 ! מpv&۱Sٍm*Ƶaj,}MLij&"X&ٍňPY,sN*ptI'H:sY"[v6dӜm&B&{E9HK͚.ӧV+4y10b_<nsU΅h98{d>^-MX*.f}z-7h+?=xcl.u>|Gs!ְ +߁"ge|Ƥ;,e}d z}7JR.}#rg՞A͠v/WOO{;E?T(5J.d6u|DhC Z/08?He@B)Q_xs9J59xa^iY;3GkSt^A|E` + +SU$OU<"X꾢41JΜ,Wqvm5si2d`2 +[-[)c Vyu.D-iyrRWHnA 5É&3mW*'^lKF.]ʜaI853Z$3\Nv"rKS>sRX?;, ^$*0t>m*1CNɢ=H|]xhiDqaweyN'&Y9 +◕!^tX`dSWeϽ@/Pb8K=l/zƃSdNk0:T{`!C)?XR^L^rm["!MҬ{u5A6jIQ _czTK +NfR.hT)%12ܮL9!)O$r<-`luc^#YPZA>3k&i:U z21<<"^*@pG֥ss;&|<秀"x%zTkhz$huVX47VgGLfˌU߈Ǜ3驺U}@/VY4"h`ݾ:a^ cvYv[Ef|QbHv,Y͵׭]*Ǘ@Xe q5F)j]ԵؒȦ)'p⻗8xruSAG Ɇr[b;:>C҇zZtִ,6k~ܵf^o49]Vd;f8%[PZhMgzl⸙ܼ%l%]2yb>5CoӃbF:tWvla.L0a68(,\dwlgh43 efXfӛLN{:Mq*}Rc;D[P0a A! + +3Ca&(B!34@  +3g0L&f3RtAy^ k@%/?Yq>?7nh/l,06Ĝ'ԃ%" Vy! +L&l&gЇoS^0;&̡ l7܊gV2\*f+ʹ_*wMIuJ69a4JY،8cJZ-56Ȯs^n~ +6XFwcnuxո9Mj55|C~y}/t nEo݃;?Vtb9\l^蚗]׹Vg?{/~},[FA +gBb ȶEfcۃt.[srYwg.]I.wO6)diBK3o-VbPG +"U$x$b-f?}~uBOI=M;QFO,r,m,O\U+)"6 >xǘ7~AIb.Xe^ox_vM鋵gODoFY1dwOwSEwă[4ԱgYM@A1jN.fvi-ovLnըݦ^X +Z^ЫuHct zLnag\f8le'*tCV!^vU!3\YvNb1HtUv; +>}Bk`P֐gi-oi5fI!A@zjraO2B&ɥ/ @ ^`jQvvsgo`yAvp iq"{[]Tş~Y\Ge4A܄+b#kCC<5"V\\S.w\qU ʏkEr\)^TV _yQvi=o!P+ҵ+$Aohp4Mp35ʈ'4,WIo4궱L+)@dPB6Rvvb>ղ7 +to#|0y]Jj}se&ށq*jL=&׈;XA2-S]iyEEhu9jb5NՌ:g̱a `0G㥎zX o|# c8*իՏb*UFeFDjWcud,ؒÌ3)ղ8s8n7I2 +X7ju-w.cЀ=Nחe3ev,@{مI4VϤy֭h8?R⋒.`kespa&X$+$<,U$2HA)jmfhTN{tAPz +"":Zu&Ƥ=jFM[.6,Vjjrkkks+4~CWؚߩک٩ݩp:55HFmܭ7nw[#ygCú +{=;Џy}?=;lOI U=W.- .H.Ϊ kWvm;H >gW +16Y|*U`l QvqYCZtz`4X@vo`Of$q!QkcG*iEar ^/||9.Lf\NՒ'\dhCA2~:RCl,I\!:vy݆uǙu\ktW^ÓoA2_4Ư7Oc>>ZQ;Ϻyt# +]juV#ܞ){>b&iyj)]:VyLȔI5@nbnAb-不G!Mٳ+tӮ=A8UʭN&*;y# += +UM/DƪZlMRtxMv^ѦB0Swg +>v%OX,|b\/]Ul{ǃ\I#Ŝ"bE~ \q*tաڀLQK%sEkV?)ox_c "1z͠5{λ&'ˇ{jzC! 1Z<ŨN $ϯ%U9o.ZӔZK^)fA +@{h}͆ɻ)4Ps=û7#7u3/Z~1pWS9>Fi/RoMՈP /TNkWTǙڄWp[A6ƤY߭n`Lt7Ybf#0bV5Fw;g?vDdzcvmK"6(Ɏ3t9.Ҙj]ѤuE-挈8QE%V/ĺvG)EKMnVtj6F DnuM*U7/'ōO%[uhn^[xCJ|kuE_tu:HDaƮ3?mfދF;sm|FۆM57cnldV1=> s4jzd?3Gf0O'jcP0ՠZuu +?G)Xt!4Kj *t9?6K")zobr;B>WXAwP!͡%h ̝@c!6vzUiPV08g[s!B,Zf-jJP[g Te6"weЦCmU 3>2WSAƘ&(M>>f¦16kJ} SX( PJAojA&ى8J;j}?k^ATw!̹Wȵ䇼dYmYtHV7bل/J_;n."ikkoO)vU`m$̐뾹f漽\K5hfeAw)_j.q`Η-׭bpKׄݲA.w1U2b:9a߮Z<\h׳juXلmtʡFSI: +:"yt7J䰄y,ݚ`n\_S0P"]h!]^4q΂˩In|WXUL/^1wf櫟|pss"T 9,-oqUC@TG+iChM%ērM߿{3h!SDU*Lpx>egIc¹*tȿyQ7π fMa!<h@ޕpe !B5š"9Pgr 'aD;T + +"߲B>yl& 0yx72 \ up@w/vA[fW.-;@ ~ #~[ըfVvvZH4!{8w{},poi+FkҌ5kfϮsgv;y̏,n_jюE[e?lw;9imu~Hg˸ezg)/g8JFPQ?5(MkPy^M_^FPW%nDu7i=j~O*q,% ugQѺX +J\+q +Z)q-S|J\f۲J\(q#倫8-%}$ؕ8RGR%})q#b%}> +'8Q%}ġGi\OUcqiK@F.Lh'mMvj*w4~G9BA?AQ4^C?49oиXmI6ZVhͨuA(#pD4 +p ++D4~ NGsg 6w,);Q3'hd"-P^*¿J+zoCx%0Lߺv½ч4-p3iP>ɽJkAx@ȗ&ZCA=%x2fJR6ɥMkO6ZFjߟ"hWi EM +PO{K+!yJuUJ|@d: +B.ɷjw8L)8hH"ZBG hp@i +;&Z8QqIQi[X)[S{\%Jm2;i%ڒJvѺv;LS:iYݴL2¶z"cU Djd8Sm_]zh+)֡&emcX)BfmLҧ]2Sh\ +D^BIeitZDž>ZFהx"T0ڮtD"# +%AQNZf2ei +Te,IΉ1A`]R]衭8w1u(x=0Q/e8lWq#rI#7iYaHBW)Na"KYiC +~T[RiK-q:l)VAEi]D+tt\vPZ+>饥 +?fv)} +ޑau/V`4lnU*C@` \<S +0<vS+%wR>0n +A'/M!TkÐ,P1#3 +۠,܇)% "Z-+@2N +wOPl>eܪP_+$-9+Je+Ӷ)sX' +2fmWJ蘆sa)_#sB7Qݧ\w> 2l2㒱7NHڬ`k@iX%2fn:w~0R\~x1*:)>ɥtyҥ6*e . eJIk4H!ۧPE+t|˔M!-_"'N.MICRhdyr$WPy9 AP{'#k*voS yT +*1IM/šעIXH̅2g745LE{ue}P ޓ% +P^[K!K(:~7s`=@XB+u]a42Dl) + tR\i>'0r8- +,u»Pp_אiDAR皮~~M}}û#iWpe`02m7zM_wtȐ' +mym!+J=0ǀ]#rIohsؽ4Gښlfwڕ٦2֟6s[OvІau%2"3?⮞~eW.pvʅ˗KΞl\ms.lIoӱ31`Hbt@ ,mU4Eoyk`'%2ʒr)C-^4 ޻2킁+Q Q:i3e^-=2x:a(EC59J(wvP943<팸 +F$ݕV@JH) +t"@ngww0KtN%% +[JK.T߶>i>2.eL0&=o|ʒ +P]5[TХXyqdASڮԛfZ +7䃞qEoP-0>& +TjUx ۦJAfaՊ6TMiⴺ&bV-\]]iiƆbCѤQw#UG!T$bwcuʸTUݲ⎽}gNOG?ZXha壅VG +-|G +-|G +-|/V.~L;izD/"s\f?)UUjjj܋|+e3ȭYDE*9K9?Ii7sKc24>kil#5Wџb_ѷFm&H'cD_cp1Hb1z} C+yMz(ȆIĨZچ NEu.`uGR! ܃peZNRGGcvg\*}ҷ;qwo#!4y~ +B/__$<B^%n% Ix{';BV@o s\,;Hbmrs<}g? ۃTJ np)E Z^:oBhyAԃQf4fYA~2Fd[efG0Z +Z +Z +\ׅ0C/8nX5F>H<{LW̜xZ]tG崜-:i}sz1꣝cEG֣t,:TMNu172reڈ#72=Rsv753}~h'MX HTpVCΒQ 8,x/;byᑼ?co#7,"> +iWsI 3\ V`p/pFʦ5*Y_U7Z.q>9ƹlV+V?lāЉ4stǕsqe4t%$Ę.suP$ *ʑ "fL_IxH%1I`$j]jM \=ۈCc;!SOmz~BWkwRk?萃4#:DKĠ:qA7 sD7ȷQ +UjGn!zҎ؎u6oj|=L:-]`3iT*F~9iGX+P 2HSmd;'Ft'W֎a~Kq8'ا/:d/.^Ԩ~^vImGիĕHM\d ^WW"ճ.j^07qum[=̦A^C:ٮF6 +_eU5:T]V7uTz1yiTܠ| qђqͺ&]\]\}nWZZ-d*Ͳ,KCd"0{rne"9;W`,,ޱSBjlZIéks8eg*(%F ( o|lOSJ{_fiʺZ ɀuw Ѽ{rj~?۾jˎc(mddZj,c=kEl98  l}Y8D؈٪$l$D6mXd +M!fy@ ft:̆PZ<-*KDgJCEiMO'Kt^GY^҇κdx ̴:q`!9%Zr +[?|9ut2Kܐ,> +endobj + +85 0 obj +<> +stream +x]ݎ0y +.+])͏>'Ej"o_9n+"a83~my׷KzLYsOn2VY=/#t9|ʊs~O?|_%/:%L_[(4x) )V +Qڱ i אruw3|i6sh-K_GmUZT{_%W]B0Cң +y㺚e)OXא_Pǐ_4N~ 5א_i>kߢ'Ve#v%6KZ v =kh;ђROWOCZ'> +:]_ %%C%B~o$0H@_'ZwZK~AKG}q`N]\G}G~t> +endobj + +87 0 obj +<> +stream +xܼy\׽7|Ι}FhG !"H +c€ +Ǝm[4d$NZN,MRm^Mm4ms:pn$8}< ͙3Ggo~猦o9?3{JI> =4ں32xq|޾uǁ@/4>:Rpe@w=u*|3sz<1yl};=C];Gdދ{V&vOmKxXz{sǸ\(zn,hkty\sLOb!q#>dk+˺>.*KJN(AGV9f'IgVh\c +Ь 1+{Ş>[2\$pIz. pig5yia޹vOJvε!]}Ī r8's3kN094DZbZO̬\t S +2KZlh_5ˣX1LlWwxLfMV&ivhvx~if=ϦVi~3皎$qu$= s>*%ʤ0վӾB6{ Ҁ!X ?s X C:.ץsc'u8>NK/ S=_{rsk{z =V0IZHv}d֓:"kWV7Lc|u-Mk7[ّr8N8ggr 9(cK@ӱuX+kCkO[Kkn٬GSɅs.$HBIp.,b`09H>\䪪*r /ICy +, [R%a$\^V^ &bq{}^_9d0rḧ́ĎCnyIE|[)/ɧ5ޢ3}meWx!CK<vcS刧!(0nS +E +SzhF:-캀CGA1t<6yIf:uܭ׷y X; +iEEMY0\0%Nuj +{?2)=v!CϹm3[Mz<1/g3c~li7$79\<|+.5 <ɇ2g6nwwn9g!&e202EGyU䋘x ̌V`2}Fx$E*/-aF( *!L化4ߕ3dt@a <@\Y̸|aĻG/A(Ail}eBŲ#{k(̡Q4ꀯ뻊y3V ڬ\[rmԫp[@7Ifvr4hWt +EODh6M^<yo^M5]ii/3g*t{MUFZ|tQ +lEq bW!H83*k`{o +_{-e޲2,*S}3%?gOq> ˲Sk!o22꒏H2Øb&|&QI&''Agb-D +u +.59 &_`byK#>oO3Q8D +Zɨ4VSvk&Z .|AjAcn{44pCU⦬h8lsEEKxR +Vz#sXZi "aq0)cwZ|V4Ē'/$ +ZR1XvĊE +(sk=‘|+\[~0quu{:PV_nS%]K ;l?ʅ6-/^n_h ;)]Ma6*mT3xdrcbOτφχx)YQI3 լvd?`!wևA%Wqvo9rrZfZ*'l%2\͵@U-AbΈߙ\H2Ҙ-T @ .RVH&!J-%`ZHO%c +qdD|]QiڠF#ejŮò lID\u}!M ŗt!MuHs}ޢ#IDSjNw]{XVJ2fܨ?㛢-dreSԥYZǰxHsY);]x>Z3E''յUbOb$a0.yjDsR͌wj?0L܃mm +ʼnQ;=:Kcըz{#fY?tbˈR~'chxv}vBg;( ;2v='1ȹAg #C ZȮ GaIa!*K*Hö;pq0Fi + m4$8ŒV4 >l= +6DjPh kx|.HVzAbq%\ CɓzS=e<eWn+JږjihRFPo\栅Sm*%6K.v* eu-A,kASr*Ĩ^S7}mMYŹ]VP*^!!h{TU +@%ITdKX\xyy5 +vclG;dt\ik::m,]BWl>d{Ͷk^FfFл#ZHXnh)n,.l,ɍDzܩBߩ&et}LT /' vw0"& mb8 vccId.|ebXuIكr +kys2I|qbǜ"J_JAeYa64$&s, CRXշRώWZ]1+rfk/sSP%W}X4$ifl"Ae$~ +uC1m?o7Zc@{KjYRYuz^U}c + jZϋZebE 3=麺2~Q1Z#K$+Un!d.=aNv̱8ә'0sԵz@|,/TPzbH'Y`2rP@-t@NIڤ "<~q9CBnߔBwAF gP-bk1 +kgyIzm*L +n$^*uuɒ.,DN\cE>ܥAj4a[j ʃyySBn4b!7bT +]J8HU;.DF*H(= +b2$xvIx@3%Q@]Qf%Ndаs:[$dڣY|"D+O 3%UDJ,2|ʥ +_ +BB:fUn#-'E"oԢQ7 *yP%e9,è:WcQiA=۲x0U7Ȃ26X݂$EN0 #">R$p/N}ie(vr-}75pdz[\Wʜ_:`d99:lW-Vͯzijd,socg2d3iϥcY$sC ?,Wielb@XEb|_I?@QcɤNQ!(1tJ~+P_Ҭ!ԇ7bhJ|^&`UIq +yNnukRxȒqm8):B4@$Dw꺡Z +32ƦL6kddSNnX?r_H |908~^Mf'_pw9(-2oVYʪ&Ӏˎ[kx[ c'.$;UF'ʉjīY#(X_uRjO׿TO׏ϸfׁsLI3QiN:/1!).uIC)bt6JƆ>Q%4$/Q44"A%`Ӥd6.%2X(3,,3B%C`$0RqjNھl6hNvٴ;E_{G=FN>wm8^TRD1㮊~lW+F 8 /ר t:Kw _~GPŠtC&>CLka7p볦gڨ[~BݭrGj3~z_tP?7v/ZW:U?4DzKVU}gsWx[<:A+:a}J]e}պdY+jFys^dRĹGmDGu2ҼzxFŅﮆG +Z@c鬕c ʼB2>/+ FL\7_.cF}*#VL'($#8}%lT<Uf8tJ*ûr +.`3ʼnb=q +6oY|(p9 +VVZoآ-wqj$A/*U $!(CECW~ C^Rpuũ9 B$5j[:hst냋_F$FZ!T\Bx!) ϲPbu&lJ"*"a S _D +ۅ$C^ +^,X踷;I,Y7O漴 Vy""s(h8wBޔtCɤ'eY,Yanڿca*)^o$ BTWHF}PYƸ2oQv_rM%`rxkǡ5ZZL%_;:Wv޾vP%28:sn2N񥖖>@ +i +^_?;+֧+0HhQmX>IĐLrdZORG#JKK6(㲻5*3x8ZIXleSu?I*GD`26 2HvCkִ҄}Z*҈HjBFWL4o*ނuX>AIYRhb/^ZxDIf?#ZRWcj>kf0DץЩ +i.vNj dr1*/"6hQLe,UmFVԊT{,̟e2XZ6:Ϟ.}禗sρ;{أw\?:uqcʧ3>c]0:n;~Ʃ|W6Lwxr>P%OzK-7@_W=p>ԧ/SSns\*M(tSLMM)L$sEr5G`app>[Xѽ{Wyxg6݄6UbxT`Pq!؁`Gaf( 8MK4&v&JV< +Qv-Vkx_E}e%X.4DD|Y=^bJ,Qc- +RYp-%rTҮ̼c{4yנbg@-3SB ]Z4@Mm,L9H6!+RB3scȠ5Zί4 uԅ&=dD^{˼ξk5t!_m-ZTtK)lhC1ب*VR]玀sjuԀ#d^b8VMa:Fclw +o}H~5ocA%0QMsKs*o7~gҩhY# +aԙɶ\wm/Ԅk ۢh,FUqvH4YY5cʑ_B0w+d5#pg FǮlX݉$J'*xs"8#EB +9cL:Rr$ 8"N6R2{=RCla)\Z +CSxq(m|O:ئ&\nLKѤ2|rWTbZ,xz0027ԬI"[XK۶@s>#֤Qૃ\A4=r6IrCg 2+ q? +d|<A.GwobhH~ eZ IEG;c$<_Ҟ{wkL >|#ȰA!sp*GHz% Y$L s~jP8/Ǝ?eUee[_׻&O57bGoJ~ǝ~zfaA׻zzْugX`fAN"fnb*767G{`A#E1coWr$R~|wftvQy5 errL!O@ ?OoG%rdSRX'42VC(geT%,/A- e9XE +;)Z /^!%ɕn>lP,*+ɶ/3NKE{+Fcڳ$FYf:s*㧛7O'TE͍07wP#pc][>};ް~;JZeIne;v1d٘?pM}b´5ƮFDQ!D +тD;Q[MfOdLMPpbbĚUՒ՗?Y\VlS+_F< ?}-/g9~ ==c=T׆FsI F~i|.=#9x<>BKt9#a? c4Hxi8>++֙GYQ˨nobYpcQ +"E)ӭxZo {LlOϿsmA&=z 8ȩ=pO(SpT'+V؅sBcg$R&<'| + r2E/l_zj$7+2WM)e$V R +>pLD)KqTJẄ́dIޟË?ǷGO9^bZ-1pϴes +tH20cY:qHs; D6J ٴc,J曷:h Ʋ +*>Fb ++0 +sڷ?7*Fj0ZWw,8FvCmo;]׊-> z2,ɰ8A4|0[Ԥ0k nhqMvʱ-Ʊ-v|澦XS`@u1epA0R'XRPS OՉN"bwEQpQ n*=ZzKϗϖ][6ƀD(Ò5ۛzi7A)ihiӮ9[e݌G8L%9t.Te v V~3b1m@#FݔzK?s%6r$.O` ˭,Z-]K"\n1d;ܿjREۄ1dtKM;_3ʩ816ڤ$V=-1f]]ϫ(ιUj^fE4/H*Jmewa]=Cp˼`RDTͼʪpq}#>b\8[3=^Rc8\- +{*VQh4(Bd{]m0S5_/t&S2X]p}iWff]1Vzoߡ +DÜd/ +-_YV@}P7AܼmXDQǐ}- +nSWN4^AE^XӁaEx-9s*~UPE~v +SQY;cXryhۀf +Y@dsFP80Op{{.)fI~h@uVƼa]WU>:ݰ5jeTgMw8^Xz)ekE}uV ʲ`L;tC|P%{9D+;DQ0&ۄeL:HDiF'FUFkwڸkmak2E +#<śU^YUb߰6sZ3s;muG] QXi4rY{/_GxKW.劷_^+xhvEBL^>p+ȹYE}1 Ҡ,V9 4WV]G$g,ƕawO{$cJ ^^LyTXSr˽"ެ+D3ܸ9jDEFV|#(ga"Dcq]YGSh,[8^֢/6:5er1^Tkx^,nkg_#PSo(tO-S70p*j燮^:/x,g&~M.j9F%aÚRgF םͿv5knש]gw9wv]Ŏk&x:%2əȭ{ef"={7&NNp{.do0ՔGL *j +1+r@ETTM粖1]2.-=(_IP m7q,RPy+S E +K +Y`NK&$$I|4,I#FX-eJf+cms}fYNdѺ$H֬lZOkc$NUŽK֦6pkZko 3 Uh5;3b e͋k[OJ124-f +dp0hƎf7"0=s7KiASdxs-2Z:rb]ӓcR͎VΝE,[wW(c\Hf;s(ev(̉̎ &dq H*#VBte +ד5^Y^ + AʼnJvpeM瀆2%"x%2QNs+=3flnc/=n >t*Xpl,07`sc}y3f|WNo:hȈ,>Q>{Q)tuAVz^cQD +6jȷ0*r-.VehzC"^[%L&zӋ7Re[GAN"ʥu'kumbg3^N$$eS%ܖ[&N_^gg39Iwvu}܎#U8S ^r^ tIp!…Kku-UyWrTLQt"YW|EY2NFd=$Mަ5:׺?$C +7V%GSiqiS [}jACe_nmQF耡̀^5B@Z`xDgU7O;BE/.kZ2 nZJ%8$MY}Zi +vSyvRAQt@: +N-Y<07s-X\<ʡ-Q#BW1ŧ5&dR˜i5KPW19A#`YR +Lg(kC؋g;"Aiw +u-vmB@5tP{=Ï={ ?6imeg動Vҕ e2ϘOxr'I̠,$ۻ&DBd:5N{ӘL ^YIPON^zG=y|+7sol +5Wn9iӈXy׮/l79tՉ48D1t@ֱ;oFzni4:23lǺm/榀ͩt{WyNbxʵO׷Zsw,z/6F ٸbx+Y mMk&DR>/!"l0G;qKuu:zŸv^=P-~ P +7'CnL7tvwu:w1`!I"A2{V(`2LV`'HB7ⱖҿBF> +SI8^/K)**3|ėBMs;ySϭy-$>cYZmPmC'Hs)dM|{KLvhWmV^3i̬pbXf Y9QVВB6 h)w/u-I"-E ܧ%: +y ?QtO(ڀUu_&)~eh W~`Qqx p/iĤVJ}⻟M6> ?*I1m‘kH"PZz!4.}bڍ?T1`=i:n߄8dp}沥?vlL|?:t˱_&HLv 3zG/w+zzdz7˯:{T*Y-2e5?o`TYvqAWѣ|QF%'?AF)V1X"Ttisi!\//q34뼿L3@L|i7nG*4yWV(4A9 ++c +M542KF@Cu-(i2`>޿L4eaeZvW˴HaL%0&iXҏeZ6my +-g1GZ7(F' 1oTh +mTTha6+w*U7 +Bg+uN)C}+T|)t?Z.WKE ,böۦ]>Źexzعy"u`ji皉]RΞSé[hq!ޕ9kwp*w;FwNRɍS;'vmyйms9=5eteΉuƷmw>ōnݶ{zt +n.ѩa|ܾgj-6Ooصh[G1L.nq[ԋ<hVƟq [&u]ND~sJ5K8PaNУP+|5C+Q7T)(¥w;w+g8)M gP1\MzZܩԻ MO}߇Kq4i>(wnUuZoz춁]ʸ28RnQZ#Mz?n=xlHx~_U{[ n_=}j6;ܣ<῎ſנ\ߧe+>c1ctYؓo_Ǖz|{Y\ǝ6rne (9Y.MiSNO1(ß~>Pɾo}U";[q\~l>qEJ][ۖ&M){Y~6RZ|7Sw)%:OmGu؏a +%=JV,$3]c@29QXI0O 6~3ϦI6QFJY'kYǶ֙L)?E5)4OIۄ4sνa`i*s߹{Ϲ\=M4V5^/({9NʑM ti+O;ESQ +QҺmQs[[f/^ RE1d&\{{I{ta@ke/c;7ԲK^&;8VB9x"=ܝkH8vrdHd:wO>`P1StGzPE:D=j6GGDwHӌii3sSKɚ#'}_E=WIL#Ҥ+6&R2z qڅAR4!Fir>sV1i,n)i)c&<*fJKIǓ7Yb;~I-NHIRהA^*6ģ 9h:EL{[Yj +LЊ䝳紾Rӎ2ٔ_uiSଋ92)k4yze}<{eB#5$]sa1u3F"ȎƑXY/uпs-n39]}ɡyۖf*`UGl&9rb8eN'|}uFc6(%$R FfXBף[GW9=!;} +vC;Ln:Nv?|^[ +V,!ZPJcRw4#=Zd\Voϐťdܰ9uI7lceU{,X_'L:]| +iSXiNV8SBl/,-,-xB炂=S9+T#(ѥ +wb7p2+7͍[[WTl}>Ԅnƚn + lBcwЏ{TB |aP5\o!s4K_uKjobuʑ \Ÿ-Vbki<0?BZALlj@MVkZZ])ͩƔ&JnI" +i!(^<*wX?8GC>qttI:'Ш@=#P@ + ]|yÃ0)n> s?x y @ + 8M|@Ih@UymWp|t_}u}u>b~_S{`8ş?K~ğ?ϟVWuuڬ6jPRTU^UQxԚaфn}1[^n5DYdo*^# +Zӷ9P-T 2X +N V4}k +5vljr?ŏ~tׯ=k~EGR?O&^;r4~}9!d)}^Xmwm֡@5Oj:mV-y)C08/9vOk'C9r=蓙,G[`Y>7g3rlf6#˚9!frQgSׇ-GB$> +endobj + +90 0 obj +<> +stream +x]n0E|";64REj 0I3Rc9t};4S@jRG:>F5m=#yחOX{_[,-]pWe!I_BCg5Xp/TjyBTMM\n4=)#c +kW5ʟ)YdY]oYB2gF8dV1;a1Hm1?%?Gc^b~üe /{ny 0fQ0kf9/wj[ +wod;qlٌc_p[4𷼧峘_<ߕJc-=zN];/]U|dH} +endstream +endobj + +91 0 obj +<> +endobj + +92 0 obj +<> +stream +x}y|[̽W\";$K^dY-NtoNb'v0&'rlgcIL mM(e+(N'h>_qRҤmB`]y!I{{H>3gfΜs̙33ג=:14h HY5$f9B?G{6 +|)>Z>ẋ +Owَ ds]7zB%hT<8C9or[7P~ʙ.F(#][~b2(W( ]>}-B|n(42z'C2tÛ4Ia9\T4Z7_/CP*YLJm=az +! >*AՇ (!m؁v[~ =&t7]yqz +eA F{7(+~4GG>&"8p`#ڄ?kay1RVw9 h=݉@rk"D~u??b"{g Dw8^#/WnC8lc@YvdZJP]^ \Tdבߍ*vz'wt WKqy=K@=7?$oG2(֢F)4B\T3̭=K췸m03"n-I VXr$xP +Z:``~F>0 +p߀{Qe$ ^6Vߧtz$A}Ylbl3{{=}}[==CCGގ*r +yP#X`D?A?a^Gic6f̓l-Ys"wʴaӑH{s_7:a(xA6Ɲ|~ ?e8Jn`ecaqNZ-٦oM"#]ȌQhzBz@0`Stp/QQ|`1˘01/3Ǚ߰Sq.[ʭ/|{ZdBϟ|}SL3YE$5 Ry)r"X\kzffuc0׿G 8R|%,} ;ax?O>'y ˸/h|%\<μLql*{VA +Q/?t\<ʹ w$w^V'[*,7"ѹ0~vX3+V _b{<^~oD:ZT]!e@{EOᷙ;`O :oe@49~q:L'Qf|+p DS~q[0/?۶A09t +,6BmFry+jvAA2/913`}=y] <FeajDË :8H{\H=$=/6|ekˊMV |\O;;+3LwmՒ 5Ŝ`7xNS +crjB\.󐲣 *TtO:)0Rʾ/PQJqB5!|!LF]Rs.ZBfBMj!;pu;k:8u*8@ '9E"LRM~)U8Q]6; +aYn^VSj{r¸Fa**&, ++ .9 uw5ޮ+lW;appҵ'mTvgMr@;w{mx@_Y۹DAEd(A5j!r,vyu'LH0Z6"D)56-HuwU/oB;Wl=`O~~^B4ڹHpb`+f̉Fzp#&mH I%hgO Cp/LCXUչ/#Xsq5]R"XN 1v/U0"Z.l`:x20jnne^Ff uC!<-ZPw80IZZVXLNAzqI+]3?z>1f]Y'`Ѹ|uPSmcRdMUml*#aL*K[!&6MszrB HkP;/jKv!h6MR3\_.Wf' +s.uΝ/s5ΰ ^::;u+BXIImoڅ6!ܚ +"LE{8 JR奧2Mpɘt7Bvz*a6P<9n6 + Tq&% @_uӟ$gLF|s$BCG֙NV9WԼ6F%{Dٶº +7Viѕiv `b?PCReY갵OD"$R0N4n&.!A@[ [ΝvgήXC;lΡ"=5\{G;:\A;֖mx[[^չ}:i-3SKJ)F Fg)mh-L`D딱:z&hO YpGp"Pr"W:wEj 2)*w#d2lҩegK + l'$qs=(Cn8e>ށJCH4T@!lqSIR<6b@s=gRVwYjm['4'o22󗾿_4GfmB<92(,Rȕ+ +Hi)-::}V&޳/Ub,.N&⢄$AXoY"4de!7.sؓRKǪ:uleỀhtc͢LRzY-Nk_|;˟u(r1ǺA^_v͝)pWxKe|yy\#G +&Hffև͢RfOK9ݒ3oIS$mp4eL0+EOfE/I XH)J6%lF?IO0D'|W1o.칞ƒ +$TT|P[ > +KOONgO0|#1WwVR̶8\vW%Ê dZV[a7x#o*K\D]w +NCԡ6{Խ  I(**Gxr~aWLExu +@= + X `LXsnå^R{Mns774կxÑ贸?0}qyyZiR9"cаLϲ?(M~fBPE|oI Bz7b!F(5$⡅~0dF4|/bLܗr8jX9{7?l*NdT۱sMAqEn"9odeI+oy>f~Ckr,j]F`Ks*04rfE\ENMwk +(ZNCAQ=a0=#/{ߑkz#G?36~no}NMW\msvM,Z,. LdFG6@Z֣&d$͖l|eGa8j4ot;'a2S\!vxQhgEov{)^;`A,={,):.yff[)34wi>i?q +LMQeH +Xs qLDEDE9(O%d(Wp?'<| ,Y%v}6}? +. +׿>;TY_ +/ԶjU^ +:'b(/4 |AܗrV~;Շyg5y +j)TL_.֫L'FÜAFztEYHEBonG޽yCW(c5*ƗgҤ%[)>cq~+ߔ +IؗjԈs+m|~I4d=R!&/+TG3ZTmhn!eh;w}8 +} @5e YQAƗkrY[Zt +ia5FhS#ּpaq}s!M'Ys@Elu=UT~!ޔ4Zfj͖zrdq +:Ӧ aB +^!(| +QѬ+l:HANTPK|#q2tb$Q''nvᖮ01{Lʩ.%3 +-U/*RLeCRA"V̌(f8K2λOtMgVpX+Yz +%?Hp|ᎀ3"`[8sWWwffql|]w=$3Ly?eg`7oNX7ac C2&͹2Ν7E>Ո^R h I N~/fD G$Z͈9TI?{^ 4 L93Cs_;h]> ba r(Q9 =uT2!AWUMϊhnPd7ߒ# +^ jFTmMn99Y&ѓ7͢Ria[uжƎ)Ҥ>zQ_X +sIY.KNQGTEyѳ C ɮpMçF\j_|'|\;S))&)q.Ih *_:G'H$抝ٌHbK/y?⣎kBWYd*5.hn +KRW5<_w6喥ksS\I|]ӫtPŒ4,|nYD9qhu&"Ll!36M,<9a4pJJuGѕfI@&35:MCIC%3LfaG(L"Tbwu + +uqFxYlv{ڣ[uB-jIƟ=ݛ 2˅ɞ_1Z^lU)4o#[Ki,5&Nу;RWى!LB}|t3> 3:L70 p#+ċf}@ $K 'Na KJ\vOt!Ҏ>ֱ!ߟp뱐qd2tҢtQ`=gM?$Fyy+±bBT!{ RKrsK%oP6EjRjFjq*w 3zX0>)L3< Zٝ ^>$%j4\'/@/:4_!e>]K[ ),Boz0Ӗ}brsrgXEC|3dom?6}4>=$!Zr*vtGZ`>QBf"=;$ .T"1>"i^9U*rQ]* ZFq +PZdğ #y U_#C&BDW3(@?qڼşfGʾ~ޕK^zkݎZ5v~qDWeWdV䱕wނ;?G>&46*<{4*6n8䪤ѕDP/Dg~FZd-Yqd@vop7ȘR)nMFfgf BT gz &Ǔz^hFC&ԌPɀp72Ց ѪT\~-j2-=Iv (vr'SFaarZg/ X4B䑪ac^0!w#AcPK]:!ǁtAwKOEpŬ@6k~'䖿Wtֲd^RηcYDqE I *,jE#}n`jtgf?U5wf>{k 0M fVZ]i ^ըeC 1̪q#OH Nk2B|fnܧ:grqJp^>On ! l8ǏʟL{2Cs4=tr[cݓ;iU)'K&LPtB,: KJ+^`]Cp>U涡D'zY#oVEhQ:GeOzGIŕ"@]ET;nqœ]SllYX,/583Ib~!$ +EK?v{:w'r |F4X +EXVrg3.`@BetvE\\k5\qqɅ|9}b*S{'O)A6ŅX_>VUe^Q.6BrE\iǞAn\v T1Ө +ܯ?5q<]iQ@bZiY%J(rWLAHDҁ+ z$DBHFHFA~y* o* gvUGMإ 9Uz:AHNSj85T% +Y +s\RNSڔ4LA3*tD$y$z<-и(e!Wg$^ +rhp!b^p^y]AFvBO[vẫE^;iB:y"4U'^eyΜMg\o\3-:=UQ<N|ww +k*% +COGOpH%}W?1uk,;"w4F;bt/D>A7vt73tK(aze?+ϫ:KտFc WS 2 yQBIZD>C^4ef^Jlp!I %.G.YkeJ]zv5H8Q5 N,,׶J8H iߖp9~_E+QN)*ӥJuY%3*J]Hu(x4.>K9/ !{Zˡ^s +2/?pg(zM[ΡP\E$pVOYa~l<np߄G$7 M&&0$7u MXa~+% +!%l%xNpe א%UQ\G<#ʴP'|lJ8g< ~Mqv^A Po{%C9DBoI8fJ(J|; xǡpǑ@q]2@ޱk$|q +ų}$㸗 I8Õ38)H85>*P8 WV + C]r=ЊQ|) +A QJ@UdC4~J!@worh&h@ghF>kAQkF :lR?27C'z/йL2wdFC! (2|)/o~hfglv:ڽP^0.L PKaZRme-70Xh45QF`<J}CV=C0F3t)'2Ӄ.: c\7Sgxb$G9,qTt4Z/uG}u팬?= +^@t']ԛ"pl#`EC" xl=T^*{9Z͙]iA7*iRB_HyRYxZe6CGFT(C[YUZmGOsh2*^G޹sl6u=P (tQ4HA:ܙ>gem +Α 5_ox +B@M ė7kཔֶ"-RS z;A>h֙VKx#JIFiN,HF(OԯS&dP]"HR. >.I[(]Eo_2GA%͆7Rx1{qhĘYy1yR%~MTTnif% :Ɲ B3u]{z=B^Rv.~rz\DiN4]T!j~ +{Ԝ /Ҩ0Yd7쥖Ƌh<snșSKKqp6fŷyQk6BR]nwJ'\&;Dn+LAk%^EN_cm/Xof?l: +O`hPhk?4( + +]]K -fD~y>$BaEp$8)[87/ +8ͩHC٦[2 FB}Y_$|M-ʾU:\5|kGF^P v:`Oph!!~@hp⡍CG&A0H0 +t~lJ{ +RezC=GMs׍y7o]/.'޻ntw(cB#kz n%-_ieMUM˄ZaI}UͲnEMҚeZVݺNCC0[o\dz7 m +m$={Bl>`#I0 1Fum + +nR! +~lX * +0Z$r_/pQ` +j3R;3OuSƮP{d$8:wrp 82BOGc 8M02`Xqpp-OdƆR=Lm F@ѨgR:o#QעI+Ct6v#rW뻶 +?LVbY DQ7;†*AiÒޔxd]h@/M\8|B31B73FP v1XuRg:@3ZFVT +!_%x|~OZ<bTĪztG,ѭlzl3jmZج>$,E)AjEч[ؗ!)y4_=!WzC~𫇀_=!WzCWE@x~Rh2rZ + ~ uͧR1Y)v)he4mwKΧjvt{z%{^v/=yT[ĕsU\W‰B+TϋҶ[,E?EXf)5`shu7_v_/.f>roua(?Vib!vT  `q&;;^Z_&@1[ +4c2{u ]9v$E{N`2*OZ+ I gR~,RN/)_$ B#y5c?WJ H A<t=0Pwq>aX%f +VLx 6  Oo7)7כM&~-q:x~rkWU +| +TE>S.#$Z@:֍\г6R+[e94/=^r }̀R2h)JPJ5}C OpeDaMM;I4=IӫhZAS\1E |nܶ}v٩q[7dOGȊ0n +jlq[dmUUMpX[c` +JqgA[7Z*UYBۓVO&'Z2^=ݩSv+vg+vi +Ҩ:FV*r%dHi"/.|$I&HQgH/|!+Ԁ:3 ᘰp?SgƖŸ1|5v ZX|uXXFغ=64[n`Ǫx+hHu{E ϗp2 N=\nPDVK܍aUm1f;̭mGHͩ B[oF*#7%n +$ I:t_oKE止Z(olO+v(vDD+nli G``"\v 0 k1Hvȼ Ԑ/{a3t8@k3 !'C/ٙE.dQ:;ϣ_goh(M|iR +͡/A6Jc/%h2.Js?G^ŗl‡ +<|w @gMc݂pI?Y:{֑+8'pZؿbӅMyz?Tڶ_!qtUhZ'a0 YMi MD5@d5MTVM?Y}mhq{ՕL/N%PnKޖzCqnkZT&XIGԔܖz?.5Pmp,F.xTȗx}JkM鯞C{=?3шT1:Fi:3:s:NKi'/z +CjxAG\"ȟ#8amnBH.5 o +endstream +endobj + +93 0 obj +15232 +endobj + +94 0 obj +<> +endobj + +95 0 obj +<> +stream +x]n <P6m(R.Re{i!C~wg=քOcyz c̹6*ܢtw,nd[/3ܳk^GŸ:#*a<!KUcلe-S,5i]eT W{(Q*n_EΉ:qF$^'R~\>w)'M| 8O +# z@Ǽ2_o?~F8ִ4Ok79t +T +endstream +endobj + +96 0 obj +<> +endobj + +97 0 obj +<> +stream +xy|TE8^u}ݝ/$! 0!B$[$#q|n⎎sQ\B@m\p}QHTY@c7Uu~ΩsNսiz6D#[;!^DZ7 : +q^սBkB6doؼʷ e}&jYǴ59+ :!NGWkߗ[$|AwHS"4;ºΈ핿!GQ:n#=!?z0|G JZ +dXmv$x}?LLJNIMC?p@!-ȋP>^"Gb1M\/Sߛi\)jCNtpe +#_C,~*C;&:Z`@%hM,h _{0hU^E)cCtƿFK=Q1=AzRˉ}sZ2 +QPض؝HN c:Ԅ6a7%3bWÜ 8! "6Eo05;=ku4-@Pp%s.{.0EǼw=ڈ.@vFbQ3aF\sz=a%.q_b6rؗgS߀vMC#@S;q/+:|?32-e/>S=㺑 ( +8S~> \ʄ sڱh4?6+%tMD)PUÚ碥02t=m_B/@% h! ^ +0Wxfy +/qKGFWXlwl ؋`*@#Fc`;Ɛcu6ç@%CL-gsNhgP 6dE2DҴ5@߿jރ 9x>/Mx +x=_ T}]%1r +t +1̯^3"v1]^`r}#aL;Q̱9 + +  x +Ђ*(ߪ`saKq^5x-пƃ |?/W gvff73 +of 6ggM+٫`=q grY+k");"{N/tDdþ<`;.aϘ2eWI;&?% LS|Y;~ ^D`ng2٥\2E}s.sӄOlK.f%D[`LwUWzP&(2QdO:]J`9?s(^؀Zu(yB:v RTgab\ځ5DAb؏=xE@ n&[a$2V\,| i'چ <4ap9Sx;'zz +# r%3l2HM11 FF[|1Ӂm}L%"l/So~U@M%J$+%pO pd&0*{"GWЅ@٠ݶ^6|^Ř:.;fދٱ_bâpN x}L'`vnw9lIКW`Mt<tO;؈ +au3LJsl:ihUhZ.q[,EWk@܂GadfUFaew5-Fh!6E%&*ܠ `>Q~syBpŌ%Ey9YԔ`/ ۬:FR*2e0ʨ 6 M\rpL6yi@T:B&LNkkb^(CeBMPx:( s.`00JNa~?4jk$ n\ۣQW" GPЀ=ؽg` +0{\g`MinXpYMoU9`*3 PavMؓqx5m8"--_`_v\1{+"\c,˸T +{ #rEty|M=[7q{ׅjV&Ju5i.:{ҕwsRrK¶26=dfN Jqiyni> +4> ŭ:u:V7Ϩƀhd!|`D*2M._,P1m% +s0yj -f#`2ZL "F@c-uR5[VɃa613 +FxEf +&c22bLOGQ"NW܁ۀ'|q?1 +Jh-*ʲeՑ+$q 8wј +̞?-{z1 qf\^\Jm g]Ce>ӷ06ܱ2W4{˱F٣0܇'!qQl'v%l=ó + +>C?L?{A?Oynṇt@؉AF9~ifkz`2m;8 +{}Z0Ü{A24R+ R~XQX@Ÿ5Xhhrri̱/.lYy}[J@!3)Zߞ郥;5z7)nDpI7ֹ]n^>կGԲ+7?yC#+pOت82yj$S6 R\wj,W| lPd3{Oph(3aƑ2nNOEr Tt=Qia˭h\*R>B8tD?IBT;SmQȩ&|Q[!Sx%YtC'|~#; vdv-T2%_9 +L6A@*]%%`SP>sk,=I_GNO$OlnͿPwqkJ!wڮ^=$ꠅuLT +:.޻#/C~#Y,eXS,ռjj@TU+Ud*Wa?=+8rAgAz]?W x@wP#`iGѩzQqE~A] ʼ^%\2$i|̴e>+m,.+zEgCSD3 +iBs$?ڔbO|+_?k_`R!?{NzۇQ_qK/2AmTGg&7[:li<^5BQt__%11\AJ7W]zAUatYYX3&:!ԟ;Jkq͝#Bw?abOcC~ +hrgږ@~R^Pƽ}4ڸ\'+T9sYQӆW:4y7=ؗdp=^T +Y-(HP|3I鷽9Czy!dgHgef,ݢu +\vljkrgך66"ˬͬdbV8VI4DjOiz"SY:1 +)V_++YDCpAPF_AguqUMAG%[TDd9SUr'](j6Jgm&0؁iӤMHN!\akx0SSwӬ֛΢p:xa'ٖnZq +sеlwxOvo Ҳ +VOfg54?)4I7(ҕא0?aeBW̛lR+2bl͞!Lzp=78)Ah$+avx}}jp_{cO~p͋-dz_{[_c[n_hϾh 8LqXDo8^9 +;]12\u%sD~Dܣ*~ӪhSٝE!a=>aaJxai:SZ6e[Ɗ@Q#ފ豾Vkxţ$>IZ!]o60/7WZ,83'# +'oJ-9s'OG~!w{ή&Y2yZ+c'?y3ӋC#S*r%#\>V&09nm" Q m&kܗ+݈ˮkh_|u ׯbB򕴌mP6gqk6\Tu?&Y_~4vTTx*٨W?$= UZVCJ#M1¢VR*Z +Ԟ'b { TbpLPV8g0!Q1VQjX oDEidrڃwݻkWڎGPv,K). z fG.]އ-fr*.-)2߹"8$~dg3s 9zv3!n~8U{?}ϯ$g%rwyg)DkZ47eИtnZZg{Nm8Mli0c=?iUw.䭮4>͔oqz +&ō;=v]e)4CvP/U6>ʰQ~W26$'БIt2ܧ>:bw0/J$f|}cq1, U>qNNDJ7{{!zk^xyBew{^b7fg_Htl@k2+kPi|@l_qf1Q!yHZ&=\f(2K +erCPeQӴ{݃\ +%EOMSyj5% +YzǦ3O/(^^17}m␉7MvʱG>jô39فiaUUU@fܛcEzQ˯RiӒj^¾[JN +)$ܟ$*qh ,r>q@l<RQ6:v峞k\SNXubOwf%RNiҸɝj}ءuQB Ĭq[FؗcN{f+ +2 BJgVW'wlap}MdU +P4!MLr1MSgSqq_ w]??/^|12(A`Q6UMUA>y_M,\ L&/L).5js_*rKJK3KJ K JKUU`JVVJE`gɛneZߦʐ +l K\5yP>#DHi0$dKhYZv`rJD:8@vB OHk$AH 9Qɮ +Qy1<̫0 +^g!K*I2I!فo++=3%,A~31^h{aV>ngt ñO!U.}~* +r~ðʤ0z5 +a,j}Qm4ͨ*0< +L"7DUȯNf ʳ83xWRV +ǎ [u qw٦1rۋE<—&[ ._*l_y]s24`?"O۰'7#R^MKϊHgSxQ|)_}bU:FaaЦQ" !'mFtz:c/^!h$x¢۲t c/>Ġ`[!}؉LeZ + `ẹWzMǾLgdO0u*)2] 2e&L*G̋&9=忋6*Eed9NS&^SSӒӓ9F֪JB+cb fWIaeqcdmFe1!+>KQ'?A,&{j">0;bOԧOAXl: b-PvTCd#P'|`}QvDCb^N!O]x8m\)kL짗F8벬_gyy[}U3dֵBԒb}%\\Z迱W0OelRy?g"&>B {MJp쇰(GJ;^`ZTHwUVkR2#NJ`ބǑL:ARa5Zm4U'nA/>.=F3N +rCܿ Npr!9y6T%C1 g:)06v|{<Ĩ߯+ۧxFKRmga,+0~ȫF֭PtjUo5]4 ŋb,y\Zj#N*ýġ+C9Gsҗҋ5,5F)InӇ] +x(:">)<,6Jg\%GqŸh-W8WwنdY5~q¦/N;Nbts6yp9L@HB|]~\g>+1^` p~goo#L`%_eeI}0~@Ҡ lɂ +N` 2CzHiXV[YuM>,0>q/ +9 &pcl$=!WLR$01ldI06ˬaXFLOΐ7/FmXO'\_Io;>2y޲n~r:gqKoc;~]OVa}nb~m/+|jCQ o:_:"e > +c pNl +?X5Ze>8r2Wx_8C +geaW'$a+x0/k`agZ +Hgc%2L!_R}H^&om#Ճ݆rsc!ΟI8e^ů>ZK8ʈ.+ٔS/E5969?B(h*O@e2m]mi;u|P:ۈp Am>%ѓ@$G#aUB9ǩQryWXe/Wyyrt샚$N =AQkŗ::&>}Jᑩ<288T aT'$p(Ը^('BKnuUo^zuhup/LЙlY⣈h۾~(L*LNӵkxɤ^>'L 0R`yZ<,.0f\66GÚ| \;HD(oRd}F+0XY +8@LevmF8F^ZbI H΁9 L 8V@Q\I1Lyw~]vEoin7mlyٖy敿+(,Yزѭ- ck[v*w]j:2pq*a1VcrOO;V܇fςQJ<01%ў٭J +SXExd+#K, `n +ɺ|b[bKxAAa- v +)0O"dS InuSJYNaşOa'mnZG[s3}-i)N$;CtSK8֊(,eգͨE*ԌZ! +E]h> 0NkYUS|eO3b(@nx9Db+EjCmЃ6BFr'ynVşD?< RvoBXD?D/Skum/gM)( U IWq>ȸKss  OR {ifKh6:.,TMzh]TFz\⻌̹K|(@n2mPZuB:G\NjA{dC5FlZ; fCui$׋VJutYmknd(|#s@怴VRx>`k!>ɯ-,^57鐚۩txQ/tS--z K:wLx$](>Q:i}q&dwPPkմȸdnF[i.G\Ke)բ>=.ͬJc;ŷR +{ѫKZWl$}K䰅)q-gI=R誦RJ;gJř#k֍tmCv/'΢cK{|/D>M$i3ꦔmڰg\dq + 71.mҢI$ cv$?R̮S҃:s~띢&4D.B5Y' _Uݒ|ĥtw+9tgrPw|5v<9=uQ[&يTn~{Ս7&X3(RK\A}?k>֫W#J>F<'ďD,K\ȑ߲+ i Tb(ͥY)E(i5 +Ig-c,4ݑUͭ~MD۵PBUWOwWOs_{:5Knk*e΄]W喔dBT%TvtWEz#=#mU]z#=¼ȦE:{OT4}c U#moZ՗69Hh.X<^=(4E:{Vۅ=}HоNh5kú>7k!kuOsͳ65 uHOu}:h+4 ꦞvP^#̙97CTm=͛ -ʶuBmPr5i%6G:"0VG&"aU0`w{_!tvel ڄގ*u>lI/%D:}׽Τ'[˄M]@So_u:: +u}Ykggoڴ)S"]VkWgΎ>ٝ+[Erl"%?զH`#ɼsjTUϙ?O_+=fr֢5uj~M{/]eA{ϛl{Ar7F6wm -[6R)ٰ +hDZuN:޼'!ٚ9vGhkwlVtuN ׵:Bl@n{[6A0MI JO +dgۉnlMn%,Y5IY펴)y\ŕC\2eyt#~ +e?a! +Nd>v=<$?< t ItP_QFpVBE°qb!```*a}0!gbW.v 0 +6䇾ϓҕRz=nkm>C +}q ksp(*8f`|NN՝0;aVw¬C;;w?삮iRWp&aT +9p ˤt){`Pe~ƻzJϧZ]p+$ٓb +$fa3؅Y4]֠$HC94΢ـw@ZLWC:$Vr*!a0j \ac-B`iMV÷ +l%Ca( # +÷3PRu!eteP F*ZAe2`ORe l!ʁB2`^0B/?s +@*Hنzm^_RE 4A GfCa%-(%K`3Y;m,ԓ ZWM2!04r,5A`@tR!G!@HbS} +%@ShkIl*`R! +mRn*`TRhC8$0p6 + + AFe"|P\ Լv-ll(j\Q2v?|T뇯_ mnnX + +1+ +^_xwᣅ +f61Ma5@%JW%pha8Lc{صB7B ++t7-[BWBB7[ݐn{HwNH7-+ C҈RL8@tPTO?Q㔽K}9p!)>+X]XSlυHYj +C27Hgͤt2֬aR<0a2֬,:zK%PBLoigPi.;.q=҄:(2.#EzqIEKJRhcp&rԴWÿ^ z{{=_og݇`Zj|nކ>Iz7 [&:6@ϸwʏ:nĦC!t$^ + +endstream +endobj + +98 0 obj +17067 +endobj + +99 0 obj +<> +endobj + +100 0 obj +<> +stream +x]n0y +CxLVB(ö>@H8 ~xw>1_׻s;ݞgs|2^CgL?tsZown,e2e7sg[9 d>_gSdMcz>s~k{\v}ClMlHVUvZlYYnMƾH-cՆ1Zm" +.R3+pZ~ҌJOgvkfz2 XkV'u/_I&|$5ܬWRW`߉[}/w'wR7JORRsTXjÓ[PdWX`n!Qt +4NL +endstream +endobj + +101 0 obj +<> +endobj + +102 0 obj +<> +endobj + +103 0 obj +<> +endobj + +1 0 obj +<>/Contents 2 0 R>> +endobj + +4 0 obj +<>/Contents 5 0 R>> +endobj + +7 0 obj +<>/Contents 8 0 R>> +endobj + +10 0 obj +<>/Contents 11 0 R>> +endobj + +13 0 obj +<>/Contents 14 0 R>> +endobj + +16 0 obj +<>/Contents 17 0 R>> +endobj + +19 0 obj +<>/Contents 20 0 R>> +endobj + +22 0 obj +<>/Contents 23 0 R>> +endobj + +25 0 obj +<>/Contents 26 0 R>> +endobj + +28 0 obj +<>/Contents 29 0 R>> +endobj + +31 0 obj +<>/Contents 32 0 R>> +endobj + +34 0 obj +<>/Contents 35 0 R>> +endobj + +37 0 obj +<>/Contents 38 0 R>> +endobj + +40 0 obj +<>/Contents 41 0 R>> +endobj + +43 0 obj +<>/Contents 44 0 R>> +endobj + +46 0 obj +<>/Contents 47 0 R>> +endobj + +51 0 obj +<> +endobj + +49 0 obj +<> +>> +endobj + +50 0 obj +<> +>> +endobj + +104 0 obj +<> +endobj + +105 0 obj +< +/Producer +/CreationDate(D:20090714221828-04'00')>> +endobj + +xref +0 106 +0000000000 65535 f +0000226265 00000 n +0000000019 00000 n +0000000380 00000 n +0000226428 00000 n +0000000400 00000 n +0000001576 00000 n +0000226591 00000 n +0000001597 00000 n +0000002522 00000 n +0000226736 00000 n +0000002542 00000 n +0000003873 00000 n +0000226883 00000 n +0000003895 00000 n +0000007544 00000 n +0000227030 00000 n +0000007566 00000 n +0000010906 00000 n +0000227177 00000 n +0000010928 00000 n +0000013803 00000 n +0000227324 00000 n +0000013825 00000 n +0000017140 00000 n +0000227471 00000 n +0000017162 00000 n +0000020039 00000 n +0000227618 00000 n +0000020061 00000 n +0000022077 00000 n +0000227765 00000 n +0000022099 00000 n +0000023705 00000 n +0000227912 00000 n +0000023727 00000 n +0000024506 00000 n +0000228059 00000 n +0000024527 00000 n +0000027796 00000 n +0000228206 00000 n +0000027818 00000 n +0000031017 00000 n +0000228353 00000 n +0000031039 00000 n +0000033572 00000 n +0000228500 00000 n +0000033594 00000 n +0000035289 00000 n +0000228852 00000 n +0000228999 00000 n +0000228647 00000 n +0000035311 00000 n +0000035970 00000 n +0000035991 00000 n +0000036181 00000 n +0000036472 00000 n +0000036633 00000 n +0000054673 00000 n +0000054696 00000 n +0000054899 00000 n +0000055351 00000 n +0000055657 00000 n +0000075588 00000 n +0000075611 00000 n +0000075805 00000 n +0000076322 00000 n +0000076686 00000 n +0000083565 00000 n +0000083587 00000 n +0000083781 00000 n +0000084147 00000 n +0000084371 00000 n +0000106354 00000 n +0000106377 00000 n +0000106566 00000 n +0000107083 00000 n +0000107442 00000 n +0000128623 00000 n +0000128646 00000 n +0000128855 00000 n +0000129326 00000 n +0000129658 00000 n +0000169160 00000 n +0000169183 00000 n +0000169382 00000 n +0000170008 00000 n +0000170481 00000 n +0000190736 00000 n +0000190759 00000 n +0000190947 00000 n +0000191426 00000 n +0000191750 00000 n +0000207069 00000 n +0000207092 00000 n +0000207291 00000 n +0000207665 00000 n +0000207904 00000 n +0000225058 00000 n +0000225081 00000 n +0000225275 00000 n +0000225753 00000 n +0000226081 00000 n +0000226208 00000 n +0000229137 00000 n +0000229223 00000 n +trailer +< + ] +/DocChecksum /2E16B381986633E52516A39438BA68AD +>> +startxref +229411 +%%EOF Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt (nonexistent) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt (revision 27)

ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/ajb_block_diagram.odg =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/ajb_block_diagram.odg =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/ajb_block_diagram.odg (nonexistent) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/ajb_block_diagram.odg (revision 27)
ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/ajb_block_diagram.odg Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/License_FDL-1.2.txt =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/License_FDL-1.2.txt (nonexistent) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/License_FDL-1.2.txt (revision 27) @@ -0,0 +1,397 @@ + GNU Free Documentation License + Version 1.2, November 2002 + + + Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document "free" in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The "Document", below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as "you". You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (Thus, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML, PostScript or PDF designed for human modification. Examples of +transparent image formats include PNG, XCF and JPG. Opaque formats +include proprietary formats that can be read and edited only by +proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML, PostScript or PDF produced by some word +processors for output purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +A section "Entitled XYZ" means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as "Acknowledgements", +"Dedications", "Endorsements", or "History".) To "Preserve the Title" +of such a section when you modify the Document means that it remains a +section "Entitled XYZ" according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has fewer than five), + unless they release you from this requirement. +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section Entitled "History", Preserve its Title, and add + to it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section Entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. For any section Entitled "Acknowledgements" or "Dedications", + Preserve the Title of the section, and preserve in the section all + the substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section Entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section to be Entitled "Endorsements" + or to conflict in title with any Invariant Section. +O. Preserve any Warranty Disclaimers. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled "History" +in the various original documents, forming one section Entitled +"History"; likewise combine any sections Entitled "Acknowledgements", +and any sections Entitled "Dedications". You must delete all sections +Entitled "Endorsements". + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an "aggregate" if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled "Acknowledgements", +"Dedications", or "History", the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the "with...Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/gpl-2.0.txt =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/gpl-2.0.txt (nonexistent) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/gpl-2.0.txt (revision 27) @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limita