diff options
Diffstat (limited to 'src')
586 files changed, 12042 insertions, 11048 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 432c31e..6d79cd6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libopenocd.la bin_PROGRAMS += %D%/openocd diff --git a/src/flash/Makefile.am b/src/flash/Makefile.am index 4c70702..c5eb248 100644 --- a/src/flash/Makefile.am +++ b/src/flash/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libflash.la %C%_libflash_la_SOURCES = \ %D%/common.c %D%/common.h diff --git a/src/flash/common.c b/src/flash/common.c index 0e7fe13..ebd9396 100644 --- a/src/flash/common.c +++ b/src/flash/common.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/common.h b/src/flash/common.h index 69f60d9..15aea5b 100644 --- a/src/flash/common.h +++ b/src/flash/common.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_COMMON_H diff --git a/src/flash/nand/Makefile.am b/src/flash/nand/Makefile.am index abe90f8..6a1a9b1 100644 --- a/src/flash/nand/Makefile.am +++ b/src/flash/nand/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libocdflashnand.la %C%_libocdflashnand_la_SOURCES = \ diff --git a/src/flash/nand/arm_io.c b/src/flash/nand/arm_io.c index 2b0c081..80bd0cf 100644 --- a/src/flash/nand/arm_io.c +++ b/src/flash/nand/arm_io.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright (C) 2009 by Marvell Semiconductors, Inc. * Written by Nicolas Pitre <nico at marvell.com> * * Copyright (C) 2009 by David Brownell - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nand/arm_io.h b/src/flash/nand/arm_io.h index 8bb3114..10f0e66 100644 --- a/src/flash/nand/arm_io.h +++ b/src/flash/nand/arm_io.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * Copyright (C) 2009 by David Brownell - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifndef OPENOCD_FLASH_NAND_ARM_IO_H #define OPENOCD_FLASH_NAND_ARM_IO_H diff --git a/src/flash/nand/at91sam9.c b/src/flash/nand/at91sam9.c index c8886d1..bfbba67 100644 --- a/src/flash/nand/at91sam9.c +++ b/src/flash/nand/at91sam9.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright (C) 2009 by Dean Glazeski * dnglaze@gmail.com - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nand/core.c b/src/flash/nand/core.c index c1f1bc4..37e1d12 100644 --- a/src/flash/nand/core.c +++ b/src/flash/nand/core.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> * * Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de> * * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * * * * Partially based on drivers/mtd/nand_ids.c from Linux. * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nand/core.h b/src/flash/nand/core.h index 12fc2b7..19c53d1 100644 --- a/src/flash/nand/core.h +++ b/src/flash/nand/core.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> * * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * @@ -6,19 +8,6 @@ * Copyright (C) 2000 David Woodhouse <dwmw2@mvhi.com> * * Copyright (C) 2000 Steven J. Hill <sjhill@realitydiluted.com> * * Copyright (C) 2000 Thomas Gleixner <tglx@linutronix.de> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NAND_CORE_H diff --git a/src/flash/nand/davinci.c b/src/flash/nand/davinci.c index 1aa7ffc..b7169fe 100644 --- a/src/flash/nand/davinci.c +++ b/src/flash/nand/davinci.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by David Brownell * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/flash/nand/driver.c b/src/flash/nand/driver.c index b525f3d..02e5c09 100644 --- a/src/flash/nand/driver.c +++ b/src/flash/nand/driver.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> * * Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> * * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> * * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nand/driver.h b/src/flash/nand/driver.h index 690ee91..a874cc8 100644 --- a/src/flash/nand/driver.h +++ b/src/flash/nand/driver.h @@ -1,21 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> * * Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> * * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> * * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NAND_DRIVER_H diff --git a/src/flash/nand/ecc.c b/src/flash/nand/ecc.c index 25b2eb1..20b8ba8 100644 --- a/src/flash/nand/ecc.c +++ b/src/flash/nand/ecc.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later WITH eCos-exception-2.0 + /* * This file contains an ECC algorithm from Toshiba that allows for detection * and correction of 1-bit errors in a 256 byte block of data. @@ -10,30 +12,6 @@ * Toshiba America Electronics Components, Inc. * * Copyright (C) 2006 Thomas Gleixner <tglx at linutronix.de> - * - * This file 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 or (at your option) any - * later version. - * - * This file 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 <http://www.gnu.org/licenses/>. - * - * As a special exception, if other files instantiate templates or use - * macros or inline functions from these files, or you compile these - * files and link them with other works to produce a work based on these - * files, these files do not by themselves cause the resulting work to be - * covered by the GNU General Public License. However the source code for - * these files must still be made available in accordance with section (3) - * of the GNU General Public License. - * - * This exception does not invalidate any other reasons why a work based on - * this file might be covered by the GNU General Public License. */ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nand/ecc_kw.c b/src/flash/nand/ecc_kw.c index fb3481d..cea1a5a 100644 --- a/src/flash/nand/ecc_kw.c +++ b/src/flash/nand/ecc_kw.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Reed-Solomon ECC handling for the Marvell Kirkwood SOC * Copyright (C) 2009 Marvell Semiconductor, Inc. * * Authors: Lennert Buytenhek <buytenh@wantstofly.org> * Nicolas Pitre <nico@fluxnic.net> - * - * This file 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 or (at your option) any - * later version. - * - * This file 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 <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nand/fileio.c b/src/flash/nand/fileio.c index b9c7f79..ca618b3 100644 --- a/src/flash/nand/fileio.c +++ b/src/flash/nand/fileio.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> * * Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de> * * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * * * * Partially based on drivers/mtd/nand_ids.c from Linux. * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nand/fileio.h b/src/flash/nand/fileio.h index 6a094c2..a8d2524 100644 --- a/src/flash/nand/fileio.h +++ b/src/flash/nand/fileio.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NAND_FILEIO_H diff --git a/src/flash/nand/imp.h b/src/flash/nand/imp.h index c8a4ed9..7b4f38e 100644 --- a/src/flash/nand/imp.h +++ b/src/flash/nand/imp.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NAND_IMP_H diff --git a/src/flash/nand/lpc3180.c b/src/flash/nand/lpc3180.c index bda7b87..c1af1d7 100644 --- a/src/flash/nand/lpc3180.c +++ b/src/flash/nand/lpc3180.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * * * Copyright (C) 2010 richard vegh <vegh.ricsi@gmail.com> * * Copyright (C) 2010 Oyvind Harboe <oyvind.harboe@zylin.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nand/lpc3180.h b/src/flash/nand/lpc3180.h index c02ee5b..519be7e 100644 --- a/src/flash/nand/lpc3180.h +++ b/src/flash/nand/lpc3180.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NAND_LPC3180_H diff --git a/src/flash/nand/lpc32xx.c b/src/flash/nand/lpc32xx.c index 49890c2..2c578d1 100644 --- a/src/flash/nand/lpc32xx.c +++ b/src/flash/nand/lpc32xx.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -9,19 +11,6 @@ * Based on a combination of the lpc3180 driver and code from * * uboot-2009.03-lpc32xx by Kevin Wells. * * Any bugs are mine. --BSt * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nand/lpc32xx.h b/src/flash/nand/lpc32xx.h index 12c8f48..f399142 100644 --- a/src/flash/nand/lpc32xx.h +++ b/src/flash/nand/lpc32xx.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NAND_LPC32XX_H diff --git a/src/flash/nand/mx3.c b/src/flash/nand/mx3.c index dc8d619..86e9468 100644 --- a/src/flash/nand/mx3.c +++ b/src/flash/nand/mx3.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by Alexei Babich * * Rezonans plc., Chelyabinsk, Russia * * impatt@mail.ru * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/flash/nand/mx3.h b/src/flash/nand/mx3.h index 00664d8..b272962 100644 --- a/src/flash/nand/mx3.h +++ b/src/flash/nand/mx3.h @@ -1,20 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 by Alexei Babich * * Rezonans plc., Chelyabinsk, Russia * * impatt@mail.ru * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NAND_MX3_H diff --git a/src/flash/nand/mxc.c b/src/flash/nand/mxc.c index 7aac721..845a3bb 100644 --- a/src/flash/nand/mxc.c +++ b/src/flash/nand/mxc.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by Alexei Babich * * Rezonans plc., Chelyabinsk, Russia * @@ -8,19 +10,6 @@ * * * Copyright (C) 2011 by Erik Ahlen * * Avalon Innovation, Sweden * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/flash/nand/mxc.h b/src/flash/nand/mxc.h index a188728..ae2c03a 100644 --- a/src/flash/nand/mxc.h +++ b/src/flash/nand/mxc.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 by Alexei Babich * * Rezonans plc., Chelyabinsk, Russia * @@ -5,19 +7,6 @@ * * * Copyright (C) 2011 by Erik Ahlen * * Avalon Innovation, Sweden * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NAND_MXC_H diff --git a/src/flash/nand/nonce.c b/src/flash/nand/nonce.c index 6fda261..bce4ed0 100644 --- a/src/flash/nand/nonce.c +++ b/src/flash/nand/nonce.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nand/nuc910.c b/src/flash/nand/nuc910.c index 9546f2f..d7f69e6 100644 --- a/src/flash/nand/nuc910.c +++ b/src/flash/nand/nuc910.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2010 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/flash/nand/nuc910.h b/src/flash/nand/nuc910.h index 8877cf6..3d633dc 100644 --- a/src/flash/nand/nuc910.h +++ b/src/flash/nand/nuc910.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2010 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/flash/nand/orion.c b/src/flash/nand/orion.c index 69814ec..7b19cbd 100644 --- a/src/flash/nand/orion.c +++ b/src/flash/nand/orion.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by Marvell Semiconductors, Inc. * * Written by Nicolas Pitre <nico at marvell.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/flash/nand/s3c2410.c b/src/flash/nand/s3c2410.c index 57b51b4..98268eb 100644 --- a/src/flash/nand/s3c2410.c +++ b/src/flash/nand/s3c2410.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007, 2008 by Ben Dooks * * ben@fluff.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/flash/nand/s3c2412.c b/src/flash/nand/s3c2412.c index 002378a..0eec35f 100644 --- a/src/flash/nand/s3c2412.c +++ b/src/flash/nand/s3c2412.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007, 2008 by Ben Dooks * * ben@fluff.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/flash/nand/s3c2440.c b/src/flash/nand/s3c2440.c index 44670e6..789144c 100644 --- a/src/flash/nand/s3c2440.c +++ b/src/flash/nand/s3c2440.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007, 2008 by Ben Dooks * * ben@fluff.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/flash/nand/s3c2443.c b/src/flash/nand/s3c2443.c index ffd3864..7166702 100644 --- a/src/flash/nand/s3c2443.c +++ b/src/flash/nand/s3c2443.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007, 2008 by Ben Dooks * * ben@fluff.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/flash/nand/s3c24xx.c b/src/flash/nand/s3c24xx.c index c0471ed..5c2f2bc 100644 --- a/src/flash/nand/s3c24xx.c +++ b/src/flash/nand/s3c24xx.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007, 2008 by Ben Dooks * * ben@fluff.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/flash/nand/s3c24xx.h b/src/flash/nand/s3c24xx.h index 4b0c02f..6b196a1 100644 --- a/src/flash/nand/s3c24xx.h +++ b/src/flash/nand/s3c24xx.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007, 2008 by Ben Dooks * * ben@fluff.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NAND_S3C24XX_H diff --git a/src/flash/nand/s3c24xx_regs.h b/src/flash/nand/s3c24xx_regs.h index 46bda6b..3960cb3 100644 --- a/src/flash/nand/s3c24xx_regs.h +++ b/src/flash/nand/s3c24xx_regs.h @@ -1,19 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + /*************************************************************************** * Copyright (C) 2004, 2005 by Simtec Electronics * * linux@simtec.co.uk * * http://www.simtec.co.uk/products/SWLINUX/ * - * * - * 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; version 2 of the License. * - * * - * 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 <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/flash/nand/s3c6400.c b/src/flash/nand/s3c6400.c index 7058133..aebe044 100644 --- a/src/flash/nand/s3c6400.c +++ b/src/flash/nand/s3c6400.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2010 by Peter Korsgaard <jacmet@sunsite.dk> * * Heavily based on s3c2412.c by Ben Dooks <ben@fluff.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nand/tcl.c b/src/flash/nand/tcl.c index b796fb7..4bb15fa 100644 --- a/src/flash/nand/tcl.c +++ b/src/flash/nand/tcl.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> * * Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de> * * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * * * * Partially based on drivers/mtd/nand_ids.c from Linux. * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am index a5ef422..f04f0d2 100644 --- a/src/flash/nor/Makefile.am +++ b/src/flash/nor/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libocdflashnor.la %C%_libocdflashnor_la_SOURCES = \ %D%/core.c \ @@ -54,6 +56,7 @@ NOR_DRIVERS = \ %D%/psoc6.c \ %D%/renesas_rpchf.c \ %D%/rp2040.c \ + %D%/rsl10.c \ %D%/sfdp.c \ %D%/sh_qspi.c \ %D%/sim3x.c \ diff --git a/src/flash/nor/aduc702x.c b/src/flash/nor/aduc702x.c index 492b658..ea7f5e3 100644 --- a/src/flash/nor/aduc702x.c +++ b/src/flash/nor/aduc702x.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2008 by Kevin McGuire * * Copyright (C) 2008 by Marcel Wijlaars * * Copyright (C) 2009 by Michael Ashton * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/aducm360.c b/src/flash/nor/aducm360.c index 4e816fd..ce9bf24 100644 --- a/src/flash/nor/aducm360.c +++ b/src/flash/nor/aducm360.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 by Ivan Buliev * * i.buliev@mikrosistemi.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /*************************************************************************** diff --git a/src/flash/nor/ambiqmicro.c b/src/flash/nor/ambiqmicro.c index 6eda928..2b458bc 100644 --- a/src/flash/nor/ambiqmicro.c +++ b/src/flash/nor/ambiqmicro.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause + /****************************************************************************** * * @file ambiqmicro.c @@ -14,33 +16,6 @@ * Copyright (c) 2015-2016, Ambiq Micro, Inc. * * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * *****************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/flash/nor/at91sam3.c b/src/flash/nor/at91sam3.c index cec86fc..fb6d98b 100644 --- a/src/flash/nor/at91sam3.c +++ b/src/flash/nor/at91sam3.c @@ -1,59 +1,17 @@ -/*************************************************************************** - * Copyright (C) 2009 by Duane Ellis * - * openocd@duaneellis.com * - * * - * Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) * - * olaf@uni-paderborn.de * - * * - * Copyright (C) 2011 by Olivier Schonken (at91sam3x* support) * * - * and Jim Norris * - * 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, see <http://www.gnu.org/licenses/>. * -****************************************************************************/ - -/* Some of the lower level code was based on code supplied by - * ATMEL under this copyright. */ - -/* BEGIN ATMEL COPYRIGHT */ -/* ---------------------------------------------------------------------------- - * ATMEL Microcontroller Software Support - * ---------------------------------------------------------------------------- - * Copyright (c) 2009, Atmel Corporation - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer below. +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-Source-Code) + +/* + * Copyright (C) 2009 by Duane Ellis <openocd@duaneellis.com> * - * Atmel's name may not be used to endorse or promote products derived from - * this software without specific prior written permission. + * at91sam3s* support + * Copyright (C) 2010 by Olaf Lüke <olaf@uni-paderborn.de> + * Copyright (C) 2011 by Olivier Schonken and Jim Norris * - * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * ---------------------------------------------------------------------------- + * Some of the lower level code was based on code supplied by + * ATMEL under BSD-Source-Code License and this copyright. + * ATMEL Microcontroller Software Support + * Copyright (c) 2009, Atmel Corporation. All rights reserved. */ -/* END ATMEL COPYRIGHT */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/flash/nor/at91sam4.c b/src/flash/nor/at91sam4.c index 4ec2ee8..6b94373 100644 --- a/src/flash/nor/at91sam4.c +++ b/src/flash/nor/at91sam4.c @@ -1,60 +1,19 @@ -/*************************************************************************** - * Copyright (C) 2009 by Duane Ellis * - * openocd@duaneellis.com * - * * - * Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) * - * olaf@uni-paderborn.de * - * * - * Copyright (C) 2011 by Olivier Schonken, Jim Norris * - * (at91sam3x* & at91sam4 support)* * - * * - * 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, see <http://www.gnu.org/licenses/>. * -****************************************************************************/ - -/* Some of the lower level code was based on code supplied by - * ATMEL under this copyright. */ - -/* BEGIN ATMEL COPYRIGHT */ -/* ---------------------------------------------------------------------------- - * ATMEL Microcontroller Software Support - * ---------------------------------------------------------------------------- - * Copyright (c) 2009, Atmel Corporation - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-Source-Code) + +/* + * Copyright (C) 2009 by Duane Ellis <openocd@duaneellis.com> * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer below. + * at91sam3s* support + * Copyright (C) 2010 by Olaf Lüke <olaf@uni-paderborn.de> * - * Atmel's name may not be used to endorse or promote products derived from - * this software without specific prior written permission. + * at91sam3x* & at91sam4 support + * Copyright (C) 2011 by Olivier Schonken, Jim Norris * - * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * ---------------------------------------------------------------------------- + * Some of the lower level code was based on code supplied by + * ATMEL under BSD-Source-Code License and this copyright. + * ATMEL Microcontroller Software Support + * Copyright (c) 2009, Atmel Corporation. All rights reserved. */ -/* END ATMEL COPYRIGHT */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/flash/nor/at91sam4l.c b/src/flash/nor/at91sam4l.c index 77dc07f..ddf42a8 100644 --- a/src/flash/nor/at91sam4l.c +++ b/src/flash/nor/at91sam4l.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 by Andrey Yurovsky * * Andrey Yurovsky <yurovsky@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/at91sam7.c b/src/flash/nor/at91sam7.c index f98d186..8d8cf22 100644 --- a/src/flash/nor/at91sam7.c +++ b/src/flash/nor/at91sam7.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Magnus Lundin * * lundin@mlu.mine.nu * * * * Copyright (C) 2008 by Gheorghe Guran (atlas) * - * * - * 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, see <http://www.gnu.org/licenses/>. * ****************************************************************************/ /*************************************************************************** @@ -587,8 +576,6 @@ static int at91sam7_read_part_info(struct flash_bank *bank) t_bank->bank_number = bnk; t_bank->base = base_address + bnk * bank_size; t_bank->size = bank_size; - t_bank->chip_width = 0; - t_bank->bus_width = 4; t_bank->num_sectors = sectors_num; /* allocate sectors */ @@ -702,8 +689,6 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command) uint32_t bank_size; uint32_t ext_freq = 0; - unsigned int chip_width; - unsigned int bus_width; unsigned int banks_num; unsigned int num_sectors; @@ -727,9 +712,6 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command) COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], base_address); - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[3], chip_width); - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[4], bus_width); - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[8], banks_num); COMMAND_PARSE_NUMBER(uint, CMD_ARGV[9], num_sectors); COMMAND_PARSE_NUMBER(u16, CMD_ARGV[10], pages_per_sector); @@ -743,7 +725,7 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command) at91sam7_info->ext_freq = ext_freq; } - if ((bus_width == 0) || (banks_num == 0) || (num_sectors == 0) || + if ((banks_num == 0) || (num_sectors == 0) || (pages_per_sector == 0) || (page_size == 0) || (num_nvmbits == 0)) { at91sam7_info->flash_autodetection = 1; return ERROR_OK; @@ -772,8 +754,6 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command) t_bank->bank_number = bnk; t_bank->base = base_address + bnk * bank_size; t_bank->size = bank_size; - t_bank->chip_width = chip_width; - t_bank->bus_width = bus_width; t_bank->num_sectors = num_sectors; /* allocate sectors */ diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c index 5f314d8..a0252a2 100644 --- a/src/flash/nor/at91samd.c +++ b/src/flash/nor/at91samd.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 by Andrey Yurovsky * * Andrey Yurovsky <yurovsky@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/ath79.c b/src/flash/nor/ath79.c index 394b6dd..1d1ec02 100644 --- a/src/flash/nor/ath79.c +++ b/src/flash/nor/ath79.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 by Tobias Diedrich * * <ranma+openwrt@tdiedrich.de> * @@ -5,20 +7,6 @@ * based on the stmsmi code written by Antonio Borneo * * <borneo.antonio@gmail.com> * * * - * 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. * - * * ***************************************************************************/ /* * Driver for the Atheros AR7xxx/AR9xxx SPI flash interface. diff --git a/src/flash/nor/atsame5.c b/src/flash/nor/atsame5.c index fbf0fb2..fdd610f 100644 --- a/src/flash/nor/atsame5.c +++ b/src/flash/nor/atsame5.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2017 by Tomas Vanek * * vanekt@fbl.cz * @@ -5,19 +7,6 @@ * Based on at91samd.c * * Copyright (C) 2013 by Andrey Yurovsky * * Andrey Yurovsky <yurovsky@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/atsamv.c b/src/flash/nor/atsamv.c index efc2423..67533fc 100644 --- a/src/flash/nor/atsamv.c +++ b/src/flash/nor/atsamv.c @@ -1,63 +1,22 @@ -/*************************************************************************** - * Copyright (C) 2009 by Duane Ellis * - * openocd@duaneellis.com * - * * - * Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) * - * olaf@uni-paderborn.de * - * * - * Copyright (C) 2011 by Olivier Schonken, Jim Norris * - * (at91sam3x* & at91sam4 support)* * - * * - * Copyright (C) 2015 Morgan Quigley * - * (atsamv, atsams, and atsame support) * - * * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -/* Some of the lower level code was based on code supplied by - * ATMEL under this copyright. */ - -/* BEGIN ATMEL COPYRIGHT */ -/* ---------------------------------------------------------------------------- - * ATMEL Microcontroller Software Support - * ---------------------------------------------------------------------------- - * Copyright (c) 2009, Atmel Corporation - * - * All rights reserved. +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-Source-Code) + +/* + * Copyright (C) 2009 by Duane Ellis <openocd@duaneellis.com> * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * at91sam3s* support + * Copyright (C) 2010 by Olaf Lüke <olaf@uni-paderborn.de> * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer below. + * at91sam3x* & at91sam4 support + * Copyright (C) 2011 by Olivier Schonken and Jim Norris * - * Atmel's name may not be used to endorse or promote products derived from - * this software without specific prior written permission. + * atsamv, atsams, and atsame support + * Copyright (C) 2015 Morgan Quigley * - * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * ---------------------------------------------------------------------------- + * Some of the lower level code was based on code supplied by + * ATMEL under BSD-Source-Code License and this copyright. + * ATMEL Microcontroller Software Support + * Copyright (c) 2009, Atmel Corporation. All rights reserved. */ -/* END ATMEL COPYRIGHT */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c index 634f739..0e2e263 100644 --- a/src/flash/nor/avrf.c +++ b/src/flash/nor/avrf.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by Simon Qian * * SimonQian@SimonQian.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/bluenrg-x.c b/src/flash/nor/bluenrg-x.c index 16075ec..9ced2e9 100644 --- a/src/flash/nor/bluenrg-x.c +++ b/src/flash/nor/bluenrg-x.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2017 by Michele Sardo * * msmttchr@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -247,7 +236,7 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, struct target *target = bank->target; uint32_t buffer_size = 16384 + 8; struct working_area *write_algorithm; - struct working_area *write_algorithm_sp; + struct working_area *write_algorithm_stack; struct working_area *source; uint32_t address = bank->base + offset; struct reg_param reg_params[5]; @@ -296,10 +285,10 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } - /* Stack pointer area */ + /* Stack area */ if (target_alloc_working_area(target, 128, - &write_algorithm_sp) != ERROR_OK) { - LOG_DEBUG("no working area for write code stack pointer"); + &write_algorithm_stack) != ERROR_OK) { + LOG_DEBUG("no working area for target algorithm stack"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } @@ -311,8 +300,19 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, init_reg_param(®_params[2], "r2", 32, PARAM_OUT); init_reg_param(®_params[3], "r3", 32, PARAM_OUT); init_reg_param(®_params[4], "sp", 32, PARAM_OUT); - /* Put the parameter at the first available stack location */ - init_mem_param(&mem_params[0], write_algorithm_sp->address + 80, 32, PARAM_OUT); + /* Put the 4th parameter at the location in the stack frame of target write() function. + * See contrib/loaders/flash/bluenrg-x/bluenrg-x_write.lst + * 34 ldr r6, [sp, #80] + * ^^^ offset + */ + init_mem_param(&mem_params[0], write_algorithm_stack->address + 80, 32, PARAM_OUT); + /* Stack for target write algorithm - target write() function has + * __attribute__((naked)) so it does not setup the new stack frame. + * Therefore the stack frame uses the area from SP upwards! + * Interrupts are disabled and no subroutines are called from write() + * so no need to allocate stack below SP. + * TODO: remove __attribute__((naked)) and use similar parameter passing as stm32l4x */ + buf_set_u32(reg_params[4].value, 0, 32, write_algorithm_stack->address); /* FIFO start address (first two words used for write and read pointers) */ buf_set_u32(reg_params[0].value, 0, 32, source->address); @@ -322,14 +322,12 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, buf_set_u32(reg_params[2].value, 0, 32, address); /* Number of bytes */ buf_set_u32(reg_params[3].value, 0, 32, count); - /* Stack pointer for program working area */ - buf_set_u32(reg_params[4].value, 0, 32, write_algorithm_sp->address); /* Flash register base address */ buf_set_u32(mem_params[0].value, 0, 32, bluenrgx_info->flash_ptr->flash_regs_base); LOG_DEBUG("source->address = " TARGET_ADDR_FMT, source->address); LOG_DEBUG("source->address+ source->size = " TARGET_ADDR_FMT, source->address+source->size); - LOG_DEBUG("write_algorithm_sp->address = " TARGET_ADDR_FMT, write_algorithm_sp->address); + LOG_DEBUG("write_algorithm_stack->address = " TARGET_ADDR_FMT, write_algorithm_stack->address); LOG_DEBUG("address = %08" PRIx32, address); LOG_DEBUG("count = %08" PRIx32, count); @@ -368,7 +366,7 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, } target_free_working_area(target, source); target_free_working_area(target, write_algorithm); - target_free_working_area(target, write_algorithm_sp); + target_free_working_area(target, write_algorithm_stack); destroy_reg_param(®_params[0]); destroy_reg_param(®_params[1]); diff --git a/src/flash/nor/bluenrg-x.h b/src/flash/nor/bluenrg-x.h index 3b84b8b..720cb6e 100644 --- a/src/flash/nor/bluenrg-x.h +++ b/src/flash/nor/bluenrg-x.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2019 by STMicroelectronics. * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_BLUENRGX_H diff --git a/src/flash/nor/cc26xx.c b/src/flash/nor/cc26xx.c index 7e52649..6256ba6 100644 --- a/src/flash/nor/cc26xx.c +++ b/src/flash/nor/cc26xx.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2017 by Texas Instruments, Inc. * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -45,6 +34,16 @@ struct cc26xx_bank { uint32_t params_addr[2]; }; +/* Flash helper algorithm for CC26x0 Chameleon targets */ +static const uint8_t cc26x0_algo[] = { +#include "../../../contrib/loaders/flash/cc26xx/cc26x0_algo.inc" +}; + +/* Flash helper algorithm for CC26x2 Agama targets */ +static const uint8_t cc26x2_algo[] = { +#include "../../../contrib/loaders/flash/cc26xx/cc26x2_algo.inc" +}; + static int cc26xx_auto_probe(struct flash_bank *bank); static uint32_t cc26xx_device_type(uint32_t icepick_id, uint32_t user_id) diff --git a/src/flash/nor/cc26xx.h b/src/flash/nor/cc26xx.h index 51a09f1..83fc940 100644 --- a/src/flash/nor/cc26xx.h +++ b/src/flash/nor/cc26xx.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2017 by Texas Instruments, Inc. * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_CC26XX_H @@ -88,14 +77,4 @@ struct cc26xx_algo_params { uint8_t status[4]; }; -/* Flash helper algorithm for CC26x0 Chameleon targets */ -const uint8_t cc26x0_algo[] = { -#include "../../../contrib/loaders/flash/cc26xx/cc26x0_algo.inc" -}; - -/* Flash helper algorithm for CC26x2 Agama targets */ -const uint8_t cc26x2_algo[] = { -#include "../../../contrib/loaders/flash/cc26xx/cc26x2_algo.inc" -}; - #endif /* OPENOCD_FLASH_NOR_CC26XX_H */ diff --git a/src/flash/nor/cc3220sf.c b/src/flash/nor/cc3220sf.c index 723e605..432a393 100644 --- a/src/flash/nor/cc3220sf.c +++ b/src/flash/nor/cc3220sf.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2017 by Texas Instruments, Inc. * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -33,6 +22,11 @@ struct cc3220sf_bank { struct armv7m_algorithm armv7m_info; }; +/* Flash helper algorithm for CC3220SF */ +static const uint8_t cc3220sf_algo[] = { +#include "../../../contrib/loaders/flash/cc3220sf/cc3220sf.inc" +}; + static int cc3220sf_mass_erase(struct flash_bank *bank) { struct target *target = bank->target; diff --git a/src/flash/nor/cc3220sf.h b/src/flash/nor/cc3220sf.h index 36c17be..eb2a6c6 100644 --- a/src/flash/nor/cc3220sf.h +++ b/src/flash/nor/cc3220sf.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2017 by Texas Instruments, Inc. * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_CC3220SF_H @@ -37,9 +26,4 @@ #define FMC_ERASE_VALUE (FMC_DEFAULT_VALUE | FMC_ERASE_BIT) #define FMC_MERASE_VALUE (FMC_DEFAULT_VALUE | FMC_MERASE_BIT) -/* Flash helper algorithm for CC3220SF */ -const uint8_t cc3220sf_algo[] = { -#include "../../../contrib/loaders/flash/cc3220sf/cc3220sf.inc" -}; - #endif /* OPENOCD_FLASH_NOR_CC3220SF_H */ diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 8511586..78bc91e 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005, 2007 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -5,19 +7,6 @@ * michael@schwingen.org * * Copyright (C) 2010 Øyvind Harboe <oyvind.harboe@zylin.com> * * Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/cfi.h b/src/flash/nor/cfi.h index f8ca290..ec7f474 100644 --- a/src/flash/nor/cfi.h +++ b/src/flash/nor/cfi.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_CFI_H diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c index f4ff5df..5e6c971 100644 --- a/src/flash/nor/core.c +++ b/src/flash/nor/core.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> * * Copyright (C) 2007-2010 Øyvind Harboe <oyvind.harboe@zylin.com> * @@ -5,19 +7,6 @@ * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * * Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> * * Copyright (C) 2017-2018 Tomas Vanek <vanekt@fbl.cz> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h index 97a368e..8c26ba0 100644 --- a/src/flash/nor/core.h +++ b/src/flash/nor/core.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> * * Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> * * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> * * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * * Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_CORE_H @@ -31,8 +20,6 @@ struct image; -#define FLASH_MAX_ERROR_STR (128) - /** * Describes the geometry and status of a single flash sector * within a flash bank. A single bank typically consists of multiple diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h index 7a5be65..931f794 100644 --- a/src/flash/nor/driver.h +++ b/src/flash/nor/driver.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> * * Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> * * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> * * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * * Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_DRIVER_H diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c index 387fc71..bd3363b 100644 --- a/src/flash/nor/drivers.c +++ b/src/flash/nor/drivers.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -90,6 +79,7 @@ extern const struct flash_driver w600_flash; extern const struct flash_driver xcf_flash; extern const struct flash_driver xmc1xxx_flash; extern const struct flash_driver xmc4xxx_flash; +extern const struct flash_driver rsl10_flash; /** * The list of built-in flash drivers. @@ -166,6 +156,7 @@ static const struct flash_driver * const flash_drivers[] = { &xmc1xxx_flash, &xmc4xxx_flash, &w600_flash, + &rsl10_flash, NULL, }; diff --git a/src/flash/nor/dsp5680xx_flash.c b/src/flash/nor/dsp5680xx_flash.c index 858b669..b1625f1 100644 --- a/src/flash/nor/dsp5680xx_flash.c +++ b/src/flash/nor/dsp5680xx_flash.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Rodrigo L. Rosa * * rodrigorosa.LG@gmail.com * @@ -6,19 +8,6 @@ * Kevin McGuire * * Marcel Wijlaars * * Michael Ashton * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /** diff --git a/src/flash/nor/efm32.c b/src/flash/nor/efm32.c index 2c5a502..3a49afc 100644 --- a/src/flash/nor/efm32.c +++ b/src/flash/nor/efm32.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -16,19 +18,6 @@ * * * Copyright (C) 2021 Doug Brunner * * doug.a.brunner@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -1086,8 +1075,8 @@ static int efm32x_probe(struct flash_bank *bank) LOG_INFO("detected part: %s Gecko, rev %d", efm32_mcu_info->family_data->name, efm32_mcu_info->prod_rev); - LOG_INFO("flash size = %dkbytes", efm32_mcu_info->flash_sz_kib); - LOG_INFO("flash page size = %dbytes", efm32_mcu_info->page_size); + LOG_INFO("flash size = %d KiB", efm32_mcu_info->flash_sz_kib); + LOG_INFO("flash page size = %d B", efm32_mcu_info->page_size); assert(efm32_mcu_info->page_size != 0); diff --git a/src/flash/nor/em357.c b/src/flash/nor/em357.c index 705c1b3..043494c 100644 --- a/src/flash/nor/em357.c +++ b/src/flash/nor/em357.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * Copyright (C) 2011 by Erik Botö * erik.boto@pelagicore.com - * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -720,7 +709,7 @@ static int em357_probe(struct flash_bank *bank) em357_info->ppage_size = 4; - LOG_INFO("flash size = %dkbytes", num_pages*page_size/1024); + LOG_INFO("flash size = %d KiB", num_pages*page_size/1024); free(bank->sectors); diff --git a/src/flash/nor/esirisc_flash.c b/src/flash/nor/esirisc_flash.c index 23fd01e..938d0f6 100644 --- a/src/flash/nor/esirisc_flash.c +++ b/src/flash/nor/esirisc_flash.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2018 by Square, Inc. * * Steven Stallion <stallion@squareup.com> * * James Zhao <hjz@squareup.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/faux.c b/src/flash/nor/faux.c index 7646e4b..e76dc49 100644 --- a/src/flash/nor/faux.c +++ b/src/flash/nor/faux.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/fespi.c b/src/flash/nor/fespi.c index 5474ffa..9191764 100644 --- a/src/flash/nor/fespi.c +++ b/src/flash/nor/fespi.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> * * Modified by Megan Wachs <megan@sifive.com> from the original stmsmi.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* The Freedom E SPI controller is a SPI bus controller @@ -523,6 +512,12 @@ static int fespi_write(struct flash_bank *bank, const uint8_t *buffer, } } + struct riscv_info *riscv = riscv_info(target); + if (!is_riscv(riscv)) { + LOG_ERROR("Unexpected target type"); + return ERROR_FAIL; + } + unsigned int xlen = riscv_xlen(target); struct working_area *algorithm_wa = NULL; struct working_area *data_wa = NULL; diff --git a/src/flash/nor/fm3.c b/src/flash/nor/fm3.c index 831f342..48f4493 100644 --- a/src/flash/nor/fm3.c +++ b/src/flash/nor/fm3.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Marc Willam, Holger Wech * * openOCD.fseu(AT)de.fujitsu.com * @@ -5,19 +7,6 @@ * * * Copyright (C) 2013 Nemui Trinomius * * nemuisan_kawausogasuki@live.jp * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/fm4.c b/src/flash/nor/fm4.c index 09865d2..979ae84 100644 --- a/src/flash/nor/fm4.c +++ b/src/flash/nor/fm4.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Spansion FM4 flash * @@ -686,24 +688,8 @@ FLASH_BANK_COMMAND_HANDLER(fm4_flash_bank_command) return ret; } -static const struct command_registration fm4_exec_command_handlers[] = { - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration fm4_command_handlers[] = { - { - .name = "fm4", - .mode = COMMAND_ANY, - .help = "fm4 flash command group", - .usage = "", - .chain = fm4_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - const struct flash_driver fm4_flash = { .name = "fm4", - .commands = fm4_command_handlers, .flash_bank_command = fm4_flash_bank_command, .info = fm4_get_info_command, .probe = fm4_probe, diff --git a/src/flash/nor/imp.h b/src/flash/nor/imp.h index f66cf03..199d670 100644 --- a/src/flash/nor/imp.h +++ b/src/flash/nor/imp.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_IMP_H diff --git a/src/flash/nor/jtagspi.c b/src/flash/nor/jtagspi.c index a5672c6..c176ca8 100644 --- a/src/flash/nor/jtagspi.c +++ b/src/flash/nor/jtagspi.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 Robert Jordens <jordens@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c index edb4eb5..7137b4a 100644 --- a/src/flash/nor/kinetis.c +++ b/src/flash/nor/kinetis.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Mathias Kuester * * kesmtp@freenet.de * @@ -13,19 +15,6 @@ * * * Copyright (C) 2015 Tomas Vanek * * vanekt@fbl.cz * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -108,6 +97,8 @@ #define SMC_PMSTAT 0x4007E003 #define SMC32_PMCTRL 0x4007E00C #define SMC32_PMSTAT 0x4007E014 +#define PMC_REGSC 0x4007D002 +#define MC_PMCTRL 0x4007E003 #define MCM_PLACR 0xF000300C /* Offsets */ @@ -199,6 +190,9 @@ #define KINETIS_K_SDID_K60_M150 0x000001C0 #define KINETIS_K_SDID_K70_M150 0x000001D0 +#define KINETIS_K_REVID_MASK 0x0000F000 +#define KINETIS_K_REVID_SHIFT 12 + #define KINETIS_SDID_SERIESID_MASK 0x00F00000 #define KINETIS_SDID_SERIESID_K 0x00000000 #define KINETIS_SDID_SERIESID_KL 0x00100000 @@ -309,6 +303,7 @@ struct kinetis_chip { enum { KINETIS_SMC, KINETIS_SMC32, + KINETIS_MC, } sysmodectrlr_type; char name[40]; @@ -402,16 +397,23 @@ static int kinetis_auto_probe(struct flash_bank *bank); static int kinetis_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value) { - int retval; LOG_DEBUG("MDM_REG[0x%02x] <- %08" PRIX32, reg, value); - retval = dap_queue_ap_write(dap_ap(dap, MDM_AP), reg, value); + struct adiv5_ap *ap = dap_get_ap(dap, MDM_AP); + if (!ap) { + LOG_DEBUG("MDM: failed to get AP"); + return ERROR_FAIL; + } + + int retval = dap_queue_ap_write(ap, reg, value); if (retval != ERROR_OK) { LOG_DEBUG("MDM: failed to queue a write request"); + dap_put_ap(ap); return retval; } retval = dap_run(dap); + dap_put_ap(ap); if (retval != ERROR_OK) { LOG_DEBUG("MDM: dap_run failed"); return retval; @@ -423,15 +425,21 @@ static int kinetis_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint3 static int kinetis_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result) { - int retval; + struct adiv5_ap *ap = dap_get_ap(dap, MDM_AP); + if (!ap) { + LOG_DEBUG("MDM: failed to get AP"); + return ERROR_FAIL; + } - retval = dap_queue_ap_read(dap_ap(dap, MDM_AP), reg, result); + int retval = dap_queue_ap_read(ap, reg, result); if (retval != ERROR_OK) { LOG_DEBUG("MDM: failed to queue a read request"); + dap_put_ap(ap); return retval; } retval = dap_run(dap); + dap_put_ap(ap); if (retval != ERROR_OK) { LOG_DEBUG("MDM: dap_run failed"); return retval; @@ -787,12 +795,18 @@ COMMAND_HANDLER(kinetis_check_flash_security_status) if ((val & (MDM_STAT_SYSSEC | MDM_STAT_FREADY)) != MDM_STAT_FREADY) { uint32_t stats[32]; + struct adiv5_ap *ap = dap_get_ap(dap, MDM_AP); + if (!ap) { + LOG_ERROR("MDM: failed to get AP"); + return ERROR_OK; + } for (unsigned int i = 0; i < 32; i++) { stats[i] = MDM_STAT_FREADY; - dap_queue_ap_read(dap_ap(dap, MDM_AP), MDM_REG_STAT, &stats[i]); + dap_queue_ap_read(ap, MDM_REG_STAT, &stats[i]); } retval = dap_run(dap); + dap_put_ap(ap); if (retval != ERROR_OK) { LOG_DEBUG("MDM: dap_run failed when validating secured state"); return ERROR_OK; @@ -934,7 +948,7 @@ static int kinetis_create_missing_banks(struct kinetis_chip *k_chip) unsigned num_blocks; struct kinetis_flash_bank *k_bank; struct flash_bank *bank; - char base_name[69], name[80], num[4]; + char base_name[69], name[87], num[11]; char *class, *p; num_blocks = k_chip->num_pflash_blocks + k_chip->num_nvm_blocks; @@ -1529,6 +1543,17 @@ static int kinetis_read_pmstat(struct kinetis_chip *k_chip, uint8_t *pmstat) if (result == ERROR_OK) *pmstat = stat32 & 0xff; return result; + + case KINETIS_MC: + /* emulate SMC by reading PMC_REGSC bit 3 (VLPRS) */ + result = target_read_u8(target, PMC_REGSC, pmstat); + if (result == ERROR_OK) { + if (*pmstat & 0x08) + *pmstat = PM_STAT_VLPR; + else + *pmstat = PM_STAT_RUN; + } + return result; } return ERROR_FAIL; } @@ -1569,6 +1594,10 @@ static int kinetis_check_run_mode(struct kinetis_chip *k_chip) case KINETIS_SMC32: result = target_write_u32(target, SMC32_PMCTRL, PM_CTRL_RUNM_RUN); break; + + case KINETIS_MC: + result = target_write_u32(target, MC_PMCTRL, PM_CTRL_RUNM_RUN); + break; } if (result != ERROR_OK) return result; @@ -2135,6 +2164,24 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip) } } + /* first revision of some devices has no SMC */ + switch (mcu_type) { + case KINETIS_K_SDID_K10_M100: + case KINETIS_K_SDID_K20_M100: + case KINETIS_K_SDID_K30_M100: + case KINETIS_K_SDID_K40_M100: + case KINETIS_K_SDID_K60_M100: + { + uint32_t revid = (k_chip->sim_sdid & KINETIS_K_REVID_MASK) >> KINETIS_K_REVID_SHIFT; + /* highest bit set corresponds to rev 2.x */ + if (revid <= 7) { + k_chip->sysmodectrlr_type = KINETIS_MC; + strcat(name, " Rev 1.x"); + } + } + break; + } + } else { /* Newer K-series or KL series MCU */ familyid = (k_chip->sim_sdid & KINETIS_SDID_FAMILYID_MASK) >> KINETIS_SDID_FAMILYID_SHIFT; @@ -2615,12 +2662,12 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip) snprintf(k_chip->name, sizeof(k_chip->name), name, flash_marking); LOG_INFO("Kinetis %s detected: %u flash blocks", k_chip->name, num_blocks); - LOG_INFO("%u PFlash banks: %" PRIu32 "k total", k_chip->num_pflash_blocks, pflash_size_k); + LOG_INFO("%u PFlash banks: %" PRIu32 " KiB total", k_chip->num_pflash_blocks, pflash_size_k); if (k_chip->num_nvm_blocks) { nvm_size_k = k_chip->nvm_size / 1024; dflash_size_k = k_chip->dflash_size / 1024; - LOG_INFO("%u FlexNVM banks: %" PRIu32 "k total, %" PRIu32 "k available as data flash, %" PRIu32 "bytes FlexRAM", - k_chip->num_nvm_blocks, nvm_size_k, dflash_size_k, ee_size); + LOG_INFO("%u FlexNVM banks: %" PRIu32 " KiB total, %" PRIu32 " KiB available as data flash, %" + PRIu32 " bytes FlexRAM", k_chip->num_nvm_blocks, nvm_size_k, dflash_size_k, ee_size); } k_chip->probed = true; diff --git a/src/flash/nor/kinetis_ke.c b/src/flash/nor/kinetis_ke.c index 48749e6..c069f3a 100644 --- a/src/flash/nor/kinetis_ke.c +++ b/src/flash/nor/kinetis_ke.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 by Ivan Meleca * * ivan@artekit.eu * @@ -18,19 +20,6 @@ * * * Copyright (C) 2015 Tomas Vanek * * vanekt@fbl.cz * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -147,16 +136,23 @@ struct kinetis_ke_flash_bank { static int kinetis_ke_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value) { - int retval; LOG_DEBUG("MDM_REG[0x%02x] <- %08" PRIX32, reg, value); - retval = dap_queue_ap_write(dap_ap(dap, 1), reg, value); + struct adiv5_ap *ap = dap_get_ap(dap, 1); + if (!ap) { + LOG_DEBUG("MDM: failed to get AP"); + return ERROR_FAIL; + } + + int retval = dap_queue_ap_write(ap, reg, value); if (retval != ERROR_OK) { LOG_DEBUG("MDM: failed to queue a write request"); + dap_put_ap(ap); return retval; } retval = dap_run(dap); + dap_put_ap(ap); if (retval != ERROR_OK) { LOG_DEBUG("MDM: dap_run failed"); return retval; @@ -167,14 +163,21 @@ static int kinetis_ke_mdm_write_register(struct adiv5_dap *dap, unsigned reg, ui static int kinetis_ke_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result) { - int retval; - retval = dap_queue_ap_read(dap_ap(dap, 1), reg, result); + struct adiv5_ap *ap = dap_get_ap(dap, 1); + if (!ap) { + LOG_DEBUG("MDM: failed to get AP"); + return ERROR_FAIL; + } + + int retval = dap_queue_ap_read(ap, reg, result); if (retval != ERROR_OK) { LOG_DEBUG("MDM: failed to queue a read request"); + dap_put_ap(ap); return retval; } retval = dap_run(dap); + dap_put_ap(ap); if (retval != ERROR_OK) { LOG_DEBUG("MDM: dap_run failed"); return retval; diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c index 465199d..f12eef7 100644 --- a/src/flash/nor/lpc2000.c +++ b/src/flash/nor/lpc2000.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -14,19 +16,6 @@ * * * LPC8N04/HNS31xx support Copyright (C) 2018 * * by Jean-Christian de Rivaz jcdr [at] innodelec [dot] ch * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/lpc288x.c b/src/flash/nor/lpc288x.c index 1c10e50..3006db1 100644 --- a/src/flash/nor/lpc288x.c +++ b/src/flash/nor/lpc288x.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2008 by * * Karl RobinSod <karl.robinsod@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /*************************************************************************** diff --git a/src/flash/nor/lpc2900.c b/src/flash/nor/lpc2900.c index 4bf5297..c30fa76 100644 --- a/src/flash/nor/lpc2900.c +++ b/src/flash/nor/lpc2900.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by * * Rolf Meeser <rolfm_9dq@yahoo.de> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/lpcspifi.c b/src/flash/nor/lpcspifi.c index 160e2dc..f950f21 100644 --- a/src/flash/nor/lpcspifi.c +++ b/src/flash/nor/lpcspifi.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2012 by George Harris * * george@luminairecoffee.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/max32xxx.c b/src/flash/nor/max32xxx.c index e7a690d..51d6ae2 100644 --- a/src/flash/nor/max32xxx.c +++ b/src/flash/nor/max32xxx.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2016 by Maxim Integrated * * Kevin Gillespie <kevin.gillespie@maximintegrated.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/mdr.c b/src/flash/nor/mdr.c index f3c8552..f6285de 100644 --- a/src/flash/nor/mdr.c +++ b/src/flash/nor/mdr.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -10,19 +12,6 @@ * * * Copyright (C) 2013 by Paul Fertser * * fercerpav@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/mrvlqspi.c b/src/flash/nor/mrvlqspi.c index a752f09..4eb6522 100644 --- a/src/flash/nor/mrvlqspi.c +++ b/src/flash/nor/mrvlqspi.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2014 by Mahavir Jain <mjain@marvell.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/flash/nor/msp432.c b/src/flash/nor/msp432.c index 61741c8..d9b9695 100644 --- a/src/flash/nor/msp432.c +++ b/src/flash/nor/msp432.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2018 by Texas Instruments, Inc. * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -56,6 +45,21 @@ struct msp432_bank { struct armv7m_algorithm armv7m_info; }; +/* Flash helper algorithm for MSP432P401x targets */ +static const uint8_t msp432p401x_algo[] = { +#include "../../../contrib/loaders/flash/msp432/msp432p401x_algo.inc" +}; + +/* Flash helper algorithm for MSP432P411x targets */ +static const uint8_t msp432p411x_algo[] = { +#include "../../../contrib/loaders/flash/msp432/msp432p411x_algo.inc" +}; + +/* Flash helper algorithm for MSP432E4x targets */ +static const uint8_t msp432e4x_algo[] = { +#include "../../../contrib/loaders/flash/msp432/msp432e4x_algo.inc" +}; + static int msp432_auto_probe(struct flash_bank *bank); static int msp432_device_type(uint32_t family_type, uint32_t device_id, diff --git a/src/flash/nor/msp432.h b/src/flash/nor/msp432.h index af1d40c..d0a62c4 100644 --- a/src/flash/nor/msp432.h +++ b/src/flash/nor/msp432.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2018 by Texas Instruments, Inc. * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_MSP432_H @@ -112,19 +101,4 @@ struct msp432_algo_params { uint8_t unlock_bsl[4]; }; -/* Flash helper algorithm for MSP432P401x targets */ -const uint8_t msp432p401x_algo[] = { -#include "../../../contrib/loaders/flash/msp432/msp432p401x_algo.inc" -}; - -/* Flash helper algorithm for MSP432P411x targets */ -const uint8_t msp432p411x_algo[] = { -#include "../../../contrib/loaders/flash/msp432/msp432p411x_algo.inc" -}; - -/* Flash helper algorithm for MSP432E4x targets */ -const uint8_t msp432e4x_algo[] = { -#include "../../../contrib/loaders/flash/msp432/msp432e4x_algo.inc" -}; - #endif /* OPENOCD_FLASH_NOR_MSP432_H */ diff --git a/src/flash/nor/niietcm4.c b/src/flash/nor/niietcm4.c index 6f9a5d3..0c36e2c 100644 --- a/src/flash/nor/niietcm4.c +++ b/src/flash/nor/niietcm4.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 by Bogdan Kolbov * * kolbov@niiet.ru * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/non_cfi.c b/src/flash/nor/non_cfi.c index 1566f38..f096ba6 100644 --- a/src/flash/nor/non_cfi.c +++ b/src/flash/nor/non_cfi.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * * Copyright (C) 2009 Michael Schwingen * * michael@schwingen.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/non_cfi.h b/src/flash/nor/non_cfi.h index c411cb8..47d7e59 100644 --- a/src/flash/nor/non_cfi.h +++ b/src/flash/nor/non_cfi.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_NON_CFI_H diff --git a/src/flash/nor/npcx.c b/src/flash/nor/npcx.c index a4d6395..bc84753 100644 --- a/src/flash/nor/npcx.c +++ b/src/flash/nor/npcx.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2020 by Nuvoton Technology Corporation @@ -17,7 +17,7 @@ #include "../../../contrib/loaders/flash/npcx/npcx_flash.h" /* NPCX flash loader */ -const uint8_t npcx_algo[] = { +static const uint8_t npcx_algo[] = { #include "../../../contrib/loaders/flash/npcx/npcx_algo.inc" }; diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index c964155..d5de4a4 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 Synapse Product Development * * Andrey Smirnov <andrew.smironv@gmail.com> * * Angus Gratton <gus@projectgus.com> * * Erdem U. Altunyurt <spamjunkeater@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -147,7 +136,7 @@ struct nrf5_device_spec { }; struct nrf5_info { - uint32_t refcount; + unsigned int refcount; struct nrf5_bank { struct nrf5_info *chip; diff --git a/src/flash/nor/numicro.c b/src/flash/nor/numicro.c index 3487508..1a73eb2 100644 --- a/src/flash/nor/numicro.c +++ b/src/flash/nor/numicro.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by James K. Larson * * jlarson@pacifier.com * @@ -10,19 +12,6 @@ * * * Copyright (C) 2015 Nemui Trinomius * * nemuisan_kawausogasuki@live.jp * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/ocl.c b/src/flash/nor/ocl.c index 813537d..e00c365 100644 --- a/src/flash/nor/ocl.c +++ b/src/flash/nor/ocl.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Pavel Chromy * * chromy@asix.cz * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/ocl.h b/src/flash/nor/ocl.h index b1fe308..4c86495 100644 --- a/src/flash/nor/ocl.h +++ b/src/flash/nor/ocl.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007 by Pavel Chromy * * chromy@asix.cz * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_OCL_H diff --git a/src/flash/nor/pic32mx.c b/src/flash/nor/pic32mx.c index 31433e0..9a1a634 100644 --- a/src/flash/nor/pic32mx.c +++ b/src/flash/nor/pic32mx.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by John McCarthy * * jgmcc@magma.ca * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -770,7 +759,7 @@ static int pic32mx_probe(struct flash_bank *bank) } } - LOG_INFO("flash size = %" PRIu32 "kbytes", num_pages / 1024); + LOG_INFO("flash size = %" PRIu32 " KiB", num_pages / 1024); free(bank->sectors); diff --git a/src/flash/nor/psoc4.c b/src/flash/nor/psoc4.c index 0a2702a..c935bd5 100644 --- a/src/flash/nor/psoc4.c +++ b/src/flash/nor/psoc4.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -10,19 +12,6 @@ * * * Copyright (C) 2014 by Tomas Vanek (PSoC 4 support derived from STM32) * * vanekt@fbl.cz * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -662,8 +651,8 @@ static int psoc4_write(struct flash_bank *bank, const uint8_t *buffer, if (row_offset) memset(row_buffer, bank->default_padded_value, row_offset); - bool save_poll = jtag_poll_get_enabled(); - jtag_poll_set_enabled(false); + /* Mask automatic polling triggered by execution of halted events */ + bool save_poll_mask = jtag_poll_mask(); while (count) { uint32_t chunk_size = psoc4_info->row_size - row_offset; @@ -704,7 +693,7 @@ static int psoc4_write(struct flash_bank *bank, const uint8_t *buffer, } cleanup: - jtag_poll_set_enabled(save_poll); + jtag_poll_unmask(save_poll_mask); free(sysrq_buffer); return retval; @@ -785,7 +774,7 @@ static int psoc4_probe(struct flash_bank *bank) num_macros++; } - LOG_DEBUG("SPCIF geometry: %" PRIu32 " kb flash, row %" PRIu32 " bytes.", + LOG_DEBUG("SPCIF geometry: %" PRIu32 " KiB flash, row %" PRIu32 " bytes.", flash_size_in_kb, row_size); /* if the user sets the size manually then ignore the probed value @@ -799,7 +788,7 @@ static int psoc4_probe(struct flash_bank *bank) if (num_macros > 1) snprintf(macros_txt, sizeof(macros_txt), " in %" PRIu32 " macros", num_macros); - LOG_INFO("flash size = %" PRIu32 " kbytes%s", flash_size_in_kb, macros_txt); + LOG_INFO("flash size = %" PRIu32 " KiB%s", flash_size_in_kb, macros_txt); /* calculate number of pages */ uint32_t num_rows = flash_size_in_kb * 1024 / row_size; diff --git a/src/flash/nor/psoc5lp.c b/src/flash/nor/psoc5lp.c index f383213..407efbc 100644 --- a/src/flash/nor/psoc5lp.c +++ b/src/flash/nor/psoc5lp.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * PSoC 5LP flash driver * * Copyright (c) 2016 Andreas Färber - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H @@ -822,24 +811,8 @@ FLASH_BANK_COMMAND_HANDLER(psoc5lp_nvl_flash_bank_command) return ERROR_OK; } -static const struct command_registration psoc5lp_nvl_exec_command_handlers[] = { - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration psoc5lp_nvl_command_handlers[] = { - { - .name = "psoc5lp_nvl", - .mode = COMMAND_ANY, - .help = "PSoC 5LP NV Latch command group", - .usage = "", - .chain = psoc5lp_nvl_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - const struct flash_driver psoc5lp_nvl_flash = { .name = "psoc5lp_nvl", - .commands = psoc5lp_nvl_command_handlers, .flash_bank_command = psoc5lp_nvl_flash_bank_command, .info = psoc5lp_nvl_get_info_command, .probe = psoc5lp_nvl_probe, @@ -1021,24 +994,8 @@ FLASH_BANK_COMMAND_HANDLER(psoc5lp_eeprom_flash_bank_command) return ERROR_OK; } -static const struct command_registration psoc5lp_eeprom_exec_command_handlers[] = { - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration psoc5lp_eeprom_command_handlers[] = { - { - .name = "psoc5lp_eeprom", - .mode = COMMAND_ANY, - .help = "PSoC 5LP EEPROM command group", - .usage = "", - .chain = psoc5lp_eeprom_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - const struct flash_driver psoc5lp_eeprom_flash = { .name = "psoc5lp_eeprom", - .commands = psoc5lp_eeprom_command_handlers, .flash_bank_command = psoc5lp_eeprom_flash_bank_command, .info = psoc5lp_eeprom_get_info_command, .probe = psoc5lp_eeprom_probe, diff --git a/src/flash/nor/psoc6.c b/src/flash/nor/psoc6.c index c6166af..b7ba102 100644 --- a/src/flash/nor/psoc6.c +++ b/src/flash/nor/psoc6.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * * * Copyright (C) 2018 by Bohdan Tymkiv * * bohdan.tymkiv@cypress.com bohdan200@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -602,8 +591,7 @@ static int psoc6_probe(struct flash_bank *bank) unsigned int num_sectors = bank_size / row_sz; bank->size = bank_size; - bank->chip_width = 4; - bank->bus_width = 4; + bank->erased_value = 0; bank->default_padded_value = 0; diff --git a/src/flash/nor/renesas_rpchf.c b/src/flash/nor/renesas_rpchf.c index f99749f..6c51b8f 100644 --- a/src/flash/nor/renesas_rpchf.c +++ b/src/flash/nor/renesas_rpchf.c @@ -1,4 +1,5 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Renesas RCar Gen3 RPC Hyperflash driver * Based on U-Boot RPC Hyperflash driver diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index fb34172..667498c 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/flash/nor/rsl10.c b/src/flash/nor/rsl10.c new file mode 100644 index 0000000..d92c4b8 --- /dev/null +++ b/src/flash/nor/rsl10.c @@ -0,0 +1,843 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * Copyright (C) 2022 by Toms StÅ«rmanis * + * toms.sturmanis@gmail.com * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdint.h> + +#include <helper/binarybuffer.h> +#include <helper/bits.h> + +#include <target/algorithm.h> +#include <target/arm_adi_v5.h> +#include <target/armv7m.h> +#include <target/cortex_m.h> + +#include "imp.h" + +#define RSL10_FLASH_ADDRESS_MAIN 0x00100000 +#define RSL10_FLASH_ADDRESS_NVR1 0x00080000 +#define RSL10_FLASH_ADDRESS_NVR2 0x00080800 +#define RSL10_FLASH_ADDRESS_NVR3 0x00081000 +#define RSL10_FLASH_ADDRESS_NVR4 0x00081800 +#define RSL10_FLASH_ADDRESS_LOCK_INFO_SETTING 0x00081040 + +#define RSL10_REG_ID 0x1FFFFFFC + +#define RSL10_FLASH_REG_MAIN_WRITE_UNLOCK 0x40000504 +#define RSL10_FLASH_REG_MAIN_CTRL 0x40000508 +#define RSL10_FLASH_REG_IF_STATUS 0x40000538 +#define RSL10_FLASH_REG_NVR_WRITE_UNLOCK 0x40000548 +#define RSL10_FLASH_REG_NVR_CTRL 0x4000054C + +#define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY1 0x400000F0 +#define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY2 0x400000F4 +#define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY3 0x400000F8 +#define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY4 0x400000FC + +#define RSL10_NVR3_USER_KEY_OFFSET 0x40 + +#define RSL10_ID 0x09010106 +#define RSL10_FLASH_KEY_MAIN 0xDBC8264E +#define RSL10_FLASH_KEY_NVR 0x71B371F5 +#define RSL10_KEY_DEBUG_LOCK 0x4C6F634B + +#define RSL10_FLASH_REG_MAIN_CTRL_LOW_W_ENABLE BIT(0) +#define RSL10_FLASH_REG_MAIN_CTRL_MIDDLE_W_ENABLE BIT(1) +#define RSL10_FLASH_REG_MAIN_CTRL_HIGH_W_ENABLE BIT(2) + +#define RSL10_FLASH_REG_NVR_CTRL_NVR1_W_ENABLE BIT(1) +#define RSL10_FLASH_REG_NVR_CTRL_NVR2_W_ENABLE BIT(2) +#define RSL10_FLASH_REG_NVR_CTRL_NVR3_W_ENABLE BIT(3) + +#define RSL10_FLASH_REG_STATUS_LOW_W_UNLOCKED BIT(0) +#define RSL10_FLASH_REG_STATUS_MIDDLE_W_UNLOCKED BIT(1) +#define RSL10_FLASH_REG_STATUS_HIGH_W_UNLOCKED BIT(2) +#define RSL10_FLASH_REG_STATUS_NVR1_W_UNLOCKED BIT(4) +#define RSL10_FLASH_REG_STATUS_NVR2_W_UNLOCKED BIT(5) +#define RSL10_FLASH_REG_STATUS_NVR3_W_UNLOCKED BIT(6) + +#define RSL10_ROM_CMD_WRITE_WORD_PAIR 0x3C +#define RSL10_ROM_CMD_WRITE_BUFFER 0x40 +#define RSL10_ROM_CMD_ERASE_SECTOR 0x44 +#define RSL10_ROM_CMD_ERASE_ALL 0x48 + +#define FLASH_SECTOR_SIZE 0x2000 + +#define RSL10_ROM_CMD_WRITE_BUFFER_MAX_SIZE FLASH_SECTOR_SIZE + +#define ALGO_STACK_POINTER_ADDR 0x20002000 + +/* Used to launch flash related functions from ROM + * Params : + * r0-r2 = arguments + * r3 = target address in rom + */ +static const uint8_t rsl10_rom_launcher_code[] = { +#include "../../../contrib/loaders/flash/rsl10/rom_launcher.inc" +}; + +enum rsl10_flash_status { + RSL10_FLASH_ERR_NONE = 0x0, + RSL10_FLASH_ERR_GENERAL_FAILURE = 0x1, + RSL10_FLASH_ERR_WRITE_NOT_ENABLED = 0x2, + RSL10_FLASH_ERR_BAD_ADDRESS = 0x3, + RSL10_FLASH_ERR_ERASE_FAILED = 0x4, + RSL10_FLASH_ERR_BAD_LENGTH = 0x5, + RSL10_FLASH_ERR_INACCESSIBLE = 0x6, + RSL10_FLASH_ERR_COPIER_BUSY = 0x7, + RSL10_FLASH_ERR_PROG_FAILED = 0x8, + RSL10_FLASH_MAX_ERR_CODES /* must be the last one */ +}; + +static const char *const rsl10_error_list[] = { + [RSL10_FLASH_ERR_GENERAL_FAILURE] = "general failure", + [RSL10_FLASH_ERR_WRITE_NOT_ENABLED] = "write not enabled, protected", + [RSL10_FLASH_ERR_BAD_ADDRESS] = "bad address", + [RSL10_FLASH_ERR_ERASE_FAILED] = "erase failed", + [RSL10_FLASH_ERR_BAD_LENGTH] = "bad length", + [RSL10_FLASH_ERR_INACCESSIBLE] = "inaccessible: not powered up, or isolated", + [RSL10_FLASH_ERR_COPIER_BUSY] = "copier busy", + [RSL10_FLASH_ERR_PROG_FAILED] = "prog failed", +}; + +const char *rsl10_error(enum rsl10_flash_status x) +{ + if (x >= RSL10_FLASH_MAX_ERR_CODES || !rsl10_error_list[x]) + return "unknown"; + return rsl10_error_list[x]; +} + +const struct flash_driver rsl10_flash; + +struct rsl10_info { + unsigned int refcount; + + struct rsl10_bank { + struct rsl10_info *chip; + bool probed; + } bank[5]; + struct target *target; + + unsigned int flash_size_kb; +}; + +static bool rsl10_bank_is_probed(const struct flash_bank *bank) +{ + struct rsl10_bank *nbank = bank->driver_priv; + assert(nbank); + return nbank->probed; +} + +static int rsl10_probe(struct flash_bank *bank); + +static int rsl10_get_probed_chip_if_halted(struct flash_bank *bank, struct rsl10_info **chip) +{ + if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + struct rsl10_bank *nbank = bank->driver_priv; + *chip = nbank->chip; + + if (rsl10_bank_is_probed(bank)) + return ERROR_OK; + + return rsl10_probe(bank); +} + +static int rsl10_protect_check(struct flash_bank *bank) +{ + struct rsl10_bank *nbank = bank->driver_priv; + struct rsl10_info *chip = nbank->chip; + + assert(chip); + + uint32_t status; + + int retval = target_read_u32(bank->target, RSL10_FLASH_REG_IF_STATUS, &status); + if (retval != ERROR_OK) + return retval; + + if (bank->base == RSL10_FLASH_ADDRESS_MAIN) { + for (unsigned int i = 0; i < bank->num_prot_blocks; i++) + bank->prot_blocks[i].is_protected = (status & (1 << i)) ? 0 : 1; + + } else { + uint32_t test_bit = 0; + switch (bank->base) { + case RSL10_FLASH_ADDRESS_NVR1: + test_bit = RSL10_FLASH_REG_STATUS_NVR1_W_UNLOCKED; + break; + case RSL10_FLASH_ADDRESS_NVR2: + test_bit = RSL10_FLASH_REG_STATUS_NVR2_W_UNLOCKED; + break; + case RSL10_FLASH_ADDRESS_NVR3: + test_bit = RSL10_FLASH_REG_STATUS_NVR3_W_UNLOCKED; + break; + default: + break; + } + + bank->sectors[0].is_protected = (status & test_bit) ? 0 : 1; + } + return ERROR_OK; +} + +static int rsl10_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last) +{ + + struct rsl10_info *chip; + int retval = rsl10_get_probed_chip_if_halted(bank, &chip); + if (retval != ERROR_OK) + return retval; + + if (bank->base == RSL10_FLASH_ADDRESS_MAIN) { + uint32_t status; + retval = target_read_u32(bank->target, RSL10_FLASH_REG_MAIN_CTRL, &status); + if (retval != ERROR_OK) + return retval; + + for (unsigned int i = first; i <= last; i++) { + if (set) + status &= ~(1 << i); + else + status |= (1 << i); + } + + retval = target_write_u32(bank->target, RSL10_FLASH_REG_MAIN_CTRL, status); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u32(bank->target, RSL10_FLASH_REG_MAIN_WRITE_UNLOCK, RSL10_FLASH_KEY_MAIN); + if (retval != ERROR_OK) + return retval; + } else { + uint32_t bit = 0; + switch (bank->base) { + case RSL10_FLASH_ADDRESS_NVR1: + bit = RSL10_FLASH_REG_NVR_CTRL_NVR1_W_ENABLE; + break; + case RSL10_FLASH_ADDRESS_NVR2: + bit = RSL10_FLASH_REG_NVR_CTRL_NVR2_W_ENABLE; + break; + case RSL10_FLASH_ADDRESS_NVR3: + bit = RSL10_FLASH_REG_NVR_CTRL_NVR3_W_ENABLE; + break; + default: + break; + } + + uint32_t status; + retval = target_read_u32(bank->target, RSL10_FLASH_REG_NVR_CTRL, &status); + if (retval != ERROR_OK) + return retval; + + if (set) + status &= ~bit; + else + status |= bit; + + retval = target_write_u32(bank->target, RSL10_FLASH_REG_NVR_CTRL, status); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u32(bank->target, RSL10_FLASH_REG_NVR_WRITE_UNLOCK, RSL10_FLASH_KEY_NVR); + if (retval != ERROR_OK) + return retval; + } + + return ERROR_OK; +} + +static int rsl10_check_device(struct flash_bank *bank) +{ + uint32_t configid; + int retval = target_read_u32(bank->target, RSL10_REG_ID, &configid); + if (retval != ERROR_OK) + return retval; + + if (configid != RSL10_ID) { + LOG_ERROR("This is not supported (RSL10) device, use other flash driver!!!"); + return ERROR_TARGET_INVALID; + } + return ERROR_OK; +} + +static int rsl10_probe(struct flash_bank *bank) +{ + struct rsl10_bank *nbank = bank->driver_priv; + struct rsl10_info *chip = nbank->chip; + + int retval = rsl10_check_device(bank); + if (retval != ERROR_OK) + return retval; + + unsigned int bank_id; + unsigned int num_prot_blocks = 0; + switch (bank->base) { + case RSL10_FLASH_ADDRESS_MAIN: + bank_id = 0; + num_prot_blocks = 3; + break; + case RSL10_FLASH_ADDRESS_NVR1: + bank_id = 1; + break; + case RSL10_FLASH_ADDRESS_NVR2: + bank_id = 2; + break; + case RSL10_FLASH_ADDRESS_NVR3: + bank_id = 3; + break; + default: + return ERROR_FAIL; + } + + uint32_t flash_page_size = 2048; + + bank->write_start_alignment = 8; + bank->write_end_alignment = 8; + + bank->num_sectors = bank->size / flash_page_size; + chip->flash_size_kb = bank->size / 1024; + + free(bank->sectors); + bank->sectors = NULL; + + bank->sectors = alloc_block_array(0, flash_page_size, bank->num_sectors); + if (!bank->sectors) + return ERROR_FAIL; + + free(bank->prot_blocks); + bank->prot_blocks = NULL; + + if (num_prot_blocks > 0) { + bank->num_prot_blocks = num_prot_blocks; + bank->prot_blocks = alloc_block_array(0, bank->num_sectors / 3 * flash_page_size, bank->num_prot_blocks); + if (!bank->prot_blocks) + return ERROR_FAIL; + } + + chip->bank[bank_id].probed = true; + return ERROR_OK; +} + +static int rsl10_auto_probe(struct flash_bank *bank) +{ + if (rsl10_bank_is_probed(bank)) + return ERROR_OK; + + return rsl10_probe(bank); +} + +static int rsl10_ll_flash_erase(struct rsl10_info *chip, uint32_t address) +{ + struct target *target = chip->target; + struct working_area *write_algorithm; + + LOG_DEBUG("erasing buffer flash address=0x%" PRIx32, address); + + int retval = target_alloc_working_area(target, sizeof(rsl10_rom_launcher_code), &write_algorithm); + if (retval != ERROR_OK) { + LOG_ERROR("Current working area 0x%x is too small! Increase working area size!", target->working_area_size); + return ERROR_FAIL; + } + + retval = + target_write_buffer(target, write_algorithm->address, sizeof(rsl10_rom_launcher_code), rsl10_rom_launcher_code); + if (retval != ERROR_OK) + goto free_algorithm; + + struct reg_param reg_params[3]; + struct armv7m_algorithm armv7m_info; + armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; + armv7m_info.core_mode = ARM_MODE_THREAD; + + init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* address */ + init_reg_param(®_params[1], "r3", 32, PARAM_OUT); /* cmd */ + init_reg_param(®_params[2], "sp", 32, PARAM_OUT); /* stack pointer */ + + buf_set_u32(reg_params[0].value, 0, 32, address); + uint32_t cmd; + retval = target_read_u32(target, RSL10_ROM_CMD_ERASE_SECTOR, &cmd); + if (retval != ERROR_OK) + goto free_reg_params; + buf_set_u32(reg_params[1].value, 0, 32, cmd); + buf_set_u32(reg_params[2].value, 0, 32, ALGO_STACK_POINTER_ADDR); + + retval = target_run_algorithm( + target, 0, NULL, ARRAY_SIZE(reg_params), reg_params, write_algorithm->address, + write_algorithm->address + sizeof(rsl10_rom_launcher_code) - 2, 1000, &armv7m_info + ); + if (retval != ERROR_OK) + goto free_reg_params; + + int algo_ret = buf_get_u32(reg_params[0].value, 0, 32); + if (algo_ret != RSL10_FLASH_ERR_NONE) { + LOG_ERROR("RSL10 ERASE ERROR: '%s' (%d)", rsl10_error(algo_ret), algo_ret); + retval = ERROR_FLASH_SECTOR_NOT_ERASED; + } + +free_reg_params: + for (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++) + destroy_reg_param(®_params[i]); + +free_algorithm: + target_free_working_area(target, write_algorithm); + return retval; +} + +static int rsl10_ll_flash_write(struct rsl10_info *chip, uint32_t address, const uint8_t *buffer, uint32_t bytes) +{ + struct target *target = chip->target; + struct working_area *write_algorithm; + + if (bytes == 8) { + uint32_t data; + data = buf_get_u32(buffer, 0, 32); + LOG_DEBUG("Writing 0x%" PRIx32 " to flash address=0x%" PRIx32 " bytes=0x%" PRIx32, data, address, bytes); + } else + LOG_DEBUG("Writing buffer to flash address=0x%" PRIx32 " bytes=0x%" PRIx32, address, bytes); + + /* allocate working area with flash programming code */ + int retval = target_alloc_working_area(target, sizeof(rsl10_rom_launcher_code), &write_algorithm); + if (retval != ERROR_OK) { + LOG_ERROR("Current working area 0x%x is too small! Increase working area size!", target->working_area_size); + return ERROR_FAIL; + } + + retval = + target_write_buffer(target, write_algorithm->address, sizeof(rsl10_rom_launcher_code), rsl10_rom_launcher_code); + if (retval != ERROR_OK) + goto free_algorithm; + + /* memory buffer, rounded down, to be multiple of 8 */ + uint32_t buffer_avail = target_get_working_area_avail(target) & ~7; + uint32_t buffer_size = MIN(RSL10_ROM_CMD_WRITE_BUFFER_MAX_SIZE, buffer_avail); + struct working_area *source; + retval = target_alloc_working_area(target, buffer_size, &source); + if (retval != ERROR_OK) { + LOG_ERROR("Current working area 0x%x is too small! Increase working area size!", target->working_area_size); + goto free_algorithm; + } + + struct reg_param reg_params[5]; + struct armv7m_algorithm armv7m_info; + armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; + armv7m_info.core_mode = ARM_MODE_THREAD; + + init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* start addr, return value */ + init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* length */ + init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* data */ + init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* cmd */ + init_reg_param(®_params[4], "sp", 32, PARAM_OUT); /* stack pointer */ + buf_set_u32(reg_params[4].value, 0, 32, ALGO_STACK_POINTER_ADDR); + + uint32_t cmd = 0; + uint32_t sent_bytes = 0; + uint32_t write_address = 0; + uint32_t bytes_to_send = 0; + uint32_t remaining_bytes = 0; + + retval = target_read_u32(target, RSL10_ROM_CMD_WRITE_BUFFER, &cmd); + if (retval != ERROR_OK) + goto free_everything; + + while (sent_bytes < bytes) { + remaining_bytes = bytes - sent_bytes; + bytes_to_send = remaining_bytes >= buffer_size ? buffer_size : remaining_bytes; + + retval = target_write_buffer(target, source->address, bytes_to_send, buffer + sent_bytes); + if (retval != ERROR_OK) + goto free_everything; + + write_address = address + sent_bytes; + + LOG_DEBUG( + "write_address: 0x%" PRIx32 ", words: 0x%" PRIx32 ", source: 0x%" PRIx64 ", cmd: 0x%" PRIx32, write_address, + bytes_to_send / 4, source->address, cmd + ); + buf_set_u32(reg_params[0].value, 0, 32, write_address); + buf_set_u32(reg_params[1].value, 0, 32, bytes_to_send / 4); + buf_set_u32(reg_params[2].value, 0, 32, source->address); + buf_set_u32(reg_params[3].value, 0, 32, cmd); + + retval = target_run_algorithm( + target, 0, NULL, ARRAY_SIZE(reg_params), reg_params, write_algorithm->address, + write_algorithm->address + sizeof(rsl10_rom_launcher_code) - 2, 1000, &armv7m_info + ); + if (retval != ERROR_OK) + goto free_everything; + + int algo_ret = buf_get_u32(reg_params[0].value, 0, 32); + if (algo_ret != RSL10_FLASH_ERR_NONE) { + LOG_ERROR("RSL10 WRITE ERROR: '%s' (%d)", rsl10_error(algo_ret), algo_ret); + retval = ERROR_FLASH_OPERATION_FAILED; + goto free_everything; + } + + sent_bytes += bytes_to_send; + } + +free_everything: + target_free_working_area(target, source); + + for (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++) + destroy_reg_param(®_params[i]); + +free_algorithm: + target_free_working_area(target, write_algorithm); + + return retval; +} + +static int rsl10_mass_erase(struct target *target) +{ + struct working_area *write_algorithm; + + int retval = target_alloc_working_area(target, sizeof(rsl10_rom_launcher_code), &write_algorithm); + if (retval != ERROR_OK) { + LOG_ERROR("Current working area 0x%x is too small! Increase working area size!", target->working_area_size); + return ERROR_FAIL; + } + + retval = + target_write_buffer(target, write_algorithm->address, sizeof(rsl10_rom_launcher_code), rsl10_rom_launcher_code); + if (retval != ERROR_OK) + goto free_algorithm; + + struct reg_param reg_params[3]; + struct armv7m_algorithm armv7m_info; + armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; + armv7m_info.core_mode = ARM_MODE_THREAD; + + init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* return value */ + init_reg_param(®_params[1], "r3", 32, PARAM_OUT); /* cmd */ + init_reg_param(®_params[2], "sp", 32, PARAM_OUT); /* stack pointer */ + + uint32_t cmd; + retval = target_read_u32(target, RSL10_ROM_CMD_ERASE_ALL, &cmd); + if (retval != ERROR_OK) + goto free_reg_params; + buf_set_u32(reg_params[1].value, 0, 32, cmd); + buf_set_u32(reg_params[2].value, 0, 32, ALGO_STACK_POINTER_ADDR); + + retval = target_run_algorithm( + target, 0, NULL, ARRAY_SIZE(reg_params), reg_params, write_algorithm->address, + write_algorithm->address + sizeof(rsl10_rom_launcher_code) - 2, 1000, &armv7m_info + ); + if (retval != ERROR_OK) + goto free_reg_params; + + int algo_ret = buf_get_u32(reg_params[0].value, 0, 32); + if (algo_ret != RSL10_FLASH_ERR_NONE) { + LOG_ERROR("RSL10 MASS ERASE ERROR: '%s' (%d)", rsl10_error(algo_ret), algo_ret); + retval = ERROR_FLASH_OPERATION_FAILED; + } + +free_reg_params: + for (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++) + destroy_reg_param(®_params[i]); + +free_algorithm: + target_free_working_area(target, write_algorithm); + return retval; +} + +static int rsl10_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) +{ + struct rsl10_info *chip; + + int retval = rsl10_get_probed_chip_if_halted(bank, &chip); + if (retval != ERROR_OK) + return retval; + + return rsl10_ll_flash_write(chip, bank->base + offset, buffer, count); +} + +static int rsl10_erase(struct flash_bank *bank, unsigned int first, unsigned int last) +{ + LOG_INFO("erase bank: %x, %x", first, last); + int retval; + struct rsl10_info *chip; + + retval = rsl10_get_probed_chip_if_halted(bank, &chip); + if (retval != ERROR_OK) + return retval; + + for (unsigned int i = first; i <= last; i++) { + retval = rsl10_ll_flash_erase(chip, bank->base + i * 0x800); + if (retval != ERROR_OK) + return retval; + } + + return ERROR_OK; +} + +static void rsl10_free_driver_priv(struct flash_bank *bank) +{ + struct rsl10_bank *nbank = bank->driver_priv; + struct rsl10_info *chip = nbank->chip; + if (!chip) + return; + + chip->refcount--; + if (chip->refcount == 0) { + free(chip); + bank->driver_priv = NULL; + } +} + +static struct rsl10_info *rsl10_get_chip(struct target *target) +{ + struct flash_bank *bank_iter; + + /* iterate over rsl10 banks of same target */ + for (bank_iter = flash_bank_list(); bank_iter; bank_iter = bank_iter->next) { + if (bank_iter->driver != &rsl10_flash) + continue; + + if (bank_iter->target != target) + continue; + + struct rsl10_bank *nbank = bank_iter->driver_priv; + if (!nbank) + continue; + + if (nbank->chip) + return nbank->chip; + } + return NULL; +} + +FLASH_BANK_COMMAND_HANDLER(rsl10_flash_bank_command) +{ + struct rsl10_info *chip = NULL; + struct rsl10_bank *nbank = NULL; + LOG_INFO("Creating flash @ " TARGET_ADDR_FMT, bank->base); + + switch (bank->base) { + case RSL10_FLASH_ADDRESS_MAIN: + case RSL10_FLASH_ADDRESS_NVR1: + case RSL10_FLASH_ADDRESS_NVR2: + case RSL10_FLASH_ADDRESS_NVR3: + case RSL10_FLASH_ADDRESS_NVR4: + break; + default: + LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base); + return ERROR_FAIL; + } + + chip = rsl10_get_chip(bank->target); + if (!chip) { + chip = calloc(1, sizeof(*chip)); + if (!chip) + return ERROR_FAIL; + + chip->target = bank->target; + } + + switch (bank->base) { + case RSL10_FLASH_ADDRESS_MAIN: + nbank = &chip->bank[0]; + break; + case RSL10_FLASH_ADDRESS_NVR1: + nbank = &chip->bank[1]; + break; + case RSL10_FLASH_ADDRESS_NVR2: + nbank = &chip->bank[2]; + break; + case RSL10_FLASH_ADDRESS_NVR3: + nbank = &chip->bank[3]; + break; + case RSL10_FLASH_ADDRESS_NVR4: + nbank = &chip->bank[4]; + break; + } + assert(nbank); + + chip->refcount++; + nbank->chip = chip; + nbank->probed = false; + bank->driver_priv = nbank; + + return ERROR_OK; +} + +COMMAND_HANDLER(rsl10_lock_command) +{ + struct target *target = get_current_target(CMD_CTX); + + if (CMD_ARGC != 4) + return ERROR_COMMAND_SYNTAX_ERROR; + + struct flash_bank *bank; + int retval = get_flash_bank_by_addr(target, RSL10_FLASH_ADDRESS_NVR3, true, &bank); + if (retval != ERROR_OK) + return retval; + + LOG_INFO("Keys used: %s %s %s %s", CMD_ARGV[0], CMD_ARGV[1], CMD_ARGV[2], CMD_ARGV[3]); + + uint32_t user_key[4]; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], user_key[0]); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], user_key[1]); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], user_key[2]); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], user_key[3]); + + uint8_t write_buffer[6 * 4]; + target_buffer_set_u32(target, write_buffer, RSL10_KEY_DEBUG_LOCK); + target_buffer_set_u32_array(target, &write_buffer[4], 4, user_key); + /* pad the end to 64-bit word boundary */ + memset(&write_buffer[5 * 4], bank->default_padded_value, 4); + + retval = rsl10_erase(bank, 0, 0); + if (retval != ERROR_OK) + return retval; + + retval = rsl10_write(bank, write_buffer, RSL10_NVR3_USER_KEY_OFFSET, sizeof(write_buffer)); + if (retval != ERROR_OK) { + /* erase sector, if write fails, otherwise it can lock debug with wrong keys */ + return rsl10_erase(bank, 0, 0); + } + + command_print( + CMD, "****** WARNING ******\n" + "rsl10 device has been successfully prepared to lock.\n" + "Debug port is locked after restart.\n" + "Unlock with 'rsl10_unlock key0 key1 key2 key3'\n" + "****** ....... ******\n" + ); + + return rsl10_protect(bank, true, 0, 0); +} + +COMMAND_HANDLER(rsl10_unlock_command) +{ + if (CMD_ARGC != 4) + return ERROR_COMMAND_SYNTAX_ERROR; + + struct target *target = get_current_target(CMD_CTX); + struct cortex_m_common *cortex_m = target_to_cm(target); + + struct adiv5_dap *dap = cortex_m->armv7m.arm.dap; + struct adiv5_ap *ap = dap_get_ap(dap, 0); + + uint32_t user_key[4]; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], user_key[0]); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], user_key[1]); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], user_key[2]); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], user_key[3]); + + uint8_t write_buffer1[4 * 4]; + target_buffer_set_u32_array(target, write_buffer1, 4, user_key); + int retval = mem_ap_write_buf(ap, write_buffer1, 4, 4, RSL10_FLASH_REG_DEBUG_UNLOCK_KEY1); + if (retval != ERROR_OK) { + dap_put_ap(ap); + return retval; + } + + dap_put_ap(ap); + + uint32_t key; + retval = mem_ap_read_atomic_u32(ap, RSL10_FLASH_ADDRESS_LOCK_INFO_SETTING, &key); + if (retval != ERROR_OK) + return retval; + LOG_INFO("mem read: 0x%08" PRIx32, key); + + if (key == RSL10_KEY_DEBUG_LOCK) { + retval = command_run_line(CMD_CTX, "reset init"); + if (retval != ERROR_OK) + return retval; + + struct flash_bank *bank; + retval = get_flash_bank_by_addr(target, RSL10_FLASH_ADDRESS_NVR3, true, &bank); + if (retval != ERROR_OK) + return retval; + + retval = rsl10_protect(bank, false, 0, 0); + if (retval != ERROR_OK) + return retval; + + uint8_t write_buffer2[4 * 2]; + target_buffer_set_u32(target, write_buffer2, 0x1); + /* pad the end to 64-bit word boundary */ + memset(&write_buffer2[4], bank->default_padded_value, 4); + + /* let it fail, because sector is not erased, maybe just erase all? */ + (void)rsl10_write(bank, write_buffer2, RSL10_NVR3_USER_KEY_OFFSET, sizeof(write_buffer2)); + command_print(CMD, "Debug port is unlocked!"); + } + + return ERROR_OK; +} + +COMMAND_HANDLER(rsl10_mass_erase_command) +{ + if (CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + + struct target *target = get_current_target(CMD_CTX); + + int retval = rsl10_mass_erase(target); + if (retval != ERROR_OK) + return retval; + + command_print(CMD, "Mass erase was succesfull!"); + return ERROR_OK; +} + +static const struct command_registration rsl10_exec_command_handlers[] = { + { + .name = "lock", + .handler = rsl10_lock_command, + .mode = COMMAND_EXEC, + .help = "Lock rsl10 debug, with passed keys", + .usage = "key1 key2 key3 key4", + }, + { + .name = "unlock", + .handler = rsl10_unlock_command, + .mode = COMMAND_EXEC, + .help = "Unlock rsl10 debug, with passed keys", + .usage = "key1 key2 key3 key4", + }, + { + .name = "mass_erase", + .handler = rsl10_mass_erase_command, + .mode = COMMAND_EXEC, + .help = "Mass erase all unprotected flash areas", + .usage = "", + }, + COMMAND_REGISTRATION_DONE}; + +static const struct command_registration rsl10_command_handlers[] = { + { + .name = "rsl10", + .mode = COMMAND_ANY, + .help = "rsl10 flash command group", + .usage = "", + .chain = rsl10_exec_command_handlers, + }, + COMMAND_REGISTRATION_DONE}; + +const struct flash_driver rsl10_flash = { + .name = "rsl10", + .commands = rsl10_command_handlers, + .flash_bank_command = rsl10_flash_bank_command, + .erase = rsl10_erase, + .protect = rsl10_protect, + .write = rsl10_write, + .read = default_flash_read, + .probe = rsl10_probe, + .auto_probe = rsl10_auto_probe, + .erase_check = default_flash_blank_check, + .protect_check = rsl10_protect_check, + .free_driver_priv = rsl10_free_driver_priv, +}; diff --git a/src/flash/nor/sfdp.c b/src/flash/nor/sfdp.c index 88d3b96..5bfb541 100644 --- a/src/flash/nor/sfdp.c +++ b/src/flash/nor/sfdp.c @@ -1,17 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2019 by Andreas Bolsch <andreas.bolsch@mni.thm.de * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/sfdp.h b/src/flash/nor/sfdp.h index f924a4e..1c9af32 100644 --- a/src/flash/nor/sfdp.h +++ b/src/flash/nor/sfdp.h @@ -1,17 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2019 by Andreas Bolsch <andreas.bolsch@mni.thm.de * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_SFDP_H diff --git a/src/flash/nor/sh_qspi.c b/src/flash/nor/sh_qspi.c index 02af17a..e8ca626 100644 --- a/src/flash/nor/sh_qspi.c +++ b/src/flash/nor/sh_qspi.c @@ -1,4 +1,5 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +// SPDX-License-Identifier: GPL-2.0-only + /* * SH QSPI (Quad SPI) driver * Copyright (C) 2019 Marek Vasut <marek.vasut@gmail.com> diff --git a/src/flash/nor/sim3x.c b/src/flash/nor/sim3x.c index 8913838..42550d0 100644 --- a/src/flash/nor/sim3x.c +++ b/src/flash/nor/sim3x.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2014 by Ladislav Bábel * * ladababel@seznam.cz * * * * Copyright (C) 2015 by Andreas Bomholtz * * andreas@seluxit.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -872,16 +861,23 @@ static int sim3x_flash_info(struct flash_bank *bank, struct command_invocation * */ static int ap_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value) { - int retval; LOG_DEBUG("DAP_REG[0x%02x] <- %08" PRIX32, reg, value); - retval = dap_queue_ap_write(dap_ap(dap, SIM3X_AP), reg, value); + struct adiv5_ap *ap = dap_get_ap(dap, SIM3X_AP); + if (!ap) { + LOG_DEBUG("DAP: failed to get AP"); + return ERROR_FAIL; + } + + int retval = dap_queue_ap_write(ap, reg, value); if (retval != ERROR_OK) { LOG_DEBUG("DAP: failed to queue a write request"); + dap_put_ap(ap); return retval; } retval = dap_run(dap); + dap_put_ap(ap); if (retval != ERROR_OK) { LOG_DEBUG("DAP: dap_run failed"); return retval; @@ -892,15 +888,21 @@ static int ap_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value static int ap_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result) { - int retval; + struct adiv5_ap *ap = dap_get_ap(dap, SIM3X_AP); + if (!ap) { + LOG_DEBUG("DAP: failed to get AP"); + return ERROR_FAIL; + } - retval = dap_queue_ap_read(dap_ap(dap, SIM3X_AP), reg, result); + int retval = dap_queue_ap_read(ap, reg, result); if (retval != ERROR_OK) { LOG_DEBUG("DAP: failed to queue a read request"); + dap_put_ap(ap); return retval; } retval = dap_run(dap); + dap_put_ap(ap); if (retval != ERROR_OK) { LOG_DEBUG("DAP: dap_run failed"); return retval; diff --git a/src/flash/nor/spi.c b/src/flash/nor/spi.c index 627bb41..b269bd7 100644 --- a/src/flash/nor/spi.c +++ b/src/flash/nor/spi.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2018 by Andreas Bolsch * * andreas.bolsch@mni.thm.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2010 by Antonio Borneo * * borneo.antonio@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/spi.h b/src/flash/nor/spi.h index f8a0a65..807af12 100644 --- a/src/flash/nor/spi.h +++ b/src/flash/nor/spi.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2018-2019 by Andreas Bolsch * * andreas.bolsch@mni.thm.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2010 by Antonio Borneo * * borneo.antonio@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_SPI_H diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c index 6135c95..3a78952 100644 --- a/src/flash/nor/stellaris.c +++ b/src/flash/nor/stellaris.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Magnus Lundin * * lundin@mlu.mine.nu * * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /*************************************************************************** diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c index b5b10af..292b66d 100644 --- a/src/flash/nor/stm32f1x.c +++ b/src/flash/nor/stm32f1x.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2011 by Andreas Fritiofson * * andreas.fritiofson@gmail.com * - * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -1017,7 +1006,7 @@ static int stm32x_probe(struct flash_bank *bank) flash_size_in_kb = stm32x_info->user_bank_size / 1024; } - LOG_INFO("flash size = %dkbytes", flash_size_in_kb); + LOG_INFO("flash size = %d KiB", flash_size_in_kb); /* did we assign flash size? */ assert(flash_size_in_kb != 0xffff); diff --git a/src/flash/nor/stm32f2x.c b/src/flash/nor/stm32f2x.c index 622ef34..36b7a0d 100644 --- a/src/flash/nor/stm32f2x.c +++ b/src/flash/nor/stm32f2x.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2011 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -1136,7 +1125,7 @@ static int stm32x_probe(struct flash_bank *bank) flash_size_in_kb = stm32x_info->user_bank_size / 1024; } - LOG_INFO("flash size = %" PRIu16 " kbytes", flash_size_in_kb); + LOG_INFO("flash size = %" PRIu16 " KiB", flash_size_in_kb); /* did we assign flash size? */ assert(flash_size_in_kb != 0xffff); diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index d2914eb..8be8037 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2017 by STMicroelectronics * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 0a9d59c..7a6ec3f 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 by Uwe Bonnes * * bon@elektron.ikp.physik.tu-darmstadt.de * * * * Copyright (C) 2019 by Tarek Bochkati for STMicroelectronics * * tarek.bouchkati@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -300,7 +289,7 @@ static const struct stm32l4_rev stm32l45_l46xx_revs[] = { { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" }, }; -static const struct stm32l4_rev stm32l41_L42xx_revs[] = { +static const struct stm32l4_rev stm32l41_l42xx_revs[] = { { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" }, }; @@ -431,8 +420,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = { }, { .id = DEVID_STM32L41_L42XX, - .revs = stm32l41_L42xx_revs, - .num_revs = ARRAY_SIZE(stm32l41_L42xx_revs), + .revs = stm32l41_l42xx_revs, + .num_revs = ARRAY_SIZE(stm32l41_l42xx_revs), .device_str = "STM32L41/L42xx", .max_flash_size_kb = 128, .flags = F_NONE, @@ -1827,7 +1816,7 @@ static int stm32l4_probe(struct flash_bank *bank) flash_size_kb = stm32l4_info->user_bank_size / 1024; } - LOG_INFO("flash size = %dkbytes", flash_size_kb); + LOG_INFO("flash size = %d KiB", flash_size_kb); /* did we assign a flash size? */ assert((flash_size_kb != 0xffff) && flash_size_kb); diff --git a/src/flash/nor/stm32l4x.h b/src/flash/nor/stm32l4x.h index 4458c08..06cc66d 100644 --- a/src/flash/nor/stm32l4x.h +++ b/src/flash/nor/stm32l4x.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2015 by Uwe Bonnes * * bon@elektron.ikp.physik.tu-darmstadt.de * - * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_STM32L4X diff --git a/src/flash/nor/stm32lx.c b/src/flash/nor/stm32lx.c index f6a8ffc..860bab3 100644 --- a/src/flash/nor/stm32lx.c +++ b/src/flash/nor/stm32lx.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2011 by Clement Burin des Roziers * * clement.burin-des-roziers@hikob.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -152,7 +141,7 @@ static const struct stm32lx_rev stm32_429_revs[] = { { 0x1000, "A" }, { 0x1018, "Z" }, }; static const struct stm32lx_rev stm32_436_revs[] = { - { 0x1000, "A" }, { 0x1008, "Z" }, { 0x1018, "Y" }, + { 0x1000, "A" }, { 0x1008, "Z" }, { 0x1018, "Y" }, { 0x1038, "X" }, }; static const struct stm32lx_rev stm32_437_revs[] = { { 0x1000, "A" }, diff --git a/src/flash/nor/stmqspi.c b/src/flash/nor/stmqspi.c index 8278601..9c266e9 100644 --- a/src/flash/nor/stmqspi.c +++ b/src/flash/nor/stmqspi.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2016 - 2019 by Andreas Bolsch * * andreas.bolsch@mni.thm.de * * * * Copyright (C) 2010 by Antonio Borneo * * borneo.antonio@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* STM QuadSPI (QSPI) and OctoSPI (OCTOSPI) controller are SPI bus controllers @@ -765,13 +754,13 @@ COMMAND_HANDLER(stmqspi_handle_set) bank->sectors = sectors; stmqspi_info->dev.name = stmqspi_info->devname; if (stmqspi_info->dev.size_in_bytes / 4096) - LOG_INFO("flash \'%s\' id = unknown\nchip size = %" PRIu32 "kbytes," - " bank size = %" PRIu32 "kbytes", stmqspi_info->dev.name, + LOG_INFO("flash \'%s\' id = unknown\nchip size = %" PRIu32 " KiB," + " bank size = %" PRIu32 " KiB", stmqspi_info->dev.name, stmqspi_info->dev.size_in_bytes / 1024, (stmqspi_info->dev.size_in_bytes / 1024) << dual); else - LOG_INFO("flash \'%s\' id = unknown\nchip size = %" PRIu32 "bytes," - " bank size = %" PRIu32 "bytes", stmqspi_info->dev.name, + LOG_INFO("flash \'%s\' id = unknown\nchip size = %" PRIu32 " B," + " bank size = %" PRIu32 " B", stmqspi_info->dev.name, stmqspi_info->dev.size_in_bytes, stmqspi_info->dev.size_in_bytes << dual); @@ -2217,10 +2206,10 @@ static int stmqspi_probe(struct flash_bank *bank) memcpy(&stmqspi_info->dev, p, sizeof(stmqspi_info->dev)); if (p->size_in_bytes / 4096) LOG_INFO("flash1 \'%s\' id = 0x%06" PRIx32 " size = %" PRIu32 - "kbytes", p->name, id1, p->size_in_bytes / 1024); + " KiB", p->name, id1, p->size_in_bytes / 1024); else LOG_INFO("flash1 \'%s\' id = 0x%06" PRIx32 " size = %" PRIu32 - "bytes", p->name, id1, p->size_in_bytes); + " B", p->name, id1, p->size_in_bytes); break; } } @@ -2239,7 +2228,7 @@ static int stmqspi_probe(struct flash_bank *bank) if (retval == ERROR_OK) { LOG_INFO("flash1 \'%s\' id = 0x%06" PRIx32 " size = %" PRIu32 - "kbytes", temp.name, id1, temp.size_in_bytes / 1024); + " KiB", temp.name, id1, temp.size_in_bytes / 1024); /* save info and retrieved *good* id as spi_sfdp clears all info */ memcpy(&stmqspi_info->dev, &temp, sizeof(stmqspi_info->dev)); stmqspi_info->dev.device_id = id1; @@ -2257,10 +2246,10 @@ static int stmqspi_probe(struct flash_bank *bank) if (p->device_id == id2) { if (p->size_in_bytes / 4096) LOG_INFO("flash2 \'%s\' id = 0x%06" PRIx32 " size = %" PRIu32 - "kbytes", p->name, id2, p->size_in_bytes / 1024); + " KiB", p->name, id2, p->size_in_bytes / 1024); else LOG_INFO("flash2 \'%s\' id = 0x%06" PRIx32 " size = %" PRIu32 - "bytes", p->name, id2, p->size_in_bytes); + " B", p->name, id2, p->size_in_bytes); if (!id1) memcpy(&stmqspi_info->dev, p, sizeof(stmqspi_info->dev)); @@ -2297,7 +2286,7 @@ static int stmqspi_probe(struct flash_bank *bank) if (retval == ERROR_OK) LOG_INFO("flash2 \'%s\' id = 0x%06" PRIx32 " size = %" PRIu32 - "kbytes", temp.name, id2, temp.size_in_bytes / 1024); + " KiB", temp.name, id2, temp.size_in_bytes / 1024); else { /* even not identified by SFDP, then give up */ LOG_WARNING("Unknown flash2 device id = 0x%06" PRIx32 @@ -2403,22 +2392,22 @@ static int get_stmqspi_info(struct flash_bank *bank, struct command_invocation * } command_print_sameline(cmd, "flash%s%s \'%s\', device id = 0x%06" PRIx32 - ", flash size = %" PRIu32 "%sbytes\n(page size = %" PRIu32 + ", flash size = %" PRIu32 "%s B\n(page size = %" PRIu32 ", read = 0x%02" PRIx8 ", qread = 0x%02" PRIx8 ", pprog = 0x%02" PRIx8 ", mass_erase = 0x%02" PRIx8 - ", sector size = %" PRIu32 "%sbytes, sector_erase = 0x%02" PRIx8 ")", + ", sector size = %" PRIu32 " %sB, sector_erase = 0x%02" PRIx8 ")", ((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) | BIT(SPI_FSEL_FLASH))) != BIT(SPI_FSEL_FLASH)) ? "1" : "", ((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) | BIT(SPI_FSEL_FLASH))) != 0) ? "2" : "", stmqspi_info->dev.name, stmqspi_info->dev.device_id, bank->size / 4096 ? bank->size / 1024 : bank->size, - bank->size / 4096 ? "k" : "", stmqspi_info->dev.pagesize, + bank->size / 4096 ? "Ki" : "", stmqspi_info->dev.pagesize, stmqspi_info->dev.read_cmd, stmqspi_info->dev.qread_cmd, stmqspi_info->dev.pprog_cmd, stmqspi_info->dev.chip_erase_cmd, stmqspi_info->dev.sectorsize / 4096 ? stmqspi_info->dev.sectorsize / 1024 : stmqspi_info->dev.sectorsize, - stmqspi_info->dev.sectorsize / 4096 ? "k" : "", + stmqspi_info->dev.sectorsize / 4096 ? "Ki" : "", stmqspi_info->dev.erase_cmd); return ERROR_OK; diff --git a/src/flash/nor/stmqspi.h b/src/flash/nor/stmqspi.h index 85da25f..245df40 100644 --- a/src/flash/nor/stmqspi.h +++ b/src/flash/nor/stmqspi.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2016 - 2018 by Andreas Bolsch * * andreas.bolsch@mni.thm.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_FLASH_NOR_STMQSPI_H diff --git a/src/flash/nor/stmsmi.c b/src/flash/nor/stmsmi.c index 553bf29..1aa2447 100644 --- a/src/flash/nor/stmsmi.c +++ b/src/flash/nor/stmsmi.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* STM Serial Memory Interface (SMI) controller is a SPI bus controller diff --git a/src/flash/nor/str7x.c b/src/flash/nor/str7x.c index 9b977bf..b91e22e 100644 --- a/src/flash/nor/str7x.c +++ b/src/flash/nor/str7x.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2010 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/str9x.c b/src/flash/nor/str9x.c index 8f39d75..1a26b83 100644 --- a/src/flash/nor/str9x.c +++ b/src/flash/nor/str9x.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * Copyright (C) 2008 by Oyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/str9xpec.c b/src/flash/nor/str9xpec.c index da66a99..c39eb3a 100644 --- a/src/flash/nor/str9xpec.c +++ b/src/flash/nor/str9xpec.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/swm050.c b/src/flash/nor/swm050.c index be7452b..89e59ae 100644 --- a/src/flash/nor/swm050.c +++ b/src/flash/nor/swm050.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2019 Icenowy Zheng <icenowy@aosc.io> * * Copyright (C) 2019 Caleb Szalacinski <contact@skiboy.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 05db314..0562906 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> * * Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> * * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> * * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * * Copyright (C) 2017-2018 Tomas Vanek <vanekt@fbl.cz> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/flash/nor/tms470.c b/src/flash/nor/tms470.c index 37f0933..e01d2df 100644 --- a/src/flash/nor/tms470.c +++ b/src/flash/nor/tms470.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007,2008 by Christopher Kilgour * * techie |_at_| whiterocker |_dot_| com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -259,9 +248,6 @@ static int tms470_read_part_info(struct flash_bank *bank) target_write_u32(target, 0xFFFFFFE4, 0x00000000); target_write_u32(target, 0xFFFFFFE0, 0x00000000); - bank->chip_width = 32; - bank->bus_width = 32; - LOG_INFO("Identified %s, ver=%d, core=%s, nvmem=%s.", part_name, (int)(silicon_version), diff --git a/src/flash/nor/virtual.c b/src/flash/nor/virtual.c index 01a9247..c5e3338 100644 --- a/src/flash/nor/virtual.c +++ b/src/flash/nor/virtual.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2010 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/w600.c b/src/flash/nor/w600.c index cd2aa01..20968dc 100644 --- a/src/flash/nor/w600.c +++ b/src/flash/nor/w600.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2018 by Simon Qian * * SimonQian@SimonQian.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -323,7 +312,7 @@ static int w600_probe(struct flash_bank *bank) flash_size = 1 << flash_size; } - LOG_INFO("flash size = %" PRIu32 "kbytes", flash_size / 1024); + LOG_INFO("flash size = %" PRIu32 " KiB", flash_size / 1024); /* calculate numbers of pages */ size_t num_pages = flash_size / W600_FLASH_SECSIZE; diff --git a/src/flash/nor/xcf.c b/src/flash/nor/xcf.c index c6de1ac..2870725 100644 --- a/src/flash/nor/xcf.c +++ b/src/flash/nor/xcf.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2016 by Uladzimir Pylinski aka barthess * * barthess@yandex.ru * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/nor/xmc1xxx.c b/src/flash/nor/xmc1xxx.c index 9e5f0a3..6e30fc1 100644 --- a/src/flash/nor/xmc1xxx.c +++ b/src/flash/nor/xmc1xxx.c @@ -1,9 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * XMC1000 flash driver * * Copyright (c) 2016 Andreas Färber - * - * License: GPL-2.0+ */ #ifdef HAVE_CONFIG_H @@ -520,24 +520,8 @@ FLASH_BANK_COMMAND_HANDLER(xmc1xxx_flash_bank_command) return ERROR_OK; } -static const struct command_registration xmc1xxx_exec_command_handlers[] = { - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration xmc1xxx_command_handlers[] = { - { - .name = "xmc1xxx", - .mode = COMMAND_ANY, - .help = "xmc1xxx flash command group", - .usage = "", - .chain = xmc1xxx_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - const struct flash_driver xmc1xxx_flash = { .name = "xmc1xxx", - .commands = xmc1xxx_command_handlers, .flash_bank_command = xmc1xxx_flash_bank_command, .info = xmc1xxx_get_info_command, .probe = xmc1xxx_probe, diff --git a/src/flash/nor/xmc4xxx.c b/src/flash/nor/xmc4xxx.c index 1668e89..54fd5a5 100644 --- a/src/flash/nor/xmc4xxx.c +++ b/src/flash/nor/xmc4xxx.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /************************************************************************** * Copyright (C) 2015 Jeff Ciesielski <jeffciesielski@gmail.com> * -* * -* 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl index 16cbe19..654f201 100644 --- a/src/flash/startup.tcl +++ b/src/flash/startup.tcl @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + # Defines basic Tcl procs for OpenOCD flash module # diff --git a/src/hello.c b/src/hello.c index 9d078c0..4a4ce01 100644 --- a/src/hello.c +++ b/src/hello.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/hello.h b/src/hello.h index c88c89d..1a087b1 100644 --- a/src/hello.h +++ b/src/hello.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_HELLO_H diff --git a/src/helper/Makefile.am b/src/helper/Makefile.am index 822578a..0268694 100644 --- a/src/helper/Makefile.am +++ b/src/helper/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libhelper.la %C%_libhelper_la_SOURCES = \ diff --git a/src/helper/bin2char.sh b/src/helper/bin2char.sh index 128ea9a..b89433d 100755 --- a/src/helper/bin2char.sh +++ b/src/helper/bin2char.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later [ $# != 0 ] && { echo "Usage: $0" diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c index e2dfa87..5f38b43 100644 --- a/src/helper/binarybuffer.c +++ b/src/helper/binarybuffer.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2004, 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/helper/binarybuffer.h b/src/helper/binarybuffer.h index 36d6adc..a8a5ef8 100644 --- a/src/helper/binarybuffer.h +++ b/src/helper/binarybuffer.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2004, 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_HELPER_BINARYBUFFER_H diff --git a/src/helper/bits.h b/src/helper/bits.h index 6151b33..4e2a345 100644 --- a/src/helper/bits.h +++ b/src/helper/bits.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * Copyright (C) 2018, STMicroelectronics - All Rights Reserved * Author(s): Antonio Borneo <borneo.antonio@gmail.com> for STMicroelectronics - * - * 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, see <http://www.gnu.org/licenses/>. */ /* diff --git a/src/helper/command.c b/src/helper/command.c index 1e769d7..6898e2d 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -10,19 +12,6 @@ * * * part of this file is taken from libcli (libcli.sourceforge.net) * * Copyright (C) David Parrish (david@dparrish.com) * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -713,14 +702,12 @@ static int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv) * This is necessary in order to avoid accidentally getting a non-empty * string for tcl fn's. */ - bool save_poll = jtag_poll_get_enabled(); - - jtag_poll_set_enabled(false); + bool save_poll_mask = jtag_poll_mask(); const char *str = Jim_GetString(argv[1], NULL); int retcode = Jim_Eval_Named(interp, str, __THIS__FILE__, __LINE__); - jtag_poll_set_enabled(save_poll); + jtag_poll_unmask(save_poll_mask); command_log_capture_finish(state); @@ -949,7 +936,19 @@ static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *a if (!command_can_run(cmd_ctx, c, Jim_GetString(argv[0], NULL))) return JIM_ERR; - target_call_timer_callbacks_now(); + /* + * TODO: to be removed after v0.12.0 + * workaround for https://sourceforge.net/p/openocd/tickets/362/ + * After syntax change of "expr" in jimtcl 0.81 + * the replacement of jimtcl "expr" with openocd version in + * https://review.openocd.org/6510/ + * introduces too many target polling during math expressions with + * "expr" commands. + * After v0.12.0 replace the following two lines with + * target_call_timer_callbacks(); + */ + if (strcmp(c->name, "expr")) + target_call_timer_callbacks_now(); /* * Black magic of overridden current target: diff --git a/src/helper/command.h b/src/helper/command.h index 796cd9d..478e5c8 100644 --- a/src/helper/command.h +++ b/src/helper/command.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_HELPER_COMMAND_H diff --git a/src/helper/configuration.c b/src/helper/configuration.c index 7e791d0..16732eb 100644 --- a/src/helper/configuration.c +++ b/src/helper/configuration.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2004, 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -148,6 +137,10 @@ int parse_config_file(struct command_context *cmd_ctx) char *get_home_dir(const char *append_path) { +#ifdef _WIN32 + char homepath[MAX_PATH]; +#endif + char *home = getenv("HOME"); if (!home) { @@ -156,8 +149,6 @@ char *get_home_dir(const char *append_path) home = getenv("USERPROFILE"); if (!home) { - - char homepath[MAX_PATH]; char *drive = getenv("HOMEDRIVE"); char *path = getenv("HOMEPATH"); if (drive && path) { diff --git a/src/helper/configuration.h b/src/helper/configuration.h index cc28efc..295ea59 100644 --- a/src/helper/configuration.h +++ b/src/helper/configuration.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2004, 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_HELPER_CONFIGURATION_H diff --git a/src/helper/fileio.c b/src/helper/fileio.c index cec7dec..a290a5d 100644 --- a/src/helper/fileio.c +++ b/src/helper/fileio.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/helper/fileio.h b/src/helper/fileio.h index 16c1046..6b4be8e 100644 --- a/src/helper/fileio.h +++ b/src/helper/fileio.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_HELPER_FILEIO_H diff --git a/src/helper/jep106.c b/src/helper/jep106.c index 5cf769a..d422561 100644 --- a/src/helper/jep106.c +++ b/src/helper/jep106.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 Andreas Fritiofson * * andreas.fritiofson@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/helper/jep106.h b/src/helper/jep106.h index 61b177a..c554dae 100644 --- a/src/helper/jep106.h +++ b/src/helper/jep106.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2015 Andreas Fritiofson * * andreas.fritiofson@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_HELPER_JEP106_H diff --git a/src/helper/jep106.inc b/src/helper/jep106.inc index 41afdb8..01c3aac 100644 --- a/src/helper/jep106.inc +++ b/src/helper/jep106.inc @@ -1,9 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* - * Should be autogenerated with update_jep106.pl but latest - * file from JEDEC is only available in PDF form. The PDF - * also breaks the pdftotext flow due to embedded watermarks. - * Created with a mix of scripts and manual editing. + * The manufacturer's standard identification code list appears in JEP106. + * Copyright (c) 2022 JEDEC. All rights reserved. + * + * JEP106 is regularly updated. For the current manufacturer's standard + * identification code list, please visit the JEDEC website at www.jedec.org . */ + +/* This file is aligned to revision JEP106BE January 2022. */ + [0][0x01 - 1] = "AMD", [0][0x02 - 1] = "AMI", [0][0x03 - 1] = "Fairchild", @@ -1553,7 +1559,7 @@ [12][0x23 - 1] = "Tangem AG", [12][0x24 - 1] = "FuturePath Technology (Shenzhen) Co", [12][0x25 - 1] = "RC Module", -[12][0x26 - 1] = "Team Research Inc", +[12][0x26 - 1] = "Timetec International Inc", [12][0x27 - 1] = "ICMAX Technologies Co Limited", [12][0x28 - 1] = "Lynxi Technologies Ltd Co", [12][0x29 - 1] = "Guangzhou Taisupanke Computer Equipment", @@ -1571,7 +1577,7 @@ [12][0x35 - 1] = "Shenzhen Xinxinshun Technology Co", [12][0x36 - 1] = "Galois Inc", [12][0x37 - 1] = "Ubilite Inc", -[12][0x38 - 1] = "Shenzhen Quanzing Technology Co Ltd", +[12][0x38 - 1] = "Shenzhen Quanxing Technology Co Ltd", [12][0x39 - 1] = "Group RZX Technology LTDA", [12][0x3a - 1] = "Yottac Technology (XI'AN) Cooperation", [12][0x3b - 1] = "Shenzhen RuiRen Technology Co Ltd", @@ -1611,4 +1617,92 @@ [12][0x5d - 1] = "OLOy Technology", [12][0x5e - 1] = "Wuhan P&S Semiconductor Co Ltd", [12][0x5f - 1] = "Sitrus Technology", +[12][0x60 - 1] = "AnHui Conner Storage Co Ltd", +[12][0x61 - 1] = "Rochester Electronics", +[12][0x62 - 1] = "Wuxi Petabyte Technologies Co Ltd", +[12][0x63 - 1] = "Star Memory", +[12][0x64 - 1] = "Agile Memory Technology Co Ltd", +[12][0x65 - 1] = "MEJEC", +[12][0x66 - 1] = "Rockchip Electronics Co Ltd", +[12][0x67 - 1] = "Dongguan Guanma e-commerce Co Ltd", +[12][0x68 - 1] = "Rayson Hi-Tech (SZ) Limited", +[12][0x69 - 1] = "MINRES Technologies GmbH", +[12][0x6a - 1] = "Himax Technologies Inc", +[12][0x6b - 1] = "Shenzhen Cwinner Technology Co Ltd", +[12][0x6c - 1] = "Tecmiyo", +[12][0x6d - 1] = "Shenzhen Suhuicun Technology Co Ltd", +[12][0x6e - 1] = "Vickter Electronics Co. Ltd.", +[12][0x6f - 1] = "lowRISC", +[12][0x70 - 1] = "EXEGate FZE", +[12][0x71 - 1] = "Shenzhen 9 Chapter Technologies Co", +[12][0x72 - 1] = "Addlink", +[12][0x73 - 1] = "Starsway", +[12][0x74 - 1] = "Pensando Systems Inc.", +[12][0x75 - 1] = "AirDisk", +[12][0x76 - 1] = "Shenzhen Speedmobile Technology Co", +[12][0x77 - 1] = "PEZY Computing", +[12][0x78 - 1] = "Extreme Engineering Solutions Inc", +[12][0x79 - 1] = "Shangxin Technology Co Ltd", +[12][0x7a - 1] = "Shanghai Zhaoxin Semiconductor Co", +[12][0x7b - 1] = "Xsight Labs Ltd", +[12][0x7c - 1] = "Hangzhou Hikstorage Technology Co", +[12][0x7d - 1] = "Dell Technologies", +[12][0x7e - 1] = "Guangdong StarFive Technology Co", +[13][0x01 - 1] = "TECOTON", +[13][0x02 - 1] = "Abko Co Ltd", +[13][0x03 - 1] = "Shenzhen Feisrike Technology Co Ltd", +[13][0x04 - 1] = "Shenzhen Sunhome Electronics Co Ltd", +[13][0x05 - 1] = "Global Mixed-mode Technology Inc", +[13][0x06 - 1] = "Shenzhen Weien Electronics Co. Ltd.", +[13][0x07 - 1] = "Shenzhen Cooyes Technology Co Ltd", +[13][0x08 - 1] = "Keymos Electronics Co., Limited", +[13][0x09 - 1] = "E-Rockic Technology Company Limited", +[13][0x0a - 1] = "Aerospace Science Memory Shenzhen", +[13][0x0b - 1] = "Shenzhen Quanji Technology Co Ltd", +[13][0x0c - 1] = "Dukosi", +[13][0x0d - 1] = "Maxell Corporation of America", +[13][0x0e - 1] = "Shenshen Xinxintao Electronics Co Ltd", +[13][0x0f - 1] = "Zhuhai Sanxia Semiconductor Co Ltd", +[13][0x10 - 1] = "Groq Inc", +[13][0x11 - 1] = "AstraTek", +[13][0x12 - 1] = "Shenzhen Xinyuze Technology Co Ltd", +[13][0x13 - 1] = "All Bit Semiconductor", +[13][0x14 - 1] = "ACFlow", +[13][0x15 - 1] = "Shenzhen Sipeed Technology Co Ltd", +[13][0x16 - 1] = "Linzhi Hong Kong Co Limited", +[13][0x17 - 1] = "Supreme Wise Limited", +[13][0x18 - 1] = "Blue Cheetah Analog Design Inc", +[13][0x19 - 1] = "Hefei Laiku Technology Co Ltd", +[13][0x1a - 1] = "Zord", +[13][0x1b - 1] = "SBO Hearing A/S", +[13][0x1c - 1] = "Regent Sharp International Limited", +[13][0x1d - 1] = "Permanent Potential Limited", +[13][0x1e - 1] = "Creative World International Limited", +[13][0x1f - 1] = "Base Creation International Limited", +[13][0x20 - 1] = "Shenzhen Zhixin Chuanglian Technology", +[13][0x21 - 1] = "Protected Logic Corporation", +[13][0x22 - 1] = "Sabrent", +[13][0x23 - 1] = "Union Memory", +[13][0x24 - 1] = "NEUCHIPS Corporation", +[13][0x25 - 1] = "Ingenic Semiconductor Co Ltd", +[13][0x26 - 1] = "SiPearl", +[13][0x27 - 1] = "Shenzhen Actseno Information Technology", +[13][0x28 - 1] = "RIVAI Technologies (Shenzhen) Co Ltd", +[13][0x29 - 1] = "Shenzhen Sunny Technology Co Ltd", +[13][0x2a - 1] = "Cott Electronics Ltd", +[13][0x2b - 1] = "Shanghai Synsense Technologies Co Ltd", +[13][0x2c - 1] = "Shenzhen Jintang Fuming Optoelectronics", +[13][0x2d - 1] = "CloudBEAR LLC", +[13][0x2e - 1] = "Emzior, LLC", +[13][0x2f - 1] = "Ehiway Microelectronic Science Tech Co", +[13][0x30 - 1] = "UNIM Innovation Technology (Wu XI)", +[13][0x31 - 1] = "GDRAMARS", +[13][0x32 - 1] = "Meminsights Technology", +[13][0x33 - 1] = "Zhuzhou Hongda Electronics Corp Ltd", +[13][0x34 - 1] = "Luminous Computing Inc", +[13][0x35 - 1] = "PROXMEM", +[13][0x36 - 1] = "Draper Labs", +[13][0x37 - 1] = "ORICO Technologies Co. Ltd.", +[13][0x38 - 1] = "Space Exploration Technologies Corp", +[13][0x39 - 1] = "AONDEVICES Inc", /* EOF */ diff --git a/src/helper/jim-nvp.c b/src/helper/jim-nvp.c index 0409a83..e1ab64a 100644 --- a/src/helper/jim-nvp.c +++ b/src/helper/jim-nvp.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: BSD-2-Clause-Views + /* Jim - A small embeddable Tcl interpreter * * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org> @@ -11,34 +13,7 @@ * Copyright 2009 Nico Coesel <ncoesel@dealogic.nl> * Copyright 2009 Zachary T Welch zw@superlucidity.net * Copyright 2009 David Brownell - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of the Jim Tcl Project. + * Copyright (c) 2005-2011 Jim Tcl Project. All rights reserved. */ #ifdef HAVE_CONFIG_H diff --git a/src/helper/jim-nvp.h b/src/helper/jim-nvp.h index 00e4af9..11824ca 100644 --- a/src/helper/jim-nvp.h +++ b/src/helper/jim-nvp.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause-Views */ + /* Jim - A small embeddable Tcl interpreter * * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org> @@ -11,34 +13,7 @@ * Copyright 2009 Nico Coesel <ncoesel@dealogic.nl> * Copyright 2009 Zachary T Welch zw@superlucidity.net * Copyright 2009 David Brownell - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of the Jim Tcl Project. + * Copyright (c) 2005-2011 Jim Tcl Project. All rights reserved. */ #ifndef OPENOCD_HELPER_JIM_NVP_H @@ -326,144 +301,4 @@ void jim_getopt_nvp_unknown(struct jim_getopt_info *goi, const struct jim_nvp *l */ int jim_getopt_enum(struct jim_getopt_info *goi, const char *const *lookup, int *puthere); -/* - * DEPRECATED API - * Do not use these API anymore, as they do not comply with OpenOCD coding style - * They are listed here to avoid breaking build after merge of patches already queued in gerrit - */ - -static inline __attribute__ ((deprecated)) -const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - return jim_debug_argv_string(interp, argc, argv); -} - -static inline __attribute__ ((deprecated)) -int Jim_GetNvp(Jim_Interp *interp, Jim_Obj *objptr, const struct jim_nvp *nvp_table, const struct jim_nvp **result) -{ - return jim_get_nvp(interp, objptr, nvp_table, result); -} - -static inline __attribute__ ((deprecated)) -void Jim_GetOpt_Debug(struct jim_getopt_info *goi) -{ - jim_getopt_debug(goi); -} - -static inline __attribute__ ((deprecated)) -int Jim_GetOpt_Double(struct jim_getopt_info *goi, double *puthere) -{ - return jim_getopt_double(goi, puthere); -} - -static inline __attribute__ ((deprecated)) -int Jim_GetOpt_Enum(struct jim_getopt_info *goi, const char *const *lookup, int *puthere) -{ - return jim_getopt_enum(goi, lookup, puthere); -} - -static inline __attribute__ ((deprecated)) -int Jim_GetOpt_Nvp(struct jim_getopt_info *goi, const struct jim_nvp *lookup, struct jim_nvp **puthere) -{ - return jim_getopt_nvp(goi, lookup, puthere); -} - -static inline __attribute__ ((deprecated)) -void Jim_GetOpt_NvpUnknown(struct jim_getopt_info *goi, const struct jim_nvp *lookup, int hadprefix) -{ - jim_getopt_nvp_unknown(goi, lookup, hadprefix); -} - -static inline __attribute__ ((deprecated)) -int Jim_GetOpt_Obj(struct jim_getopt_info *goi, Jim_Obj **puthere) -{ - return jim_getopt_obj(goi, puthere); -} - -static inline __attribute__ ((deprecated)) -int Jim_GetOpt_Setup(struct jim_getopt_info *goi, Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - return jim_getopt_setup(goi, interp, argc, argv); -} - -static inline __attribute__ ((deprecated)) -int Jim_GetOpt_String(struct jim_getopt_info *goi, const char **puthere, int *len) -{ - return jim_getopt_string(goi, puthere, len); -} - -static inline __attribute__ ((deprecated)) -int Jim_GetOpt_Wide(struct jim_getopt_info *goi, jim_wide *puthere) -{ - return jim_getopt_wide(goi, puthere); -} - -static inline __attribute__ ((deprecated)) -int Jim_Nvp_name2value(Jim_Interp *interp, const struct jim_nvp *nvp_table, const char *name, struct jim_nvp **result) -{ - return jim_nvp_name2value(interp, nvp_table, name, result); -} - -static inline __attribute__ ((deprecated)) -int Jim_Nvp_name2value_nocase(Jim_Interp *interp, const struct jim_nvp *nvp_table, const char *name, - struct jim_nvp **result) -{ - return jim_nvp_name2value_nocase(interp, nvp_table, name, result); -} - -static inline __attribute__ ((deprecated)) -struct jim_nvp *Jim_Nvp_name2value_nocase_simple(const struct jim_nvp *nvp_table, const char *name) -{ - return jim_nvp_name2value_nocase_simple(nvp_table, name); -} - -static inline __attribute__ ((deprecated)) -int Jim_Nvp_name2value_obj(Jim_Interp *interp, const struct jim_nvp *nvp_table, Jim_Obj *name_obj, - struct jim_nvp **result) -{ - return jim_nvp_name2value_obj(interp, nvp_table, name_obj, result); -} - -static inline __attribute__ ((deprecated)) -int Jim_Nvp_name2value_obj_nocase(Jim_Interp *interp, const struct jim_nvp *nvp_table, Jim_Obj *name_obj, - struct jim_nvp **result) -{ - return jim_nvp_name2value_obj_nocase(interp, nvp_table, name_obj, result); -} - -static inline __attribute__ ((deprecated)) -struct jim_nvp *Jim_Nvp_name2value_simple(const struct jim_nvp *nvp_table, const char *name) -{ - return jim_nvp_name2value_simple(nvp_table, name); -} - -static inline __attribute__ ((deprecated)) -int Jim_Nvp_value2name(Jim_Interp *interp, const struct jim_nvp *nvp_table, int value, struct jim_nvp **result) -{ - return jim_nvp_value2name(interp, nvp_table, value, result); -} - -static inline __attribute__ ((deprecated)) -int Jim_Nvp_value2name_obj(Jim_Interp *interp, const struct jim_nvp *nvp_table, Jim_Obj *value_obj, - struct jim_nvp **result) -{ - return jim_nvp_value2name_obj(interp, nvp_table, value_obj, result); -} - -static inline __attribute__ ((deprecated)) -struct jim_nvp *Jim_Nvp_value2name_simple(const struct jim_nvp *nvp_table, int v) -{ - return jim_nvp_value2name_simple(nvp_table, v); -} - -static inline __attribute__ ((deprecated)) -void Jim_SetResult_NvpUnknown(Jim_Interp *interp, Jim_Obj *param_name, Jim_Obj *param_value, - const struct jim_nvp *nvp_table) -{ - jim_set_result_nvp_unknown(interp, param_name, param_value, nvp_table); -} - -typedef struct jim_getopt_info Jim_GetOptInfo __attribute__ ((deprecated)); -typedef struct jim_nvp Jim_Nvp __attribute__ ((deprecated)); - #endif /* OPENOCD_HELPER_JIM_NVP_H */ diff --git a/src/helper/log.c b/src/helper/log.c index 106d228..e6a70a3 100644 --- a/src/helper/log.c +++ b/src/helper/log.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -306,12 +295,6 @@ void log_exit(void) log_output = NULL; } -int set_log_output(struct command_context *cmd_ctx, FILE *output) -{ - log_output = output; - return ERROR_OK; -} - /* add/remove log callback handler */ int log_add_callback(log_callback_fn fn, void *priv) { diff --git a/src/helper/log.h b/src/helper/log.h index f0378ae..ee71bf0 100644 --- a/src/helper/log.h +++ b/src/helper/log.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_HELPER_LOG_H @@ -73,7 +62,6 @@ __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6))); */ void log_init(void); void log_exit(void); -int set_log_output(struct command_context *cmd_ctx, FILE *output); int log_register_commands(struct command_context *cmd_ctx); diff --git a/src/helper/options.c b/src/helper/options.c index 1996727..327c418 100644 --- a/src/helper/options.c +++ b/src/helper/options.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2004, 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007-2010 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/helper/replacements.c b/src/helper/replacements.c index c34b17e..b30dbd5 100644 --- a/src/helper/replacements.c +++ b/src/helper/replacements.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* DANGER!!!! These must be defined *BEFORE* replacements.h and the malloc() macro!!!! */ diff --git a/src/helper/replacements.h b/src/helper/replacements.h index 4d70d9c..9eac4d2 100644 --- a/src/helper/replacements.h +++ b/src/helper/replacements.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_HELPER_REPLACEMENTS_H diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl index 6389262..5a0d479 100644 --- a/src/helper/startup.tcl +++ b/src/helper/startup.tcl @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + # Defines basic Tcl procs that must exist for OpenOCD scripts to work. # # Embedded into OpenOCD executable diff --git a/src/helper/system.h b/src/helper/system.h index 0d8be64..bd96d62 100644 --- a/src/helper/system.h +++ b/src/helper/system.h @@ -1,21 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath <Dominic.Rath@gmx.de> * * Copyright (C) 2007-2008 by Øyvind Harboe <oyvind.harboe@zylin.com> * * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> * * Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_HELPER_SYSTEM_H diff --git a/src/helper/time_support.c b/src/helper/time_support.c index 861889e..dda3cb3 100644 --- a/src/helper/time_support.c +++ b/src/helper/time_support.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/helper/time_support.h b/src/helper/time_support.h index b83c0ac..c984296 100644 --- a/src/helper/time_support.h +++ b/src/helper/time_support.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_HELPER_TIME_SUPPORT_H diff --git a/src/helper/time_support_common.c b/src/helper/time_support_common.c index b733c27..9d17a31 100644 --- a/src/helper/time_support_common.c +++ b/src/helper/time_support_common.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/helper/types.h b/src/helper/types.h index 010529f..b99ece1 100644 --- a/src/helper/types.h +++ b/src/helper/types.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2004, 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_HELPER_TYPES_H diff --git a/src/helper/update_jep106.pl b/src/helper/update_jep106.pl index 561e04b..60472e3 100755 --- a/src/helper/update_jep106.pl +++ b/src/helper/update_jep106.pl @@ -1,4 +1,6 @@ #!/usr/bin/perl +# SPDX-License-Identifier: GPL-2.0-or-later + use strict; use warnings; use File::Basename; diff --git a/src/helper/util.c b/src/helper/util.c index be163b2..bf18f8e 100644 --- a/src/helper/util.c +++ b/src/helper/util.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2010 by Øyvind Harboe * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* this file contains various functionality useful to standalone systems */ diff --git a/src/helper/util.h b/src/helper/util.h index c9a11dd..3ccdc4f 100644 --- a/src/helper/util.h +++ b/src/helper/util.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2010 by Øyvind Harboe * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_HELPER_UTIL_H diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am index 23424f5..43c6f8b 100644 --- a/src/jtag/Makefile.am +++ b/src/jtag/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libjtag.la %C%_libjtag_la_LIBADD = diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index 1c34a26..58d97d3 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> * Copyright (C) 2007-2010 Øyvind Harboe <oyvind.harboe@zylin.com> @@ -32,6 +32,8 @@ enum adapter_clk_mode { CLOCK_MODE_RCLK }; +#define DEFAULT_CLOCK_SPEED_KHZ 100U + /** * Adapter configuration */ @@ -42,13 +44,74 @@ static struct { enum adapter_clk_mode clock_mode; int speed_khz; int rclk_fallback_speed_khz; + struct adapter_gpio_config gpios[ADAPTER_GPIO_IDX_NUM]; + bool gpios_initialized; /* Initialization of GPIOs to their unset values performed at run time */ } adapter_config; +static const struct gpio_map { + const char *name; + enum adapter_gpio_direction direction; + bool permit_drive_option; + bool permit_init_state_option; +} gpio_map[ADAPTER_GPIO_IDX_NUM] = { + [ADAPTER_GPIO_IDX_TDO] = { "tdo", ADAPTER_GPIO_DIRECTION_INPUT, false, true, }, + [ADAPTER_GPIO_IDX_TDI] = { "tdi", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, }, + [ADAPTER_GPIO_IDX_TMS] = { "tms", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, }, + [ADAPTER_GPIO_IDX_TCK] = { "tck", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, }, + [ADAPTER_GPIO_IDX_SWDIO] = { "swdio", ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL, true, true, }, + [ADAPTER_GPIO_IDX_SWDIO_DIR] = { "swdio_dir", ADAPTER_GPIO_DIRECTION_OUTPUT, true, false, }, + [ADAPTER_GPIO_IDX_SWCLK] = { "swclk", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, }, + [ADAPTER_GPIO_IDX_TRST] = { "trst", ADAPTER_GPIO_DIRECTION_OUTPUT, false, true, }, + [ADAPTER_GPIO_IDX_SRST] = { "srst", ADAPTER_GPIO_DIRECTION_OUTPUT, false, true, }, + [ADAPTER_GPIO_IDX_LED] = { "led", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, }, +}; + bool is_adapter_initialized(void) { return adapter_config.adapter_initialized; } +/* For convenience of the bit-banging drivers keep the gpio_config drive + * settings for srst and trst in sync with values set by the "adapter + * reset_config" command. + */ +static void sync_adapter_reset_with_gpios(void) +{ + enum reset_types cfg = jtag_get_reset_config(); + if (cfg & RESET_SRST_PUSH_PULL) + adapter_config.gpios[ADAPTER_GPIO_IDX_SRST].drive = ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL; + else + adapter_config.gpios[ADAPTER_GPIO_IDX_SRST].drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN; + if (cfg & RESET_TRST_OPEN_DRAIN) + adapter_config.gpios[ADAPTER_GPIO_IDX_TRST].drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN; + else + adapter_config.gpios[ADAPTER_GPIO_IDX_TRST].drive = ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL; +} + +static void adapter_driver_gpios_init(void) +{ + if (adapter_config.gpios_initialized) + return; + + for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i) { + adapter_config.gpios[i].gpio_num = -1; + adapter_config.gpios[i].chip_num = -1; + if (gpio_map[i].direction == ADAPTER_GPIO_DIRECTION_INPUT) + adapter_config.gpios[i].init_state = ADAPTER_GPIO_INIT_STATE_INPUT; + } + + /* Drivers assume active low, and this is the normal behaviour for reset + * lines so should be the default. */ + adapter_config.gpios[ADAPTER_GPIO_IDX_SRST].active_low = true; + adapter_config.gpios[ADAPTER_GPIO_IDX_TRST].active_low = true; + sync_adapter_reset_with_gpios(); + + /* JTAG GPIOs should be inactive except for tms */ + adapter_config.gpios[ADAPTER_GPIO_IDX_TMS].init_state = ADAPTER_GPIO_INIT_STATE_ACTIVE; + + adapter_config.gpios_initialized = true; +} + /** * Do low-level setup like initializing registers, output signals, * and clocking. @@ -65,7 +128,21 @@ int adapter_init(struct command_context *cmd_ctx) return ERROR_JTAG_INVALID_INTERFACE; } + adapter_driver_gpios_init(); + int retval; + + if (adapter_config.clock_mode == CLOCK_MODE_UNSELECTED) { + LOG_WARNING("An adapter speed is not selected in the init scripts." + " OpenOCD will try to run the adapter at the low speed (%d kHz)", + DEFAULT_CLOCK_SPEED_KHZ); + LOG_WARNING("To remove this warnings and achieve reasonable communication speed with the target," + " set \"adapter speed\" or \"jtag_rclk\" in the init scripts."); + retval = adapter_config_khz(DEFAULT_CLOCK_SPEED_KHZ); + if (retval != ERROR_OK) + return ERROR_JTAG_INIT_FAILED; + } + retval = adapter_driver->init(); if (retval != ERROR_OK) return retval; @@ -76,12 +153,6 @@ int adapter_init(struct command_context *cmd_ctx) return ERROR_OK; } - if (adapter_config.clock_mode == CLOCK_MODE_UNSELECTED) { - LOG_ERROR("An adapter speed is not selected in the init script." - " Insert a call to \"adapter speed\" or \"jtag_rclk\" to proceed."); - return ERROR_JTAG_INIT_FAILED; - } - int requested_khz = adapter_get_speed_khz(); int actual_khz = requested_khz; int speed_var = 0; @@ -528,6 +599,8 @@ next: old_cfg &= ~mask; new_cfg |= old_cfg; jtag_set_reset_config(new_cfg); + sync_adapter_reset_with_gpios(); + } else new_cfg = jtag_get_reset_config(); @@ -758,6 +831,218 @@ COMMAND_HANDLER(handle_adapter_reset_de_assert) (srst == VALUE_DEASSERT) ? SRST_DEASSERT : SRST_ASSERT); } +static int get_gpio_index(const char *signal_name) +{ + for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i) { + if (strcmp(gpio_map[i].name, signal_name) == 0) + return i; + } + return -1; +} + +static COMMAND_HELPER(helper_adapter_gpio_print_config, enum adapter_gpio_config_index gpio_idx) +{ + struct adapter_gpio_config *gpio_config = &adapter_config.gpios[gpio_idx]; + const char *active_state = gpio_config->active_low ? "low" : "high"; + const char *dir = ""; + const char *drive = ""; + const char *pull = ""; + const char *init_state = ""; + + switch (gpio_map[gpio_idx].direction) { + case ADAPTER_GPIO_DIRECTION_INPUT: + dir = "input"; + break; + case ADAPTER_GPIO_DIRECTION_OUTPUT: + dir = "output"; + break; + case ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL: + dir = "bidirectional"; + break; + } + + if (gpio_map[gpio_idx].permit_drive_option) { + switch (gpio_config->drive) { + case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL: + drive = ", push-pull"; + break; + case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN: + drive = ", open-drain"; + break; + case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE: + drive = ", open-source"; + break; + } + } + + switch (gpio_config->pull) { + case ADAPTER_GPIO_PULL_NONE: + pull = ", pull-none"; + break; + case ADAPTER_GPIO_PULL_UP: + pull = ", pull-up"; + break; + case ADAPTER_GPIO_PULL_DOWN: + pull = ", pull-down"; + break; + } + + if (gpio_map[gpio_idx].permit_init_state_option) { + switch (gpio_config->init_state) { + case ADAPTER_GPIO_INIT_STATE_INACTIVE: + init_state = ", init-state inactive"; + break; + case ADAPTER_GPIO_INIT_STATE_ACTIVE: + init_state = ", init-state active"; + break; + case ADAPTER_GPIO_INIT_STATE_INPUT: + init_state = ", init-state input"; + break; + } + } + + command_print(CMD, "adapter gpio %s (%s): num %d, chip %d, active-%s%s%s%s", + gpio_map[gpio_idx].name, dir, gpio_config->gpio_num, gpio_config->chip_num, active_state, + drive, pull, init_state); + + return ERROR_OK; +} + +COMMAND_HANDLER(helper_adapter_gpio_print_all_configs) +{ + for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i) + CALL_COMMAND_HANDLER(helper_adapter_gpio_print_config, i); + return ERROR_OK; +} + +COMMAND_HANDLER(adapter_gpio_config_handler) +{ + unsigned int i = 1; + struct adapter_gpio_config *gpio_config; + + adapter_driver_gpios_init(); + + if (CMD_ARGC == 0) { + CALL_COMMAND_HANDLER(helper_adapter_gpio_print_all_configs); + return ERROR_OK; + } + + int gpio_idx = get_gpio_index(CMD_ARGV[0]); + if (gpio_idx == -1) { + LOG_ERROR("adapter has no gpio named %s", CMD_ARGV[0]); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + if (CMD_ARGC == 1) { + CALL_COMMAND_HANDLER(helper_adapter_gpio_print_config, gpio_idx); + return ERROR_OK; + } + + gpio_config = &adapter_config.gpios[gpio_idx]; + while (i < CMD_ARGC) { + LOG_DEBUG("Processing %s", CMD_ARGV[i]); + + if (isdigit(*CMD_ARGV[i])) { + int gpio_num; /* Use a meaningful output parameter for more helpful error messages */ + COMMAND_PARSE_NUMBER(int, CMD_ARGV[i], gpio_num); + gpio_config->gpio_num = gpio_num; + ++i; + continue; + } + + if (strcmp(CMD_ARGV[i], "-chip") == 0) { + if (CMD_ARGC - i < 2) { + LOG_ERROR("-chip option requires a parameter"); + return ERROR_FAIL; + } + LOG_DEBUG("-chip arg is %s", CMD_ARGV[i + 1]); + int chip_num; /* Use a meaningful output parameter for more helpful error messages */ + COMMAND_PARSE_NUMBER(int, CMD_ARGV[i + 1], chip_num); + gpio_config->chip_num = chip_num; + i += 2; + continue; + } + + if (strcmp(CMD_ARGV[i], "-active-high") == 0) { + ++i; + gpio_config->active_low = false; + continue; + } + if (strcmp(CMD_ARGV[i], "-active-low") == 0) { + ++i; + gpio_config->active_low = true; + continue; + } + + if (gpio_map[gpio_idx].permit_drive_option) { + if (strcmp(CMD_ARGV[i], "-push-pull") == 0) { + ++i; + gpio_config->drive = ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL; + continue; + } + if (strcmp(CMD_ARGV[i], "-open-drain") == 0) { + ++i; + gpio_config->drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN; + continue; + } + if (strcmp(CMD_ARGV[i], "-open-source") == 0) { + ++i; + gpio_config->drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE; + continue; + } + } + + if (strcmp(CMD_ARGV[i], "-pull-none") == 0) { + ++i; + gpio_config->pull = ADAPTER_GPIO_PULL_NONE; + continue; + } + if (strcmp(CMD_ARGV[i], "-pull-up") == 0) { + ++i; + gpio_config->pull = ADAPTER_GPIO_PULL_UP; + continue; + } + if (strcmp(CMD_ARGV[i], "-pull-down") == 0) { + ++i; + gpio_config->pull = ADAPTER_GPIO_PULL_DOWN; + continue; + } + + if (gpio_map[gpio_idx].permit_init_state_option) { + if (strcmp(CMD_ARGV[i], "-init-inactive") == 0) { + ++i; + gpio_config->init_state = ADAPTER_GPIO_INIT_STATE_INACTIVE; + continue; + } + if (strcmp(CMD_ARGV[i], "-init-active") == 0) { + ++i; + gpio_config->init_state = ADAPTER_GPIO_INIT_STATE_ACTIVE; + continue; + } + + if (gpio_map[gpio_idx].direction == ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL && + strcmp(CMD_ARGV[i], "-init-input") == 0) { + ++i; + gpio_config->init_state = ADAPTER_GPIO_INIT_STATE_INPUT; + continue; + } + } + + LOG_ERROR("illegal option for adapter %s %s: %s", + CMD_NAME, gpio_map[gpio_idx].name, CMD_ARGV[i]); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + /* Force swdio_dir init state to be compatible with swdio init state */ + if (gpio_idx == ADAPTER_GPIO_IDX_SWDIO) + adapter_config.gpios[ADAPTER_GPIO_IDX_SWDIO_DIR].init_state = + (gpio_config->init_state == ADAPTER_GPIO_INIT_STATE_INPUT) ? + ADAPTER_GPIO_INIT_STATE_INACTIVE : + ADAPTER_GPIO_INIT_STATE_ACTIVE; + + return ERROR_OK; +} + #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS COMMAND_HANDLER(handle_usb_location_command) { @@ -875,6 +1160,19 @@ static const struct command_registration adapter_command_handlers[] = { .help = "Controls SRST and TRST lines.", .usage = "|assert [srst|trst [deassert|assert srst|trst]]", }, + { + .name = "gpio", + .handler = adapter_gpio_config_handler, + .mode = COMMAND_CONFIG, + .help = "gpio adapter command group", + .usage = "[ tdo|tdi|tms|tck|trst|swdio|swdio_dir|swclk|srst|led" + "[gpio_number] " + "[-chip chip_number] " + "[-active-high|-active-low] " + "[-push-pull|-open-drain|-open-source] " + "[-pull-none|-pull-up|-pull-down]" + "[-init-inactive|-init-active|-init-input] ]", + }, COMMAND_REGISTRATION_DONE }; @@ -911,3 +1209,14 @@ int adapter_register_commands(struct command_context *ctx) { return register_commands(ctx, NULL, interface_command_handlers); } + +const char *adapter_gpio_get_name(enum adapter_gpio_config_index idx) +{ + return gpio_map[idx].name; +} + +/* Allow drivers access to the GPIO configuration */ +const struct adapter_gpio_config *adapter_gpio_get_config(void) +{ + return adapter_config.gpios; +} diff --git a/src/jtag/adapter.h b/src/jtag/adapter.h index 300769c..682fc10 100644 --- a/src/jtag/adapter.h +++ b/src/jtag/adapter.h @@ -11,6 +11,59 @@ #include <stddef.h> #include <stdint.h> +/** Supported output drive modes for adaptor GPIO */ +enum adapter_gpio_drive_mode { + ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL, + ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN, + ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE, +}; + +/** Supported GPIO directions */ +enum adapter_gpio_direction { + ADAPTER_GPIO_DIRECTION_INPUT, + ADAPTER_GPIO_DIRECTION_OUTPUT, + ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL, +}; + +/** Supported initial states for GPIO */ +enum adapter_gpio_init_state { + ADAPTER_GPIO_INIT_STATE_INACTIVE, /* Should be zero so it is the default state */ + ADAPTER_GPIO_INIT_STATE_ACTIVE, + ADAPTER_GPIO_INIT_STATE_INPUT, +}; + +/** Supported pull directions for GPIO */ +enum adapter_gpio_pull { + ADAPTER_GPIO_PULL_NONE, + ADAPTER_GPIO_PULL_UP, + ADAPTER_GPIO_PULL_DOWN, +}; + +/** Adapter GPIO */ +enum adapter_gpio_config_index { + ADAPTER_GPIO_IDX_TDO, + ADAPTER_GPIO_IDX_TDI, + ADAPTER_GPIO_IDX_TMS, + ADAPTER_GPIO_IDX_TCK, + ADAPTER_GPIO_IDX_TRST, + ADAPTER_GPIO_IDX_SWDIO, + ADAPTER_GPIO_IDX_SWDIO_DIR, + ADAPTER_GPIO_IDX_SWCLK, + ADAPTER_GPIO_IDX_SRST, + ADAPTER_GPIO_IDX_LED, + ADAPTER_GPIO_IDX_NUM, /* must be the last item */ +}; + +/** Configuration options for a single GPIO */ +struct adapter_gpio_config { + int gpio_num; + int chip_num; + enum adapter_gpio_drive_mode drive; /* For outputs only */ + enum adapter_gpio_init_state init_state; + bool active_low; + enum adapter_gpio_pull pull; +}; + struct command_context; /** Register the adapter's commands */ @@ -58,4 +111,14 @@ unsigned int adapter_get_speed_khz(void); /** Retrieves the serial number set with command 'adapter serial' */ const char *adapter_get_required_serial(void); +/** + * Retrieves gpio name + */ +const char *adapter_gpio_get_name(enum adapter_gpio_config_index idx); + +/** + * Retrieves gpio configuration set with command "adapter gpio <signal_name>" + */ +const struct adapter_gpio_config *adapter_gpio_get_config(void); + #endif /* OPENOCD_JTAG_ADAPTER_H */ diff --git a/src/jtag/aice/Makefile.am b/src/jtag/aice/Makefile.am index b6a7ba9..bc5dac1 100644 --- a/src/jtag/aice/Makefile.am +++ b/src/jtag/aice/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libocdaice.la %C%_libocdaice_la_CPPFLAGS = -I$(top_srcdir)/src/jtag/drivers $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) diff --git a/src/jtag/aice/aice_interface.c b/src/jtag/aice/aice_interface.c index cb126c6..89f82a0 100644 --- a/src/jtag/aice/aice_interface.c +++ b/src/jtag/aice/aice_interface.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 by Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/aice/aice_interface.h b/src/jtag/aice/aice_interface.h index 3bddfa3..615e90f 100644 --- a/src/jtag/aice/aice_interface.h +++ b/src/jtag/aice/aice_interface.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 by Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_AICE_AICE_INTERFACE_H diff --git a/src/jtag/aice/aice_pipe.c b/src/jtag/aice/aice_pipe.c index e464b86..d2befde 100644 --- a/src/jtag/aice/aice_pipe.c +++ b/src/jtag/aice/aice_pipe.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 by Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/jtag/aice/aice_pipe.h b/src/jtag/aice/aice_pipe.h index 467ad0a..5a1f410 100644 --- a/src/jtag/aice/aice_pipe.h +++ b/src/jtag/aice/aice_pipe.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 by Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_AICE_AICE_PIPE_H diff --git a/src/jtag/aice/aice_port.c b/src/jtag/aice/aice_port.c index 2fa346c..ac38cec 100644 --- a/src/jtag/aice/aice_port.c +++ b/src/jtag/aice/aice_port.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 by Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/jtag/aice/aice_port.h b/src/jtag/aice/aice_port.h index 1593688..fb914d8 100644 --- a/src/jtag/aice/aice_port.h +++ b/src/jtag/aice/aice_port.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 by Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_AICE_AICE_PORT_H diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c index 2f2542e..49f899d 100644 --- a/src/jtag/aice/aice_transport.c +++ b/src/jtag/aice/aice_transport.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 by Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/aice/aice_transport.h b/src/jtag/aice/aice_transport.h index 3af8bc2..b000031 100644 --- a/src/jtag/aice/aice_transport.h +++ b/src/jtag/aice/aice_transport.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 by Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_AICE_AICE_TRANSPORT_H diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c index fc46e37..ef0ac63 100644 --- a/src/jtag/aice/aice_usb.c +++ b/src/jtag/aice/aice_usb.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 by Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/jtag/aice/aice_usb.h b/src/jtag/aice/aice_usb.h index 04021de..d85d25f 100644 --- a/src/jtag/aice/aice_usb.h +++ b/src/jtag/aice/aice_usb.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 by Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_AICE_AICE_USB_H diff --git a/src/jtag/commands.c b/src/jtag/commands.c index 206c5e8..43cda8a 100644 --- a/src/jtag/commands.c +++ b/src/jtag/commands.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -11,19 +13,6 @@ * * * Copyright (C) 2009 Zachary T Welch * * zw@superlucidity.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/commands.h b/src/jtag/commands.h index c037596..a8c7ffd 100644 --- a/src/jtag/commands.h +++ b/src/jtag/commands.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2009 Zachary T Welch * * zw@superlucidity.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_COMMANDS_H diff --git a/src/jtag/core.c b/src/jtag/core.c index bbc9877..5748011 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 Zachary T Welch * * zw@superlucidity.net * @@ -11,19 +13,6 @@ * * * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -147,14 +136,19 @@ int jtag_error_clear(void) /************/ -static bool jtag_poll = 1; +static bool jtag_poll = true; +static bool jtag_poll_en = true; bool is_jtag_poll_safe(void) { /* Polling can be disabled explicitly with set_enabled(false). + * It can also be masked with mask(). * It is also implicitly disabled while TRST is active and * while SRST is gating the JTAG clock. */ + if (!jtag_poll_en) + return false; + if (!transport_is_jtag()) return jtag_poll; @@ -173,6 +167,18 @@ void jtag_poll_set_enabled(bool value) jtag_poll = value; } +bool jtag_poll_mask(void) +{ + bool retval = jtag_poll_en; + jtag_poll_en = false; + return retval; +} + +void jtag_poll_unmask(bool saved) +{ + jtag_poll_en = saved; +} + /************/ struct jtag_tap *jtag_all_taps(void) diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am index d05b7b9..6410f37 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libocdjtagdrivers.la %C%_libocdjtagdrivers_la_LIBADD = @@ -106,6 +108,9 @@ endif if PRESTO DRIVERFILES += %D%/presto.c endif +if ESP_USB_JTAG +DRIVERFILES += %D%/esp_usb_jtag.c +endif if USBPROG DRIVERFILES += %D%/usbprog.c endif diff --git a/src/jtag/drivers/Makefile.rlink b/src/jtag/drivers/Makefile.rlink index 6168332..538228d 100644 --- a/src/jtag/drivers/Makefile.rlink +++ b/src/jtag/drivers/Makefile.rlink @@ -1,20 +1,9 @@ -#*************************************************************************** -#* Copyright (C) 2008 Lou Deluxe * -#* lou.openocd012@fixit.nospammail.net * -#* * -#* 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, see <http://www.gnu.org/licenses/>. * -#*************************************************************************** +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Copyright (C) 2008 Lou Deluxe +# lou.openocd012@fixit.nospammail.net +# TOP = ../../.. INTERFACE_NAME = rlink diff --git a/src/jtag/drivers/OpenULINK/Makefile b/src/jtag/drivers/OpenULINK/Makefile index 9f6acc6..d65edcb 100644 --- a/src/jtag/drivers/OpenULINK/Makefile +++ b/src/jtag/drivers/OpenULINK/Makefile @@ -1,20 +1,9 @@ -############################################################################ -# Copyright (C) 2011 by Martin Schmoelzer # -# <martin.schmoelzer@student.tuwien.ac.at> # -# # -# 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, see <http://www.gnu.org/licenses/>. # -############################################################################ +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Copyright (C) 2011 by Martin Schmoelzer +# <martin.schmoelzer@student.tuwien.ac.at> +# # Define the name of our tools. Some distributions (e. g. Fedora) prefix # the SDCC executables, change this accordingly! diff --git a/src/jtag/drivers/OpenULINK/include/common.h b/src/jtag/drivers/OpenULINK/include/common.h index 56222fe..8f41fd0 100644 --- a/src/jtag/drivers/OpenULINK/include/common.h +++ b/src/jtag/drivers/OpenULINK/include/common.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef __COMMON_H diff --git a/src/jtag/drivers/OpenULINK/include/delay.h b/src/jtag/drivers/OpenULINK/include/delay.h index ed454be..be0d762 100644 --- a/src/jtag/drivers/OpenULINK/include/delay.h +++ b/src/jtag/drivers/OpenULINK/include/delay.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef __DELAY_H diff --git a/src/jtag/drivers/OpenULINK/include/io.h b/src/jtag/drivers/OpenULINK/include/io.h index 497c235..1330ebd 100644 --- a/src/jtag/drivers/OpenULINK/include/io.h +++ b/src/jtag/drivers/OpenULINK/include/io.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef __IO_H diff --git a/src/jtag/drivers/OpenULINK/include/jtag.h b/src/jtag/drivers/OpenULINK/include/jtag.h index fa492b9..1b5c3af 100644 --- a/src/jtag/drivers/OpenULINK/include/jtag.h +++ b/src/jtag/drivers/OpenULINK/include/jtag.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef __JTAG_H diff --git a/src/jtag/drivers/OpenULINK/include/main.h b/src/jtag/drivers/OpenULINK/include/main.h index 9e7dd5a86..d399c33 100644 --- a/src/jtag/drivers/OpenULINK/include/main.h +++ b/src/jtag/drivers/OpenULINK/include/main.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef __MAIN_H diff --git a/src/jtag/drivers/OpenULINK/include/msgtypes.h b/src/jtag/drivers/OpenULINK/include/msgtypes.h index f761a84..ae61ddb 100644 --- a/src/jtag/drivers/OpenULINK/include/msgtypes.h +++ b/src/jtag/drivers/OpenULINK/include/msgtypes.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /** diff --git a/src/jtag/drivers/OpenULINK/include/protocol.h b/src/jtag/drivers/OpenULINK/include/protocol.h index 0b6a7d6..91b5640 100644 --- a/src/jtag/drivers/OpenULINK/include/protocol.h +++ b/src/jtag/drivers/OpenULINK/include/protocol.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef __PROTOCOL_H diff --git a/src/jtag/drivers/OpenULINK/include/reg_ezusb.h b/src/jtag/drivers/OpenULINK/include/reg_ezusb.h index 4988367..6c38ab6 100644 --- a/src/jtag/drivers/OpenULINK/include/reg_ezusb.h +++ b/src/jtag/drivers/OpenULINK/include/reg_ezusb.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef REG_EZUSB_H diff --git a/src/jtag/drivers/OpenULINK/include/usb.h b/src/jtag/drivers/OpenULINK/include/usb.h index 9a261fe..30968b3 100644 --- a/src/jtag/drivers/OpenULINK/include/usb.h +++ b/src/jtag/drivers/OpenULINK/include/usb.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef __USB_H diff --git a/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51 b/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51 index f10ad48..f62508b 100644 --- a/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51 +++ b/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51 @@ -1,20 +1,9 @@ -;--------------------------------------------------------------------------; -; Copyright (C) 2011-2013 by Martin Schmoelzer ; -; <martin.schmoelzer@student.tuwien.ac.at> ; -; ; -; 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, see <http://www.gnu.org/licenses/>. ; -;--------------------------------------------------------------------------; +; SPDX-License-Identifier: GPL-2.0-or-later + +; +; Copyright (C) 2011-2013 by Martin Schmoelzer +; <martin.schmoelzer@student.tuwien.ac.at> +; .module JUMPTABLE .globl USB_AutoVector diff --git a/src/jtag/drivers/OpenULINK/src/delay.c b/src/jtag/drivers/OpenULINK/src/delay.c index 3260567..b68e814 100644 --- a/src/jtag/drivers/OpenULINK/src/delay.c +++ b/src/jtag/drivers/OpenULINK/src/delay.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #include "delay.h" diff --git a/src/jtag/drivers/OpenULINK/src/jtag.c b/src/jtag/drivers/OpenULINK/src/jtag.c index c76f034..c9253a3 100644 --- a/src/jtag/drivers/OpenULINK/src/jtag.c +++ b/src/jtag/drivers/OpenULINK/src/jtag.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #include "jtag.h" diff --git a/src/jtag/drivers/OpenULINK/src/main.c b/src/jtag/drivers/OpenULINK/src/main.c index f331c9e..51d3a3b 100644 --- a/src/jtag/drivers/OpenULINK/src/main.c +++ b/src/jtag/drivers/OpenULINK/src/main.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #include "main.h" diff --git a/src/jtag/drivers/OpenULINK/src/protocol.c b/src/jtag/drivers/OpenULINK/src/protocol.c index f8f84ed..b3d5622 100644 --- a/src/jtag/drivers/OpenULINK/src/protocol.c +++ b/src/jtag/drivers/OpenULINK/src/protocol.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #include "protocol.h" diff --git a/src/jtag/drivers/OpenULINK/src/usb.c b/src/jtag/drivers/OpenULINK/src/usb.c index 032b23b..408e212 100644 --- a/src/jtag/drivers/OpenULINK/src/usb.c +++ b/src/jtag/drivers/OpenULINK/src/usb.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011-2013 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /** diff --git a/src/jtag/drivers/am335xgpio.c b/src/jtag/drivers/am335xgpio.c index e04c44c..e641a4f 100644 --- a/src/jtag/drivers/am335xgpio.c +++ b/src/jtag/drivers/am335xgpio.c @@ -1,43 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2022 by Steve Marple, stevemarple@googlemail.com * * * * Based on bcm2835gpio.c and linuxgpiod.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include <jtag/adapter.h> #include <jtag/interface.h> #include <transport/transport.h> #include "bitbang.h" #include <sys/mman.h> -/* - * GPIO register base addresses. Values taken from "AM335x and AMIC110 Sitara +/* GPIO register base addresses. Values taken from "AM335x and AMIC110 Sitara * Processors Technical Reference Manual", Chapter 2 Memory Map. */ -#define AM335XGPIO_NUM_GPIO_PORTS 4 +#define AM335XGPIO_NUM_GPIO_PER_CHIP 32 +#define AM335XGPIO_NUM_GPIO_CHIPS 4 #define AM335XGPIO_GPIO0_HW_ADDR 0x44E07000 #define AM335XGPIO_GPIO1_HW_ADDR 0x4804C000 #define AM335XGPIO_GPIO2_HW_ADDR 0x481AC000 #define AM335XGPIO_GPIO3_HW_ADDR 0x481AE000 -/* 32-bit offsets from GPIO port base address. Values taken from "AM335x and +/* 32-bit offsets from GPIO chip base address. Values taken from "AM335x and * AMIC110 Sitara Processors Technical Reference Manual", Chapter 25 * General-Purpose Input/Output. */ @@ -47,34 +37,34 @@ #define AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET (0x190 / 4) #define AM335XGPIO_GPIO_SETDATAOUT_OFFSET (0x194 / 4) -/* GPIOs are integer values; need to map to a port module, and the pin within - * that module. GPIOs 0 to 31 map to GPIO0, 32 to 63 to GPIO1 etc. This scheme - * matches that used by Linux on the BeagleBone. - */ -#define AM335XGPIO_PORT_NUM(gpio_num) ((gpio_num) / 32) -#define AM335XGPIO_BIT_NUM(gpio_num) ((gpio_num) % 32) -#define AM335XGPIO_BIT_MASK(gpio_num) BIT(AM335XGPIO_BIT_NUM(gpio_num)) +#define AM335XGPIO_READ_REG(chip_num, offset) \ + (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset))) -#define AM335XGPIO_READ_REG(gpio_num, offset) \ - (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset))) +#define AM335XGPIO_WRITE_REG(chip_num, offset, value) \ + (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) = (value)) -#define AM335XGPIO_WRITE_REG(gpio_num, offset, value) \ - (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset)) = (value)) +#define AM335XGPIO_SET_REG_BITS(chip_num, offset, bit_mask) \ + (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) |= (bit_mask)) -#define AM335XGPIO_SET_REG_BITS(gpio_num, offset, bit_mask) \ - (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset)) |= (bit_mask)) +#define AM335XGPIO_CLEAR_REG_BITS(chip_num, offset, bit_mask) \ + (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) &= ~(bit_mask)) -#define AM335XGPIO_CLEAR_REG_BITS(gpio_num, offset, bit_mask) \ - (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset)) &= ~(bit_mask)) +#define AM335XGPIO_SET_INPUT(gpio_config) \ + AM335XGPIO_SET_REG_BITS((gpio_config)->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT((gpio_config)->gpio_num)) +#define AM335XGPIO_SET_OUTPUT(gpio_config) \ + AM335XGPIO_CLEAR_REG_BITS((gpio_config)->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT((gpio_config)->gpio_num)) +#define AM335XGPIO_SET_HIGH(gpio_config) \ + AM335XGPIO_WRITE_REG((gpio_config)->chip_num, AM335XGPIO_GPIO_SETDATAOUT_OFFSET, BIT((gpio_config)->gpio_num)) +#define AM335XGPIO_SET_LOW(gpio_config) \ + AM335XGPIO_WRITE_REG((gpio_config)->chip_num, AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, BIT((gpio_config)->gpio_num)) -enum amx335gpio_gpio_mode { +enum amx335gpio_initial_gpio_mode { AM335XGPIO_GPIO_MODE_INPUT, - AM335XGPIO_GPIO_MODE_OUTPUT, /* To set output mode but not state */ AM335XGPIO_GPIO_MODE_OUTPUT_LOW, AM335XGPIO_GPIO_MODE_OUTPUT_HIGH, }; -static const uint32_t am335xgpio_gpio_port_hw_addr[AM335XGPIO_NUM_GPIO_PORTS] = { +static const uint32_t am335xgpio_gpio_chip_hw_addr[AM335XGPIO_NUM_GPIO_CHIPS] = { AM335XGPIO_GPIO0_HW_ADDR, AM335XGPIO_GPIO1_HW_ADDR, AM335XGPIO_GPIO2_HW_ADDR, @@ -82,117 +72,151 @@ static const uint32_t am335xgpio_gpio_port_hw_addr[AM335XGPIO_NUM_GPIO_PORTS] = }; /* Memory-mapped address pointers */ -static volatile uint32_t *am335xgpio_gpio_port_mmap_addr[AM335XGPIO_NUM_GPIO_PORTS]; +static volatile uint32_t *am335xgpio_gpio_chip_mmap_addr[AM335XGPIO_NUM_GPIO_CHIPS]; static int dev_mem_fd; - -/* GPIO numbers for each signal. Negative values are invalid */ -static int tck_gpio = -1; -static enum amx335gpio_gpio_mode tck_gpio_mode; -static int tms_gpio = -1; -static enum amx335gpio_gpio_mode tms_gpio_mode; -static int tdi_gpio = -1; -static enum amx335gpio_gpio_mode tdi_gpio_mode; -static int tdo_gpio = -1; -static enum amx335gpio_gpio_mode tdo_gpio_mode; -static int trst_gpio = -1; -static enum amx335gpio_gpio_mode trst_gpio_mode; -static int srst_gpio = -1; -static enum amx335gpio_gpio_mode srst_gpio_mode; -static int swclk_gpio = -1; -static enum amx335gpio_gpio_mode swclk_gpio_mode; -static int swdio_gpio = -1; -static enum amx335gpio_gpio_mode swdio_gpio_mode; -static int swdio_dir_gpio = -1; -static enum amx335gpio_gpio_mode swdio_dir_gpio_mode; -static int led_gpio = -1; -static enum amx335gpio_gpio_mode led_gpio_mode = -1; - -static bool swdio_dir_is_active_high = true; /* Active state means output */ -static bool led_is_active_high = true; +static enum amx335gpio_initial_gpio_mode initial_gpio_mode[ADAPTER_GPIO_IDX_NUM]; /* Transition delay coefficients */ static int speed_coeff = 600000; static int speed_offset = 575; static unsigned int jtag_delay; -static int is_gpio_valid(int gpio_num) -{ - return gpio_num >= 0 && gpio_num < (32 * AM335XGPIO_NUM_GPIO_PORTS); -} +static const struct adapter_gpio_config *adapter_gpio_config; -static int get_gpio_value(int gpio_num) +static bool is_gpio_config_valid(const struct adapter_gpio_config *gpio_config) { - unsigned int shift = AM335XGPIO_BIT_NUM(gpio_num); - return (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_DATAIN_OFFSET) >> shift) & 1; + return gpio_config->chip_num >= 0 + && gpio_config->chip_num < AM335XGPIO_NUM_GPIO_CHIPS + && gpio_config->gpio_num >= 0 + && gpio_config->gpio_num < AM335XGPIO_NUM_GPIO_PER_CHIP; } -static void set_gpio_value(int gpio_num, int value) +static int get_gpio_value(const struct adapter_gpio_config *gpio_config) { - if (value) - AM335XGPIO_WRITE_REG(gpio_num, AM335XGPIO_GPIO_SETDATAOUT_OFFSET, AM335XGPIO_BIT_MASK(gpio_num)); - else - AM335XGPIO_WRITE_REG(gpio_num, AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, AM335XGPIO_BIT_MASK(gpio_num)); + unsigned int shift = gpio_config->gpio_num; + uint32_t value = AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_DATAIN_OFFSET); + value = (value >> shift) & 1; + return value ^ (gpio_config->active_low ? 1 : 0); } -static enum amx335gpio_gpio_mode get_gpio_mode(int gpio_num) +static void set_gpio_value(const struct adapter_gpio_config *gpio_config, int value) { - if (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_OE_OFFSET) & AM335XGPIO_BIT_MASK(gpio_num)) { - return AM335XGPIO_GPIO_MODE_INPUT; - } else { - /* Return output level too so that pin mode can be fully restored */ - if (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_DATAOUT_OFFSET) & AM335XGPIO_BIT_MASK(gpio_num)) - return AM335XGPIO_GPIO_MODE_OUTPUT_HIGH; + value = value ^ (gpio_config->active_low ? 1 : 0); + switch (gpio_config->drive) { + case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL: + if (value) + AM335XGPIO_SET_HIGH(gpio_config); else - return AM335XGPIO_GPIO_MODE_OUTPUT_LOW; + AM335XGPIO_SET_LOW(gpio_config); + /* For performance reasons assume the GPIO is already set as an output + * and therefore the call can be omitted here. + */ + break; + case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN: + if (value) { + AM335XGPIO_SET_INPUT(gpio_config); + } else { + AM335XGPIO_SET_LOW(gpio_config); + AM335XGPIO_SET_OUTPUT(gpio_config); + } + break; + case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE: + if (value) { + AM335XGPIO_SET_HIGH(gpio_config); + AM335XGPIO_SET_OUTPUT(gpio_config); + } else { + AM335XGPIO_SET_INPUT(gpio_config); + } + break; } } -static void set_gpio_mode(int gpio_num, enum amx335gpio_gpio_mode gpio_mode) +static enum amx335gpio_initial_gpio_mode get_gpio_mode(const struct adapter_gpio_config *gpio_config) { - if (gpio_mode == AM335XGPIO_GPIO_MODE_INPUT) { - AM335XGPIO_SET_REG_BITS(gpio_num, AM335XGPIO_GPIO_OE_OFFSET, AM335XGPIO_BIT_MASK(gpio_num)); - return; - } - - if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_LOW) - set_gpio_value(gpio_num, 0); - if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_HIGH) - set_gpio_value(gpio_num, 1); + if (AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_OE_OFFSET) & BIT(gpio_config->gpio_num)) + return AM335XGPIO_GPIO_MODE_INPUT; - if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT || - gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_LOW || - gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_HIGH) { - AM335XGPIO_CLEAR_REG_BITS(gpio_num, AM335XGPIO_GPIO_OE_OFFSET, AM335XGPIO_BIT_MASK(gpio_num)); - } + /* Return output level too so that pin mode can be fully restored */ + if (AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_DATAOUT_OFFSET) & BIT(gpio_config->gpio_num)) + return AM335XGPIO_GPIO_MODE_OUTPUT_HIGH; + return AM335XGPIO_GPIO_MODE_OUTPUT_LOW; } -static const char *get_gpio_mode_name(enum amx335gpio_gpio_mode gpio_mode) +static const char *get_gpio_mode_name(enum amx335gpio_initial_gpio_mode gpio_mode) { switch (gpio_mode) { case AM335XGPIO_GPIO_MODE_INPUT: return "input"; - case AM335XGPIO_GPIO_MODE_OUTPUT: - return "output"; case AM335XGPIO_GPIO_MODE_OUTPUT_LOW: return "output (low)"; case AM335XGPIO_GPIO_MODE_OUTPUT_HIGH: return "output (high)"; - default: - return "unknown"; + } + return "unknown"; +} + +static void initialize_gpio(enum adapter_gpio_config_index idx) +{ + if (!is_gpio_config_valid(&adapter_gpio_config[idx])) + return; + + initial_gpio_mode[idx] = get_gpio_mode(&adapter_gpio_config[idx]); + LOG_DEBUG("saved GPIO mode for %s (GPIO %d %d): %s", + adapter_gpio_get_name(idx), adapter_gpio_config[idx].chip_num, adapter_gpio_config[idx].gpio_num, + get_gpio_mode_name(initial_gpio_mode[idx])); + + if (adapter_gpio_config[idx].pull != ADAPTER_GPIO_PULL_NONE) { + LOG_WARNING("am335xgpio does not support pull-up or pull-down settings (signal %s)", + adapter_gpio_get_name(idx)); + } + + switch (adapter_gpio_config[idx].init_state) { + case ADAPTER_GPIO_INIT_STATE_INACTIVE: + set_gpio_value(&adapter_gpio_config[idx], 0); + break; + case ADAPTER_GPIO_INIT_STATE_ACTIVE: + set_gpio_value(&adapter_gpio_config[idx], 1); + break; + case ADAPTER_GPIO_INIT_STATE_INPUT: + AM335XGPIO_SET_INPUT(&adapter_gpio_config[idx]); + break; + } + + /* Direction for non push-pull is already set by set_gpio_value() */ + if (adapter_gpio_config[idx].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL) + AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]); +} + +static void restore_gpio(enum adapter_gpio_config_index idx) +{ + if (is_gpio_config_valid(&adapter_gpio_config[idx])) { + switch (initial_gpio_mode[idx]) { + case AM335XGPIO_GPIO_MODE_INPUT: + AM335XGPIO_SET_INPUT(&adapter_gpio_config[idx]); + break; + case AM335XGPIO_GPIO_MODE_OUTPUT_LOW: + AM335XGPIO_SET_LOW(&adapter_gpio_config[idx]); + AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]); + break; + case AM335XGPIO_GPIO_MODE_OUTPUT_HIGH: + AM335XGPIO_SET_HIGH(&adapter_gpio_config[idx]); + AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]); + break; + } } } static bb_value_t am335xgpio_read(void) { - return get_gpio_value(tdo_gpio) ? BB_HIGH : BB_LOW; + return get_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDO]) ? BB_HIGH : BB_LOW; } static int am335xgpio_write(int tck, int tms, int tdi) { - set_gpio_value(tdi_gpio, tdi); - set_gpio_value(tms_gpio, tms); - set_gpio_value(tck_gpio, tck); /* Write clock last */ + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDI], tdi); + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TMS], tms); + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TCK], tck); /* Write clock last */ for (unsigned int i = 0; i < jtag_delay; ++i) asm volatile (""); @@ -202,8 +226,8 @@ static int am335xgpio_write(int tck, int tms, int tdi) static int am335xgpio_swd_write(int swclk, int swdio) { - set_gpio_value(swdio_gpio, swdio); - set_gpio_value(swclk_gpio, swclk); /* Write clock last */ + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO], swdio); + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK], swclk); /* Write clock last */ for (unsigned int i = 0; i < jtag_delay; ++i) asm volatile (""); @@ -214,49 +238,45 @@ static int am335xgpio_swd_write(int swclk, int swdio) /* (1) assert or (0) deassert reset lines */ static int am335xgpio_reset(int trst, int srst) { - /* assume active low */ - if (is_gpio_valid(srst_gpio)) { - if (jtag_get_reset_config() & RESET_SRST_PUSH_PULL) - set_gpio_mode(srst_gpio, srst ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_OUTPUT_HIGH); - else - set_gpio_mode(srst_gpio, srst ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_INPUT); - } + /* As the "adapter reset_config" command keeps the srst and trst gpio drive + * mode settings in sync we can use our standard set_gpio_value() function + * that honours drive mode and active low. + */ + if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SRST])) + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SRST], srst); - /* assume active low */ - if (is_gpio_valid(trst_gpio)) { - if (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN) - set_gpio_mode(trst_gpio, trst ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_INPUT); - else - set_gpio_mode(trst_gpio, trst ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_OUTPUT_HIGH); - } + if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TRST])) + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TRST], trst); - LOG_DEBUG("am335xgpio_reset(%d, %d), trst_gpio: %d (%s), srst_gpio: %d (%s)", + LOG_DEBUG("am335xgpio_reset(%d, %d), trst_gpio: %d %d, srst_gpio: %d %d", trst, srst, - trst_gpio, get_gpio_mode_name(get_gpio_mode(trst_gpio)), - srst_gpio, get_gpio_mode_name(get_gpio_mode(srst_gpio))); + adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].gpio_num, + adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].gpio_num); return ERROR_OK; } static void am335xgpio_swdio_drive(bool is_output) { if (is_output) { - set_gpio_value(swdio_dir_gpio, swdio_dir_is_active_high ? 1 : 0); - set_gpio_mode(swdio_gpio, AM335XGPIO_GPIO_MODE_OUTPUT); + if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR])) + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 1); + AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]); } else { - set_gpio_mode(swdio_gpio, AM335XGPIO_GPIO_MODE_INPUT); - set_gpio_value(swdio_dir_gpio, swdio_dir_is_active_high ? 0 : 1); + AM335XGPIO_SET_INPUT(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]); + if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR])) + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 0); } } static int am335xgpio_swdio_read(void) { - return get_gpio_value(swdio_gpio); + return get_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]); } static int am335xgpio_blink(int on) { - if (is_gpio_valid(led_gpio)) - set_gpio_value(led_gpio, (!on ^ led_is_active_high) ? 1 : 0); + if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_LED])) + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_LED], on); return ERROR_OK; } @@ -294,144 +314,6 @@ static int am335xgpio_speed(int speed) return ERROR_OK; } -COMMAND_HANDLER(am335xgpio_handle_jtag_gpionums) -{ - if (CMD_ARGC == 4) { - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio); - } else if (CMD_ARGC != 0) { - return ERROR_COMMAND_SYNTAX_ERROR; - } - - command_print(CMD, "AM335x GPIO config: tck = %d, tms = %d, tdi = %d, tdo = %d", - tck_gpio, tms_gpio, tdi_gpio, tdo_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_tck) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio); - - command_print(CMD, "AM335x GPIO config: tck = %d", tck_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_tms) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio); - - command_print(CMD, "AM335x GPIO config: tms = %d", tms_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_tdo) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio); - - command_print(CMD, "AM335x GPIO config: tdo = %d", tdo_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_tdi) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio); - - command_print(CMD, "AM335x GPIO config: tdi = %d", tdi_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_srst) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio); - - command_print(CMD, "AM335x GPIO config: srst = %d", srst_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_trst) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio); - - command_print(CMD, "AM335x GPIO config: trst = %d", trst_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_swd_gpionums) -{ - if (CMD_ARGC == 2) { - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio); - } else if (CMD_ARGC != 0) { - return ERROR_COMMAND_SYNTAX_ERROR; - } - - command_print(CMD, "AM335x GPIO config: swclk = %d, swdio = %d", swclk_gpio, swdio_gpio); - - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_swd_gpionum_swclk) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio); - - command_print(CMD, "AM335x GPIO config: swclk = %d", swclk_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_swd_gpionum_swdio) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio); - - command_print(CMD, "AM335x GPIO config: swdio = %d", swdio_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_swd_gpionum_swdio_dir) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_dir_gpio); - - command_print(CMD, "AM335x GPIO config: swdio_dir = %d", swdio_dir_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_swd_dir_output_state) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_BOOL(CMD_ARGV[0], swdio_dir_is_active_high, "high", "low"); - - command_print(CMD, "AM335x GPIO config: swdio_dir_output_state = %s", swdio_dir_is_active_high ? "high" : "low"); - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_gpionum_led) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], led_gpio); - - command_print(CMD, "AM335x GPIO config: led = %d", led_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_led_on_state) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_BOOL(CMD_ARGV[0], led_is_active_high, "high", "low"); - - command_print(CMD, "AM335x GPIO config: led_on_state = %s", led_is_active_high ? "high" : "low"); - return ERROR_OK; -} - COMMAND_HANDLER(am335xgpio_handle_speed_coeffs) { if (CMD_ARGC == 2) { @@ -446,104 +328,6 @@ COMMAND_HANDLER(am335xgpio_handle_speed_coeffs) static const struct command_registration am335xgpio_subcommand_handlers[] = { { - .name = "jtag_nums", - .handler = am335xgpio_handle_jtag_gpionums, - .mode = COMMAND_CONFIG, - .help = "gpio numbers for tck, tms, tdi, tdo (in that order).", - .usage = "[tck tms tdi tdo]", - }, - { - .name = "tck_num", - .handler = am335xgpio_handle_jtag_gpionum_tck, - .mode = COMMAND_CONFIG, - .help = "gpio number for tck.", - .usage = "[tck]", - }, - { - .name = "tms_num", - .handler = am335xgpio_handle_jtag_gpionum_tms, - .mode = COMMAND_CONFIG, - .help = "gpio number for tms.", - .usage = "[tms]", - }, - { - .name = "tdo_num", - .handler = am335xgpio_handle_jtag_gpionum_tdo, - .mode = COMMAND_CONFIG, - .help = "gpio number for tdo.", - .usage = "[tdo]", - }, - { - .name = "tdi_num", - .handler = am335xgpio_handle_jtag_gpionum_tdi, - .mode = COMMAND_CONFIG, - .help = "gpio number for tdi.", - .usage = "[tdi]", - }, - { - .name = "swd_nums", - .handler = am335xgpio_handle_swd_gpionums, - .mode = COMMAND_CONFIG, - .help = "gpio numbers for swclk, swdio (in that order).", - .usage = "[swclk swdio]", - }, - { - .name = "swclk_num", - .handler = am335xgpio_handle_swd_gpionum_swclk, - .mode = COMMAND_CONFIG, - .help = "gpio number for swclk.", - .usage = "[swclk]", - }, - { - .name = "swdio_num", - .handler = am335xgpio_handle_swd_gpionum_swdio, - .mode = COMMAND_CONFIG, - .help = "gpio number for swdio.", - .usage = "[swdio]", - }, - { - .name = "swdio_dir_num", - .handler = am335xgpio_handle_swd_gpionum_swdio_dir, - .mode = COMMAND_CONFIG, - .help = "gpio number for swdio direction control pin.", - .usage = "[swdio_dir]", - }, - { - .name = "swdio_dir_output_state", - .handler = am335xgpio_handle_swd_dir_output_state, - .mode = COMMAND_CONFIG, - .help = "required state for swdio_dir pin to select SWDIO buffer to be output.", - .usage = "['off'|'on']", - }, - { - .name = "srst_num", - .handler = am335xgpio_handle_jtag_gpionum_srst, - .mode = COMMAND_CONFIG, - .help = "gpio number for srst.", - .usage = "[srst]", - }, - { - .name = "trst_num", - .handler = am335xgpio_handle_jtag_gpionum_trst, - .mode = COMMAND_CONFIG, - .help = "gpio number for trst.", - .usage = "[trst]", - }, - { - .name = "led_num", - .handler = am335xgpio_handle_gpionum_led, - .mode = COMMAND_CONFIG, - .help = "gpio number for led.", - .usage = "[led]", - }, - { - .name = "led_on_state", - .handler = am335xgpio_handle_led_on_state, - .mode = COMMAND_CONFIG, - .help = "required state for led pin to turn on LED.", - .usage = "['off'|'on']", - }, - { .name = "speed_coeffs", .handler = am335xgpio_handle_speed_coeffs, .mode = COMMAND_CONFIG, @@ -573,32 +357,40 @@ static struct jtag_interface am335xgpio_interface = { static bool am335xgpio_jtag_mode_possible(void) { - if (!is_gpio_valid(tck_gpio)) + if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TCK])) return false; - if (!is_gpio_valid(tms_gpio)) + if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TMS])) return false; - if (!is_gpio_valid(tdi_gpio)) + if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDI])) return false; - if (!is_gpio_valid(tdo_gpio)) + if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDO])) return false; return true; } static bool am335xgpio_swd_mode_possible(void) { - if (!is_gpio_valid(swclk_gpio)) + if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK])) return false; - if (!is_gpio_valid(swdio_gpio)) + if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO])) return false; return true; } -static int am335xgpio_init(void) +static void am335xgpio_munmap(void) { - bitbang_interface = &am335xgpio_bitbang; + for (unsigned int i = 0; i < AM335XGPIO_NUM_GPIO_CHIPS && am335xgpio_gpio_chip_mmap_addr[i] != MAP_FAILED; ++i) + if (munmap((void *)am335xgpio_gpio_chip_mmap_addr[i], sysconf(_SC_PAGE_SIZE)) < 0) + LOG_ERROR("Cannot unmap GPIO memory for chip %d: %s", i, strerror(errno)); +} +static int am335xgpio_init(void) +{ LOG_INFO("AM335x GPIO JTAG/SWD bitbang driver"); + bitbang_interface = &am335xgpio_bitbang; + adapter_gpio_config = adapter_gpio_get_config(); + if (transport_is_jtag() && !am335xgpio_jtag_mode_possible()) { LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode"); return ERROR_JTAG_INIT_FAILED; @@ -619,99 +411,81 @@ static int am335xgpio_init(void) return ERROR_JTAG_INIT_FAILED; } - for (unsigned int i = 0; i < AM335XGPIO_NUM_GPIO_PORTS; ++i) { - am335xgpio_gpio_port_mmap_addr[i] = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE, - MAP_SHARED, dev_mem_fd, am335xgpio_gpio_port_hw_addr[i]); + for (unsigned int i = 0; i < AM335XGPIO_NUM_GPIO_CHIPS; ++i) { + am335xgpio_gpio_chip_mmap_addr[i] = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE, + MAP_SHARED, dev_mem_fd, am335xgpio_gpio_chip_hw_addr[i]); - if (am335xgpio_gpio_port_mmap_addr[i] == MAP_FAILED) { + if (am335xgpio_gpio_chip_mmap_addr[i] == MAP_FAILED) { LOG_ERROR("mmap: %s", strerror(errno)); + am335xgpio_munmap(); close(dev_mem_fd); return ERROR_JTAG_INIT_FAILED; } } + close(dev_mem_fd); - /* - * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST as outputs. - * Drive TDI and TCK low, and TMS high. + /* Configure JTAG/SWD signals. Default directions and initial states are handled + * by adapter.c and "adapter gpio" command. */ if (transport_is_jtag()) { - tdo_gpio_mode = get_gpio_mode(tdo_gpio); - tdi_gpio_mode = get_gpio_mode(tdi_gpio); - tck_gpio_mode = get_gpio_mode(tck_gpio); - tms_gpio_mode = get_gpio_mode(tms_gpio); - LOG_DEBUG("saved GPIO mode for tdo (GPIO #%d): %s", tdo_gpio, get_gpio_mode_name(tdo_gpio_mode)); - LOG_DEBUG("saved GPIO mode for tdi (GPIO #%d): %s", tdi_gpio, get_gpio_mode_name(tdi_gpio_mode)); - LOG_DEBUG("saved GPIO mode for tck (GPIO #%d): %s", tck_gpio, get_gpio_mode_name(tck_gpio_mode)); - LOG_DEBUG("saved GPIO mode for tms (GPIO #%d): %s", tms_gpio, get_gpio_mode_name(tms_gpio_mode)); - - set_gpio_mode(tdo_gpio, AM335XGPIO_GPIO_MODE_INPUT); - set_gpio_mode(tdi_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_LOW); - set_gpio_mode(tms_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_HIGH); - set_gpio_mode(tck_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_LOW); - - if (is_gpio_valid(trst_gpio)) { - trst_gpio_mode = get_gpio_mode(trst_gpio); - LOG_DEBUG("saved GPIO mode for trst (GPIO #%d): %s", trst_gpio, get_gpio_mode_name(trst_gpio_mode)); - } + initialize_gpio(ADAPTER_GPIO_IDX_TDO); + initialize_gpio(ADAPTER_GPIO_IDX_TDI); + initialize_gpio(ADAPTER_GPIO_IDX_TMS); + initialize_gpio(ADAPTER_GPIO_IDX_TCK); + initialize_gpio(ADAPTER_GPIO_IDX_TRST); } if (transport_is_swd()) { - swclk_gpio_mode = get_gpio_mode(swclk_gpio); - swdio_gpio_mode = get_gpio_mode(swdio_gpio); - LOG_DEBUG("saved GPIO mode for swclk (GPIO #%d): %s", swclk_gpio, get_gpio_mode_name(swclk_gpio_mode)); - LOG_DEBUG("saved GPIO mode for swdio (GPIO #%d): %s", swdio_gpio, get_gpio_mode_name(swdio_gpio_mode)); - if (is_gpio_valid(swdio_dir_gpio)) { - swdio_dir_gpio_mode = get_gpio_mode(swdio_dir_gpio); - LOG_DEBUG("saved GPIO mode for swdio_dir (GPIO #%d): %s", - swdio_dir_gpio, get_gpio_mode_name(swdio_dir_gpio_mode)); - set_gpio_mode(swdio_dir_gpio, - swdio_dir_is_active_high ? AM335XGPIO_GPIO_MODE_OUTPUT_HIGH : AM335XGPIO_GPIO_MODE_OUTPUT_LOW); - + /* swdio and its buffer should be initialized in the order that prevents + * two outputs from being connected together. This will occur if the + * swdio GPIO of the AM335x is configured as an output while its + * external buffer is configured to send the swdio signal from the + * target to the AM335x. + */ + if (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].init_state == ADAPTER_GPIO_INIT_STATE_INPUT) { + initialize_gpio(ADAPTER_GPIO_IDX_SWDIO); + initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR); + } else { + initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR); + initialize_gpio(ADAPTER_GPIO_IDX_SWDIO); } - set_gpio_mode(swdio_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_LOW); - set_gpio_mode(swclk_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_LOW); - } - if (is_gpio_valid(srst_gpio)) { - srst_gpio_mode = get_gpio_mode(srst_gpio); - LOG_DEBUG("saved GPIO mode for srst (GPIO #%d): %s", srst_gpio, get_gpio_mode_name(srst_gpio_mode)); + initialize_gpio(ADAPTER_GPIO_IDX_SWCLK); } - if (is_gpio_valid(led_gpio)) { - led_gpio_mode = get_gpio_mode(led_gpio); - LOG_DEBUG("saved GPIO mode for led (GPIO #%d): %s", led_gpio, get_gpio_mode_name(led_gpio_mode)); - set_gpio_mode(led_gpio, - led_is_active_high ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_OUTPUT_HIGH); - } + initialize_gpio(ADAPTER_GPIO_IDX_SRST); + initialize_gpio(ADAPTER_GPIO_IDX_LED); - /* Set GPIO modes for TRST and SRST and make both inactive */ - am335xgpio_reset(0, 0); return ERROR_OK; } static int am335xgpio_quit(void) { if (transport_is_jtag()) { - set_gpio_mode(tdo_gpio, tdo_gpio_mode); - set_gpio_mode(tdi_gpio, tdi_gpio_mode); - set_gpio_mode(tck_gpio, tck_gpio_mode); - set_gpio_mode(tms_gpio, tms_gpio_mode); - if (is_gpio_valid(trst_gpio)) - set_gpio_mode(trst_gpio, trst_gpio_mode); + restore_gpio(ADAPTER_GPIO_IDX_TDO); + restore_gpio(ADAPTER_GPIO_IDX_TDI); + restore_gpio(ADAPTER_GPIO_IDX_TMS); + restore_gpio(ADAPTER_GPIO_IDX_TCK); + restore_gpio(ADAPTER_GPIO_IDX_TRST); } if (transport_is_swd()) { - set_gpio_mode(swclk_gpio, swclk_gpio_mode); - set_gpio_mode(swdio_gpio, swdio_gpio_mode); - if (is_gpio_valid(swdio_dir_gpio)) - set_gpio_mode(swdio_dir_gpio, swdio_dir_gpio_mode); + /* Restore swdio/swdio_dir to their initial modes, even if that means + * connecting two outputs. Begin by making swdio an input so that the + * current and final states of swdio and swdio_dir do not have to be + * considered to calculate the safe restoration order. + */ + AM335XGPIO_SET_INPUT(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]); + restore_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR); + restore_gpio(ADAPTER_GPIO_IDX_SWDIO); + + restore_gpio(ADAPTER_GPIO_IDX_SWCLK); } - if (is_gpio_valid(srst_gpio)) - set_gpio_mode(srst_gpio, srst_gpio_mode); + restore_gpio(ADAPTER_GPIO_IDX_SRST); + restore_gpio(ADAPTER_GPIO_IDX_LED); - if (is_gpio_valid(led_gpio)) - set_gpio_mode(led_gpio, led_gpio_mode); + am335xgpio_munmap(); return ERROR_OK; } diff --git a/src/jtag/drivers/amt_jtagaccel.c b/src/jtag/drivers/amt_jtagaccel.c index c204f23..a4c8f32 100644 --- a/src/jtag/drivers/amt_jtagaccel.c +++ b/src/jtag/drivers/amt_jtagaccel.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/arm-jtag-ew.c b/src/jtag/drivers/arm-jtag-ew.c index 7033789..a3e9e17 100644 --- a/src/jtag/drivers/arm-jtag-ew.c +++ b/src/jtag/drivers/arm-jtag-ew.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by Dimitar Dimitrov <dinuxbg@gmail.com> * * based on Dominic Rath's and Benedikt Sauter's usbprog.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/at91rm9200.c b/src/jtag/drivers/at91rm9200.c index 7bb5d85..08daa00 100644 --- a/src/jtag/drivers/at91rm9200.c +++ b/src/jtag/drivers/at91rm9200.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Anders Larsen * * al@alarsen.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c index 22d237f..bd44fca 100644 --- a/src/jtag/drivers/bcm2835gpio.c +++ b/src/jtag/drivers/bcm2835gpio.c @@ -1,28 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 by Paul Fertser, fercerpav@gmail.com * * * * Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au * * Based on at91rm9200.c (c) Anders Larsen * * and RPi GPIO examples by Gert van Loo & Dom * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include <jtag/adapter.h> #include <jtag/interface.h> #include <transport/transport.h> #include "bitbang.h" @@ -35,79 +25,142 @@ uint32_t bcm2835_peri_base = 0x20000000; #define BCM2835_PADS_GPIO_0_27 (bcm2835_peri_base + 0x100000) #define BCM2835_PADS_GPIO_0_27_OFFSET (0x2c / 4) +/* See "GPIO Function Select Registers (GPFSELn)" in "Broadcom BCM2835 ARM Peripherals" datasheet. */ +#define BCM2835_GPIO_MODE_INPUT 0 +#define BCM2835_GPIO_MODE_OUTPUT 1 + /* GPIO setup macros */ #define MODE_GPIO(g) (*(pio_base+((g)/10))>>(((g)%10)*3) & 7) #define INP_GPIO(g) do { *(pio_base+((g)/10)) &= ~(7<<(((g)%10)*3)); } while (0) #define SET_MODE_GPIO(g, m) do { /* clear the mode bits first, then set as necessary */ \ INP_GPIO(g); \ *(pio_base+((g)/10)) |= ((m)<<(((g)%10)*3)); } while (0) -#define OUT_GPIO(g) SET_MODE_GPIO(g, 1) +#define OUT_GPIO(g) SET_MODE_GPIO(g, BCM2835_GPIO_MODE_OUTPUT) #define GPIO_SET (*(pio_base+7)) /* sets bits which are 1, ignores bits which are 0 */ #define GPIO_CLR (*(pio_base+10)) /* clears bits which are 1, ignores bits which are 0 */ #define GPIO_LEV (*(pio_base+13)) /* current level of the pin */ static int dev_mem_fd; -static volatile uint32_t *pio_base; - -static bb_value_t bcm2835gpio_read(void); -static int bcm2835gpio_write(int tck, int tms, int tdi); - -static int bcm2835_swdio_read(void); -static void bcm2835_swdio_drive(bool is_output); -static int bcm2835gpio_swd_write(int swclk, int swdio); - -static int bcm2835gpio_init(void); -static int bcm2835gpio_quit(void); - -static struct bitbang_interface bcm2835gpio_bitbang = { - .read = bcm2835gpio_read, - .write = bcm2835gpio_write, - .swdio_read = bcm2835_swdio_read, - .swdio_drive = bcm2835_swdio_drive, - .swd_write = bcm2835gpio_swd_write, - .blink = NULL -}; - -/* GPIO numbers for each signal. Negative values are invalid */ -static int tck_gpio = -1; -static int tck_gpio_mode; -static int tms_gpio = -1; -static int tms_gpio_mode; -static int tdi_gpio = -1; -static int tdi_gpio_mode; -static int tdo_gpio = -1; -static int tdo_gpio_mode; -static int trst_gpio = -1; -static int trst_gpio_mode; -static int srst_gpio = -1; -static int srst_gpio_mode; -static int swclk_gpio = -1; -static int swclk_gpio_mode; -static int swdio_gpio = -1; -static int swdio_gpio_mode; -static int swdio_dir_gpio = -1; -static int swdio_dir_gpio_mode; +static volatile uint32_t *pio_base = MAP_FAILED; +static volatile uint32_t *pads_base = MAP_FAILED; /* Transition delay coefficients */ static int speed_coeff = 113714; static int speed_offset = 28; static unsigned int jtag_delay; -static int is_gpio_valid(int gpio) +static const struct adapter_gpio_config *adapter_gpio_config; +static struct initial_gpio_state { + unsigned int mode; + unsigned int output_level; +} initial_gpio_state[ADAPTER_GPIO_IDX_NUM]; +static uint32_t initial_drive_strength_etc; + +static bool is_gpio_config_valid(enum adapter_gpio_config_index idx) +{ + /* Only chip 0 is supported, accept unset value (-1) too */ + return adapter_gpio_config[idx].chip_num >= -1 + && adapter_gpio_config[idx].chip_num <= 0 + && adapter_gpio_config[idx].gpio_num >= 0 + && adapter_gpio_config[idx].gpio_num <= 31; +} + +static void set_gpio_value(const struct adapter_gpio_config *gpio_config, int value) +{ + value = value ^ (gpio_config->active_low ? 1 : 0); + switch (gpio_config->drive) { + case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL: + if (value) + GPIO_SET = 1 << gpio_config->gpio_num; + else + GPIO_CLR = 1 << gpio_config->gpio_num; + /* For performance reasons assume the GPIO is already set as an output + * and therefore the call can be omitted here. + */ + break; + case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN: + if (value) { + INP_GPIO(gpio_config->gpio_num); + } else { + GPIO_CLR = 1 << gpio_config->gpio_num; + OUT_GPIO(gpio_config->gpio_num); + } + break; + case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE: + if (value) { + GPIO_SET = 1 << gpio_config->gpio_num; + OUT_GPIO(gpio_config->gpio_num); + } else { + INP_GPIO(gpio_config->gpio_num); + } + break; + } +} + +static void restore_gpio(enum adapter_gpio_config_index idx) +{ + if (is_gpio_config_valid(idx)) { + SET_MODE_GPIO(adapter_gpio_config[idx].gpio_num, initial_gpio_state[idx].mode); + if (initial_gpio_state[idx].mode == BCM2835_GPIO_MODE_OUTPUT) { + if (initial_gpio_state[idx].output_level) + GPIO_SET = 1 << adapter_gpio_config[idx].gpio_num; + else + GPIO_CLR = 1 << adapter_gpio_config[idx].gpio_num; + } + } +} + +static void initialize_gpio(enum adapter_gpio_config_index idx) { - return gpio >= 0 && gpio <= 31; + if (!is_gpio_config_valid(idx)) + return; + + initial_gpio_state[idx].mode = MODE_GPIO(adapter_gpio_config[idx].gpio_num); + unsigned int shift = adapter_gpio_config[idx].gpio_num; + initial_gpio_state[idx].output_level = (GPIO_LEV >> shift) & 1; + LOG_DEBUG("saved GPIO mode for %s (GPIO %d %d): %d", + adapter_gpio_get_name(idx), adapter_gpio_config[idx].chip_num, adapter_gpio_config[idx].gpio_num, + initial_gpio_state[idx].mode); + + if (adapter_gpio_config[idx].pull != ADAPTER_GPIO_PULL_NONE) { + LOG_WARNING("BCM2835 GPIO does not support pull-up or pull-down settings (signal %s)", + adapter_gpio_get_name(idx)); + } + + switch (adapter_gpio_config[idx].init_state) { + case ADAPTER_GPIO_INIT_STATE_INACTIVE: + set_gpio_value(&adapter_gpio_config[idx], 0); + break; + case ADAPTER_GPIO_INIT_STATE_ACTIVE: + set_gpio_value(&adapter_gpio_config[idx], 1); + break; + case ADAPTER_GPIO_INIT_STATE_INPUT: + INP_GPIO(adapter_gpio_config[idx].gpio_num); + break; + } + + /* Direction for non push-pull is already set by set_gpio_value() */ + if (adapter_gpio_config[idx].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL) + OUT_GPIO(adapter_gpio_config[idx].gpio_num); } static bb_value_t bcm2835gpio_read(void) { - return (GPIO_LEV & 1<<tdo_gpio) ? BB_HIGH : BB_LOW; + unsigned int shift = adapter_gpio_config[ADAPTER_GPIO_IDX_TDO].gpio_num; + uint32_t value = (GPIO_LEV >> shift) & 1; + return value ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_TDO].active_low ? BB_HIGH : BB_LOW); + } static int bcm2835gpio_write(int tck, int tms, int tdi) { - uint32_t set = tck<<tck_gpio | tms<<tms_gpio | tdi<<tdi_gpio; - uint32_t clear = !tck<<tck_gpio | !tms<<tms_gpio | !tdi<<tdi_gpio; + uint32_t set = tck << adapter_gpio_config[ADAPTER_GPIO_IDX_TCK].gpio_num | + tms << adapter_gpio_config[ADAPTER_GPIO_IDX_TMS].gpio_num | + tdi << adapter_gpio_config[ADAPTER_GPIO_IDX_TDI].gpio_num; + uint32_t clear = !tck << adapter_gpio_config[ADAPTER_GPIO_IDX_TCK].gpio_num | + !tms << adapter_gpio_config[ADAPTER_GPIO_IDX_TMS].gpio_num | + !tdi << adapter_gpio_config[ADAPTER_GPIO_IDX_TDI].gpio_num; GPIO_SET = set; GPIO_CLR = clear; @@ -118,10 +171,16 @@ static int bcm2835gpio_write(int tck, int tms, int tdi) return ERROR_OK; } -static int bcm2835gpio_swd_write(int swclk, int swdio) +/* Requires push-pull drive mode for swclk and swdio */ +static int bcm2835gpio_swd_write_fast(int swclk, int swdio) { - uint32_t set = swclk << swclk_gpio | swdio << swdio_gpio; - uint32_t clear = !swclk << swclk_gpio | !swdio << swdio_gpio; + swclk = swclk ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].active_low ? 1 : 0); + swdio = swdio ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].active_low ? 1 : 0); + + uint32_t set = swclk << adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].gpio_num | + swdio << adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num; + uint32_t clear = !swclk << adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].gpio_num | + !swdio << adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num; GPIO_SET = set; GPIO_CLR = clear; @@ -132,55 +191,62 @@ static int bcm2835gpio_swd_write(int swclk, int swdio) return ERROR_OK; } -/* (1) assert or (0) deassert reset lines */ -static int bcm2835gpio_reset(int trst, int srst) +/* Generic mode that works for open-drain/open-source drive modes, but slower */ +static int bcm2835gpio_swd_write_generic(int swclk, int swdio) { - uint32_t set = 0; - uint32_t clear = 0; + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO], swdio); + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK], swclk); /* Write clock last */ - if (is_gpio_valid(trst_gpio)) { - set |= !trst<<trst_gpio; - clear |= trst<<trst_gpio; - } + for (unsigned int i = 0; i < jtag_delay; ++i) + asm volatile (""); - if (is_gpio_valid(srst_gpio)) { - set |= !srst<<srst_gpio; - clear |= srst<<srst_gpio; - } + return ERROR_OK; +} - GPIO_SET = set; - GPIO_CLR = clear; +/* (1) assert or (0) deassert reset lines */ +static int bcm2835gpio_reset(int trst, int srst) +{ + /* As the "adapter reset_config" command keeps the srst and trst gpio drive + * mode settings in sync we can use our standard set_gpio_value() function + * that honours drive mode and active low. + */ + if (is_gpio_config_valid(ADAPTER_GPIO_IDX_SRST)) + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SRST], srst); + if (is_gpio_config_valid(ADAPTER_GPIO_IDX_TRST)) + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TRST], trst); + + LOG_DEBUG("BCM2835 GPIO: bcm2835gpio_reset(%d, %d), trst_gpio: %d %d, srst_gpio: %d %d", + trst, srst, + adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].gpio_num, + adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].gpio_num); return ERROR_OK; } static void bcm2835_swdio_drive(bool is_output) { - if (is_gpio_valid(swdio_dir_gpio)) { - if (is_output) { - GPIO_SET = 1 << swdio_dir_gpio; - OUT_GPIO(swdio_gpio); - } else { - INP_GPIO(swdio_gpio); - GPIO_CLR = 1 << swdio_dir_gpio; - } + if (is_output) { + if (is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO_DIR)) + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 1); + OUT_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num); } else { - if (is_output) - OUT_GPIO(swdio_gpio); - else - INP_GPIO(swdio_gpio); + INP_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num); + if (is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO_DIR)) + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 0); } } static int bcm2835_swdio_read(void) { - return !!(GPIO_LEV & 1 << swdio_gpio); + unsigned int shift = adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num; + uint32_t value = (GPIO_LEV >> shift) & 1; + return value ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].active_low ? 1 : 0); } static int bcm2835gpio_khz(int khz, int *jtag_speed) { if (!khz) { - LOG_DEBUG("RCLK not supported"); + LOG_DEBUG("BCM2835 GPIO: RCLK not supported"); return ERROR_FAIL; } *jtag_speed = speed_coeff/khz - speed_offset; @@ -201,121 +267,6 @@ static int bcm2835gpio_speed(int speed) return ERROR_OK; } -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionums) -{ - if (CMD_ARGC == 4) { - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio); - } else if (CMD_ARGC != 0) { - return ERROR_COMMAND_SYNTAX_ERROR; - } - - command_print(CMD, - "BCM2835 GPIO config: tck = %d, tms = %d, tdi = %d, tdo = %d", - tck_gpio, tms_gpio, tdi_gpio, tdo_gpio); - - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tck) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio); - - command_print(CMD, "BCM2835 GPIO config: tck = %d", tck_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tms) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio); - - command_print(CMD, "BCM2835 GPIO config: tms = %d", tms_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdo) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio); - - command_print(CMD, "BCM2835 GPIO config: tdo = %d", tdo_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdi) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio); - - command_print(CMD, "BCM2835 GPIO config: tdi = %d", tdi_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_srst) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio); - - command_print(CMD, "BCM2835 GPIO config: srst = %d", srst_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_trst) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio); - - command_print(CMD, "BCM2835 GPIO config: trst = %d", trst_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionums) -{ - if (CMD_ARGC == 2) { - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio); - } else if (CMD_ARGC != 0) { - return ERROR_COMMAND_SYNTAX_ERROR; - } - - command_print(CMD, - "BCM2835 GPIO nums: swclk = %d, swdio = %d", - swclk_gpio, swdio_gpio); - - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swclk) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio); - - command_print(CMD, "BCM2835 num: swclk = %d", swclk_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swdio) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio); - - command_print(CMD, "BCM2835 num: swdio = %d", swdio_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_swd_dir_gpionum_swdio) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_dir_gpio); - - command_print(CMD, "BCM2835 num: swdio_dir = %d", swdio_dir_gpio); - return ERROR_OK; -} - COMMAND_HANDLER(bcm2835gpio_handle_speed_coeffs) { if (CMD_ARGC == 2) { @@ -340,83 +291,6 @@ COMMAND_HANDLER(bcm2835gpio_handle_peripheral_base) static const struct command_registration bcm2835gpio_subcommand_handlers[] = { { - .name = "jtag_nums", - .handler = &bcm2835gpio_handle_jtag_gpionums, - .mode = COMMAND_CONFIG, - .help = "gpio numbers for tck, tms, tdi, tdo. (in that order)", - .usage = "[tck tms tdi tdo]", - }, - { - .name = "tck_num", - .handler = &bcm2835gpio_handle_jtag_gpionum_tck, - .mode = COMMAND_CONFIG, - .help = "gpio number for tck.", - .usage = "[tck]", - }, - { - .name = "tms_num", - .handler = &bcm2835gpio_handle_jtag_gpionum_tms, - .mode = COMMAND_CONFIG, - .help = "gpio number for tms.", - .usage = "[tms]", - }, - { - .name = "tdo_num", - .handler = &bcm2835gpio_handle_jtag_gpionum_tdo, - .mode = COMMAND_CONFIG, - .help = "gpio number for tdo.", - .usage = "[tdo]", - }, - { - .name = "tdi_num", - .handler = &bcm2835gpio_handle_jtag_gpionum_tdi, - .mode = COMMAND_CONFIG, - .help = "gpio number for tdi.", - .usage = "[tdi]", - }, - { - .name = "swd_nums", - .handler = &bcm2835gpio_handle_swd_gpionums, - .mode = COMMAND_CONFIG, - .help = "gpio numbers for swclk, swdio. (in that order)", - .usage = "[swclk swdio]", - }, - { - .name = "swclk_num", - .handler = &bcm2835gpio_handle_swd_gpionum_swclk, - .mode = COMMAND_CONFIG, - .help = "gpio number for swclk.", - .usage = "[swclk]", - }, - { - .name = "swdio_num", - .handler = &bcm2835gpio_handle_swd_gpionum_swdio, - .mode = COMMAND_CONFIG, - .help = "gpio number for swdio.", - .usage = "[swdio]", - }, - { - .name = "swdio_dir_num", - .handler = &bcm2835gpio_handle_swd_dir_gpionum_swdio, - .mode = COMMAND_CONFIG, - .help = "gpio number for swdio direction control pin (set=output mode, clear=input mode)", - .usage = "[swdio_dir]", - }, - { - .name = "srst_num", - .handler = &bcm2835gpio_handle_jtag_gpionum_srst, - .mode = COMMAND_CONFIG, - .help = "gpio number for srst.", - .usage = "[srst]", - }, - { - .name = "trst_num", - .handler = &bcm2835gpio_handle_jtag_gpionum_trst, - .mode = COMMAND_CONFIG, - .help = "gpio number for trst.", - .usage = "[trst]", - }, - { .name = "speed_coeffs", .handler = &bcm2835gpio_handle_speed_coeffs, .mode = COMMAND_CONFIG, @@ -445,57 +319,65 @@ static const struct command_registration bcm2835gpio_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -static const char * const bcm2835_transports[] = { "jtag", "swd", NULL }; - -static struct jtag_interface bcm2835gpio_interface = { - .supported = DEBUG_CAP_TMS_SEQ, - .execute_queue = bitbang_execute_queue, -}; - -struct adapter_driver bcm2835gpio_adapter_driver = { - .name = "bcm2835gpio", - .transports = bcm2835_transports, - .commands = bcm2835gpio_command_handlers, - - .init = bcm2835gpio_init, - .quit = bcm2835gpio_quit, - .reset = bcm2835gpio_reset, - .speed = bcm2835gpio_speed, - .khz = bcm2835gpio_khz, - .speed_div = bcm2835gpio_speed_div, - - .jtag_ops = &bcm2835gpio_interface, - .swd_ops = &bitbang_swd, -}; - static bool bcm2835gpio_jtag_mode_possible(void) { - if (!is_gpio_valid(tck_gpio)) - return 0; - if (!is_gpio_valid(tms_gpio)) - return 0; - if (!is_gpio_valid(tdi_gpio)) - return 0; - if (!is_gpio_valid(tdo_gpio)) - return 0; - return 1; + if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TCK)) + return false; + if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TMS)) + return false; + if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDI)) + return false; + if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDO)) + return false; + return true; } static bool bcm2835gpio_swd_mode_possible(void) { - if (!is_gpio_valid(swclk_gpio)) - return 0; - if (!is_gpio_valid(swdio_gpio)) - return 0; - return 1; + if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWCLK)) + return false; + if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO)) + return false; + return true; } -static int bcm2835gpio_init(void) +static void bcm2835gpio_munmap(void) { - bitbang_interface = &bcm2835gpio_bitbang; + if (pio_base != MAP_FAILED) { + munmap((void *)pio_base, sysconf(_SC_PAGE_SIZE)); + pio_base = MAP_FAILED; + } + + if (pads_base != MAP_FAILED) { + munmap((void *)pads_base, sysconf(_SC_PAGE_SIZE)); + pads_base = MAP_FAILED; + } +} + +static int bcm2835gpio_blink(int on) +{ + if (is_gpio_config_valid(ADAPTER_GPIO_IDX_LED)) + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_LED], on); + + return ERROR_OK; +} + +static struct bitbang_interface bcm2835gpio_bitbang = { + .read = bcm2835gpio_read, + .write = bcm2835gpio_write, + .swdio_read = bcm2835_swdio_read, + .swdio_drive = bcm2835_swdio_drive, + .swd_write = bcm2835gpio_swd_write_generic, + .blink = bcm2835gpio_blink, +}; +static int bcm2835gpio_init(void) +{ LOG_INFO("BCM2835 GPIO JTAG/SWD bitbang driver"); + bitbang_interface = &bcm2835gpio_bitbang; + adapter_gpio_config = adapter_gpio_get_config(); + if (transport_is_jtag() && !bcm2835gpio_jtag_mode_possible()) { LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode"); return ERROR_JTAG_INIT_FAILED; @@ -525,71 +407,62 @@ static int bcm2835gpio_init(void) return ERROR_JTAG_INIT_FAILED; } - static volatile uint32_t *pads_base; pads_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_SHARED, dev_mem_fd, BCM2835_PADS_GPIO_0_27); if (pads_base == MAP_FAILED) { LOG_ERROR("mmap: %s", strerror(errno)); + bcm2835gpio_munmap(); close(dev_mem_fd); return ERROR_JTAG_INIT_FAILED; } + close(dev_mem_fd); + /* set 4mA drive strength, slew rate limited, hysteresis on */ + initial_drive_strength_etc = pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] & 0x1f; pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1; - /* - * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST - * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high. + /* Configure JTAG/SWD signals. Default directions and initial states are handled + * by adapter.c and "adapter gpio" command. */ if (transport_is_jtag()) { - tdo_gpio_mode = MODE_GPIO(tdo_gpio); - tdi_gpio_mode = MODE_GPIO(tdi_gpio); - tck_gpio_mode = MODE_GPIO(tck_gpio); - tms_gpio_mode = MODE_GPIO(tms_gpio); - - INP_GPIO(tdo_gpio); - - GPIO_CLR = 1<<tdi_gpio | 1<<tck_gpio; - GPIO_SET = 1<<tms_gpio; - - OUT_GPIO(tdi_gpio); - OUT_GPIO(tck_gpio); - OUT_GPIO(tms_gpio); - - if (is_gpio_valid(trst_gpio)) { - trst_gpio_mode = MODE_GPIO(trst_gpio); - GPIO_SET = 1 << trst_gpio; - OUT_GPIO(trst_gpio); - } + initialize_gpio(ADAPTER_GPIO_IDX_TDO); + initialize_gpio(ADAPTER_GPIO_IDX_TDI); + initialize_gpio(ADAPTER_GPIO_IDX_TMS); + initialize_gpio(ADAPTER_GPIO_IDX_TCK); + initialize_gpio(ADAPTER_GPIO_IDX_TRST); } if (transport_is_swd()) { - /* Make buffer an output before the GPIO connected to it */ - if (is_gpio_valid(swdio_dir_gpio)) { - swdio_dir_gpio_mode = MODE_GPIO(swdio_dir_gpio); - GPIO_SET = 1 << swdio_dir_gpio; - OUT_GPIO(swdio_dir_gpio); + /* swdio and its buffer should be initialized in the order that prevents + * two outputs from being connected together. This will occur if the + * swdio GPIO of the AM335x is configured as an output while its + * external buffer is configured to send the swdio signal from the + * target to the AM335x. + */ + if (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].init_state == ADAPTER_GPIO_INIT_STATE_INPUT) { + initialize_gpio(ADAPTER_GPIO_IDX_SWDIO); + initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR); + } else { + initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR); + initialize_gpio(ADAPTER_GPIO_IDX_SWDIO); } - swclk_gpio_mode = MODE_GPIO(swclk_gpio); - swdio_gpio_mode = MODE_GPIO(swdio_gpio); - - GPIO_CLR = 1<<swdio_gpio | 1<<swclk_gpio; - - OUT_GPIO(swclk_gpio); - OUT_GPIO(swdio_gpio); - } + initialize_gpio(ADAPTER_GPIO_IDX_SWCLK); - if (is_gpio_valid(srst_gpio)) { - srst_gpio_mode = MODE_GPIO(srst_gpio); - GPIO_SET = 1 << srst_gpio; - OUT_GPIO(srst_gpio); + if (adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL && + adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL) { + LOG_DEBUG("BCM2835 GPIO using fast mode for SWD write"); + bcm2835gpio_bitbang.swd_write = bcm2835gpio_swd_write_fast; + } else { + LOG_DEBUG("BCM2835 GPIO using generic mode for SWD write"); + bcm2835gpio_bitbang.swd_write = bcm2835gpio_swd_write_generic; + } } - LOG_DEBUG("saved pinmux settings: tck %d tms %d tdi %d " - "tdo %d trst %d srst %d", tck_gpio_mode, tms_gpio_mode, - tdi_gpio_mode, tdo_gpio_mode, trst_gpio_mode, srst_gpio_mode); + initialize_gpio(ADAPTER_GPIO_IDX_SRST); + initialize_gpio(ADAPTER_GPIO_IDX_LED); return ERROR_OK; } @@ -597,24 +470,54 @@ static int bcm2835gpio_init(void) static int bcm2835gpio_quit(void) { if (transport_is_jtag()) { - SET_MODE_GPIO(tdo_gpio, tdo_gpio_mode); - SET_MODE_GPIO(tdi_gpio, tdi_gpio_mode); - SET_MODE_GPIO(tck_gpio, tck_gpio_mode); - SET_MODE_GPIO(tms_gpio, tms_gpio_mode); - if (is_gpio_valid(trst_gpio)) - SET_MODE_GPIO(trst_gpio, trst_gpio_mode); + restore_gpio(ADAPTER_GPIO_IDX_TDO); + restore_gpio(ADAPTER_GPIO_IDX_TDI); + restore_gpio(ADAPTER_GPIO_IDX_TCK); + restore_gpio(ADAPTER_GPIO_IDX_TMS); + restore_gpio(ADAPTER_GPIO_IDX_TRST); } if (transport_is_swd()) { - SET_MODE_GPIO(swclk_gpio, swclk_gpio_mode); - SET_MODE_GPIO(swdio_gpio, swdio_gpio_mode); + /* Restore swdio/swdio_dir to their initial modes, even if that means + * connecting two outputs. Begin by making swdio an input so that the + * current and final states of swdio and swdio_dir do not have to be + * considered to calculate the safe restoration order. + */ + INP_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num); + restore_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR); + restore_gpio(ADAPTER_GPIO_IDX_SWDIO); + restore_gpio(ADAPTER_GPIO_IDX_SWCLK); } - if (is_gpio_valid(srst_gpio)) - SET_MODE_GPIO(srst_gpio, srst_gpio_mode); + restore_gpio(ADAPTER_GPIO_IDX_SRST); + restore_gpio(ADAPTER_GPIO_IDX_LED); - if (is_gpio_valid(swdio_dir_gpio)) - SET_MODE_GPIO(swdio_dir_gpio, swdio_dir_gpio_mode); + /* Restore drive strength. MSB is password ("5A") */ + pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5A000000 | initial_drive_strength_etc; + bcm2835gpio_munmap(); return ERROR_OK; } + + +static const char * const bcm2835_transports[] = { "jtag", "swd", NULL }; + +static struct jtag_interface bcm2835gpio_interface = { + .supported = DEBUG_CAP_TMS_SEQ, + .execute_queue = bitbang_execute_queue, +}; +struct adapter_driver bcm2835gpio_adapter_driver = { + .name = "bcm2835gpio", + .transports = bcm2835_transports, + .commands = bcm2835gpio_command_handlers, + + .init = bcm2835gpio_init, + .quit = bcm2835gpio_quit, + .reset = bcm2835gpio_reset, + .speed = bcm2835gpio_speed, + .khz = bcm2835gpio_khz, + .speed_div = bcm2835gpio_speed_div, + + .jtag_ops = &bcm2835gpio_interface, + .swd_ops = &bitbang_swd, +}; diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c index 78dcb29..d49e16f 100644 --- a/src/jtag/drivers/bitbang.c +++ b/src/jtag/drivers/bitbang.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* 2014-12: Addition of the SWD protocol support is based on the initial work diff --git a/src/jtag/drivers/bitbang.h b/src/jtag/drivers/bitbang.h index bc2c506..4ea1cc0 100644 --- a/src/jtag/drivers/bitbang.h +++ b/src/jtag/drivers/bitbang.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_BITBANG_H diff --git a/src/jtag/drivers/bitq.c b/src/jtag/drivers/bitq.c index 04fc78b..59e4f35 100644 --- a/src/jtag/drivers/bitq.c +++ b/src/jtag/drivers/bitq.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Pavel Chromy * * chromy@asix.cz * -* * -* 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/bitq.h b/src/jtag/drivers/bitq.h index df6a08d..8e06fcf 100644 --- a/src/jtag/drivers/bitq.h +++ b/src/jtag/drivers/bitq.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007 by Pavel Chromy * * chromy@asix.cz * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_BITQ_H diff --git a/src/jtag/drivers/buspirate.c b/src/jtag/drivers/buspirate.c index 51ace61..03b48e6 100644 --- a/src/jtag/drivers/buspirate.c +++ b/src/jtag/drivers/buspirate.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2010 by Michal Demin * * based on usbprog.c and arm-jtag-ew.c * * Several fixes by R. Diez in 2013. * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c index eaa65ab..e708d52 100644 --- a/src/jtag/drivers/cmsis_dap.c +++ b/src/jtag/drivers/cmsis_dap.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2021 by Adrian Negreanu * * groleo@gmail.com * @@ -19,19 +21,6 @@ * * * Copyright (C) 2013 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/cmsis_dap.h b/src/jtag/drivers/cmsis_dap.h index 7c64d49..cf929b0 100644 --- a/src/jtag/drivers/cmsis_dap.h +++ b/src/jtag/drivers/cmsis_dap.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + #ifndef OPENOCD_JTAG_DRIVERS_CMSIS_DAP_H #define OPENOCD_JTAG_DRIVERS_CMSIS_DAP_H diff --git a/src/jtag/drivers/cmsis_dap_usb_bulk.c b/src/jtag/drivers/cmsis_dap_usb_bulk.c index 819596b..a738200 100644 --- a/src/jtag/drivers/cmsis_dap_usb_bulk.c +++ b/src/jtag/drivers/cmsis_dap_usb_bulk.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2018 by Mickaël Thomas * * mickael9@gmail.com * @@ -16,19 +18,6 @@ * * * Copyright (C) 2013 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/cmsis_dap_usb_hid.c b/src/jtag/drivers/cmsis_dap_usb_hid.c index 912ba39..592eb09 100644 --- a/src/jtag/drivers/cmsis_dap_usb_hid.c +++ b/src/jtag/drivers/cmsis_dap_usb_hid.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2018 by Mickaël Thomas * * mickael9@gmail.com * @@ -16,19 +18,6 @@ * * * Copyright (C) 2013 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/driver.c b/src/jtag/drivers/driver.c index dbe3b08..409b800 100644 --- a/src/jtag/drivers/driver.c +++ b/src/jtag/drivers/driver.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -11,19 +13,6 @@ * * * Copyright (C) 2009 Zachary T Welch * * zw@superlucidity.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/dummy.c b/src/jtag/drivers/dummy.c index e66cb6b..1b1e573 100644 --- a/src/jtag/drivers/dummy.c +++ b/src/jtag/drivers/dummy.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2008 by Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/ep93xx.c b/src/jtag/drivers/ep93xx.c index 94d6550..393fc7e 100644 --- a/src/jtag/drivers/ep93xx.c +++ b/src/jtag/drivers/ep93xx.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -35,7 +24,7 @@ static uint8_t output_value; static int dev_mem_fd; -static void *gpio_controller; +static uint8_t *gpio_controller; static volatile uint8_t *gpio_data_register; static volatile uint8_t *gpio_data_direction_register; @@ -121,19 +110,16 @@ static int ep93xx_reset(int trst, int srst) static int set_gonk_mode(void) { - void *syscon; - uint32_t devicecfg; - - syscon = mmap(NULL, 4096, PROT_READ | PROT_WRITE, + void *syscon = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, dev_mem_fd, 0x80930000); if (syscon == MAP_FAILED) { LOG_ERROR("mmap: %s", strerror(errno)); return ERROR_JTAG_INIT_FAILED; } - devicecfg = *((volatile int *)(syscon + 0x80)); - *((volatile int *)(syscon + 0xc0)) = 0xaa; - *((volatile int *)(syscon + 0x80)) = devicecfg | 0x08000000; + uint32_t devicecfg = *((volatile uint32_t *)((uintptr_t)syscon + 0x80)); + *((volatile uint32_t *)((uintptr_t)syscon + 0xc0)) = 0xaa; + *((volatile uint32_t *)((uintptr_t)syscon + 0x80)) = devicecfg | 0x08000000; munmap(syscon, 4096); diff --git a/src/jtag/drivers/esp_usb_jtag.c b/src/jtag/drivers/esp_usb_jtag.c new file mode 100644 index 0000000..65293ee --- /dev/null +++ b/src/jtag/drivers/esp_usb_jtag.c @@ -0,0 +1,796 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * Espressif USB to Jtag adapter * + * Copyright (C) 2020 Espressif Systems (Shanghai) Co. Ltd. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <jtag/adapter.h> +#include <jtag/interface.h> +#include <helper/time_support.h> +#include <helper/bits.h> +#include "bitq.h" +#include "libusb_helper.h" + +#define __packed __attribute__((packed)) + +/* +Holy Crap, it's protocol documentation, and it's even vendor-provided! + +A device that speaks this protocol has two endpoints intended for JTAG debugging: one +OUT for the host to send encoded commands to, one IN from which the host can read any read +TDO bits. The device will also respond to vendor-defined interface requests on ep0. + +The main communication method is over the IN/OUT endpoints. The commands that are expected +on the OUT endpoint are one nibble wide and are processed high-nibble-first, low-nibble-second, +and in the order the bytes come in. Commands are defined as follows: + + bit 3 2 1 0 +CMD_CLK [ 0 cap tdi tms ] +CMD_RST [ 1 0 0 srst ] +CMD_FLUSH [ 1 0 1 0 ] +CMD_RSV [ 1 0 1 1 ] +CMD_REP [ 1 1 R1 R0 ] + +CMD_CLK sets the TDI and TMS lines to the value of `tdi` and `tms` and lowers, then raises, TCK. If +`cap` is 1, the value of TDO is captured and can be retrieved over the IN endpoint. The bytes read from +the IN endpoint specifically are these bits, with the lowest it in every byte captured first and the +bytes returned in the order the data in them was captured. The durations of TCK being high / low can +be set using the VEND_JTAG_SETDIV vendor-specific interface request. + +CMD_RST controls the SRST line; as soon as the command is processed, the SRST line will be set +to the value of `srst`. + +CMD_FLUSH flushes the IN endpoint; zeroes will be added to the amount of bits in the endpoint until +the payload is a multiple of bytes, and the data is offered to the host. If the IN endpoint has +no data, this effectively becomes a no-op; the endpoint won't send any 0-byte payloads. + +CMD_RSV is reserved for future use. + +CMD_REP repeats the last command that is not CMD_REP. The amount of times a CMD_REP command will +re-execute this command is (r1*2+r0)<<(2*n), where n is the amount of previous repeat commands executed +since the command to be repeated. + +An example for CMD_REP: Say the host queues: +1. CMD_CLK - This will execute one CMD_CLK. +2. CMD_REP with r1=0 and r0=1 - This will execute 1. another (0*2+1)<<(2*0)=1 time. +3. CMD_REP with r1=1 and r0=0 - This will execute 1. another (1*2+0)<<(2*1)=4 times. +4. CMD_REP with r1=0 and r0=1 - This will execute 1. another (0*2+1)<<(2*2)=8 time. +5. CMD_FLUSH - This will flush the IN pipeline. +6. CMD_CLK - This will execute one CMD_CLK +7. CMD_REP with r1=1 and r0=0 - This will execute 6. another (1*2+0)<<(2*0)=2 times. +8. CMD_FLUSH - This will flush the IN pipeline. + +Note that the net effect of the repetitions is that command 1 is executed (1+1+4+8=) 14 times and +command 6 is executed (1+2=) 3 times. + +Note that the device only has a fairly limited amount of endpoint RAM. It's probably best to keep +an eye on the amount of bytes that are supposed to be in the IN endpoint and grab those before stuffing +more commands into the OUT endpoint: the OUT endpoint will not accept any more commands (writes will +time out) when the IN endpoint buffers are all filled up. + +The device also supports some vendor-specific interface requests. These requests are sent as control +transfers on endpoint 0 to the JTAG endpoint. Note that these commands bypass the data in the OUT +endpoint; if timing is important, it's important that this endpoint is empty. This can be done by +e.g sending one CMD_CLK capturing TDI, then one CMD_FLUSH, then waiting until the bit appears on the +IN endpoint. + +bmRequestType bRequest wValue wIndex wLength Data +01000000b VEND_JTAG_SETDIV [divide] interface 0 None +01000000b VEND_JTAG_SETIO [iobits] interface 0 None +11000000b VEND_JTAG_GETTDO 0 interface 1 [iostate] +10000000b GET_DESCRIPTOR(6) 0x2000 0 256 [jtag cap desc] + +VEND_JTAG_SETDIV indirectly controls the speed of the TCK clock. The value written here is the length +of a TCK cycle, in ticks of the adapters base clock. Both the base clock value as well as the +minimum and maximum divider can be read from the jtag capabilities descriptor, as explained +below. Note that this should not be set to a value outside of the range described there, +otherwise results are undefined. + +VEND_JTAG_SETIO can be controlled to directly set the IO pins. The format of [iobits] normally is +{11'b0, srst, trst, tck, tms, tdi} +Note that the first 11 0 bits are reserved for future use, current hardware ignores them. + +VEND_JTAG_GETTDO returns one byte, of which bit 0 indicates the current state of the TDO input. +Note that other bits are reserved for future use and should be ignored. + +To describe the capabilities of the JTAG adapter, a specific descriptor (0x20) can be retrieved. +The format of the descriptor documented below. The descriptor works in the same fashion as USB +descriptors: a header indicating the version and total length followed by descriptors with a +specific type and size. Forward compatibility is guaranteed as software can skip over an unknown +descriptor. + +*/ + +#define JTAG_PROTO_CAPS_VER 1 /* Version field. At the moment, only version 1 is defined. */ +struct jtag_proto_caps_hdr { + uint8_t proto_ver; /* Protocol version. Expects JTAG_PROTO_CAPS_VER for now. */ + uint8_t length; /* of this plus any following descriptors */ +} __packed; + +/* start of the descriptor headers */ +#define JTAG_BUILTIN_DESCR_START_OFF 0 /* Devices with builtin usb jtag */ +/* +* ESP USB Bridge https://github.com/espressif/esp-usb-bridge uses string descriptor. +* Skip 1 byte length and 1 byte descriptor type +*/ +#define JTAG_EUB_DESCR_START_OFF 2 /* ESP USB Bridge */ + +/* +Note: At the moment, there is only a speed_caps version indicating the base speed of the JTAG +hardware is derived from the APB bus speed of the SoC. If later on, there are standalone +converters using the protocol, we should define e.g. JTAG_PROTO_CAPS_SPEED_FIXED_TYPE to distinguish +between the two. + +Note: If the JTAG device has larger buffers than endpoint-size-plus-a-bit, we should have some kind +of caps header to assume this. If no such caps exist, assume a minimum (in) buffer of endpoint size + 4. +*/ + +struct jtag_gen_hdr { + uint8_t type; + uint8_t length; +} __packed; + +struct jtag_proto_caps_speed_apb { + uint8_t type; /* Type, always JTAG_PROTO_CAPS_SPEED_APB_TYPE */ + uint8_t length; /* Length of this */ + uint8_t apb_speed_10khz[2]; /* ABP bus speed, in 10KHz increments. Base speed is half this. */ + uint8_t div_min[2]; /* minimum divisor (to base speed), inclusive */ + uint8_t div_max[2]; /* maximum divisor (to base speed), inclusive */ +} __packed; + +#define JTAG_PROTO_CAPS_DATA_LEN 255 +#define JTAG_PROTO_CAPS_SPEED_APB_TYPE 1 + +#define VEND_DESCR_BUILTIN_JTAG_CAPS 0x2000 + +#define VEND_JTAG_SETDIV 0 +#define VEND_JTAG_SETIO 1 +#define VEND_JTAG_GETTDO 2 +#define VEND_JTAG_SET_CHIPID 3 + +#define VEND_JTAG_SETIO_TDI BIT(0) +#define VEND_JTAG_SETIO_TMS BIT(1) +#define VEND_JTAG_SETIO_TCK BIT(2) +#define VEND_JTAG_SETIO_TRST BIT(3) +#define VEND_JTAG_SETIO_SRST BIT(4) + +#define CMD_CLK(cap, tdi, tms) ((cap ? BIT(2) : 0) | (tms ? BIT(1) : 0) | (tdi ? BIT(0) : 0)) +#define CMD_RST(srst) (0x8 | (srst ? BIT(0) : 0)) +#define CMD_FLUSH 0xA +#define CMD_RSVD 0xB +#define CMD_REP(r) (0xC + ((r) & 3)) + +/* The internal repeats register is 10 bits, which means we can have 5 repeat commands in a + *row at max. This translates to ('b1111111111+1=)1024 reps max. */ +#define CMD_REP_MAX_REPS 1024 + +/* Currently we only support one USB device. */ +#define USB_CONFIGURATION 0 + +/* Buffer size; is equal to the endpoint size. In bytes + * TODO for future adapters: read from device configuration? */ +#define OUT_EP_SZ 64 +/* Out data can be buffered for longer without issues (as long as the in buffer does not overflow), + * so we'll use an out buffer that is much larger than the out ep size. */ +#define OUT_BUF_SZ (OUT_EP_SZ * 32) +/* The in buffer cannot be larger than the device can offer, though. */ +#define IN_BUF_SZ 64 + +/* Because a series of out commands can lead to a multitude of IN_BUF_SZ-sized in packets + *to be read, we have multiple buffers to store those before the bitq interface reads them out. */ +#define IN_BUF_CT 8 + +#define ESP_USB_INTERFACE 1 + +/* Private data */ +struct esp_usb_jtag { + struct libusb_device_handle *usb_device; + uint32_t base_speed_khz; + uint16_t div_min; + uint16_t div_max; + uint8_t out_buf[OUT_BUF_SZ]; + unsigned int out_buf_pos_nibbles; /* write position in out_buf */ + + uint8_t in_buf[IN_BUF_CT][IN_BUF_SZ]; + unsigned int in_buf_size_bits[IN_BUF_CT]; /* size in bits of the data stored in an in_buf */ + unsigned int cur_in_buf_rd, cur_in_buf_wr; /* read/write index */ + unsigned int in_buf_pos_bits; /* which bit in the in buf needs to be returned to bitq next */ + + unsigned int read_ep; + unsigned int write_ep; + + unsigned int prev_cmd; /* previous command, stored here for RLEing. */ + int prev_cmd_repct; /* Amount of repetitions of that command we have seen until now */ + + /* This is the total number of in bits we need to read, including in unsent commands */ + unsigned int pending_in_bits; + + unsigned int hw_in_fifo_len; + + struct bitq_interface bitq_interface; +}; + +/* For now, we only use one static private struct. Technically, we can re-work this, but I don't think + * OpenOCD supports multiple JTAG adapters anyway. */ +static struct esp_usb_jtag esp_usb_jtag_priv; +static struct esp_usb_jtag *priv = &esp_usb_jtag_priv; + +static int esp_usb_vid; +static int esp_usb_pid; +static int esp_usb_jtag_caps; +static int esp_usb_target_chip_id; + +static int esp_usb_jtag_init(void); +static int esp_usb_jtag_quit(void); + +/* Try to receive from USB endpoint into the current priv->in_buf */ +static int esp_usb_jtag_recv_buf(void) +{ + if (priv->in_buf_size_bits[priv->cur_in_buf_wr] != 0) + LOG_ERROR("esp_usb_jtag: IN buffer overflow! (%d, size %d)", + priv->cur_in_buf_wr, + priv->in_buf_size_bits[priv->cur_in_buf_wr]); + + unsigned int recvd = 0, ct = (priv->pending_in_bits + 7) / 8; + if (ct > IN_BUF_SZ) + ct = IN_BUF_SZ; + if (ct == 0) { + /* Note that the adapters IN EP specifically does *not* usually generate 0-byte in + * packets if there has been no data since the last flush. + * As such, we don't need (and shouldn't) try to read it. */ + return ERROR_OK; + } + + priv->in_buf_size_bits[priv->cur_in_buf_wr] = 0; + while (recvd < ct) { + unsigned int tr; + int ret = jtag_libusb_bulk_read(priv->usb_device, + priv->read_ep, + (char *)priv->in_buf[priv->cur_in_buf_wr] + recvd, + ct, + LIBUSB_TIMEOUT_MS, /*ms*/ + (int *)&tr); + if (ret != ERROR_OK || tr == 0) { + /* Sometimes the hardware returns 0 bytes instead of NAKking the transaction. Ignore this. */ + return ERROR_FAIL; + } + + if (tr != ct) { + /* Huh, short read? */ + LOG_DEBUG("esp_usb_jtag: usb received only %d out of %d bytes.", tr, ct); + } + /* Adjust the amount of bits we still expect to read from the USB device after this. */ + unsigned int bits_in_buf = priv->pending_in_bits; /* initially assume we read + * everything that was pending */ + if (bits_in_buf > tr * 8) + bits_in_buf = tr * 8; /* ...but correct that if that was not the case. */ + priv->pending_in_bits -= bits_in_buf; + priv->in_buf_size_bits[priv->cur_in_buf_wr] += bits_in_buf; + recvd += tr; + } + /* next in buffer for the next time. */ + priv->cur_in_buf_wr++; + if (priv->cur_in_buf_wr == IN_BUF_CT) + priv->cur_in_buf_wr = 0; + LOG_DEBUG_IO("esp_usb_jtag: In ep: received %d bytes; %d bytes (%d bits) left.", recvd, + (priv->pending_in_bits + 7) / 8, priv->pending_in_bits); + return ERROR_OK; +} + +/* Sends priv->out_buf to the USB device. */ +static int esp_usb_jtag_send_buf(void) +{ + unsigned int ct = priv->out_buf_pos_nibbles / 2; + unsigned int written = 0; + + while (written < ct) { + int tr = 0, ret = jtag_libusb_bulk_write(priv->usb_device, + priv->write_ep, + (char *)priv->out_buf + written, + ct - written, + LIBUSB_TIMEOUT_MS, /*ms*/ + &tr); + LOG_DEBUG_IO("esp_usb_jtag: sent %d bytes.", tr); + if (written + tr != ct) { + LOG_DEBUG("esp_usb_jtag: usb sent only %d out of %d bytes.", + written + tr, + ct); + } + if (ret != ERROR_OK) + return ret; + written += tr; + } + priv->out_buf_pos_nibbles = 0; + + /* If there's more than a bufferful of data queuing up in the jtag adapters IN endpoint, empty + * all but one buffer. */ + while (priv->pending_in_bits > (IN_BUF_SZ + priv->hw_in_fifo_len - 1) * 8) + esp_usb_jtag_recv_buf(); + + return ERROR_OK; +} + +/* Simply adds a command to the buffer. Is called by the RLE encoding mechanism. + *Also sends the intermediate buffer if there's enough to go into one USB packet. */ +static int esp_usb_jtag_command_add_raw(unsigned int cmd) +{ + int ret = ERROR_OK; + + if ((priv->out_buf_pos_nibbles & 1) == 0) + priv->out_buf[priv->out_buf_pos_nibbles / 2] = (cmd << 4); + else + priv->out_buf[priv->out_buf_pos_nibbles / 2] |= cmd; + priv->out_buf_pos_nibbles++; + + if (priv->out_buf_pos_nibbles == OUT_BUF_SZ * 2) + ret = esp_usb_jtag_send_buf(); + if (ret == ERROR_OK && priv->out_buf_pos_nibbles % (OUT_EP_SZ * 2) == 0) { + if (priv->pending_in_bits > (IN_BUF_SZ + priv->hw_in_fifo_len - 1) * 8) + ret = esp_usb_jtag_send_buf(); + } + return ret; +} + +/* Writes a command stream equivalent to writing `cmd` `ct` times. */ +static int esp_usb_jtag_write_rlestream(unsigned int cmd, int ct) +{ + /* Special case: stacking flush commands does not make sense (and may not make the hardware very happy) */ + if (cmd == CMD_FLUSH) + ct = 1; + /* Output previous command and repeat commands */ + int ret = esp_usb_jtag_command_add_raw(cmd); + if (ret != ERROR_OK) + return ret; + ct--; /* as the previous line already executes the command one time */ + while (ct > 0) { + ret = esp_usb_jtag_command_add_raw(CMD_REP(ct & 3)); + if (ret != ERROR_OK) + return ret; + ct >>= 2; + } + return ERROR_OK; +} + +/* Adds a command to the buffer of things to be sent. Transparently handles RLE compression using + * the CMD_REP_x commands */ +static int esp_usb_jtag_command_add(unsigned int cmd) +{ + if (cmd == priv->prev_cmd && priv->prev_cmd_repct < CMD_REP_MAX_REPS) { + priv->prev_cmd_repct++; + } else { + /* We can now write out the previous command plus repeat count. */ + if (priv->prev_cmd_repct) { + int ret = esp_usb_jtag_write_rlestream(priv->prev_cmd, priv->prev_cmd_repct); + if (ret != ERROR_OK) + return ret; + } + /* Ready for new command. */ + priv->prev_cmd = cmd; + priv->prev_cmd_repct = 1; + } + return ERROR_OK; +} + +/* Called by bitq interface to output a bit on tdi and perhaps read a bit from tdo */ +static int esp_usb_jtag_out(int tms, int tdi, int tdo_req) +{ + int ret = esp_usb_jtag_command_add(CMD_CLK(tdo_req, tdi, tms)); + if (ret != ERROR_OK) + return ret; + if (tdo_req) + priv->pending_in_bits++; + return ERROR_OK; +} + +/* Called by bitq interface to flush all output commands and get returned data ready to read */ +static int esp_usb_jtag_flush(void) +{ + int ret; + /*Make sure last command is written */ + if (priv->prev_cmd_repct) { + ret = esp_usb_jtag_write_rlestream(priv->prev_cmd, priv->prev_cmd_repct); + if (ret != ERROR_OK) + return ret; + } + priv->prev_cmd_repct = 0; + /* Flush in buffer */ + ret = esp_usb_jtag_command_add_raw(CMD_FLUSH); + if (ret != ERROR_OK) + return ret; + /* Make sure we have an even amount of commands, as we can't write a nibble by itself. */ + if (priv->out_buf_pos_nibbles & 1) { + /*If not, pad with an extra FLUSH */ + ret = esp_usb_jtag_command_add_raw(CMD_FLUSH); + if (ret != ERROR_OK) + return ret; + } + LOG_DEBUG_IO("esp_usb_jtag: Flush!"); + /* Send off the buffer. */ + ret = esp_usb_jtag_send_buf(); + if (ret != ERROR_OK) + return ret; + + /* Immediately fetch the response bits. */ + while (priv->pending_in_bits > 0) + esp_usb_jtag_recv_buf(); + + return ERROR_OK; +} + +/* Called by bitq interface to sleep for a determined amount of time */ +static int esp_usb_jtag_sleep(unsigned long us) +{ + esp_usb_jtag_flush(); + /* TODO: we can sleep more precisely (for small amounts of sleep at least) by sending dummy + * commands to the adapter. */ + jtag_sleep(us); + return 0; +} + +/* Called by the bitq interface to set the various resets */ +static int esp_usb_jtag_reset(int trst, int srst) +{ + /* TODO: handle trst using setup commands. Kind-of superfluous, however, as we can also do + * a tap reset using tms, and it's also not implemented on other ESP32 chips with external JTAG. */ + return esp_usb_jtag_command_add(CMD_RST(srst)); +} + +/* Called by bitq to see if the IN data already is returned to the host. */ +static int esp_usb_jtag_in_rdy(void) +{ + /* We read all bits in the flush() routine, so if we're here, we have bits or are at EOF. */ + return 1; +} + +/* Read one bit from the IN data */ +static int esp_usb_jtag_in(void) +{ + if (!esp_usb_jtag_in_rdy()) { + LOG_ERROR("esp_usb_jtag: Eeek! bitq asked us for in data while not ready!"); + return -1; + } + if (priv->cur_in_buf_rd == priv->cur_in_buf_wr && + priv->in_buf_size_bits[priv->cur_in_buf_rd] == 0) + return -1; + + /* Extract the bit */ + int r = (priv->in_buf[priv->cur_in_buf_rd][priv->in_buf_pos_bits / 8] & + BIT(priv->in_buf_pos_bits & 7)) ? 1 : 0; + /* Move to next bit. */ + priv->in_buf_pos_bits++; + if (priv->in_buf_pos_bits == priv->in_buf_size_bits[priv->cur_in_buf_rd]) { + /* No more bits in this buffer; mark as re-usable and move to next buffer. */ + priv->in_buf_pos_bits = 0; + priv->in_buf_size_bits[priv->cur_in_buf_rd] = 0;/*indicate it is free again */ + priv->cur_in_buf_rd++; + if (priv->cur_in_buf_rd == IN_BUF_CT) + priv->cur_in_buf_rd = 0; + } + return r; +} + +static int esp_usb_jtag_init(void) +{ + memset(priv, 0, sizeof(struct esp_usb_jtag)); + + const uint16_t vids[] = { esp_usb_vid, 0 }; /* must be null terminated */ + const uint16_t pids[] = { esp_usb_pid, 0 }; /* must be null terminated */ + + bitq_interface = &priv->bitq_interface; + bitq_interface->out = esp_usb_jtag_out; + bitq_interface->flush = esp_usb_jtag_flush; + bitq_interface->sleep = esp_usb_jtag_sleep; + bitq_interface->reset = esp_usb_jtag_reset; + bitq_interface->in_rdy = esp_usb_jtag_in_rdy; + bitq_interface->in = esp_usb_jtag_in; + + int r = jtag_libusb_open(vids, pids, &priv->usb_device, NULL); + if (r != ERROR_OK) { + LOG_ERROR("esp_usb_jtag: could not find or open device!"); + goto out; + } + + jtag_libusb_set_configuration(priv->usb_device, USB_CONFIGURATION); + + r = jtag_libusb_choose_interface(priv->usb_device, &priv->read_ep, &priv->write_ep, + LIBUSB_CLASS_VENDOR_SPEC, LIBUSB_CLASS_VENDOR_SPEC, ESP_USB_INTERFACE, LIBUSB_TRANSFER_TYPE_BULK); + if (r != ERROR_OK) { + LOG_ERROR("esp_usb_jtag: error finding/claiming JTAG interface on device!"); + goto out; + } + + /* TODO: This is not proper way to get caps data. Two requests can be done. + * 1- With the minimum size required to get to know the total length of that struct, + * 2- Then exactly the length of that struct. */ + uint8_t jtag_caps_desc[JTAG_PROTO_CAPS_DATA_LEN]; + int jtag_caps_read_len = jtag_libusb_control_transfer(priv->usb_device, + LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE, + LIBUSB_REQUEST_GET_DESCRIPTOR, esp_usb_jtag_caps, 0, + (char *)jtag_caps_desc, JTAG_PROTO_CAPS_DATA_LEN, LIBUSB_TIMEOUT_MS); + if (jtag_caps_read_len <= 0) { + LOG_ERROR("esp_usb_jtag: could not retrieve jtag_caps descriptor!"); + goto out; + } + + /* defaults for values we normally get from the jtag caps descriptor */ + priv->base_speed_khz = UINT32_MAX; + priv->div_min = 1; + priv->div_max = 1; + + int p = esp_usb_jtag_caps == + VEND_DESCR_BUILTIN_JTAG_CAPS ? JTAG_BUILTIN_DESCR_START_OFF : JTAG_EUB_DESCR_START_OFF; + + if (p + sizeof(struct jtag_proto_caps_hdr) > (unsigned int)jtag_caps_read_len) { + LOG_ERROR("esp_usb_jtag: not enough data to get header"); + goto out; + } + + struct jtag_proto_caps_hdr *hdr = (struct jtag_proto_caps_hdr *)&jtag_caps_desc[p]; + if (hdr->proto_ver != JTAG_PROTO_CAPS_VER) { + LOG_ERROR("esp_usb_jtag: unknown jtag_caps descriptor version 0x%X!", + hdr->proto_ver); + goto out; + } + if (hdr->length > jtag_caps_read_len) { + LOG_ERROR("esp_usb_jtag: header length (%d) bigger then max read bytes (%d)", + hdr->length, jtag_caps_read_len); + goto out; + } + + p += sizeof(struct jtag_proto_caps_hdr); + + while (p + sizeof(struct jtag_gen_hdr) < hdr->length) { + struct jtag_gen_hdr *dhdr = (struct jtag_gen_hdr *)&jtag_caps_desc[p]; + if (dhdr->type == JTAG_PROTO_CAPS_SPEED_APB_TYPE) { + if (p + sizeof(struct jtag_proto_caps_speed_apb) < hdr->length) { + LOG_ERROR("esp_usb_jtag: not enough data to get caps speed"); + goto out; + } + struct jtag_proto_caps_speed_apb *spcap = (struct jtag_proto_caps_speed_apb *)dhdr; + /* base speed always is half APB speed */ + priv->base_speed_khz = le_to_h_u16(spcap->apb_speed_10khz) * 10 / 2; + priv->div_min = le_to_h_u16(spcap->div_min); + priv->div_max = le_to_h_u16(spcap->div_max); + /* TODO: mark in priv that this is apb-derived and as such may change if apb + * ever changes? */ + } else { + LOG_WARNING("esp_usb_jtag: unknown caps type 0x%X", dhdr->type); + } + p += dhdr->length; + } + if (priv->base_speed_khz == UINT32_MAX) { + LOG_WARNING("esp_usb_jtag: No speed caps found... using sane-ish defaults."); + priv->base_speed_khz = 1000; + } + LOG_INFO("esp_usb_jtag: Device found. Base speed %dKHz, div range %d to %d", + priv->base_speed_khz, priv->div_min, priv->div_max); + + /* TODO: grab from (future) descriptor if we ever have a device with larger IN buffers */ + priv->hw_in_fifo_len = 4; + + /* inform bridge board about the connected target chip for the specific operations + * it is also safe to send this info to chips that have builtin usb jtag */ + jtag_libusb_control_transfer(priv->usb_device, + LIBUSB_REQUEST_TYPE_VENDOR, + VEND_JTAG_SET_CHIPID, + esp_usb_target_chip_id, + 0, + NULL, + 0, + LIBUSB_TIMEOUT_MS); + + return ERROR_OK; + +out: + if (priv->usb_device) + jtag_libusb_close(priv->usb_device); + bitq_interface = NULL; + priv->usb_device = NULL; + return ERROR_FAIL; +} + +static int esp_usb_jtag_quit(void) +{ + if (!priv->usb_device) + return ERROR_OK; + jtag_libusb_close(priv->usb_device); + bitq_cleanup(); + bitq_interface = NULL; + return ERROR_OK; +} + +static int esp_usb_jtag_speed_div(int divisor, int *khz) +{ + *khz = priv->base_speed_khz / divisor; + return ERROR_OK; +} + +static int esp_usb_jtag_khz(int khz, int *divisor) +{ + if (khz == 0) { + LOG_WARNING("esp_usb_jtag: RCLK not supported"); + return ERROR_FAIL; + } + + *divisor = priv->base_speed_khz / khz; + LOG_DEBUG("Divisor for %d KHz with base clock of %d khz is %d", + khz, + priv->base_speed_khz, + *divisor); + if (*divisor < priv->div_min) + *divisor = priv->div_min; + if (*divisor > priv->div_max) + *divisor = priv->div_max; + + return ERROR_OK; +} + +static int esp_usb_jtag_speed(int divisor) +{ + if (divisor == 0) { + LOG_ERROR("esp_usb_jtag: Adaptive clocking is not supported."); + return ERROR_JTAG_NOT_IMPLEMENTED; + } + + LOG_DEBUG("esp_usb_jtag: setting divisor %d", divisor); + jtag_libusb_control_transfer(priv->usb_device, + LIBUSB_REQUEST_TYPE_VENDOR, VEND_JTAG_SETDIV, divisor, 0, NULL, 0, LIBUSB_TIMEOUT_MS); + + return ERROR_OK; +} + +COMMAND_HANDLER(esp_usb_jtag_tdo_cmd) +{ + char tdo; + if (!priv->usb_device) + return ERROR_FAIL; + int r = jtag_libusb_control_transfer(priv->usb_device, + LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR, VEND_JTAG_GETTDO, 0, 0, &tdo, 1, LIBUSB_TIMEOUT_MS); + if (r < 1) + return r; + + command_print(CMD, "%d", tdo); + + return ERROR_OK; +} + +COMMAND_HANDLER(esp_usb_jtag_setio_cmd) +{ + uint32_t tdi, tms, tck, trst, srst; + uint16_t d = 0; + + if (!priv->usb_device) + return ERROR_FAIL; + + if (CMD_ARGC != 5) + return ERROR_COMMAND_SYNTAX_ERROR; + + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], tdi); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], tms); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], tck); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], trst); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], srst); + if (tdi) + d |= VEND_JTAG_SETIO_TDI; + if (tms) + d |= VEND_JTAG_SETIO_TMS; + if (tck) + d |= VEND_JTAG_SETIO_TCK; + if (trst) + d |= VEND_JTAG_SETIO_TRST; + if (srst) + d |= VEND_JTAG_SETIO_SRST; + + jtag_libusb_control_transfer(priv->usb_device, + 0x40, VEND_JTAG_SETIO, d, 0, NULL, 0, LIBUSB_TIMEOUT_MS); + + return ERROR_OK; +} + +COMMAND_HANDLER(esp_usb_jtag_vid_pid) +{ + if (CMD_ARGC != 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], esp_usb_vid); + COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], esp_usb_pid); + LOG_INFO("esp_usb_jtag: VID set to 0x%x and PID to 0x%x", esp_usb_vid, esp_usb_pid); + + return ERROR_OK; +} + +COMMAND_HANDLER(esp_usb_jtag_caps_descriptor) +{ + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], esp_usb_jtag_caps); + LOG_INFO("esp_usb_jtag: capabilities descriptor set to 0x%x", esp_usb_jtag_caps); + + return ERROR_OK; +} + +COMMAND_HANDLER(esp_usb_jtag_chip_id) +{ + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], esp_usb_target_chip_id); + LOG_INFO("esp_usb_jtag: target chip id set to %d", esp_usb_target_chip_id); + + return ERROR_OK; +} + +static const struct command_registration esp_usb_jtag_subcommands[] = { + { + .name = "tdo", + .handler = &esp_usb_jtag_tdo_cmd, + .mode = COMMAND_EXEC, + .help = "Returns the current state of the TDO line", + .usage = "", + }, + { + .name = "setio", + .handler = &esp_usb_jtag_setio_cmd, + .mode = COMMAND_EXEC, + .help = "Manually set the status of the output lines", + .usage = "tdi tms tck trst srst" + }, + { + .name = "vid_pid", + .handler = &esp_usb_jtag_vid_pid, + .mode = COMMAND_CONFIG, + .help = "set vendor ID and product ID for ESP usb jtag driver", + .usage = "vid pid", + }, + { + .name = "caps_descriptor", + .handler = &esp_usb_jtag_caps_descriptor, + .mode = COMMAND_CONFIG, + .help = "set jtag descriptor to read capabilities of ESP usb jtag driver", + .usage = "descriptor", + }, + { + .name = "chip_id", + .handler = &esp_usb_jtag_chip_id, + .mode = COMMAND_CONFIG, + .help = "set chip_id to transfer to the bridge", + .usage = "chip_id", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration esp_usb_jtag_commands[] = { + { + .name = "espusbjtag", + .mode = COMMAND_ANY, + .help = "ESP-USB-JTAG commands", + .chain = esp_usb_jtag_subcommands, + .usage = "", + }, + COMMAND_REGISTRATION_DONE +}; + +static struct jtag_interface esp_usb_jtag_interface = { + .supported = DEBUG_CAP_TMS_SEQ, + .execute_queue = bitq_execute_queue, +}; + +struct adapter_driver esp_usb_adapter_driver = { + .name = "esp_usb_jtag", + .transports = jtag_only, + .commands = esp_usb_jtag_commands, + + .init = esp_usb_jtag_init, + .quit = esp_usb_jtag_quit, + .speed_div = esp_usb_jtag_speed_div, + .speed = esp_usb_jtag_speed, + .khz = esp_usb_jtag_khz, + + .jtag_ops = &esp_usb_jtag_interface, +}; diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c index c930d8c..816b2d0 100644 --- a/src/jtag/drivers/ft232r.c +++ b/src/jtag/drivers/ft232r.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2010 Serge Vakulenko * * serge@vak.ru * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index 16cb027..d2dd893 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /************************************************************************** * Copyright (C) 2012 by Andreas Fritiofson * * andreas.fritiofson@gmail.com * -* * -* 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /** diff --git a/src/jtag/drivers/gw16012.c b/src/jtag/drivers/gw16012.c index db0a677..592e170 100644 --- a/src/jtag/drivers/gw16012.c +++ b/src/jtag/drivers/gw16012.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/imx_gpio.c b/src/jtag/drivers/imx_gpio.c index 39b463d..d44b127 100644 --- a/src/jtag/drivers/imx_gpio.c +++ b/src/jtag/drivers/imx_gpio.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2017 by Grzegorz Kostka, kostka.grzegorz@gmail.com * * * * Based on bcm2835gpio.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index 5c21874..0a96ac2 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Juergen Stuber <juergen@jstuber.net> * * based on Dominic Rath's and Benedikt Sauter's usbprog.c * @@ -13,19 +15,6 @@ * * * Copyright (C) 2015 by Paul Fertser * * fercerpav@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/jtag_dpi.c b/src/jtag/drivers/jtag_dpi.c index 016ff55..2a36331 100644 --- a/src/jtag/drivers/jtag_dpi.c +++ b/src/jtag/drivers/jtag_dpi.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * JTAG to DPI driver * @@ -7,19 +9,6 @@ * * See file CREDITS for list of people who contributed to this * project. - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c index eb53a5b..f19e9ab 100644 --- a/src/jtag/drivers/jtag_vpi.c +++ b/src/jtag/drivers/jtag_vpi.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * JTAG to VPI driver * @@ -5,19 +7,6 @@ * * See file CREDITS for list of people who contributed to this * project. - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index 5e2168e..0af1ff7 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Juergen Stuber <juergen@jstuber.net> * * based on Dominic Rath's and Benedikt Sauter's usbprog.c * @@ -16,19 +18,6 @@ * * * Copyright (C) 2015-2017 by Forest Crossman * * cyrozap@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -90,8 +79,24 @@ #define HID_COMMAND_CONFIGURE 0x8f #define HID_COMMAND_BOOTLOADER 0xa0 -/* 512 bytes seems to work reliably */ -#define SWD_MAX_BUFFER_LENGTH 512 +/* 512 bytes seemed to work reliably. + * It works with both full queue of mostly reads or mostly writes. + * + * Unfortunately the commit 88f429ead019fd6df96ec15f0d897385f3cef0d0 + * 5321: target/cortex_m: faster reading of all CPU registers + * revealed a serious Kitprog firmware problem: + * If the queue contains more than 63 transactions in the repeated pattern + * one write, two reads, the firmware fails badly. + * Sending 64 transactions makes the adapter to loose the connection with the + * device. Sending 65 or more transactions causes the adapter to stop + * receiving USB HID commands, next kitprog_hid_command() stops in hid_write(). + * + * The problem was detected with KitProg v2.12 and v2.16. + * We can guess the problem is something like a buffer or stack overflow. + * + * Use shorter buffer as a workaround. 300 bytes (= 60 transactions) works. + */ +#define SWD_MAX_BUFFER_LENGTH 300 struct kitprog { hid_device *hid_handle; @@ -332,9 +337,13 @@ static int kitprog_hid_command(uint8_t *command, size_t command_length, return ERROR_FAIL; } - ret = hid_read(kitprog_handle->hid_handle, data, data_length); - if (ret < 0) { - LOG_DEBUG("HID read returned %i", ret); + ret = hid_read_timeout(kitprog_handle->hid_handle, + data, data_length, LIBUSB_TIMEOUT_MS); + if (ret == 0) { + LOG_ERROR("HID read timed out"); + return ERROR_TIMEOUT_REACHED; + } else if (ret < 0) { + LOG_ERROR("HID read error %ls", hid_error(kitprog_handle->hid_handle)); return ERROR_FAIL; } diff --git a/src/jtag/drivers/libjaylink b/src/jtag/drivers/libjaylink -Subproject 9aa7a5957c07bb6e862fc1a6d3153d109c7407e +Subproject 0d23921a05d5d427332a142d154c213d0c306eb diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c index fc961cb..53dfd50 100644 --- a/src/jtag/drivers/libusb_helper.c +++ b/src/jtag/drivers/libusb_helper.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> * * * * Copyright (C) 2011 by Mauro Gamba <maurillo71@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/libusb_helper.h b/src/jtag/drivers/libusb_helper.h index 9d51464..172c345 100644 --- a/src/jtag/drivers/libusb_helper.h +++ b/src/jtag/drivers/libusb_helper.h @@ -1,20 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> * * * * Copyright (C) 2011 by Mauro Gamba <maurillo71@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H diff --git a/src/jtag/drivers/linuxgpiod.c b/src/jtag/drivers/linuxgpiod.c index 288035f..d1a88c8 100644 --- a/src/jtag/drivers/linuxgpiod.c +++ b/src/jtag/drivers/linuxgpiod.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Bitbang driver for Linux GPIO descriptors through libgpiod * Copyright (C) 2020 Antonio Borneo <borneo.antonio@gmail.com> @@ -14,67 +14,41 @@ #endif #include <gpiod.h> +#include <jtag/adapter.h> #include <jtag/interface.h> #include <transport/transport.h> #include "bitbang.h" -/* gpio numbers for each gpio. Negative values are invalid */ -static int tck_gpio = -1; -static int tms_gpio = -1; -static int tdi_gpio = -1; -static int tdo_gpio = -1; -static int trst_gpio = -1; -static int srst_gpio = -1; -static int swclk_gpio = -1; -static int swdio_gpio = -1; -static int swdio_dir_gpio = -1; -static int led_gpio = -1; -static int gpiochip = -1; -static int tck_gpiochip = -1; -static int tms_gpiochip = -1; -static int tdi_gpiochip = -1; -static int tdo_gpiochip = -1; -static int trst_gpiochip = -1; -static int srst_gpiochip = -1; -static int swclk_gpiochip = -1; -static int swdio_gpiochip = -1; -static int swdio_dir_gpiochip = -1; -static int led_gpiochip = -1; - -static struct gpiod_chip *gpiod_chip_tck; -static struct gpiod_chip *gpiod_chip_tms; -static struct gpiod_chip *gpiod_chip_tdi; -static struct gpiod_chip *gpiod_chip_tdo; -static struct gpiod_chip *gpiod_chip_trst; -static struct gpiod_chip *gpiod_chip_srst; -static struct gpiod_chip *gpiod_chip_swclk; -static struct gpiod_chip *gpiod_chip_swdio; -static struct gpiod_chip *gpiod_chip_swdio_dir; -static struct gpiod_chip *gpiod_chip_led; - -static struct gpiod_line *gpiod_tck; -static struct gpiod_line *gpiod_tms; -static struct gpiod_line *gpiod_tdi; -static struct gpiod_line *gpiod_tdo; -static struct gpiod_line *gpiod_trst; -static struct gpiod_line *gpiod_swclk; -static struct gpiod_line *gpiod_swdio; -static struct gpiod_line *gpiod_swdio_dir; -static struct gpiod_line *gpiod_srst; -static struct gpiod_line *gpiod_led; +static struct gpiod_chip *gpiod_chip[ADAPTER_GPIO_IDX_NUM] = {}; +static struct gpiod_line *gpiod_line[ADAPTER_GPIO_IDX_NUM] = {}; static int last_swclk; static int last_swdio; static bool last_stored; static bool swdio_input; -static bool swdio_dir_is_active_high = true; + +static const struct adapter_gpio_config *adapter_gpio_config; + +/* + * Helper function to determine if gpio config is valid + * + * Assume here that there will be less than 10000 gpios per gpiochip, and less + * than 1000 gpiochips. + */ +static bool is_gpio_config_valid(enum adapter_gpio_config_index idx) +{ + return adapter_gpio_config[idx].chip_num >= 0 + && adapter_gpio_config[idx].chip_num < 1000 + && adapter_gpio_config[idx].gpio_num >= 0 + && adapter_gpio_config[idx].gpio_num < 10000; +} /* Bitbang interface read of TDO */ static bb_value_t linuxgpiod_read(void) { int retval; - retval = gpiod_line_get_value(gpiod_tdo); + retval = gpiod_line_get_value(gpiod_line[ADAPTER_GPIO_IDX_TDO]); if (retval < 0) { LOG_WARNING("reading tdo failed"); return 0; @@ -107,20 +81,20 @@ static int linuxgpiod_write(int tck, int tms, int tdi) } if (tdi != last_tdi) { - retval = gpiod_line_set_value(gpiod_tdi, tdi); + retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TDI], tdi); if (retval < 0) LOG_WARNING("writing tdi failed"); } if (tms != last_tms) { - retval = gpiod_line_set_value(gpiod_tms, tms); + retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TMS], tms); if (retval < 0) LOG_WARNING("writing tms failed"); } /* write clk last */ if (tck != last_tck) { - retval = gpiod_line_set_value(gpiod_tck, tck); + retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TCK], tck); if (retval < 0) LOG_WARNING("writing tck failed"); } @@ -136,7 +110,7 @@ static int linuxgpiod_swdio_read(void) { int retval; - retval = gpiod_line_get_value(gpiod_swdio); + retval = gpiod_line_get_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO]); if (retval < 0) { LOG_WARNING("Fail read swdio"); return 0; @@ -154,23 +128,23 @@ static void linuxgpiod_swdio_drive(bool is_output) * https://stackoverflow.com/questions/58735140/ * this would change in future libgpiod */ - gpiod_line_release(gpiod_swdio); + gpiod_line_release(gpiod_line[ADAPTER_GPIO_IDX_SWDIO]); if (is_output) { - if (gpiod_swdio_dir) { - retval = gpiod_line_set_value(gpiod_swdio_dir, swdio_dir_is_active_high ? 1 : 0); + if (gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR]) { + retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR], 1); if (retval < 0) LOG_WARNING("Fail set swdio_dir"); } - retval = gpiod_line_request_output(gpiod_swdio, "OpenOCD", 1); + retval = gpiod_line_request_output(gpiod_line[ADAPTER_GPIO_IDX_SWDIO], "OpenOCD", 1); if (retval < 0) LOG_WARNING("Fail request_output line swdio"); } else { - retval = gpiod_line_request_input(gpiod_swdio, "OpenOCD"); + retval = gpiod_line_request_input(gpiod_line[ADAPTER_GPIO_IDX_SWDIO], "OpenOCD"); if (retval < 0) LOG_WARNING("Fail request_input line swdio"); - if (gpiod_swdio_dir) { - retval = gpiod_line_set_value(gpiod_swdio_dir, swdio_dir_is_active_high ? 0 : 1); + if (gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR]) { + retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR], 0); if (retval < 0) LOG_WARNING("Fail set swdio_dir"); } @@ -186,7 +160,7 @@ static int linuxgpiod_swd_write(int swclk, int swdio) if (!swdio_input) { if (!last_stored || (swdio != last_swdio)) { - retval = gpiod_line_set_value(gpiod_swdio, swdio); + retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO], swdio); if (retval < 0) LOG_WARNING("Fail set swdio"); } @@ -194,7 +168,7 @@ static int linuxgpiod_swd_write(int swclk, int swdio) /* write swclk last */ if (!last_stored || (swclk != last_swclk)) { - retval = gpiod_line_set_value(gpiod_swclk, swclk); + retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWCLK], swclk); if (retval < 0) LOG_WARNING("Fail set swclk"); } @@ -210,10 +184,10 @@ static int linuxgpiod_blink(int on) { int retval; - if (!gpiod_led) + if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_LED)) return ERROR_OK; - retval = gpiod_line_set_value(gpiod_led, on); + retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_LED], on); if (retval < 0) LOG_WARNING("Fail set led"); return retval; @@ -239,16 +213,18 @@ static int linuxgpiod_reset(int trst, int srst) LOG_DEBUG("linuxgpiod_reset"); - /* assume active low */ - if (gpiod_srst) { - retval1 = gpiod_line_set_value(gpiod_srst, srst ? 0 : 1); + /* + * active low behaviour handled by "adaptor gpio" command and + * GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW flag when requesting the line. + */ + if (gpiod_line[ADAPTER_GPIO_IDX_SRST]) { + retval1 = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SRST], srst); if (retval1 < 0) LOG_WARNING("set srst value failed"); } - /* assume active low */ - if (gpiod_trst) { - retval2 = gpiod_line_set_value(gpiod_trst, trst ? 0 : 1); + if (gpiod_line[ADAPTER_GPIO_IDX_TRST]) { + retval2 = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TRST], trst); if (retval2 < 0) LOG_WARNING("set trst value failed"); } @@ -256,127 +232,134 @@ static int linuxgpiod_reset(int trst, int srst) return ((retval1 < 0) || (retval2 < 0)) ? ERROR_FAIL : ERROR_OK; } -/* - * Helper function to determine if gpio number is valid - * - * Assume here that there will be less than 10000 gpios per gpiochip - */ -static bool is_gpio_valid(int gpio) -{ - return gpio >= 0 && gpio < 10000; -} - static bool linuxgpiod_jtag_mode_possible(void) { - if (!is_gpio_valid(tck_gpio)) + if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TCK)) return false; - if (!is_gpio_valid(tms_gpio)) + if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TMS)) return false; - if (!is_gpio_valid(tdi_gpio)) + if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDI)) return false; - if (!is_gpio_valid(tdo_gpio)) + if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDO)) return false; return true; } static bool linuxgpiod_swd_mode_possible(void) { - if (!is_gpio_valid(swclk_gpio)) + if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWCLK)) return false; - if (!is_gpio_valid(swdio_gpio)) + if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO)) return false; return true; } -static inline void helper_release(struct gpiod_line *line) +static inline void helper_release(enum adapter_gpio_config_index idx) { - if (line) - gpiod_line_release(line); + if (gpiod_line[idx]) { + gpiod_line_release(gpiod_line[idx]); + gpiod_line[idx] = NULL; + } + if (gpiod_chip[idx]) { + gpiod_chip_close(gpiod_chip[idx]); + gpiod_chip[idx] = NULL; + } } static int linuxgpiod_quit(void) { - helper_release(gpiod_led); - helper_release(gpiod_srst); - helper_release(gpiod_swdio); - helper_release(gpiod_swclk); - helper_release(gpiod_trst); - helper_release(gpiod_tms); - helper_release(gpiod_tck); - helper_release(gpiod_tdi); - helper_release(gpiod_tdo); - - if (gpiod_chip_led != NULL) - gpiod_chip_close(gpiod_chip_led); - if (gpiod_chip_srst != NULL) - gpiod_chip_close(gpiod_chip_srst); - if (gpiod_chip_swdio != NULL) - gpiod_chip_close(gpiod_chip_swdio); - if (gpiod_chip_swdio_dir != NULL) - gpiod_chip_close(gpiod_chip_swdio_dir); - if (gpiod_chip_swclk != NULL) - gpiod_chip_close(gpiod_chip_swclk); - if (gpiod_chip_trst != NULL) - gpiod_chip_close(gpiod_chip_trst); - if (gpiod_chip_tms != NULL) - gpiod_chip_close(gpiod_chip_tms); - if (gpiod_chip_tck != NULL) - gpiod_chip_close(gpiod_chip_tck); - if (gpiod_chip_tdi != NULL) - gpiod_chip_close(gpiod_chip_tdi); - if (gpiod_chip_tdo != NULL) - gpiod_chip_close(gpiod_chip_tdo); + LOG_DEBUG("linuxgpiod_quit"); + for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i) + helper_release(i); return ERROR_OK; } -static struct gpiod_line *helper_get_line(const char *label, - struct gpiod_chip *gpiod_chip, unsigned int offset, - int val, int dir, int flags) +static int helper_get_line(enum adapter_gpio_config_index idx) { - struct gpiod_line *line; - int retval; + if (!is_gpio_config_valid(idx)) + return ERROR_OK; + + int dir = GPIOD_LINE_REQUEST_DIRECTION_INPUT, flags = 0, val = 0, retval; + + gpiod_chip[idx] = gpiod_chip_open_by_number(adapter_gpio_config[idx].chip_num); + if (!gpiod_chip[idx]) { + LOG_ERROR("Cannot open LinuxGPIOD chip %d for %s", adapter_gpio_config[idx].chip_num, + adapter_gpio_get_name(idx)); + return ERROR_JTAG_INIT_FAILED; + } + + gpiod_line[idx] = gpiod_chip_get_line(gpiod_chip[idx], adapter_gpio_config[idx].gpio_num); + if (!gpiod_line[idx]) { + LOG_ERROR("Error get line %s", adapter_gpio_get_name(idx)); + return ERROR_JTAG_INIT_FAILED; + } + + switch (adapter_gpio_config[idx].init_state) { + case ADAPTER_GPIO_INIT_STATE_INPUT: + dir = GPIOD_LINE_REQUEST_DIRECTION_INPUT; + break; + case ADAPTER_GPIO_INIT_STATE_INACTIVE: + dir = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT; + val = 0; + break; + case ADAPTER_GPIO_INIT_STATE_ACTIVE: + dir = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT; + val = 1; + break; + } + + switch (adapter_gpio_config[idx].drive) { + case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL: + break; + case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN: + flags |= GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN; + break; + case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE: + flags |= GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE; + break; + } - line = gpiod_chip_get_line(gpiod_chip, offset); - if (!line) { - LOG_ERROR("Error get line %s", label); - return NULL; + switch (adapter_gpio_config[idx].pull) { + case ADAPTER_GPIO_PULL_NONE: +#ifdef GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE + flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE; +#endif + break; + case ADAPTER_GPIO_PULL_UP: +#ifdef GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP + flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP; +#else + LOG_WARNING("linuxgpiod: ignoring request for pull-up on %s: not supported by gpiod v%s", + adapter_gpio_get_name(idx), gpiod_version_string()); +#endif + break; + case ADAPTER_GPIO_PULL_DOWN: +#ifdef GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN + flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN; +#else + LOG_WARNING("linuxgpiod: ignoring request for pull-down on %s: not supported by gpiod v%s", + adapter_gpio_get_name(idx), gpiod_version_string()); +#endif + break; } + if (adapter_gpio_config[idx].active_low) + flags |= GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW; + struct gpiod_line_request_config config = { .consumer = "OpenOCD", .request_type = dir, .flags = flags, }; - retval = gpiod_line_request(line, &config, val); + retval = gpiod_line_request(gpiod_line[idx], &config, val); if (retval < 0) { - LOG_ERROR("Error requesting gpio line %s", label); - return NULL; + LOG_ERROR("Error requesting gpio line %s", adapter_gpio_get_name(idx)); + return ERROR_JTAG_INIT_FAILED; } - return line; -} - -static struct gpiod_line *helper_get_input_line(const char *label, - struct gpiod_chip *gpiod_chip, unsigned int offset) -{ - return helper_get_line(label, gpiod_chip, offset, 0, - GPIOD_LINE_REQUEST_DIRECTION_INPUT, 0); -} - -static struct gpiod_line *helper_get_output_line(const char *label, - struct gpiod_chip *gpiod_chip, unsigned int offset, int val) -{ - return helper_get_line(label, gpiod_chip, offset, val, - GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, 0); -} - -static struct gpiod_line *helper_get_open_drain_output_line(const char *label, - struct gpiod_chip *gpiod_chip, unsigned int offset, int val) -{ - return helper_get_line(label, gpiod_chip, offset, val, - GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN); + return ERROR_OK; } static int linuxgpiod_init(void) @@ -384,11 +367,11 @@ static int linuxgpiod_init(void) LOG_INFO("Linux GPIOD JTAG/SWD bitbang driver"); bitbang_interface = &linuxgpiod_bitbang; + adapter_gpio_config = adapter_gpio_get_config(); /* - * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST - * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high. - * For SWD, SWCLK and SWDIO are configures as output high. + * Configure JTAG/SWD signals. Default directions and initial states are handled + * by adapter.c and "adapter gpio" command. */ if (transport_is_jtag()) { @@ -397,129 +380,44 @@ static int linuxgpiod_init(void) goto out_error; } - gpiod_chip_tdo = gpiod_chip_open_by_number(tdo_gpiochip); - if (!gpiod_chip_tdo) { - LOG_ERROR("Cannot open LinuxGPIOD tdo_gpiochip %d", tdo_gpiochip); - goto out_error; - } - gpiod_chip_tdi = gpiod_chip_open_by_number(tdi_gpiochip); - if (!gpiod_chip_tdi) { - LOG_ERROR("Cannot open LinuxGPIOD tdi_gpiochip %d", tdi_gpiochip); - goto out_error; - } - gpiod_chip_tck = gpiod_chip_open_by_number(tck_gpiochip); - if (!gpiod_chip_tck) { - LOG_ERROR("Cannot open LinuxGPIOD tck_gpiochip %d", tck_gpiochip); - goto out_error; - } - gpiod_chip_tms = gpiod_chip_open_by_number(tms_gpiochip); - if (!gpiod_chip_tms) { - LOG_ERROR("Cannot open LinuxGPIOD tms_gpiochip %d", tms_gpiochip); - goto out_error; - } - - gpiod_tdo = helper_get_input_line("tdo", gpiod_chip_tdo, tdo_gpio); - if (!gpiod_tdo) - goto out_error; - - gpiod_tdi = helper_get_output_line("tdi", gpiod_chip_tdi, tdi_gpio, 0); - if (!gpiod_tdi) - goto out_error; - - gpiod_tck = helper_get_output_line("tck", gpiod_chip_tck, tck_gpio, 0); - if (!gpiod_tck) - goto out_error; - - gpiod_tms = helper_get_output_line("tms", gpiod_chip_tms, tms_gpio, 1); - if (!gpiod_tms) - goto out_error; - - if (is_gpio_valid(trst_gpio)) { - gpiod_chip_trst = gpiod_chip_open_by_number(trst_gpiochip); - if (!gpiod_chip_trst) { - LOG_ERROR("Cannot open LinuxGPIOD trst_gpiochip %d", trst_gpiochip); + if (helper_get_line(ADAPTER_GPIO_IDX_TDO) != ERROR_OK || + helper_get_line(ADAPTER_GPIO_IDX_TDI) != ERROR_OK || + helper_get_line(ADAPTER_GPIO_IDX_TCK) != ERROR_OK || + helper_get_line(ADAPTER_GPIO_IDX_TMS) != ERROR_OK || + helper_get_line(ADAPTER_GPIO_IDX_TRST) != ERROR_OK) goto out_error; - } - - if (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN) - gpiod_trst = helper_get_open_drain_output_line("trst", gpiod_chip_trst, trst_gpio, 1); - else - gpiod_trst = helper_get_output_line("trst", gpiod_chip_trst, trst_gpio, 1); - - if (!gpiod_trst) - goto out_error; - } } if (transport_is_swd()) { + int retval1, retval2; if (!linuxgpiod_swd_mode_possible()) { LOG_ERROR("Require swclk and swdio gpio for SWD mode"); goto out_error; } - gpiod_chip_swclk = gpiod_chip_open_by_number(swclk_gpiochip); - if (!gpiod_chip_swclk) { - LOG_ERROR("Cannot open LinuxGPIOD swclk_gpiochip %d", swclk_gpiochip); - goto out_error; + /* + * swdio and its buffer should be initialized in the order that prevents + * two outputs from being connected together. This will occur if the + * swdio GPIO is configured as an output while the external buffer is + * configured to send the swdio signal from the target to the GPIO. + */ + if (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].init_state == ADAPTER_GPIO_INIT_STATE_INPUT) { + retval1 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO); + retval2 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO_DIR); + } else { + retval1 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO_DIR); + retval2 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO); } - gpiod_chip_swdio = gpiod_chip_open_by_number(swdio_gpiochip); - if (!gpiod_chip_swdio) { - LOG_ERROR("Cannot open LinuxGPIOD swdio_gpiochip %d", swdio_gpiochip); + if (retval1 != ERROR_OK || retval2 != ERROR_OK) goto out_error; - } - - if (is_gpio_valid(swdio_dir_gpio)) { - gpiod_chip_swdio_dir = gpiod_chip_open_by_number(swdio_dir_gpiochip); - if (!gpiod_chip_swdio_dir) { - LOG_ERROR("Cannot open LinuxGPIOD swdio_dir_gpiochip %d", swdio_dir_gpiochip); - goto out_error; - } - } - gpiod_swclk = helper_get_output_line("swclk", gpiod_chip_swclk, swclk_gpio, 1); - if (!gpiod_swclk) - goto out_error; - - /* Set buffer direction before making SWDIO an output */ - if (is_gpio_valid(swdio_dir_gpio)) { - gpiod_swdio_dir = helper_get_output_line("swdio_dir", gpiod_chip_swdio_dir, swdio_dir_gpio, - swdio_dir_is_active_high ? 1 : 0); - if (!gpiod_swdio_dir) - goto out_error; - } - - gpiod_swdio = helper_get_output_line("swdio", gpiod_chip_swdio, swdio_gpio, 1); - if (!gpiod_swdio) + if (helper_get_line(ADAPTER_GPIO_IDX_SWCLK) != ERROR_OK) goto out_error; } - if (is_gpio_valid(srst_gpio)) { - gpiod_chip_srst = gpiod_chip_open_by_number(srst_gpiochip); - if (!gpiod_chip_srst) { - LOG_ERROR("Cannot open LinuxGPIOD srst_gpiochip %d", srst_gpiochip); - goto out_error; - } - - if (jtag_get_reset_config() & RESET_SRST_PUSH_PULL) - gpiod_srst = helper_get_output_line("srst", gpiod_chip_srst, srst_gpio, 1); - else - gpiod_srst = helper_get_open_drain_output_line("srst", gpiod_chip_srst, srst_gpio, 1); - - if (!gpiod_srst) - goto out_error; - } - - if (is_gpio_valid(led_gpio)) { - gpiod_chip_led = gpiod_chip_open_by_number(led_gpiochip); - if (!gpiod_chip_led) { - LOG_ERROR("Cannot open LinuxGPIOD led_gpiochip %d", led_gpiochip); - goto out_error; - } - - gpiod_led = helper_get_output_line("led", gpiod_chip_led, led_gpio, 0); - if (!gpiod_led) + if (helper_get_line(ADAPTER_GPIO_IDX_SRST) != ERROR_OK || + helper_get_line(ADAPTER_GPIO_IDX_LED) != ERROR_OK) goto out_error; - } return ERROR_OK; @@ -529,241 +427,6 @@ out_error: return ERROR_JTAG_INIT_FAILED; } -COMMAND_HELPER(linuxgpiod_helper_gpionum, const char *name, int *chip, int *line) -{ - int i = 0; - if (CMD_ARGC > 2) - return ERROR_COMMAND_SYNTAX_ERROR; - if (CMD_ARGC == 2) { - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], *chip); - i = 1; - } - if (CMD_ARGC > 0) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[i], *line); - command_print(CMD, "LinuxGPIOD %s: chip = %d, num = %d", name, *chip, *line); - return ERROR_OK; -} - -COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionums) -{ - if (CMD_ARGC == 4) { - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio); - } else if (CMD_ARGC != 0) { - return ERROR_COMMAND_SYNTAX_ERROR; - } - - command_print(CMD, - "LinuxGPIOD nums: tck = %d, tms = %d, tdi = %d, tdo = %d", - tck_gpio, tms_gpio, tdi_gpio, tdo_gpio); - - return ERROR_OK; -} - -COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tck) -{ - return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tck", &tck_gpiochip, - &tck_gpio); -} - -COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tms) -{ - return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tms", &tms_gpiochip, - &tms_gpio); -} - -COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tdo) -{ - return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tdo", &tdo_gpiochip, - &tdo_gpio); -} - -COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tdi) -{ - return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tdi", &tdi_gpiochip, - &tdi_gpio); -} - -COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_srst) -{ - return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "srst", &srst_gpiochip, - &srst_gpio); -} - -COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_trst) -{ - return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "trst", &trst_gpiochip, - &trst_gpio); -} - -COMMAND_HANDLER(linuxgpiod_handle_swd_gpionums) -{ - if (CMD_ARGC == 2) { - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio); - } else if (CMD_ARGC != 0) { - return ERROR_COMMAND_SYNTAX_ERROR; - } - - command_print(CMD, - "LinuxGPIOD nums: swclk = %d, swdio = %d", - swclk_gpio, swdio_gpio); - - return ERROR_OK; -} - -COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swclk) -{ - return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swclk", &swclk_gpiochip, - &swclk_gpio); -} - -COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swdio) -{ - return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swdio", &swdio_gpiochip, - &swdio_gpio); -} - -COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swdio_dir) -{ - return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swdio_dir", &swdio_dir_gpiochip, - &swdio_dir_gpio); -} - -COMMAND_HANDLER(linuxgpiod_handle_gpionum_led) -{ - return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "led", &led_gpiochip, - &led_gpio); -} - -COMMAND_HANDLER(linuxgpiod_handle_gpiochip) -{ - if (CMD_ARGC == 1) { - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], gpiochip); - tck_gpiochip = gpiochip; - tms_gpiochip = gpiochip; - tdi_gpiochip = gpiochip; - tdo_gpiochip = gpiochip; - trst_gpiochip = gpiochip; - srst_gpiochip = gpiochip; - swclk_gpiochip = gpiochip; - swdio_gpiochip = gpiochip; - swdio_dir_gpiochip = gpiochip; - led_gpiochip = gpiochip; - } - - command_print(CMD, "LinuxGPIOD gpiochip = %d", gpiochip); - return ERROR_OK; -} - -static const struct command_registration linuxgpiod_subcommand_handlers[] = { - { - .name = "jtag_nums", - .handler = linuxgpiod_handle_jtag_gpionums, - .mode = COMMAND_CONFIG, - .help = "gpio numbers for tck, tms, tdi, tdo. (in that order)", - .usage = "tck tms tdi tdo", - }, - { - .name = "tck_num", - .handler = linuxgpiod_handle_jtag_gpionum_tck, - .mode = COMMAND_CONFIG, - .help = "gpio chip number (optional) and gpio number for tck.", - .usage = "[chip] tck", - }, - { - .name = "tms_num", - .handler = linuxgpiod_handle_jtag_gpionum_tms, - .mode = COMMAND_CONFIG, - .help = "gpio chip number (optional) and gpio number for tms.", - .usage = "[chip] tms", - }, - { - .name = "tdo_num", - .handler = linuxgpiod_handle_jtag_gpionum_tdo, - .mode = COMMAND_CONFIG, - .help = "gpio chip number (optional) and gpio number for tdo.", - .usage = "[chip] tdo", - }, - { - .name = "tdi_num", - .handler = linuxgpiod_handle_jtag_gpionum_tdi, - .mode = COMMAND_CONFIG, - .help = "gpio chip number (optional) and gpio number for tdi.", - .usage = "[chip] tdi", - }, - { - .name = "srst_num", - .handler = linuxgpiod_handle_jtag_gpionum_srst, - .mode = COMMAND_CONFIG, - .help = "gpio chip number (optional) and gpio number for srst.", - .usage = "[chip] srst", - }, - { - .name = "trst_num", - .handler = linuxgpiod_handle_jtag_gpionum_trst, - .mode = COMMAND_CONFIG, - .help = "gpio chip number (optional) and gpio number for trst.", - .usage = "[chip] trst", - }, - { - .name = "swd_nums", - .handler = linuxgpiod_handle_swd_gpionums, - .mode = COMMAND_CONFIG, - .help = "gpio numbers for swclk, swdio. (in that order)", - .usage = "swclk swdio", - }, - { - .name = "swclk_num", - .handler = linuxgpiod_handle_swd_gpionum_swclk, - .mode = COMMAND_CONFIG, - .help = "gpio chip number (optional) and gpio number for swclk.", - .usage = "[chip] swclk", - }, - { - .name = "swdio_num", - .handler = linuxgpiod_handle_swd_gpionum_swdio, - .mode = COMMAND_CONFIG, - .help = "gpio chip number (optional) and gpio number for swdio.", - .usage = "[chip] swdio", - }, - { - .name = "swdio_dir_num", - .handler = linuxgpiod_handle_swd_gpionum_swdio_dir, - .mode = COMMAND_CONFIG, - .help = "gpio chip number (optional) and gpio number for swdio_dir.", - .usage = "[chip] swdio_dir", - }, - { - .name = "led_num", - .handler = linuxgpiod_handle_gpionum_led, - .mode = COMMAND_CONFIG, - .help = "gpio chip number (optional) and gpio number for LED.", - .usage = "[chip] led", - }, - { - .name = "gpiochip", - .handler = linuxgpiod_handle_gpiochip, - .mode = COMMAND_CONFIG, - .help = "number of the gpiochip.", - .usage = "gpiochip", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration linuxgpiod_command_handlers[] = { - { - .name = "linuxgpiod", - .mode = COMMAND_ANY, - .help = "perform linuxgpiod management", - .chain = linuxgpiod_subcommand_handlers, - .usage = "", - }, - COMMAND_REGISTRATION_DONE -}; - static const char *const linuxgpiod_transport[] = { "swd", "jtag", NULL }; static struct jtag_interface linuxgpiod_interface = { @@ -774,7 +437,6 @@ static struct jtag_interface linuxgpiod_interface = { struct adapter_driver linuxgpiod_adapter_driver = { .name = "linuxgpiod", .transports = linuxgpiod_transport, - .commands = linuxgpiod_command_handlers, .init = linuxgpiod_init, .quit = linuxgpiod_quit, diff --git a/src/jtag/drivers/minidriver_imp.h b/src/jtag/drivers/minidriver_imp.h index cd59a74..7afb463 100644 --- a/src/jtag/drivers/minidriver_imp.h +++ b/src/jtag/drivers/minidriver_imp.h @@ -1,20 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> * * Copyright (C) 2007-2009 Øyvind Harboe <oyvind.harboe@zylin.com> * * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_MINIDRIVER_IMP_H diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c index 0e3d2be..18aeb38 100644 --- a/src/jtag/drivers/mpsse.c +++ b/src/jtag/drivers/mpsse.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /************************************************************************** * Copyright (C) 2012 by Andreas Fritiofson * * andreas.fritiofson@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/mpsse.h b/src/jtag/drivers/mpsse.h index 651eef9..a017aff 100644 --- a/src/jtag/drivers/mpsse.h +++ b/src/jtag/drivers/mpsse.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /************************************************************************** * Copyright (C) 2012 by Andreas Fritiofson * * andreas.fritiofson@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_MPSSE_H diff --git a/src/jtag/drivers/nulink_usb.c b/src/jtag/drivers/nulink_usb.c index 84a4420..4fdb857 100644 --- a/src/jtag/drivers/nulink_usb.c +++ b/src/jtag/drivers/nulink_usb.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2016-2017 by Nuvoton * * Zale Yu <cyyu@nuvoton.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c index ae21cf2..d0c5277 100644 --- a/src/jtag/drivers/opendous.c +++ b/src/jtag/drivers/opendous.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * * * Copyright (C) 2009 by Cahya Wirawan <cahya@gmx.at> * @@ -11,19 +13,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index 771b6e6..6be9507 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /******************************************************************************* * Driver for OpenJTAG Project (www.openjtag.org) * * Compatible with libftdi drivers. * @@ -18,19 +20,6 @@ * And jlink.c * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /*************************************************************************** diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c index f7665eb..d8fe713 100644 --- a/src/jtag/drivers/osbdm.c +++ b/src/jtag/drivers/osbdm.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2012 by Jan Dakinevich * * jan.dakinevich@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/src/jtag/drivers/parport.c b/src/jtag/drivers/parport.c index 9273e3e..4073d06 100644 --- a/src/jtag/drivers/parport.c +++ b/src/jtag/drivers/parport.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/presto.c b/src/jtag/drivers/presto.c index e938a3b..f6e13f7 100644 --- a/src/jtag/drivers/presto.c +++ b/src/jtag/drivers/presto.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Pavel Chromy * * chromy@asix.cz * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /** diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c index 6ab7cc9..36bcbe1 100644 --- a/src/jtag/drivers/remote_bitbang.c +++ b/src/jtag/drivers/remote_bitbang.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Richard Uhler * * ruhler@mit.edu * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c index 0cf9dbb..c933b3e 100644 --- a/src/jtag/drivers/rlink.c +++ b/src/jtag/drivers/rlink.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 Rob Brown, Lou Deluxe * * rob@cobbleware.com, lou.openocd012@fixit.nospammail.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/rlink.h b/src/jtag/drivers/rlink.h index 0c15a32..38f8429 100644 --- a/src/jtag/drivers/rlink.h +++ b/src/jtag/drivers/rlink.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2008 Lou Deluxe * * lou.openocd012@fixit.nospammail.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_RLINK_H diff --git a/src/jtag/drivers/rlink_call.m4 b/src/jtag/drivers/rlink_call.m4 index bf07afa..39ac25c 100644 --- a/src/jtag/drivers/rlink_call.m4 +++ b/src/jtag/drivers/rlink_call.m4 @@ -1,21 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Copyright (C) 2008 Lou Deluxe +# lou.openocd012@fixit.nospammail.net +# + m4_divert(`-1') -/*************************************************************************** - * Copyright (C) 2008 Lou Deluxe * - * lou.openocd012@fixit.nospammail.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ m4_dnl Setup and hold times depend on SHIFTER_PRESCALER m4_define(`SETUP_DELAY_CYCLES', m4_eval(`('SHIFTER_PRESCALER` + 1) / 2')) diff --git a/src/jtag/drivers/rlink_dtc_cmd.h b/src/jtag/drivers/rlink_dtc_cmd.h index ff9e8b2..b40ad17 100644 --- a/src/jtag/drivers/rlink_dtc_cmd.h +++ b/src/jtag/drivers/rlink_dtc_cmd.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2008 Lou Deluxe * * lou.openocd012@fixit.nospammail.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_RLINK_DTC_CMD_H diff --git a/src/jtag/drivers/rlink_ep1_cmd.h b/src/jtag/drivers/rlink_ep1_cmd.h index 3f9f2b3..812d7e5 100644 --- a/src/jtag/drivers/rlink_ep1_cmd.h +++ b/src/jtag/drivers/rlink_ep1_cmd.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2008 Lou Deluxe * * lou.openocd012@fixit.nospammail.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_RLINK_EP1_CMD_H diff --git a/src/jtag/drivers/rlink_init.m4 b/src/jtag/drivers/rlink_init.m4 index 8ad2f51..e77e943 100644 --- a/src/jtag/drivers/rlink_init.m4 +++ b/src/jtag/drivers/rlink_init.m4 @@ -1,21 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Copyright (C) 2008 Lou Deluxe +# lou.openocd012@fixit.nospammail.net +# + m4_divert(`-1') -/*************************************************************************** - * Copyright (C) 2008 Lou Deluxe * - * lou.openocd012@fixit.nospammail.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ m4_undefine(`CTRL_MPEG_L') m4_undefine(`CTRL_CARD_L') diff --git a/src/jtag/drivers/rlink_st7.h b/src/jtag/drivers/rlink_st7.h index 3d573e7..b891024 100644 --- a/src/jtag/drivers/rlink_st7.h +++ b/src/jtag/drivers/rlink_st7.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2008 Lou Deluxe * * lou.openocd012@fixit.nospammail.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_RLINK_ST7_H diff --git a/src/jtag/drivers/rshim.c b/src/jtag/drivers/rshim.c index 246e931..174fa12 100644 --- a/src/jtag/drivers/rshim.c +++ b/src/jtag/drivers/rshim.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright (c) 2020, Mellanox Technologies Ltd. - All Rights Reserved * Liming Sun <lsun@mellanox.com> - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H @@ -282,36 +271,44 @@ static int rshim_ap_q_read(struct adiv5_ap *ap, unsigned int reg, uint32_t addr; int rc = ERROR_OK, tile; + if (is_adiv6(ap->dap)) { + static bool error_flagged; + if (!error_flagged) + LOG_ERROR("ADIv6 dap not supported by rshim dap-direct mode"); + error_flagged = true; + return ERROR_FAIL; + } + switch (reg) { - case MEM_AP_REG_CSW: + case ADIV5_MEM_AP_REG_CSW: *data = ap_csw; break; - case MEM_AP_REG_CFG: + case ADIV5_MEM_AP_REG_CFG: *data = 0; break; - case MEM_AP_REG_BASE: + case ADIV5_MEM_AP_REG_BASE: *data = RSH_CS_ROM_BASE; break; - case AP_REG_IDR: + case ADIV5_AP_REG_IDR: if (ap->ap_num == 0) *data = APB_AP_IDR; else *data = 0; break; - case MEM_AP_REG_BD0: - case MEM_AP_REG_BD1: - case MEM_AP_REG_BD2: - case MEM_AP_REG_BD3: + case ADIV5_MEM_AP_REG_BD0: + case ADIV5_MEM_AP_REG_BD1: + case ADIV5_MEM_AP_REG_BD2: + case ADIV5_MEM_AP_REG_BD3: addr = (ap_tar & ~0xf) + (reg & 0x0C); ap_addr_2_tile(&tile, &addr); rc = coresight_read(tile, addr, data); break; - case MEM_AP_REG_DRW: + case ADIV5_MEM_AP_REG_DRW: addr = (ap_tar & ~0x3) + ap_tar_inc; ap_addr_2_tile(&tile, &addr); rc = coresight_read(tile, addr, data); @@ -338,31 +335,39 @@ static int rshim_ap_q_write(struct adiv5_ap *ap, unsigned int reg, int rc = ERROR_OK, tile; uint32_t addr; + if (is_adiv6(ap->dap)) { + static bool error_flagged; + if (!error_flagged) + LOG_ERROR("ADIv6 dap not supported by rshim dap-direct mode"); + error_flagged = true; + return ERROR_FAIL; + } + if (ap_bank != 0) { rshim_dap_retval = ERROR_FAIL; return ERROR_FAIL; } switch (reg) { - case MEM_AP_REG_CSW: + case ADIV5_MEM_AP_REG_CSW: ap_csw = data; break; - case MEM_AP_REG_TAR: + case ADIV5_MEM_AP_REG_TAR: ap_tar = data; ap_tar_inc = 0; break; - case MEM_AP_REG_BD0: - case MEM_AP_REG_BD1: - case MEM_AP_REG_BD2: - case MEM_AP_REG_BD3: + case ADIV5_MEM_AP_REG_BD0: + case ADIV5_MEM_AP_REG_BD1: + case ADIV5_MEM_AP_REG_BD2: + case ADIV5_MEM_AP_REG_BD3: addr = (ap_tar & ~0xf) + (reg & 0x0C); ap_addr_2_tile(&tile, &addr); rc = coresight_write(tile, addr, data); break; - case MEM_AP_REG_DRW: + case ADIV5_MEM_AP_REG_DRW: ap_drw = data; addr = (ap_tar & ~0x3) + ap_tar_inc; ap_addr_2_tile(&tile, &addr); diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index bb2c817..5b051c1 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2020 by Tarek Bochkati * * Tarek Bochkati <tarek.bouchkati@gmail.com> * @@ -13,19 +15,6 @@ * spen@spen-soft.co.uk * * * * This code is based on https://github.com/texane/stlink * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -4152,7 +4141,7 @@ static int stlink_dap_reinit_interface(void) stlink_dap_handle->reconnect_pending = false; /* on new FW, calling mode-leave closes all the opened AP; reopen them! */ if (stlink_dap_handle->version.flags & STLINK_F_HAS_AP_INIT) - for (int apsel = 0; apsel <= DP_APSEL_MAX; apsel++) + for (unsigned int apsel = 0; apsel <= DP_APSEL_MAX; apsel++) if (test_bit(apsel, opened_ap)) { clear_bit(apsel, opened_ap); stlink_dap_open_ap(apsel); @@ -4286,7 +4275,15 @@ static int stlink_dap_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *d uint32_t dummy; int retval; - if (reg != AP_REG_IDR) { + if (is_adiv6(dap)) { + static bool error_flagged; + if (!error_flagged) + LOG_ERROR("ADIv6 dap not supported by stlink dap-direct mode"); + error_flagged = true; + return ERROR_FAIL; + } + + if (reg != ADIV5_AP_REG_IDR) { retval = stlink_dap_open_ap(ap->ap_num); if (retval != ERROR_OK) return retval; @@ -4304,6 +4301,14 @@ static int stlink_dap_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t d struct adiv5_dap *dap = ap->dap; int retval; + if (is_adiv6(dap)) { + static bool error_flagged; + if (!error_flagged) + LOG_ERROR("ADIv6 dap not supported by stlink dap-direct mode"); + error_flagged = true; + return ERROR_FAIL; + } + retval = stlink_dap_open_ap(ap->ap_num); if (retval != ERROR_OK) return retval; @@ -4332,7 +4337,7 @@ static int stlink_usb_misc_rw_segment(void *handle, const struct dap_queue *q, u LOG_DEBUG("Queue: %u commands in %u items", len, items); - int ap_num = DP_APSEL_INVALID; + uint32_t ap_num = DP_APSEL_INVALID; unsigned int cmd_index = 0; unsigned int val_index = ALIGN_UP(items, 4); for (unsigned int i = 0; i < len; i++) { @@ -4481,7 +4486,7 @@ static int stlink_usb_count_misc_rw_queue(void *handle, const struct dap_queue * { struct stlink_usb_handle_s *h = handle; unsigned int i, items = 0; - int ap_num = DP_APSEL_INVALID; + uint32_t ap_num = DP_APSEL_INVALID; unsigned int misc_max_items = (h->version.stlink == 2) ? STLINK_V2_RW_MISC_SIZE : STLINK_V3_RW_MISC_SIZE; if (!(h->version.flags & STLINK_F_HAS_RW_MISC)) @@ -4591,7 +4596,7 @@ static void stlink_dap_run_internal(struct adiv5_dap *dap) break; case CMD_AP_WRITE: /* ignore increment packed, not supported */ - if (q->ap_w.reg == MEM_AP_REG_CSW) + if (q->ap_w.reg == ADIV5_MEM_AP_REG_CSW) q->ap_w.data &= ~CSW_ADDRINC_PACKED; retval = stlink_dap_ap_write(q->ap_w.ap, q->ap_w.reg, q->ap_w.data); break; @@ -4736,18 +4741,18 @@ static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, /* test STLINK_F_HAS_CSW implicitly tests STLINK_F_HAS_MEM_16BIT, STLINK_F_HAS_MEM_RD_NO_INC * and STLINK_F_HAS_RW_MISC */ if ((stlink_dap_handle->version.flags & STLINK_F_HAS_CSW) && - (reg == MEM_AP_REG_DRW || reg == MEM_AP_REG_BD0 || reg == MEM_AP_REG_BD1 || - reg == MEM_AP_REG_BD2 || reg == MEM_AP_REG_BD3)) { + (reg == ADIV5_MEM_AP_REG_DRW || reg == ADIV5_MEM_AP_REG_BD0 || reg == ADIV5_MEM_AP_REG_BD1 || + reg == ADIV5_MEM_AP_REG_BD2 || reg == ADIV5_MEM_AP_REG_BD3)) { /* de-queue previous write-TAR */ struct dap_queue *prev_q = q - 1; - if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_TAR) { + if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == ADIV5_MEM_AP_REG_TAR) { stlink_dap_handle->queue_index = i; i--; q = prev_q; prev_q--; } /* de-queue previous write-CSW if it didn't changed ap->csw_default */ - if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_CSW && + if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == ADIV5_MEM_AP_REG_CSW && !prev_q->ap_w.changes_csw_default) { stlink_dap_handle->queue_index = i; q = prev_q; @@ -4769,7 +4774,7 @@ static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, return ERROR_FAIL; } - q->mem_ap.addr = (reg == MEM_AP_REG_DRW) ? ap->tar_value : ((ap->tar_value & ~0x0f) | (reg & 0x0c)); + q->mem_ap.addr = (reg == ADIV5_MEM_AP_REG_DRW) ? ap->tar_value : ((ap->tar_value & ~0x0f) | (reg & 0x0c)); q->mem_ap.ap = ap; q->mem_ap.p_data = data; q->mem_ap.csw = ap->csw_default; @@ -4802,18 +4807,18 @@ static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, /* test STLINK_F_HAS_CSW implicitly tests STLINK_F_HAS_MEM_16BIT, STLINK_F_HAS_MEM_WR_NO_INC * and STLINK_F_HAS_RW_MISC */ if ((stlink_dap_handle->version.flags & STLINK_F_HAS_CSW) && - (reg == MEM_AP_REG_DRW || reg == MEM_AP_REG_BD0 || reg == MEM_AP_REG_BD1 || - reg == MEM_AP_REG_BD2 || reg == MEM_AP_REG_BD3)) { + (reg == ADIV5_MEM_AP_REG_DRW || reg == ADIV5_MEM_AP_REG_BD0 || reg == ADIV5_MEM_AP_REG_BD1 || + reg == ADIV5_MEM_AP_REG_BD2 || reg == ADIV5_MEM_AP_REG_BD3)) { /* de-queue previous write-TAR */ struct dap_queue *prev_q = q - 1; - if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_TAR) { + if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == ADIV5_MEM_AP_REG_TAR) { stlink_dap_handle->queue_index = i; i--; q = prev_q; prev_q--; } /* de-queue previous write-CSW if it didn't changed ap->csw_default */ - if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_CSW && + if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == ADIV5_MEM_AP_REG_CSW && !prev_q->ap_w.changes_csw_default) { stlink_dap_handle->queue_index = i; q = prev_q; @@ -4835,7 +4840,7 @@ static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, return ERROR_FAIL; } - q->mem_ap.addr = (reg == MEM_AP_REG_DRW) ? ap->tar_value : ((ap->tar_value & ~0x0f) | (reg & 0x0c)); + q->mem_ap.addr = (reg == ADIV5_MEM_AP_REG_DRW) ? ap->tar_value : ((ap->tar_value & ~0x0f) | (reg & 0x0c)); q->mem_ap.ap = ap; q->mem_ap.data = data; q->mem_ap.csw = ap->csw_default; @@ -4848,9 +4853,10 @@ static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, q->ap_w.reg = reg; q->ap_w.ap = ap; q->ap_w.data = data; - if (reg == MEM_AP_REG_CSW && ap->csw_default != last_csw_default[ap->ap_num]) { + uint8_t ap_num = ap->ap_num; + if (reg == ADIV5_MEM_AP_REG_CSW && ap->csw_default != last_csw_default[ap_num]) { q->ap_w.changes_csw_default = true; - last_csw_default[ap->ap_num] = ap->csw_default; + last_csw_default[ap_num] = ap->csw_default; } else { q->ap_w.changes_csw_default = false; } diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c index 103b810..ee254d6 100644 --- a/src/jtag/drivers/sysfsgpio.c +++ b/src/jtag/drivers/sysfsgpio.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* 2014-12: Addition of the SWD protocol support is based on the initial work diff --git a/src/jtag/drivers/ti_icdi_usb.c b/src/jtag/drivers/ti_icdi_usb.c index e48d0e2..ca52559 100644 --- a/src/jtag/drivers/ti_icdi_usb.c +++ b/src/jtag/drivers/ti_icdi_usb.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * * * Copyright (C) 2012 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c index 50609a6..fd29f12 100644 --- a/src/jtag/drivers/ulink.c +++ b/src/jtag/drivers/ulink.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011-2013 by Martin Schmoelzer * * <martin.schmoelzer@student.tuwien.ac.at> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/usb_blaster/Makefile.am b/src/jtag/drivers/usb_blaster/Makefile.am index a6694c5..0fb8a07 100644 --- a/src/jtag/drivers/usb_blaster/Makefile.am +++ b/src/jtag/drivers/usb_blaster/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libocdusbblaster.la %C%_libocdusbblaster_la_SOURCES = $(USB_BLASTER_SRC) %C%_libocdusbblaster_la_CPPFLAGS = -I$(top_srcdir)/src/jtag/drivers $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) $(LIBFTDI_CFLAGS) diff --git a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c index 21f9ae7..7f97818 100644 --- a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c +++ b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Driver for USB-JTAG, Altera USB-Blaster II and compatibles * * Copyright (C) 2013 Franck Jullien franck.jullien@gmail.com * - * 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, see <http://www.gnu.org/licenses/>. - * */ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/usb_blaster/ublast_access.h b/src/jtag/drivers/usb_blaster/ublast_access.h index ada764c..3e138bd 100644 --- a/src/jtag/drivers/usb_blaster/ublast_access.h +++ b/src/jtag/drivers/usb_blaster/ublast_access.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * Driver for USB-JTAG, Altera USB-Blaster and compatibles * @@ -10,19 +12,6 @@ * Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca * Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de * - * 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, see <http://www.gnu.org/licenses/>. - * */ #ifndef OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H diff --git a/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c b/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c index cb442f2..eb312ef 100644 --- a/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c +++ b/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Driver for USB-JTAG, Altera USB-Blaster and compatibles * @@ -9,19 +11,6 @@ * Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca * Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de * - * 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, see <http://www.gnu.org/licenses/>. - * */ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c index 049a243..8c37048 100644 --- a/src/jtag/drivers/usb_blaster/usb_blaster.c +++ b/src/jtag/drivers/usb_blaster/usb_blaster.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Driver for USB-JTAG, Altera USB-Blaster and compatibles * @@ -10,19 +12,6 @@ * Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca * Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de * - * 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, see <http://www.gnu.org/licenses/>. - * */ /* diff --git a/src/jtag/drivers/usbprog.c b/src/jtag/drivers/usbprog.c index a2ebdbc..0c0f24e 100644 --- a/src/jtag/drivers/usbprog.c +++ b/src/jtag/drivers/usbprog.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Benedikt Sauter * * sauter@ixbat.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* @@ -346,8 +335,6 @@ static void usbprog_reset(int trst, int srst) /*************** jtag lowlevel functions ********************/ -struct usb_bus *busses; - struct usbprog_jtag *usbprog_jtag_open(void) { const uint16_t vids[] = { VID, 0 }; diff --git a/src/jtag/drivers/vdebug.c b/src/jtag/drivers/vdebug.c index a81740c..ef7a493 100644 --- a/src/jtag/drivers/vdebug.c +++ b/src/jtag/drivers/vdebug.c @@ -1,35 +1,14 @@ -/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ -/*---------------------------------------------------------------------------- - * Copyright 2020-2021 Cadence Design Systems, Inc. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - *---------------------------------------------------------------------------- - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------- -*/ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) + +/* Copyright 2020-2022 Cadence Design Systems, Inc. */ /*! * @file * * @brief the virtual debug interface provides a connection between a sw debugger - * and the simulated, emulated core over a soft connection, implemented by DPI - * The vdebug debug driver currently supports JTAG transport - * TODO: implement support and test big endian platforms + * and the simulated, emulated core. The openOCD client connects via TCP sockets + * with vdebug server and over DPI-based transactor with the emulation or simulation + * The vdebug debug driver supports JTAG and DAP-level transports * */ @@ -68,16 +47,18 @@ #include "jtag/interface.h" #include "jtag/commands.h" #include "transport/transport.h" +#include "target/arm_adi_v5.h" #include "helper/time_support.h" #include "helper/replacements.h" #include "helper/log.h" +#include "helper/list.h" -#define VD_VERSION 43 +#define VD_VERSION 44 #define VD_BUFFER_LEN 4024 #define VD_CHEADER_LEN 24 #define VD_SHEADER_LEN 16 -#define VD_MAX_MEMORIES 4 +#define VD_MAX_MEMORIES 20 #define VD_POLL_INTERVAL 500 #define VD_SCALE_PSTOMS 1000000000 @@ -149,6 +130,8 @@ enum { VD_CMD_SIGSET = 0x0a, VD_CMD_SIGGET = 0x0b, VD_CMD_JTAGCLOCK = 0x0f, + VD_CMD_REGWRITE = 0x15, + VD_CMD_REGREAD = 0x16, VD_CMD_JTAGSHTAP = 0x1a, VD_CMD_MEMOPEN = 0x21, VD_CMD_MEMCLOSE = 0x22, @@ -156,6 +139,13 @@ enum { }; enum { + VD_ASPACE_AP = 0x01, + VD_ASPACE_DP = 0x02, + VD_ASPACE_ID = 0x03, + VD_ASPACE_AB = 0x04, +}; + +enum { VD_BATCH_NO = 0, VD_BATCH_WO = 1, VD_BATCH_WR = 2, @@ -165,37 +155,32 @@ struct vd_shm { struct { /* VD_CHEADER_LEN written by client */ uint8_t cmd; /* 000; command */ uint8_t type; /* 001; interface type */ - uint16_t waddr; /* 002; write pointer */ - uint16_t wbytes; /* 004; data bytes */ - uint16_t rbytes; /* 006; data bytes to read */ - uint16_t wwords; /* 008; data words */ - uint16_t rwords; /* 00a; data words to read */ - uint32_t rwdata; /* 00c; read/write data */ - uint32_t offset; /* 010; address offset */ - uint16_t offseth; /* 014; address offset 47:32 */ - uint16_t wid; /* 016; request id*/ - }; - union { /* 018; */ - uint8_t wd8[VD_BUFFER_LEN]; - uint16_t wd16[VD_BUFFER_LEN / 2]; - uint32_t wd32[VD_BUFFER_LEN / 4]; - uint64_t wd64[VD_BUFFER_LEN / 8]; + uint8_t waddr[2]; /* 002; write pointer */ + uint8_t wbytes[2]; /* 004; data bytes */ + uint8_t rbytes[2]; /* 006; data bytes to read */ + uint8_t wwords[2]; /* 008; data words */ + uint8_t rwords[2]; /* 00a; data words to read */ + uint8_t rwdata[4]; /* 00c; read/write data */ + uint8_t offset[4]; /* 010; address offset */ + uint8_t offseth[2]; /* 014; address offset 47:32 */ + uint8_t wid[2]; /* 016; request id*/ }; + uint8_t wd8[VD_BUFFER_LEN]; /* 018; */ struct { /* VD_SHEADER_LEN written by server */ - uint16_t rid; /* fd0: request id read */ - uint16_t awords; /* fd2: actual data words read back */ - int32_t status; /* fd4; */ - uint64_t duttime; /* fd8; */ + uint8_t rid[2]; /* fd0: request id read */ + uint8_t awords[2]; /* fd2: actual data words read back */ + uint8_t status[4]; /* fd4; */ + uint8_t duttime[8]; /* fd8; */ }; - union { /* fe0: */ - uint8_t rd8[VD_BUFFER_LEN]; - uint16_t rd16[VD_BUFFER_LEN / 2]; - uint32_t rd32[VD_BUFFER_LEN / 4]; - uint64_t rd64[VD_BUFFER_LEN / 8]; - }; - uint32_t state; /* 1f98; connection state */ - uint32_t count; /* 1f9c; */ + uint8_t rd8[VD_BUFFER_LEN]; /* fe0: */ + uint8_t state[4]; /* 1f98; connection state */ + uint8_t count[4]; /* 1f9c; */ uint8_t dummy[96]; /* 1fa0; 48+40B+8B; */ +} __attribute__((packed)); + +struct vd_rdata { + struct list_head lh; + uint8_t *rdata; }; struct vd_client { @@ -222,7 +207,7 @@ struct vd_client { char server_name[32]; char bfm_path[128]; char mem_path[VD_MAX_MEMORIES][128]; - uint8_t *tdo; + struct vd_rdata rdataq; }; struct vd_jtag_hdr { @@ -234,6 +219,16 @@ struct vd_jtag_hdr { uint64_t rlen:16; }; +struct vd_reg_hdr { + uint64_t prot:3; + uint64_t nonincr:1; + uint64_t haddr:12; + uint64_t tlen:11; + uint64_t asize:3; + uint64_t cmd:2; + uint64_t addr:32; +}; + static struct vd_shm *pbuf; static struct vd_client vdc; @@ -277,7 +272,7 @@ static int vdebug_socket_open(char *server_addr, uint32_t port) LOG_ERROR("socket_open: cannot resolve address %s, error %d", server_addr, vdebug_socket_error()); rc = VD_ERR_SOC_ADDR; } else { - ((struct sockaddr_in *)(ainfo->ai_addr))->sin_port = htons(port); + buf_set_u32((uint8_t *)ainfo->ai_addr->sa_data, 0, 16, htons(port)); if (connect(hsock, ainfo->ai_addr, sizeof(struct sockaddr)) < 0) { LOG_ERROR("socket_open: cannot connect to %s:%d, error %d", server_addr, port, vdebug_socket_error()); rc = VD_ERR_SOC_CONN; @@ -299,8 +294,8 @@ static int vdebug_socket_receive(int hsock, struct vd_shm *pmem) { int rc; int dreceived = 0; - int offset = (uint8_t *)&pmem->rid - &pmem->cmd; - int to_receive = VD_SHEADER_LEN + pmem->rbytes; + int offset = &pmem->rid[0] - &pmem->cmd; + int to_receive = VD_SHEADER_LEN + le_to_h_u16(pmem->rbytes); char *pb = (char *)pmem; do { @@ -320,7 +315,7 @@ static int vdebug_socket_receive(int hsock, struct vd_shm *pmem) static int vdebug_socket_send(int hsock, struct vd_shm *pmem) { - int rc = send(hsock, (const char *)&pmem->cmd, VD_CHEADER_LEN + pmem->wbytes, 0); + int rc = send(hsock, (const char *)&pmem->cmd, VD_CHEADER_LEN + le_to_h_u16(pmem->wbytes), 0); if (rc <= 0) LOG_WARNING("socket_send: send failed, error %d", vdebug_socket_error()); else @@ -333,6 +328,7 @@ static uint32_t vdebug_wait_server(int hsock, struct vd_shm *pmem) { if (!hsock) return VD_ERR_SOC_OPEN; + int st = vdebug_socket_send(hsock, pmem); if (st <= 0) return VD_ERR_SOC_SEND; @@ -341,9 +337,9 @@ static uint32_t vdebug_wait_server(int hsock, struct vd_shm *pmem) if (rd <= 0) return VD_ERR_SOC_RECV; - int rc = pmem->status; + int rc = le_to_h_u32(pmem->status); LOG_DEBUG_IO("wait_server: cmd %02" PRIx8 " done, sent %d, rcvd %d, status %d", - pmem->cmd, st, rd, rc); + pmem->cmd, st, rd, rc); return rc; } @@ -356,22 +352,23 @@ int vdebug_run_jtag_queue(int hsock, struct vd_shm *pm, unsigned int count) int64_t ts, te; uint8_t *tdo; int rc; - struct vd_jtag_hdr *hdr; + uint64_t jhdr; + struct vd_rdata *rd; req = 0; /* beginning of request */ waddr = 0; rwords = 0; - pm->wbytes = pm->wwords * vdc.buf_width; - pm->rbytes = pm->rwords * vdc.buf_width; + h_u16_to_le(pm->wbytes, le_to_h_u16(pm->wwords) * vdc.buf_width); + h_u16_to_le(pm->rbytes, le_to_h_u16(pm->rwords) * vdc.buf_width); ts = timeval_ms(); rc = vdebug_wait_server(hsock, pm); while (!rc && (req < count)) { /* loop over requests to read data and print out */ - hdr = (struct vd_jtag_hdr *)&pm->wd8[waddr * 4]; - hwords = hdr->wlen; - words = hdr->rlen; - anum = hdr->tlen; - num_pre = hdr->pre; - num_post = hdr->post; + jhdr = le_to_h_u64(&pm->wd8[waddr * 4]); + words = jhdr >> 48; + hwords = (jhdr >> 32) & 0xffff; + anum = jhdr & 0xffffff; + num_pre = (jhdr >> 27) & 0x7; + num_post = (jhdr >> 24) & 0x7; if (num_post) num = anum - num_pre - num_post + 1; else @@ -379,21 +376,29 @@ int vdebug_run_jtag_queue(int hsock, struct vd_shm *pm, unsigned int count) bytes = (num + 7) / 8; vdc.trans_last = (req + 1) < count ? 0 : 1; vdc.trans_first = waddr ? 0 : 1; - if (hdr->cmd == 3) { /* read */ - tdo = vdc.tdo; + if (((jhdr >> 30) & 0x3) == 3) { /* cmd is read */ + if (!rwords) { + rd = &vdc.rdataq; + tdo = rd->rdata; + } else { + rd = list_first_entry(&vdc.rdataq.lh, struct vd_rdata, lh); + tdo = rd->rdata; + list_del(&rd->lh); + free(rd); + } for (unsigned int j = 0; j < bytes; j++) { tdo[j] = (pm->rd8[rwords * 8 + j] >> num_pre) | (pm->rd8[rwords * 8 + j + 1] << (8 - num_pre)); - LOG_DEBUG_IO("%04x D0[%02x]:%02x", pm->wid - count + req, j, tdo[j]); + LOG_DEBUG_IO("%04x D0[%02x]:%02x", le_to_h_u16(pm->wid) - count + req, j, tdo[j]); } rwords += words; /* read data offset */ } else { tdo = NULL; } - waddr += sizeof(struct vd_jtag_hdr) / 4; /* waddr past header */ + waddr += sizeof(uint64_t) / 4; /* waddr past header */ tdi = (pm->wd8[waddr * 4] >> num_pre) | (pm->wd8[waddr * 4 + 1] << (8 - num_pre)); tms = (pm->wd8[waddr * 4 + 4] >> num_pre) | (pm->wd8[waddr * 4 + 4 + 1] << (8 - num_pre)); - LOG_DEBUG("%04x L:%02d O:%05x @%03x DI:%02x MS:%02x DO:%02x", - pm->wid - count + req, num, (vdc.trans_first << 14) | (vdc.trans_last << 15), + LOG_DEBUG_IO("%04x L:%02d O:%05x @%03x DI:%02x MS:%02x DO:%02x", + le_to_h_u16(pm->wid) - count + req, num, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr - 2, tdi, tms, (tdo ? tdo[0] : 0xdd)); waddr += hwords * 2; /* start of next request */ req += 1; @@ -406,10 +411,83 @@ int vdebug_run_jtag_queue(int hsock, struct vd_shm *pm, unsigned int count) te = timeval_ms(); vdc.targ_time += (uint32_t)(te - ts); - pm->offseth = 0; /* reset buffer write address */ - pm->offset = 0; - pm->rwords = 0; - pm->waddr = 0; + h_u16_to_le(pm->offseth, 0); /* reset buffer write address */ + h_u32_to_le(pm->offset, 0); + h_u16_to_le(pm->rwords, 0); + h_u16_to_le(pm->waddr, 0); + assert(list_empty(&vdc.rdataq.lh));/* list should be empty after run queue */ + + return rc; +} + +int vdebug_run_reg_queue(int hsock, struct vd_shm *pm, unsigned int count) +{ + unsigned int num, awidth, wwidth; + unsigned int req, waddr, rwords; + uint8_t aspace; + uint32_t addr; + int64_t ts, te; + uint8_t *data; + int rc; + uint64_t rhdr; + struct vd_rdata *rd; + + req = 0; /* beginning of request */ + waddr = 0; + rwords = 0; + h_u16_to_le(pm->wbytes, le_to_h_u16(pm->wwords) * vdc.buf_width); + h_u16_to_le(pm->rbytes, le_to_h_u16(pm->rwords) * vdc.buf_width); + ts = timeval_ms(); + rc = vdebug_wait_server(hsock, pm); + while (!rc && (req < count)) { /* loop over requests to read data and print out */ + rhdr = le_to_h_u64(&pm->wd8[waddr * 4]); + addr = rhdr >> 32; /* reconstruct data for a single request */ + num = (rhdr >> 16) & 0x7ff; + aspace = rhdr & 0x3; + awidth = (1 << ((rhdr >> 27) & 0x7)); + wwidth = (awidth + vdc.buf_width - 1) / vdc.buf_width; + vdc.trans_last = (req + 1) < count ? 0 : 1; + vdc.trans_first = waddr ? 0 : 1; + if (((rhdr >> 30) & 0x3) == 2) { /* cmd is read */ + if (num) { + if (!rwords) { + rd = &vdc.rdataq; + data = rd->rdata; + } else { + rd = list_first_entry(&vdc.rdataq.lh, struct vd_rdata, lh); + data = rd->rdata; + list_del(&rd->lh); + free(rd); + } + for (unsigned int j = 0; j < num; j++) + memcpy(&data[j * awidth], &pm->rd8[(rwords + j) * awidth], awidth); + } + LOG_DEBUG_IO("read %04x AS:%02x RG:%02x O:%05x @%03x D:%08x", le_to_h_u16(pm->wid) - count + req, + aspace, addr, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr, + (num ? le_to_h_u32(&pm->rd8[rwords * 4]) : 0xdead)); + rwords += num * wwidth; + waddr += sizeof(uint64_t) / 4; /* waddr past header */ + } else { + LOG_DEBUG_IO("write %04x AS:%02x RG:%02x O:%05x @%03x D:%08x", le_to_h_u16(pm->wid) - count + req, + aspace, addr, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr, + le_to_h_u32(&pm->wd8[(waddr + num + 1) * 4])); + waddr += sizeof(uint64_t) / 4 + (num * wwidth * awidth + 3) / 4; + } + req += 1; + } + + if (rc) { + LOG_ERROR("0x%x executing transaction", rc); + rc = ERROR_FAIL; + } + + te = timeval_ms(); + vdc.targ_time += (uint32_t)(te - ts); + h_u16_to_le(pm->offseth, 0); /* reset buffer write address */ + h_u32_to_le(pm->offset, 0); + h_u16_to_le(pm->rwords, 0); + h_u16_to_le(pm->waddr, 0); + assert(list_empty(&vdc.rdataq.lh));/* list should be empty after run queue */ return rc; } @@ -420,35 +498,35 @@ static int vdebug_open(int hsock, struct vd_shm *pm, const char *path, int rc = VD_ERR_NOT_OPEN; pm->cmd = VD_CMD_OPEN; - pm->wid = VD_VERSION; /* client version */ - pm->wbytes = 0; - pm->rbytes = 0; - pm->wwords = 0; - pm->rwords = 0; + h_u16_to_le(pm->wid, VD_VERSION); /* client version */ + h_u16_to_le(pm->wbytes, 0); + h_u16_to_le(pm->rbytes, 0); + h_u16_to_le(pm->wwords, 0); + h_u16_to_le(pm->rwords, 0); rc = vdebug_wait_server(hsock, pm); if (rc != 0) { /* communication problem */ LOG_ERROR("0x%x connecting to server", rc); - } else if (pm->rid < pm->wid) { - LOG_ERROR("server version %d too old for the client %d", pm->rid, pm->wid); + } else if (le_to_h_u16(pm->rid) < le_to_h_u16(pm->wid)) { + LOG_ERROR("server version %d too old for the client %d", le_to_h_u16(pm->rid), le_to_h_u16(pm->wid)); pm->cmd = VD_CMD_CLOSE; /* let server close the connection */ vdebug_wait_server(hsock, pm); rc = VD_ERR_VERSION; } else { pm->cmd = VD_CMD_CONNECT; pm->type = type; /* BFM type to connect to, here JTAG */ - pm->rwdata = sig_mask | VD_SIG_BUF | (VD_SIG_BUF << 16); - pm->wbytes = strlen(path) + 1; - pm->rbytes = 12; - pm->wid = 0; /* reset wid for transaction ID */ - pm->wwords = 0; - pm->rwords = 0; - memcpy(pm->wd8, path, pm->wbytes + 1); + h_u32_to_le(pm->rwdata, sig_mask | VD_SIG_BUF | (VD_SIG_BUF << 16)); + h_u16_to_le(pm->wbytes, strlen(path) + 1); + h_u16_to_le(pm->rbytes, 12); + h_u16_to_le(pm->wid, 0); /* reset wid for transaction ID */ + h_u16_to_le(pm->wwords, 0); + h_u16_to_le(pm->rwords, 0); + memcpy(pm->wd8, path, le_to_h_u16(pm->wbytes)); rc = vdebug_wait_server(hsock, pm); - vdc.sig_read = pm->rwdata >> 16; /* signal read mask */ - vdc.sig_write = pm->rwdata; /* signal write mask */ + vdc.sig_read = le_to_h_u32(pm->rwdata) >> 16; /* signal read mask */ + vdc.sig_write = le_to_h_u32(pm->rwdata); /* signal write mask */ vdc.bfm_period = period_ps; - vdc.buf_width = pm->rd32[0] / 8;/* access width in bytes */ - vdc.addr_bits = pm->rd32[2]; /* supported address bits */ + vdc.buf_width = le_to_h_u32(&pm->rd8[0]) / 8;/* access width in bytes */ + vdc.addr_bits = le_to_h_u32(&pm->rd8[2 * 4]); /* supported address bits */ } if (rc) { @@ -456,6 +534,7 @@ static int vdebug_open(int hsock, struct vd_shm *pm, const char *path, return ERROR_FAIL; } + INIT_LIST_HEAD(&vdc.rdataq.lh); LOG_DEBUG("%s type %0x, period %dps, buffer %dx%dB signals r%04xw%04x", path, type, vdc.bfm_period, VD_BUFFER_LEN / vdc.buf_width, vdc.buf_width, vdc.sig_read, vdc.sig_write); @@ -467,17 +546,17 @@ static int vdebug_close(int hsock, struct vd_shm *pm, uint8_t type) { pm->cmd = VD_CMD_DISCONNECT; pm->type = type; /* BFM type, here JTAG */ - pm->wbytes = 0; - pm->rbytes = 0; - pm->wwords = 0; - pm->rwords = 0; + h_u16_to_le(pm->wbytes, 0); + h_u16_to_le(pm->rbytes, 0); + h_u16_to_le(pm->wwords, 0); + h_u16_to_le(pm->rwords, 0); vdebug_wait_server(hsock, pm); pm->cmd = VD_CMD_CLOSE; - pm->wid = VD_VERSION; /* client version */ - pm->wbytes = 0; - pm->rbytes = 0; - pm->wwords = 0; - pm->rwords = 0; + h_u16_to_le(pm->wid, VD_VERSION); /* client version */ + h_u16_to_le(pm->wbytes, 0); + h_u16_to_le(pm->rbytes, 0); + h_u16_to_le(pm->wwords, 0); + h_u16_to_le(pm->rwords, 0); vdebug_wait_server(hsock, pm); LOG_DEBUG("type %0x", type); @@ -488,9 +567,9 @@ static int vdebug_wait(int hsock, struct vd_shm *pm, uint32_t cycles) { if (cycles) { pm->cmd = VD_CMD_WAIT; - pm->wbytes = 0; - pm->rbytes = 0; - pm->rwdata = cycles; /* clock sycles to wait */ + h_u16_to_le(pm->wbytes, 0); + h_u16_to_le(pm->rbytes, 0); + h_u32_to_le(pm->rwdata, cycles); /* clock sycles to wait */ int rc = vdebug_wait_server(hsock, pm); if (rc) { LOG_ERROR("0x%x waiting %" PRIx32 " cycles", rc, cycles); @@ -505,9 +584,9 @@ static int vdebug_wait(int hsock, struct vd_shm *pm, uint32_t cycles) static int vdebug_sig_set(int hsock, struct vd_shm *pm, uint32_t write_mask, uint32_t value) { pm->cmd = VD_CMD_SIGSET; - pm->wbytes = 0; - pm->rbytes = 0; - pm->rwdata = (write_mask << 16) | (value & 0xffff); /* mask and value of signals to set */ + h_u16_to_le(pm->wbytes, 0); + h_u16_to_le(pm->rbytes, 0); + h_u32_to_le(pm->rwdata, (write_mask << 16) | (value & 0xffff)); /* mask and value of signals to set */ int rc = vdebug_wait_server(hsock, pm); if (rc) { LOG_ERROR("0x%x setting signals %04" PRIx32, rc, write_mask); @@ -522,9 +601,9 @@ static int vdebug_sig_set(int hsock, struct vd_shm *pm, uint32_t write_mask, uin static int vdebug_jtag_clock(int hsock, struct vd_shm *pm, uint32_t value) { pm->cmd = VD_CMD_JTAGCLOCK; - pm->wbytes = 0; - pm->rbytes = 0; - pm->rwdata = value; /* divider value */ + h_u16_to_le(pm->wbytes, 0); + h_u16_to_le(pm->rbytes, 0); + h_u32_to_le(pm->rwdata, value); /* divider value */ int rc = vdebug_wait_server(hsock, pm); if (rc) { LOG_ERROR("0x%x setting jtag_clock", rc); @@ -546,11 +625,11 @@ static int vdebug_jtag_shift_tap(int hsock, struct vd_shm *pm, uint8_t num_pre, int rc = 0; pm->cmd = VD_CMD_JTAGSHTAP; - vdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO) || tdo; + vdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO); if (vdc.trans_first) waddr = 0; /* reset buffer offset */ else - waddr = pm->offseth; /* continue from the previous transaction */ + waddr = le_to_h_u32(pm->offseth); /* continue from the previous transaction */ if (num_post) /* actual number of bits to shift */ anum = num + num_pre + num_post - 1; else @@ -559,25 +638,22 @@ static int vdebug_jtag_shift_tap(int hsock, struct vd_shm *pm, uint8_t num_pre, words = (hwords + 1) / 2; /* in 8B TDO words to read */ bytes = (num + 7) / 8; /* data only portion in bytes */ /* buffer overflow check and flush */ - if (4 * waddr + sizeof(struct vd_jtag_hdr) + 8 * hwords + 64 > VD_BUFFER_LEN) { + if (4 * waddr + sizeof(uint64_t) + 8 * hwords + 64 > VD_BUFFER_LEN) { vdc.trans_last = 1; /* force flush within 64B of buffer end */ - } else if (4 * waddr + sizeof(struct vd_jtag_hdr) + 8 * hwords > VD_BUFFER_LEN) { + } else if (4 * waddr + sizeof(uint64_t) + 8 * hwords > VD_BUFFER_LEN) { /* this req does not fit, discard it */ LOG_ERROR("%04x L:%02d O:%05x @%04x too many bits to shift", - pm->wid, anum, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr); + le_to_h_u16(pm->wid), anum, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr); rc = ERROR_FAIL; } if (!rc && anum) { - uint16_t i, j; - struct vd_jtag_hdr *hdr = (struct vd_jtag_hdr *)&pm->wd8[4 * waddr]; /* 8 bytes header */ - hdr->cmd = (tdo ? 3 : 1); /* R and W bits */ - hdr->pre = num_pre; - hdr->post = num_post; - hdr->tlen = anum; - hdr->wlen = hwords; - hdr->rlen = words; - pm->wid++; /* transaction ID */ + uint16_t i, j; /* portability requires to use bit operations for 8B JTAG header */ + uint64_t jhdr = (tdo ? ((uint64_t)(words) << 48) : 0) + ((uint64_t)(hwords) << 32) + + ((tdo ? 3UL : 1UL) << 30) + (num_pre << 27) + (num_post << 24) + anum; + h_u64_to_le(&pm->wd8[4 * waddr], jhdr); + + h_u16_to_le(pm->wid, le_to_h_u16(pm->wid) + 1); /* transaction ID */ waddr += 2; /* waddr past header */ /* TDI/TMS data follows as 32 bit word pairs {TMS,TDI} */ pm->wd8[4 * waddr] = (tdi ? (tdi[0] << num_pre) : 0); @@ -615,19 +691,102 @@ static int vdebug_jtag_shift_tap(int hsock, struct vd_shm *pm, uint8_t num_pre, } if (tdo) { - pm->rwords += words; /* keep track of the words to read */ - vdc.tdo = tdo; + struct vd_rdata *rd; + if (le_to_h_u16(pm->rwords) == 0) { + rd = &vdc.rdataq; + } else { + rd = calloc(1, sizeof(struct vd_rdata)); + if (!rd) /* check allocation for 24B */ + return ERROR_FAIL; + list_add_tail(&rd->lh, &vdc.rdataq.lh); + } + rd->rdata = tdo; + h_u16_to_le(pm->rwords, le_to_h_u16(pm->rwords) + words);/* keep track of the words to read */ } - pm->wwords = waddr / 2 + hwords; /* payload size *2 to include both TDI and TMS data */ - pm->waddr++; + h_u16_to_le(pm->wwords, waddr / 2 + hwords); /* payload size *2 to include both TDI and TMS data */ + h_u16_to_le(pm->waddr, le_to_h_u16(pm->waddr) + 1); } if (!waddr) /* flush issued, but buffer empty */ ; else if (!vdc.trans_last) /* buffered request */ - pm->offseth = waddr + hwords * 2; /* offset for next transaction, must be even */ + h_u16_to_le(pm->offseth, waddr + hwords * 2); /* offset for next transaction, must be even */ else /* execute batch of requests */ - rc = vdebug_run_jtag_queue(hsock, pm, pm->waddr); + rc = vdebug_run_jtag_queue(hsock, pm, le_to_h_u16(pm->waddr)); + vdc.trans_first = vdc.trans_last; /* flush forces trans_first flag */ + + return rc; +} + +static int vdebug_reg_write(int hsock, struct vd_shm *pm, const uint32_t reg, + const uint32_t data, uint8_t aspace, uint8_t f_last) +{ + uint32_t waddr; + int rc = ERROR_OK; + + pm->cmd = VD_CMD_REGWRITE; + vdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO); + if (vdc.trans_first) + waddr = 0; /* reset buffer offset */ + else + waddr = le_to_h_u16(pm->offseth); /* continue from the previous transaction */ + + if (4 * waddr + 2 * sizeof(uint64_t) + 4 > VD_BUFFER_LEN) + vdc.trans_last = 1; /* force flush, no room for next request */ + + uint64_t rhdr = ((uint64_t)reg << 32) + (1UL << 30) + (2UL << 27) + (1UL << 16) + aspace; + h_u64_to_le(&pm->wd8[4 * waddr], rhdr); + h_u32_to_le(&pm->wd8[4 * (waddr + 2)], data); + h_u16_to_le(pm->wid, le_to_h_u16(pm->wid) + 1); + h_u16_to_le(pm->wwords, waddr + 3); + h_u16_to_le(pm->waddr, le_to_h_u16(pm->waddr) + 1); + if (!vdc.trans_last) /* buffered request */ + h_u16_to_le(pm->offseth, waddr + 3); + else + rc = vdebug_run_reg_queue(hsock, pm, le_to_h_u16(pm->waddr)); + vdc.trans_first = vdc.trans_last; /* flush forces trans_first flag */ + + return rc; +} + +static int vdebug_reg_read(int hsock, struct vd_shm *pm, const uint32_t reg, + uint32_t *data, uint8_t aspace, uint8_t f_last) +{ + uint32_t waddr; + int rc = ERROR_OK; + + pm->cmd = VD_CMD_REGREAD; + vdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO); + if (vdc.trans_first) + waddr = 0; /* reset buffer offset */ + else + waddr = le_to_h_u16(pm->offseth); /* continue from the previous transaction */ + + if (4 * waddr + 2 * sizeof(uint64_t) + 4 > VD_BUFFER_LEN) + vdc.trans_last = 1; /* force flush, no room for next request */ + + uint64_t rhdr = ((uint64_t)reg << 32) + (2UL << 30) + (2UL << 27) + ((data ? 1UL : 0UL) << 16) + aspace; + h_u64_to_le(&pm->wd8[4 * waddr], rhdr); + h_u16_to_le(pm->wid, le_to_h_u16(pm->wid) + 1); + if (data) { + struct vd_rdata *rd; + if (le_to_h_u16(pm->rwords) == 0) { + rd = &vdc.rdataq; + } else { + rd = calloc(1, sizeof(struct vd_rdata)); + if (!rd) /* check allocation for 24B */ + return ERROR_FAIL; + list_add_tail(&rd->lh, &vdc.rdataq.lh); + } + rd->rdata = (uint8_t *)data; + h_u16_to_le(pm->rwords, le_to_h_u16(pm->rwords) + 1); + } + h_u16_to_le(pm->wwords, waddr + 2); + h_u16_to_le(pm->waddr, le_to_h_u16(pm->waddr) + 1); + if (!vdc.trans_last) /* buffered request */ + h_u16_to_le(pm->offseth, waddr + 2); + else + rc = vdebug_run_reg_queue(hsock, pm, le_to_h_u16(pm->waddr)); vdc.trans_first = vdc.trans_last; /* flush forces trans_first flag */ return rc; @@ -641,19 +800,19 @@ static int vdebug_mem_open(int hsock, struct vd_shm *pm, const char *path, uint8 return ERROR_OK; pm->cmd = VD_CMD_MEMOPEN; - pm->wbytes = strlen(path) + 1; /* includes terminating 0 */ - pm->rbytes = 8; - pm->wwords = 0; - pm->rwords = 0; - memcpy(pm->wd8, path, pm->wbytes); + h_u16_to_le(pm->wbytes, strlen(path) + 1); /* includes terminating 0 */ + h_u16_to_le(pm->rbytes, 8); + h_u16_to_le(pm->wwords, 0); + h_u16_to_le(pm->rwords, 0); + memcpy(pm->wd8, path, le_to_h_u16(pm->wbytes)); rc = vdebug_wait_server(hsock, pm); if (rc) { LOG_ERROR("0x%x opening memory %s", rc, path); - } else if (ndx != pm->rd16[1]) { - LOG_WARNING("Invalid memory index %" PRIu16 " returned. Direct memory access disabled", pm->rd16[1]); + } else if (ndx != pm->rd8[2]) { + LOG_WARNING("Invalid memory index %" PRIu16 " returned. Direct memory access disabled", pm->rd8[2]); } else { - vdc.mem_width[ndx] = pm->rd16[0] / 8; /* memory width in bytes */ - vdc.mem_depth[ndx] = pm->rd32[1]; /* memory depth in words */ + vdc.mem_width[ndx] = le_to_h_u16(&pm->rd8[0]) / 8; /* memory width in bytes */ + vdc.mem_depth[ndx] = le_to_h_u32(&pm->rd8[4]); /* memory depth in words */ LOG_DEBUG("%" PRIx8 ": %s memory %" PRIu32 "x%" PRIu32 "B, buffer %" PRIu32 "x%" PRIu32 "B", ndx, path, vdc.mem_depth[ndx], vdc.mem_width[ndx], VD_BUFFER_LEN / vdc.mem_width[ndx], vdc.mem_width[ndx]); } @@ -664,15 +823,16 @@ static int vdebug_mem_open(int hsock, struct vd_shm *pm, const char *path, uint8 static void vdebug_mem_close(int hsock, struct vd_shm *pm, uint8_t ndx) { pm->cmd = VD_CMD_MEMCLOSE; - pm->rwdata = ndx; /* which memory */ - pm->wbytes = 0; - pm->rbytes = 0; - pm->wwords = 0; - pm->rwords = 0; + h_u32_to_le(pm->rwdata, ndx); /* which memory */ + h_u16_to_le(pm->wbytes, 0); + h_u16_to_le(pm->rbytes, 0); + h_u16_to_le(pm->wwords, 0); + h_u16_to_le(pm->rwords, 0); vdebug_wait_server(hsock, pm); LOG_DEBUG("%" PRIx8 ": %s", ndx, vdc.mem_path[ndx]); } + static int vdebug_init(void) { vdc.hsocket = vdebug_socket_open(vdc.server_name, vdc.server_port); @@ -680,7 +840,7 @@ static int vdebug_init(void) if (!pbuf) { close_socket(vdc.hsocket); vdc.hsocket = 0; - LOG_ERROR("cannot allocate %lu bytes", sizeof(struct vd_shm)); + LOG_ERROR("cannot allocate %zu bytes", sizeof(struct vd_shm)); return ERROR_FAIL; } if (vdc.hsocket <= 0) { @@ -692,10 +852,13 @@ static int vdebug_init(void) } vdc.trans_first = 1; vdc.poll_cycles = vdc.poll_max; - uint32_t sig_mask = VD_SIG_RESET | VD_SIG_TRST | VD_SIG_TCKDIV; + uint32_t sig_mask = VD_SIG_RESET; + if (transport_is_jtag()) + sig_mask |= VD_SIG_TRST | VD_SIG_TCKDIV; + int rc = vdebug_open(vdc.hsocket, pbuf, vdc.bfm_path, vdc.bfm_type, vdc.bfm_period, sig_mask); if (rc != 0) { - LOG_ERROR("cannot connect to %s, rc 0x%x", vdc.bfm_path, rc); + LOG_ERROR("0x%x cannot connect to %s", rc, vdc.bfm_path); close_socket(vdc.hsocket); vdc.hsocket = 0; free(pbuf); @@ -704,7 +867,7 @@ static int vdebug_init(void) for (uint8_t i = 0; i < vdc.mem_ndx; i++) { rc = vdebug_mem_open(vdc.hsocket, pbuf, vdc.mem_path[i], i); if (rc != 0) - LOG_ERROR("cannot connect to %s, rc 0x%x", vdc.mem_path[i], rc); + LOG_ERROR("0x%x cannot connect to %s", rc, vdc.mem_path[i]); } LOG_INFO("vdebug %d connected to %s through %s:%" PRIu16, @@ -754,7 +917,7 @@ static int vdebug_reset(int trst, int srst) static int vdebug_jtag_tms_seq(const uint8_t *tms, int num, uint8_t f_flush) { - LOG_INFO("tms len:%d tms:%x", num, *(const uint32_t *)tms); + LOG_INFO("tms len:%d tms:%x", num, *tms); return vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num, *tms, 0, NULL, 0, 0, NULL, f_flush); } @@ -811,8 +974,8 @@ static int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush) uint8_t cur_tms_post = i == cmd->num_fields - 1 ? tms_post : 0; uint8_t cur_flush = i == cmd->num_fields - 1 ? f_flush : 0; rc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, cur_num_pre, cur_tms_pre, - cmd->fields[i].num_bits, cmd->fields[i].out_value, cur_num_post, cur_tms_post, - cmd->fields[i].in_value, cur_flush); + cmd->fields[i].num_bits, cmd->fields[i].out_value, cur_num_post, cur_tms_post, + cmd->fields[i].in_value, cur_flush); if (rc) break; } @@ -913,6 +1076,61 @@ static int vdebug_jtag_execute_queue(void) return rc; } +static int vdebug_dap_connect(struct adiv5_dap *dap) +{ + return dap_dp_init(dap); +} + +static int vdebug_dap_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq) +{ + return ERROR_OK; +} + +static int vdebug_dap_queue_dp_read(struct adiv5_dap *dap, unsigned int reg, uint32_t *data) +{ + return vdebug_reg_read(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_DP, 0); +} + +static int vdebug_dap_queue_dp_write(struct adiv5_dap *dap, unsigned int reg, uint32_t data) +{ + return vdebug_reg_write(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_DP, 0); +} + +static int vdebug_dap_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data) +{ + if ((reg & DP_SELECT_APBANK) != ap->dap->select) { + vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & DP_SELECT_APBANK, VD_ASPACE_DP, 0); + ap->dap->select = reg & DP_SELECT_APBANK; + } + + vdebug_reg_read(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, NULL, VD_ASPACE_AP, 0); + + return vdebug_reg_read(vdc.hsocket, pbuf, DP_RDBUFF >> 2, data, VD_ASPACE_DP, 0); +} + +static int vdebug_dap_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t data) +{ + if ((reg & DP_SELECT_APBANK) != ap->dap->select) { + vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & DP_SELECT_APBANK, VD_ASPACE_DP, 0); + ap->dap->select = reg & DP_SELECT_APBANK; + } + + return vdebug_reg_write(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_AP, 0); +} + +static int vdebug_dap_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) +{ + return vdebug_reg_write(vdc.hsocket, pbuf, 0, 0x1, VD_ASPACE_AB, 0); +} + +static int vdebug_dap_run(struct adiv5_dap *dap) +{ + if (pbuf->waddr) + return vdebug_run_reg_queue(vdc.hsocket, pbuf, le_to_h_u16(pbuf->waddr)); + + return ERROR_OK; +} + COMMAND_HANDLER(vdebug_set_server) { if ((CMD_ARGC != 1) || !strchr(CMD_ARGV[0], ':')) @@ -951,7 +1169,10 @@ COMMAND_HANDLER(vdebug_set_bfm) default: break; } - vdc.bfm_type = VD_BFM_JTAG; + if (transport_is_dapdirect_swd()) + vdc.bfm_type = VD_BFM_SWDP; + else + vdc.bfm_type = VD_BFM_JTAG; LOG_DEBUG("bfm_path: %s clk_period %ups", vdc.bfm_path, vdc.bfm_period); return ERROR_OK; @@ -1062,9 +1283,24 @@ static struct jtag_interface vdebug_jtag_ops = { .execute_queue = vdebug_jtag_execute_queue, }; +static const struct dap_ops vdebug_dap_ops = { + .connect = vdebug_dap_connect, + .send_sequence = vdebug_dap_send_sequence, + .queue_dp_read = vdebug_dap_queue_dp_read, + .queue_dp_write = vdebug_dap_queue_dp_write, + .queue_ap_read = vdebug_dap_queue_ap_read, + .queue_ap_write = vdebug_dap_queue_ap_write, + .queue_ap_abort = vdebug_dap_queue_ap_abort, + .run = vdebug_dap_run, + .sync = NULL, /* optional */ + .quit = NULL, /* optional */ +}; + +static const char *const vdebug_transports[] = { "jtag", "dapdirect_swd", NULL }; + struct adapter_driver vdebug_adapter_driver = { .name = "vdebug", - .transports = jtag_only, + .transports = vdebug_transports, .speed = vdebug_jtag_speed, .khz = vdebug_jtag_khz, .speed_div = vdebug_jtag_div, @@ -1073,4 +1309,5 @@ struct adapter_driver vdebug_adapter_driver = { .quit = vdebug_quit, .reset = vdebug_reset, .jtag_ops = &vdebug_jtag_ops, + .dap_swd_ops = &vdebug_dap_ops, }; diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c index 0d60725..ac5b1a2 100644 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c +++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c index bd61049..be2d8c3 100644 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c +++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c index e756817..941680a 100644 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c +++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c index 23a5097..42c8023 100644 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c +++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c index f701bb0..070f68c 100644 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c +++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h index 0ae3c03..caeaa26 100644 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h +++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_H diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h index 3698886..8a6e476 100644 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h +++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_INTERNAL_H diff --git a/src/jtag/drivers/versaloon/versaloon.c b/src/jtag/drivers/versaloon/versaloon.c index 7c2efef..48d3174 100644 --- a/src/jtag/drivers/versaloon/versaloon.c +++ b/src/jtag/drivers/versaloon/versaloon.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/versaloon/versaloon.h b/src/jtag/drivers/versaloon/versaloon.h index e4aafb2..5d7aa19 100644 --- a/src/jtag/drivers/versaloon/versaloon.h +++ b/src/jtag/drivers/versaloon/versaloon.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 by Simon Qian <SimonQian@SimonQian.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_H diff --git a/src/jtag/drivers/versaloon/versaloon_include.h b/src/jtag/drivers/versaloon/versaloon_include.h index a954b48..5804ad5 100644 --- a/src/jtag/drivers/versaloon/versaloon_include.h +++ b/src/jtag/drivers/versaloon/versaloon_include.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 by Simon Qian <SimonQian@SimonQian.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INCLUDE_H diff --git a/src/jtag/drivers/versaloon/versaloon_internal.h b/src/jtag/drivers/versaloon/versaloon_internal.h index 8372970..edeb335 100644 --- a/src/jtag/drivers/versaloon/versaloon_internal.h +++ b/src/jtag/drivers/versaloon/versaloon_internal.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INTERNAL_H diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c index dbbdef4..255ff88 100644 --- a/src/jtag/drivers/vsllink.c +++ b/src/jtag/drivers/vsllink.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009-2010 by Simon Qian <SimonQian@SimonQian.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* Versaloon is a programming tool for multiple MCUs. diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index c5249b2..ecba36b 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2017 by Texas Instruments, Inc. * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/drivers/xlnx-pcie-xvc.c b/src/jtag/drivers/xlnx-pcie-xvc.c index c05b9cf..6ad0255 100644 --- a/src/jtag/drivers/xlnx-pcie-xvc.c +++ b/src/jtag/drivers/xlnx-pcie-xvc.c @@ -1,5 +1,6 @@ -/* SPDX-License-Identifier: GPL-2.0 - * +// SPDX-License-Identifier: GPL-2.0-only + +/* * Copyright (c) 2019 Google, LLC. * Author: Moritz Fischer <moritzf@google.com> */ diff --git a/src/jtag/hla/Makefile.am b/src/jtag/hla/Makefile.am index 6bb2960..4111786 100644 --- a/src/jtag/hla/Makefile.am +++ b/src/jtag/hla/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libocdhla.la %C%_libocdhla_la_SOURCES = \ diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c index 074e3c2..6198b3d 100644 --- a/src/jtag/hla/hla_interface.c +++ b/src/jtag/hla/hla_interface.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Mathias Kuester * * Mathias Kuester <kesmtp@freenet.de> * * * * Copyright (C) 2012 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/hla/hla_interface.h b/src/jtag/hla/hla_interface.h index 31d055a..fa49658 100644 --- a/src/jtag/hla/hla_interface.h +++ b/src/jtag/hla/hla_interface.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Mathias Kuester * * Mathias Kuester <kesmtp@freenet.de> * * * * Copyright (C) 2012 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_HLA_HLA_INTERFACE_H diff --git a/src/jtag/hla/hla_layout.c b/src/jtag/hla/hla_layout.c index 16b2217..a760f0b 100644 --- a/src/jtag/hla/hla_layout.c +++ b/src/jtag/hla/hla_layout.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Mathias Kuester * * Mathias Kuester <kesmtp@freenet.de> * * * * Copyright (C) 2012 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/hla/hla_layout.h b/src/jtag/hla/hla_layout.h index 732fe1e..e13da65 100644 --- a/src/jtag/hla/hla_layout.h +++ b/src/jtag/hla/hla_layout.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Mathias Kuester * * Mathias Kuester <kesmtp@freenet.de> * * * * Copyright (C) 2012 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_HLA_HLA_LAYOUT_H diff --git a/src/jtag/hla/hla_tcl.c b/src/jtag/hla/hla_tcl.c index 6b206d2..3283399 100644 --- a/src/jtag/hla/hla_tcl.c +++ b/src/jtag/hla/hla_tcl.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Mathias Kuester * * Mathias Kuester <kesmtp@freenet.de> * * * * Copyright (C) 2012 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/hla/hla_tcl.h b/src/jtag/hla/hla_tcl.h index ac00add..b028e4b 100644 --- a/src/jtag/hla/hla_tcl.h +++ b/src/jtag/hla/hla_tcl.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Mathias Kuester * * Mathias Kuester <kesmtp@freenet.de> * * * * Copyright (C) 2012 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_HLA_HLA_TCL_H diff --git a/src/jtag/hla/hla_transport.c b/src/jtag/hla/hla_transport.c index 58dfe4b..91228be 100644 --- a/src/jtag/hla/hla_transport.c +++ b/src/jtag/hla/hla_transport.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Mathias Kuester * * Mathias Kuester <kesmtp@freenet.de> * * * * Copyright (C) 2012 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/hla/hla_transport.h b/src/jtag/hla/hla_transport.h index 0e0bea2..965f561 100644 --- a/src/jtag/hla/hla_transport.h +++ b/src/jtag/hla/hla_transport.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Mathias Kuester * * Mathias Kuester <kesmtp@freenet.de> * * * * Copyright (C) 2012 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_HLA_HLA_TRANSPORT_H diff --git a/src/jtag/interface.c b/src/jtag/interface.c index 56bbf6e..bc9ff3e 100644 --- a/src/jtag/interface.c +++ b/src/jtag/interface.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -11,19 +13,6 @@ * * * Copyright (C) 2009 Zachary T Welch * * zw@superlucidity.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/interface.h b/src/jtag/interface.h index 58bfd02..a8d9ee4 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2009 Zachary T Welch * * zw@superlucidity.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_INTERFACE_H diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c index 9afd69d..67bbb3b 100644 --- a/src/jtag/interfaces.c +++ b/src/jtag/interfaces.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -13,19 +15,6 @@ * zw@superlucidity.net * * * * Copyright (C) 2020, Ampere Computing LLC * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -54,6 +43,9 @@ extern struct adapter_driver ftdi_adapter_driver; #if BUILD_USB_BLASTER == 1 || BUILD_USB_BLASTER_2 == 1 extern struct adapter_driver usb_blaster_adapter_driver; #endif +#if BUILD_ESP_USB_JTAG == 1 +extern struct adapter_driver esp_usb_adapter_driver; +#endif #if BUILD_JTAG_VPI == 1 extern struct adapter_driver jtag_vpi_adapter_driver; #endif @@ -171,6 +163,9 @@ struct adapter_driver *adapter_drivers[] = { #if BUILD_USB_BLASTER || BUILD_USB_BLASTER_2 == 1 &usb_blaster_adapter_driver, #endif +#if BUILD_ESP_USB_JTAG == 1 + &esp_usb_adapter_driver, +#endif #if BUILD_JTAG_VPI == 1 &jtag_vpi_adapter_driver, #endif diff --git a/src/jtag/interfaces.h b/src/jtag/interfaces.h index ddbd735..6e6c2ce 100644 --- a/src/jtag/interfaces.h +++ b/src/jtag/interfaces.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -11,19 +13,6 @@ * * * Copyright (C) 2009 Zachary T Welch * * zw@superlucidity.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_INTERFACES_H diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 4ec2f1e..4f94e99 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007-2010 Øyvind Harboe * * oyvind.harboe@zylin.com * -* * -* 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_JTAG_H @@ -598,6 +587,19 @@ bool jtag_poll_get_enabled(void); */ void jtag_poll_set_enabled(bool value); +/** + * Mask (disable) polling and return the current mask status that should be + * feed to jtag_poll_unmask() to restore it. + * Multiple nested calls to jtag_poll_mask() are allowed, each balanced with + * its call to jtag_poll_unmask(). + */ +bool jtag_poll_mask(void); + +/** + * Restore saved mask for polling. + */ +void jtag_poll_unmask(bool saved); + #include <jtag/minidriver.h> int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv); diff --git a/src/jtag/minidriver.h b/src/jtag/minidriver.h index 0624c55..a40cffa 100644 --- a/src/jtag/minidriver.h +++ b/src/jtag/minidriver.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2009 Zachary T Welch * * zw@superlucidity.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_MINIDRIVER_H diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index ee11626..aeb42ed 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + # Defines basic Tcl procs for OpenOCD JTAG module # Executed during "init". Can be overridden @@ -120,6 +122,66 @@ proc jtag_ntrst_assert_width args { # # FIXME phase these aids out after some releases # +lappend _telnet_autocomplete_skip adapter_gpio_helper_with_caller +# Helper for deprecated driver functions that should call "adapter gpio XXX". + +# Call this function as: +# adapter_gpio_helper_with_caller caller sig_name +# adapter_gpio_helper_with_caller caller sig_name gpio_num +# adapter_gpio_helper_with_caller caller sig_name chip_num gpio_num +proc adapter_gpio_helper_with_caller {caller sig_name args} { + echo "DEPRECATED! use 'adapter gpio $sig_name' not '$caller'" + switch [llength $args] { + 0 {} + 1 {eval adapter gpio $sig_name $args} + 2 {eval adapter gpio $sig_name [lindex $args 1] -chip [lindex $args 0]} + default {return -code 1 -level 1 "$caller: syntax error"} + } + eval adapter gpio $sig_name +} + +lappend _telnet_autocomplete_skip adapter_gpio_helper +# Call this function as: +# adapter_gpio_helper sig_name +# adapter_gpio_helper sig_name gpio_num +# adapter_gpio_helper sig_name chip_num gpio_num +proc adapter_gpio_helper {sig_name args} { + set caller [lindex [info level -1] 0] + eval adapter_gpio_helper_with_caller {"$caller"} $sig_name $args +} + +lappend _telnet_autocomplete_skip adapter_gpio_jtag_nums_with_caller +# Helper for deprecated driver functions that implemented jtag_nums +proc adapter_gpio_jtag_nums_with_caller {caller tck_num tms_num tdi_num tdo_num} { + echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not '$caller'" + eval adapter gpio tck $tck_num + eval adapter gpio tms $tms_num + eval adapter gpio tdi $tdi_num + eval adapter gpio tdo $tdo_num +} + +lappend _telnet_autocomplete_skip adapter_gpio_jtag_nums +# Helper for deprecated driver functions that implemented jtag_nums +proc adapter_gpio_jtag_nums {args} { + set caller [lindex [info level -1] 0] + eval adapter_gpio_jtag_nums_with_caller {"$caller"} $args +} + +lappend _telnet_autocomplete_skip adapter_gpio_swd_nums_with_caller +# Helper for deprecated driver functions that implemented swd_nums +proc adapter_gpio_swd_nums_with_caller {caller swclk_num swdio_num} { + echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not '$caller'" + eval adapter gpio swclk $swclk_num + eval adapter gpio swdio $swdio_num +} + +lappend _telnet_autocomplete_skip adapter_gpio_swd_nums +# Helper for deprecated driver functions that implemented jtag_nums +proc adapter_gpio_swd_nums {args} { + set caller [lindex [info level -1] 0] + eval adapter_gpio_swd_nums_with_caller {"$caller"} $args +} + lappend _telnet_autocomplete_skip jtag_reset proc jtag_reset args { echo "DEPRECATED! use 'adapter \[de\]assert' not 'jtag_reset'" @@ -393,70 +455,140 @@ proc vsllink_usb_interface args { eval vsllink usb_interface $args } + +lappend _telnet_autocomplete_skip bcm2835_gpio_helper +proc bcm2835_gpio_helper {sig_name args} { + set caller [lindex [info level -1] 0] + echo "DEPRECATED! use 'adapter gpio $sig_name' not '$caller'" + switch [llength $args] { + 0 {} + 1 {eval adapter gpio $sig_name $args -chip 0} + 2 {eval adapter gpio $sig_name [lindex $args 1] -chip [lindex $args 0]} + default {return -code 1 -level 1 "$caller: syntax error"} + } + eval adapter gpio $sig_name +} + lappend _telnet_autocomplete_skip bcm2835gpio_jtag_nums -proc bcm2835gpio_jtag_nums args { - echo "DEPRECATED! use 'bcm2835gpio jtag_nums' not 'bcm2835gpio_jtag_nums'" - eval bcm2835gpio jtag_nums $args +proc bcm2835gpio_jtag_nums {tck_num tms_num tdi_num tdo_num} { + echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'bcm2835gpio_jtag_nums'" + eval adapter gpio tck $tck_num -chip 0 + eval adapter gpio tms $tms_num -chip 0 + eval adapter gpio tdi $tdi_num -chip 0 + eval adapter gpio tdo $tdo_num -chip 0 } lappend _telnet_autocomplete_skip bcm2835gpio_tck_num proc bcm2835gpio_tck_num args { - echo "DEPRECATED! use 'bcm2835gpio tck_num' not 'bcm2835gpio_tck_num'" - eval bcm2835gpio tck_num $args + eval bcm2835_gpio_helper tck $args } lappend _telnet_autocomplete_skip bcm2835gpio_tms_num proc bcm2835gpio_tms_num args { - echo "DEPRECATED! use 'bcm2835gpio tms_num' not 'bcm2835gpio_tms_num'" - eval bcm2835gpio tms_num $args + eval bcm2835_gpio_helper tms $args } lappend _telnet_autocomplete_skip bcm2835gpio_tdo_num proc bcm2835gpio_tdo_num args { - echo "DEPRECATED! use 'bcm2835gpio tdo_num' not 'bcm2835gpio_tdo_num'" - eval bcm2835gpio tdo_num $args + eval bcm2835_gpio_helper tdo $args } lappend _telnet_autocomplete_skip bcm2835gpio_tdi_num proc bcm2835gpio_tdi_num args { - echo "DEPRECATED! use 'bcm2835gpio tdi_num' not 'bcm2835gpio_tdi_num'" - eval bcm2835gpio tdi_num $args + eval bcm2835_gpio_helper tdi $args } lappend _telnet_autocomplete_skip bcm2835gpio_swd_nums -proc bcm2835gpio_swd_nums args { - echo "DEPRECATED! use 'bcm2835gpio swd_nums' not 'bcm2835gpio_swd_nums'" - eval bcm2835gpio swd_nums $args +proc bcm2835gpio_swd_nums {swclk_num swdio_num} { + echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'bcm2835gpio_swd_nums'" + eval adapter gpio swclk $swclk_num -chip 0 + eval adapter gpio swdio $swdio_num -chip 0 } lappend _telnet_autocomplete_skip bcm2835gpio_swclk_num proc bcm2835gpio_swclk_num args { - echo "DEPRECATED! use 'bcm2835gpio swclk_num' not 'bcm2835gpio_swclk_num'" - eval bcm2835gpio swclk_num $args + eval bcm2835_gpio_helper swclk $args } lappend _telnet_autocomplete_skip bcm2835gpio_swdio_num proc bcm2835gpio_swdio_num args { - echo "DEPRECATED! use 'bcm2835gpio swdio_num' not 'bcm2835gpio_swdio_num'" - eval bcm2835gpio swdio_num $args + eval bcm2835_gpio_helper swdio $args } lappend _telnet_autocomplete_skip bcm2835gpio_swdio_dir_num proc bcm2835gpio_swdio_dir_num args { - echo "DEPRECATED! use 'bcm2835gpio swdio_dir_num' not 'bcm2835gpio_swdio_dir_num'" - eval bcm2835gpio swdio_dir_num $args + eval bcm2835_gpio_helper swdio_dir $args } lappend _telnet_autocomplete_skip bcm2835gpio_srst_num proc bcm2835gpio_srst_num args { - echo "DEPRECATED! use 'bcm2835gpio srst_num' not 'bcm2835gpio_srst_num'" - eval bcm2835gpio srst_num $args + eval bcm2835_gpio_helper srst $args } lappend _telnet_autocomplete_skip bcm2835gpio_trst_num proc bcm2835gpio_trst_num args { - echo "DEPRECATED! use 'bcm2835gpio trst_num' not 'bcm2835gpio_trst_num'" - eval bcm2835gpio trst_num $args + eval bcm2835_gpio_helper trst $args +} + +lappend _telnet_autocomplete_skip "bcm2835gpio jtag_nums" +proc "bcm2835gpio jtag_nums" {tck_num tms_num tdi_num tdo_num} { + echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'bcm2835gpio jtag_nums'" + eval adapter gpio tck $tck_num -chip 0 + eval adapter gpio tms $tms_num -chip 0 + eval adapter gpio tdi $tdi_num -chip 0 + eval adapter gpio tdo $tdo_num -chip 0 +} + +lappend _telnet_autocomplete_skip "bcm2835gpio tck_num" +proc "bcm2835gpio tck_num" args { + eval bcm2835_gpio_helper tck $args +} + +lappend _telnet_autocomplete_skip "bcm2835gpio tms_num" +proc "bcm2835gpio tms_num" args { + eval bcm2835_gpio_helper tms $args +} + +lappend _telnet_autocomplete_skip "bcm2835gpio tdo_num" +proc "bcm2835gpio tdo_num" args { + eval bcm2835_gpio_helper tdo $args +} + +lappend _telnet_autocomplete_skip "bcm2835gpio tdi_num" +proc "bcm2835gpio tdi_num" args { + eval bcm2835_gpio_helper tdi $args +} + +lappend _telnet_autocomplete_skip "bcm2835gpio swd_nums" +proc "bcm2835gpio swd_nums" {swclk_num swdio_num} { + echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'bcm2835gpio swd_nums'" + eval adapter gpio swclk $swclk_num -chip 0 + eval adapter gpio swdio $swdio_num -chip 0 +} + +lappend _telnet_autocomplete_skip "bcm2835gpio swclk_num" +proc "bcm2835gpio swclk_num" args { + eval bcm2835_gpio_helper swclk $args +} + +lappend _telnet_autocomplete_skip "bcm2835gpio swdio_num" +proc "bcm2835gpio swdio_num" args { + eval bcm2835_gpio_helper swdio $args +} + +lappend _telnet_autocomplete_skip "bcm2835gpio swdio_dir_num" +proc "bcm2835gpio swdio_dir_num" args { + eval bcm2835_gpio_helper swdio_dir $args +} + +lappend _telnet_autocomplete_skip "bcm2835gpio srst_num" +proc "bcm2835gpio srst_num" args { + eval bcm2835_gpio_helper srst $args +} + +lappend _telnet_autocomplete_skip "bcm2835gpio trst_num" +proc "bcm2835gpio trst_num" args { + eval bcm2835_gpio_helper trst $args } lappend _telnet_autocomplete_skip bcm2835gpio_speed_coeffs @@ -473,74 +605,72 @@ proc bcm2835gpio_peripheral_base args { lappend _telnet_autocomplete_skip linuxgpiod_jtag_nums proc linuxgpiod_jtag_nums args { - echo "DEPRECATED! use 'linuxgpiod jtag_nums' not 'linuxgpiod_jtag_nums'" - eval linuxgpiod jtag_nums $args + eval adapter_gpio_jtag_nums $args } lappend _telnet_autocomplete_skip linuxgpiod_tck_num proc linuxgpiod_tck_num args { - echo "DEPRECATED! use 'linuxgpiod tck_num' not 'linuxgpiod_tck_num'" - eval linuxgpiod tck_num $args + eval adapter_gpio_helper tck $args } lappend _telnet_autocomplete_skip linuxgpiod_tms_num proc linuxgpiod_tms_num args { - echo "DEPRECATED! use 'linuxgpiod tms_num' not 'linuxgpiod_tms_num'" - eval linuxgpiod tms_num $args + eval adapter_gpio_helper tms $args } lappend _telnet_autocomplete_skip linuxgpiod_tdo_num proc linuxgpiod_tdo_num args { - echo "DEPRECATED! use 'linuxgpiod tdo_num' not 'linuxgpiod_tdo_num'" - eval linuxgpiod tdo_num $args + eval adapter_gpio_helper tdo $args } lappend _telnet_autocomplete_skip linuxgpiod_tdi_num proc linuxgpiod_tdi_num args { - echo "DEPRECATED! use 'linuxgpiod tdi_num' not 'linuxgpiod_tdi_num'" - eval linuxgpiod tdi_num $args + eval adapter_gpio_helper tdi $args } lappend _telnet_autocomplete_skip linuxgpiod_srst_num proc linuxgpiod_srst_num args { - echo "DEPRECATED! use 'linuxgpiod srst_num' not 'linuxgpiod_srst_num'" - eval linuxgpiod srst_num $args + eval adapter_gpio_helper srst $args } lappend _telnet_autocomplete_skip linuxgpiod_trst_num proc linuxgpiod_trst_num args { - echo "DEPRECATED! use 'linuxgpiod trst_num' not 'linuxgpiod_trst_num'" - eval linuxgpiod trst_num $args + eval adapter_gpio_helper trst $args } lappend _telnet_autocomplete_skip linuxgpiod_swd_nums proc linuxgpiod_swd_nums args { - echo "DEPRECATED! use 'linuxgpiod swd_nums' not 'linuxgpiod_swd_nums'" - eval linuxgpiod swd_nums $args + eval adapter_gpio_swd_nums $args } lappend _telnet_autocomplete_skip linuxgpiod_swclk_num proc linuxgpiod_swclk_num args { - echo "DEPRECATED! use 'linuxgpiod swclk_num' not 'linuxgpiod_swclk_num'" - eval linuxgpiod swclk_num $args + eval adapter_gpio_helper swclk $args } lappend _telnet_autocomplete_skip linuxgpiod_swdio_num proc linuxgpiod_swdio_num args { - echo "DEPRECATED! use 'linuxgpiod swdio_num' not 'linuxgpiod_swdio_num'" - eval linuxgpiod swdio_num $args + eval adapter_gpio_helper swdio $args } lappend _telnet_autocomplete_skip linuxgpiod_led_num proc linuxgpiod_led_num args { - echo "DEPRECATED! use 'linuxgpiod led_num' not 'linuxgpiod_led_num'" - eval linuxgpiod led_num $args + eval adapter_gpio_helper led $args } lappend _telnet_autocomplete_skip linuxgpiod_gpiochip proc linuxgpiod_gpiochip args { - echo "DEPRECATED! use 'linuxgpiod gpiochip' not 'linuxgpiod_gpiochip'" - eval linuxgpiod gpiochip $args + echo "DEPRECATED! use 'adapter <signal_name> -chip' not 'linuxgpiod_gpiochip'" + switch [llength $args] { + 0 { } + 1 { + foreach sig_name {tck tms tdi tdo trst srst swclk swdio swdio_dir led} { + eval adapter gpio $sig_name -chip $args + } + } + default {return -code 1 -level 1 "linuxgpiod_gpiochip: syntax error"} + } + eval adapter gpio } lappend _telnet_autocomplete_skip sysfsgpio_jtag_nums @@ -801,4 +931,187 @@ proc "xds110 serial" {args} { eval adapter serial $args } +lappend _telnet_autocomplete_skip linuxgpiod +# linuxgpiod command completely removed, this is required for the sub-commands to work +proc linuxgpiod {subcommand args} { + eval {"linuxgpiod $subcommand"} $args +} + +lappend _telnet_autocomplete_skip "linuxgpiod tck_num" +proc "linuxgpiod tck_num" {args} { + eval adapter_gpio_helper tck $args +} + +lappend _telnet_autocomplete_skip "linuxgpiod tms_num" +proc "linuxgpiod tms_num" {args} { + eval adapter_gpio_helper tms $args +} + +lappend _telnet_autocomplete_skip "linuxgpiod tdi_num" +proc "linuxgpiod tdi_num" {args} { + eval adapter_gpio_helper tdi $args +} + +lappend _telnet_autocomplete_skip "linuxgpiod tdo_num" +proc "linuxgpiod tdo_num" {args} { + eval adapter_gpio_helper tdo $args +} + +lappend _telnet_autocomplete_skip "linuxgpiod trst_num" +proc "linuxgpiod trst_num" {args} { + eval adapter_gpio_helper trst $args +} + +lappend _telnet_autocomplete_skip "linuxgpiod srst_num" +proc "linuxgpiod srst_num" {args} { + eval adapter_gpio_helper srst $args +} + +lappend _telnet_autocomplete_skip "linuxgpiod swclk_num" +proc "linuxgpiod swclk_num" {args} { + eval adapter_gpio_helper swclk $args +} + +lappend _telnet_autocomplete_skip "linuxgpiod swdio_num" +proc "linuxgpiod swdio_num" {args} { + eval adapter_gpio_helper swdio $args +} + +lappend _telnet_autocomplete_skip "linuxgpiod swdio_dir_num" +proc "linuxgpiod swdio_dir_num" {args} { + eval adapter_gpio_helper swdio_dir $args +} + +lappend _telnet_autocomplete_skip "linuxgpiod led_num" +proc "linuxgpiod led_num" {args} { + eval adapter_gpio_helper led $args +} + +lappend _telnet_autocomplete_skip "linuxgpiod gpiochip" +proc "linuxgpiod gpiochip" {num} { + echo "DEPRECATED! use 'adapter <signal_name> -chip' not 'linuxgpiod gpiochip'" + foreach sig_name {tck tms tdi tdo trst srst swclk swdio swdio_dir led} { + eval adapter gpio $sig_name -chip $num + } + eval adapter gpio +} + +lappend _telnet_autocomplete_skip "linuxgpiod jtag_nums" +proc "linuxgpiod jtag_nums" {tck_num tms_num tdi_num tdo_num} { + echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'linuxgpiod jtag_nums'" + eval adapter gpio tck $tck_num + eval adapter gpio tms $tms_num + eval adapter gpio tdi $tdi_num + eval adapter gpio tdo $tdo_num +} + +lappend _telnet_autocomplete_skip "linuxgpiod swd_nums" +proc "linuxgpiod swd_nums" {swclk swdio} { + echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'linuxgpiod jtag_nums'" + eval adapter gpio swclk $swclk + eval adapter gpio swdio $swdio +} + +lappend _telnet_autocomplete_skip "am335xgpio jtag_nums" +proc "am335xgpio jtag_nums" {tck_num tms_num tdi_num tdo_num} { + echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'am335xgpio jtag_nums'" + eval adapter gpio tck [expr {$tck_num % 32}] -chip [expr {$tck_num / 32}] + eval adapter gpio tms [expr {$tms_num % 32}] -chip [expr {$tms_num / 32}] + eval adapter gpio tdi [expr {$tdi_num % 32}] -chip [expr {$tdi_num / 32}] + eval adapter gpio tdo [expr {$tdo_num % 32}] -chip [expr {$tdo_num / 32}] +} + +lappend _telnet_autocomplete_skip "am335xgpio tck_num" +proc "am335xgpio tck_num" {num} { + echo "DEPRECATED! use 'adapter gpio tck' not 'am335xgpio tck_num'" + eval adapter gpio tck [expr {$num % 32}] -chip [expr {$num / 32}] +} + +lappend _telnet_autocomplete_skip "am335xgpio tms_num" +proc "am335xgpio tms_num" {num} { + echo "DEPRECATED! use 'adapter gpio tms' not 'am335xgpio tms_num'" + eval adapter gpio tms [expr {$num % 32}] -chip [expr {$num / 32}] +} + +lappend _telnet_autocomplete_skip "am335xgpio tdi_num" +proc "am335xgpio tdi_num" {num} { + echo "DEPRECATED! use 'adapter gpio tdi' not 'am335xgpio tdi_num'" + eval adapter gpio tdi [expr {$num % 32}] -chip [expr {$num / 32}] +} + +lappend _telnet_autocomplete_skip "am335xgpio tdo_num" +proc "am335xgpio tdo_num" {num} { + echo "DEPRECATED! use 'adapter gpio tdo' not 'am335xgpio tdo_num'" + eval adapter gpio tdo [expr {$num % 32}] -chip [expr {$num / 32}] +} + +lappend _telnet_autocomplete_skip "am335xgpio swd_nums" +proc "am335xgpio swd_nums" {swclk swdio} { + echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'am335xgpio jtag_nums'" + eval adapter gpio swclk [expr {$swclk % 32}] -chip [expr {$swclk / 32}] + eval adapter gpio swdio [expr {$swdio % 32}] -chip [expr {$swdio / 32}] +} + +lappend _telnet_autocomplete_skip "am335xgpio swclk_num" +proc "am335xgpio swclk_num" {num} { + echo "DEPRECATED! use 'adapter gpio swclk' not 'am335xgpio swclk_num'" + eval adapter gpio swclk [expr {$num % 32}] -chip [expr {$num / 32}] +} + +lappend _telnet_autocomplete_skip "am335xgpio swdio_num" +proc "am335xgpio swdio_num" {num} { + echo "DEPRECATED! use 'adapter gpio swdio' not 'am335xgpio swdio_num'" + eval adapter gpio swdio [expr {$num % 32}] -chip [expr {$num / 32}] +} + +lappend _telnet_autocomplete_skip "am335xgpio swdio_dir_num" +proc "am335xgpio swdio_dir_num" {num} { + echo "DEPRECATED! use 'adapter gpio swdio_dir' not 'am335xgpio swdio_dir_num'" + eval adapter gpio swdio_dir [expr {$num % 32}] -chip [expr {$num / 32}] +} + +lappend _telnet_autocomplete_skip "am335xgpio swdio_dir_output_state" +proc "am335xgpio swdio_dir_output_state" {state} { + echo "DEPRECATED! use 'adapter gpio swdio_dir -active-high' or 'adapter gpio swdio_dir -active-low', not 'am335xgpio swdio_dir_output_state'" + switch $state { + "high" + {eval adapter gpio swdio_dir -active-high} + "low" + {eval adapter gpio swdio_dir -active-low} + default + {return -code 1 -level 1 "am335xgpio swdio_dir_output_state: syntax error"} + } +} + +lappend _telnet_autocomplete_skip "am335xgpio srst_num" +proc "am335xgpio srst_num" {num} { + echo "DEPRECATED! use 'adapter gpio srst' not 'am335xgpio srst_num'" + eval adapter gpio srst [expr {$num % 32}] -chip [expr {$num / 32}] +} + +lappend _telnet_autocomplete_skip "am335xgpio trst_num" +proc "am335xgpio trst_num" {num} { + echo "DEPRECATED! use 'adapter gpio trst' not 'am335xgpio trst_num'" + eval adapter gpio trst [expr {$num % 32}] -chip [expr {$num / 32}] +} + +lappend _telnet_autocomplete_skip "am335xgpio led_num" +proc "am335xgpio led_num" {num} { + echo "DEPRECATED! use 'adapter gpio led' not 'am335xgpio led_num'" + eval adapter gpio led [expr {$num % 32}] -chip [expr {$num / 32}] +} + +lappend _telnet_autocomplete_skip "am335xgpio led_on_state" +proc "am335xgpio led_on_state" {state} { + echo "DEPRECATED! use 'adapter gpio led -active-high' or 'adapter gpio led -active-low', not 'am335xgpio led_on_state'" + switch $state { + "high" + {eval adapter gpio led -active-high} + "low" + {eval adapter gpio led -active-low} + default + {return -code 1 -level 1 "am335xgpio led_on_state: syntax error"} + } +} + # END MIGRATION AIDS diff --git a/src/jtag/swd.h b/src/jtag/swd.h index 8a436d0..5f626c1 100644 --- a/src/jtag/swd.h +++ b/src/jtag/swd.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009-2010 by David Brownell * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_SWD_H diff --git a/src/jtag/swim.c b/src/jtag/swim.c index 936268b..de3e106 100644 --- a/src/jtag/swim.c +++ b/src/jtag/swim.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2020 by Antonio Borneo <borneo.antonio@gmail.com diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index e6e976d..b1815b7 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -11,19 +13,6 @@ * * * Copyright (C) 2009 Zachary T Welch * * zw@superlucidity.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/jtag/tcl.h b/src/jtag/tcl.h index 932b47a..d67c085 100644 --- a/src/jtag/tcl.h +++ b/src/jtag/tcl.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -11,19 +13,6 @@ * * * Copyright (C) 2009 Zachary T Welch * * zw@superlucidity.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_JTAG_TCL_H @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/openocd.c b/src/openocd.c index fdc4a87..bef084f 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 Richard Missenden * * richard.missenden@googlemail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -130,6 +119,8 @@ COMMAND_HANDLER(handle_init_command) initialized = 1; + bool save_poll_mask = jtag_poll_mask(); + retval = command_run_line(CMD_CTX, "target init"); if (retval != ERROR_OK) return ERROR_FAIL; @@ -177,6 +168,8 @@ COMMAND_HANDLER(handle_init_command) if (command_run_line(CMD_CTX, "tpiu init") != ERROR_OK) return ERROR_FAIL; + jtag_poll_unmask(save_poll_mask); + /* initialize telnet subsystem */ gdb_target_add_all(all_targets); diff --git a/src/openocd.h b/src/openocd.h index 543ac3c..1c2a633 100644 --- a/src/openocd.h +++ b/src/openocd.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> * * Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_OPENOCD_H diff --git a/src/pld/Makefile.am b/src/pld/Makefile.am index 7f3a554..14786af 100644 --- a/src/pld/Makefile.am +++ b/src/pld/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libpld.la %C%_libpld_la_SOURCES = \ %D%/pld.c \ diff --git a/src/pld/pld.c b/src/pld/pld.c index fe21f6c..e2e0ef4 100644 --- a/src/pld/pld.c +++ b/src/pld/pld.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/pld/pld.h b/src/pld/pld.h index 3178fd4..a7cd20f 100644 --- a/src/pld/pld.h +++ b/src/pld/pld.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_PLD_PLD_H diff --git a/src/pld/virtex2.c b/src/pld/virtex2.c index a2de8cc..771af99 100644 --- a/src/pld/virtex2.c +++ b/src/pld/virtex2.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/pld/virtex2.h b/src/pld/virtex2.h index d6d922e..05558f7 100644 --- a/src/pld/virtex2.h +++ b/src/pld/virtex2.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_PLD_VIRTEX2_H diff --git a/src/pld/xilinx_bit.c b/src/pld/xilinx_bit.c index fe3faef..25deb80 100644 --- a/src/pld/xilinx_bit.c +++ b/src/pld/xilinx_bit.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/pld/xilinx_bit.h b/src/pld/xilinx_bit.h index 625a9d3..e30ed23 100644 --- a/src/pld/xilinx_bit.h +++ b/src/pld/xilinx_bit.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_PLD_XILINX_BIT_H diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c index 2e468c7..5038b09 100644 --- a/src/rtos/FreeRTOS.c +++ b/src/rtos/FreeRTOS.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Broadcom Corporation * * Evan Hunter - ehunter@broadcom.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -83,7 +72,8 @@ static int cortex_m_stacking(struct rtos *rtos, const struct rtos_register_stack int cm4_fpu_enabled = 0; struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target); if (is_armv7m(armv7m_target)) { - if (armv7m_target->fp_feature == FPV4_SP) { + if ((armv7m_target->fp_feature == FPV4_SP) || (armv7m_target->fp_feature == FPV5_SP) || + (armv7m_target->fp_feature == FPV5_DP)) { /* Found ARM v7m target which includes a FPU */ uint32_t cpacr; @@ -280,6 +270,7 @@ enum freertos_symbol_values { FREERTOS_VAL_X_SUSPENDED_TASK_LIST = 8, FREERTOS_VAL_UX_CURRENT_NUMBER_OF_TASKS = 9, FREERTOS_VAL_UX_TOP_USED_PRIORITY = 10, + FREERTOS_VAL_X_SCHEDULER_RUNNING = 11, }; struct symbols { @@ -299,6 +290,7 @@ static const struct symbols freertos_symbol_list[] = { { "xSuspendedTaskList", true }, /* Only if INCLUDE_vTaskSuspend */ { "uxCurrentNumberOfTasks", false }, { "uxTopUsedPriority", true }, /* Unavailable since v7.5.3 */ + { "xSchedulerRunning", false }, { NULL, false } }; @@ -529,7 +521,20 @@ static int freertos_update_threads(struct rtos *rtos) rtos->symbols[FREERTOS_VAL_PX_CURRENT_TCB].address, pxCurrentTCB); - if ((thread_list_size == 0) || (pxCurrentTCB == 0)) { + /* read scheduler running */ + uint32_t scheduler_running; + retval = target_read_u32(rtos->target, + rtos->symbols[FREERTOS_VAL_X_SCHEDULER_RUNNING].address, + &scheduler_running); + if (retval != ERROR_OK) { + LOG_ERROR("Error reading FreeRTOS scheduler state"); + return retval; + } + LOG_DEBUG("FreeRTOS: Read xSchedulerRunning at 0x%" PRIx64 ", value 0x%" PRIx32, + rtos->symbols[FREERTOS_VAL_X_SCHEDULER_RUNNING].address, + scheduler_running); + + if ((thread_list_size == 0) || (rtos->current_thread == 0) || (scheduler_running != 1)) { /* Either : No RTOS threads - there is always at least the current execution though */ /* OR : No current thread - all threads suspended - show the current execution * of idling */ diff --git a/src/rtos/Makefile.am b/src/rtos/Makefile.am index f09ac21..f00d719 100644 --- a/src/rtos/Makefile.am +++ b/src/rtos/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/librtos.la %C%_librtos_la_SOURCES = \ %D%/rtos.c \ diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c index 4161e63..7b76fb6 100644 --- a/src/rtos/ThreadX.c +++ b/src/rtos/ThreadX.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Broadcom Corporation * * Evan Hunter - ehunter@broadcom.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/rtos/chibios.c b/src/rtos/chibios.c index ef1f34d..8319cc8 100644 --- a/src/rtos/chibios.c +++ b/src/rtos/chibios.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2012 by Matthias Blaicher * * Matthias Blaicher - matthias@blaicher.com * * * * Copyright (C) 2011 by Broadcom Corporation * * Evan Hunter - ehunter@broadcom.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/rtos/chromium-ec.c b/src/rtos/chromium-ec.c index 95a228d..a95969e 100644 --- a/src/rtos/chromium-ec.c +++ b/src/rtos/chromium-ec.c @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only + /* - * SPDX-License-Identifier: GPL-2.0 - * * Copyright (c) 2018 National Instruments Corp * Author: Moritz Fischer <moritz.fischer@ettus.com> * diff --git a/src/rtos/eCos.c b/src/rtos/eCos.c index a81d7b9..3f813ac 100644 --- a/src/rtos/eCos.c +++ b/src/rtos/eCos.c @@ -1,17 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/rtos/embKernel.c b/src/rtos/embKernel.c index d70ae37..c1b5723 100644 --- a/src/rtos/embKernel.c +++ b/src/rtos/embKernel.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Broadcom Corporation * * Evan Hunter - ehunter@broadcom.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c index 28f9727..5e60c61 100644 --- a/src/rtos/hwthread.c +++ b/src/rtos/hwthread.c @@ -1,18 +1,4 @@ -/*************************************************************************** - * * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ +// SPDX-License-Identifier: GPL-2.0-or-later #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/rtos/linux.c b/src/rtos/linux.c index d147c1c..f9edabc 100644 --- a/src/rtos/linux.c +++ b/src/rtos/linux.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by STEricsson * * Heythem Bouhaja heythem.bouhaja@stericsson.com : creation * * Michel JAOUEN michel.jaouen@stericsson.com : adaptation to rtos * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/rtos/linux_header.h b/src/rtos/linux_header.h index a2b408e..7919964 100644 --- a/src/rtos/linux_header.h +++ b/src/rtos/linux_header.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + #ifndef OPENOCD_RTOS_LINUX_HEADER_H #define OPENOCD_RTOS_LINUX_HEADER_H diff --git a/src/rtos/mqx.c b/src/rtos/mqx.c index 754470e..8d483ed 100644 --- a/src/rtos/mqx.c +++ b/src/rtos/mqx.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2014 by Marian Cingel * * cingel.marian@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/rtos/nuttx.c b/src/rtos/nuttx.c index f0b3048..87b28c6 100644 --- a/src/rtos/nuttx.c +++ b/src/rtos/nuttx.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright 2016,2017 Sony Video & Sound Products Inc. * * Masatoshi Tateishi - Masatoshi.Tateishi@jp.sony.com * * Masayuki Ishikawa - Masayuki.Ishikawa@jp.sony.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -114,7 +103,7 @@ static const struct stack_register_offset nuttx_stack_offsets_cortex_m[] = { { ARMV7M_R13, 0, 32 }, /* sp */ { ARMV7M_R14, 0x3c, 32 }, /* lr */ { ARMV7M_PC, 0x40, 32 }, /* pc */ - { ARMV7M_xPSR, 0x44, 32 }, /* xPSR */ + { ARMV7M_XPSR, 0x44, 32 }, /* xPSR */ }; @@ -142,7 +131,7 @@ static const struct stack_register_offset nuttx_stack_offsets_cortex_m_fpu[] = { { ARMV7M_R13, 0, 32 }, /* sp */ { ARMV7M_R14, 0x80, 32 }, /* lr */ { ARMV7M_PC, 0x84, 32 }, /* pc */ - { ARMV7M_xPSR, 0x88, 32 }, /* xPSR */ + { ARMV7M_XPSR, 0x88, 32 }, /* xPSR */ }; static const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu = { diff --git a/src/rtos/nuttx_header.h b/src/rtos/nuttx_header.h index 00b0484..3436df1 100644 --- a/src/rtos/nuttx_header.h +++ b/src/rtos/nuttx_header.h @@ -1,20 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright 2016,2017 Sony Video & Sound Products Inc. * * Masatoshi Tateishi - Masatoshi.Tateishi@jp.sony.com * * Masayuki Ishikawa - Masayuki.Ishikawa@jp.sony.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_RTOS_NUTTX_HEADER_H diff --git a/src/rtos/riot.c b/src/rtos/riot.c index 8a38742..be5452e 100644 --- a/src/rtos/riot.c +++ b/src/rtos/riot.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 by Daniel Krebs * * Daniel Krebs - github@daniel-krebs.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c index b82ecb3..c9da33b 100644 --- a/src/rtos/rtos.c +++ b/src/rtos/rtos.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Broadcom Corporation * * Evan Hunter - ehunter@broadcom.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -148,6 +137,9 @@ int rtos_create(struct jim_getopt_info *goi, struct target *target) if (e != JIM_OK) return e; + if (strcmp(cp, "none") == 0) + return JIM_OK; + if (strcmp(cp, "auto") == 0) { /* Auto detect tries to look up all symbols for each RTOS, * and runs the RTOS driver's _detect() function when GDB @@ -167,7 +159,7 @@ int rtos_create(struct jim_getopt_info *goi, struct target *target) res = Jim_GetResult(goi->interp); for (x = 0; rtos_types[x]; x++) Jim_AppendStrings(goi->interp, res, rtos_types[x]->name, ", ", NULL); - Jim_AppendStrings(goi->interp, res, " or auto", NULL); + Jim_AppendStrings(goi->interp, res, ", auto or none", NULL); return JIM_ERR; } @@ -186,35 +178,32 @@ int gdb_thread_packet(struct connection *connection, char const *packet, int pac return target->rtos->gdb_thread_packet(connection, packet, packet_size); } -static struct symbol_table_elem *next_symbol(struct rtos *os, char *cur_symbol, uint64_t cur_addr) +static struct symbol_table_elem *find_symbol(const struct rtos *os, const char *symbol) { struct symbol_table_elem *s; - if (!os->symbols) - os->type->get_symbol_list_to_lookup(&os->symbols); - - if (!cur_symbol[0]) - return &os->symbols[0]; - for (s = os->symbols; s->symbol_name; s++) - if (!strcmp(s->symbol_name, cur_symbol)) { - s->address = cur_addr; - s++; + if (!strcmp(s->symbol_name, symbol)) return s; - } return NULL; } -/* searches for 'symbol' in the lookup table for 'os' and returns TRUE, - * if 'symbol' is not declared optional */ -static bool is_symbol_mandatory(const struct rtos *os, const char *symbol) +static struct symbol_table_elem *next_symbol(struct rtos *os, char *cur_symbol, uint64_t cur_addr) { - for (struct symbol_table_elem *s = os->symbols; s->symbol_name; ++s) { - if (!strcmp(s->symbol_name, symbol)) - return !s->optional; - } - return false; + if (!os->symbols) + os->type->get_symbol_list_to_lookup(&os->symbols); + + if (!cur_symbol[0]) + return &os->symbols[0]; + + struct symbol_table_elem *s = find_symbol(os, cur_symbol); + if (!s) + return NULL; + + s->address = cur_addr; + s++; + return s; } /* rtos_qsymbol() processes and replies to all qSymbol packets from GDB. @@ -234,6 +223,12 @@ static bool is_symbol_mandatory(const struct rtos *os, const char *symbol) * specified explicitly, then no further symbol lookup is done. When * auto-detecting, the RTOS driver _detect() function must return success. * + * The symbol is tried twice to handle the -flto case with gcc. The first + * attempt uses the symbol as-is, and the second attempt tries the symbol + * with ".lto_priv.0" appended to it. We only consider the first static + * symbol here from the -flto case. (Each subsequent static symbol with + * the same name is exported as .lto_priv.1, .lto_priv.2, etc.) + * * rtos_qsymbol() returns 1 if an RTOS has been detected, or 0 otherwise. */ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size) @@ -242,7 +237,7 @@ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_s uint64_t addr = 0; size_t reply_len; char reply[GDB_BUFFER_SIZE + 1], cur_sym[GDB_BUFFER_SIZE / 2 + 1] = ""; /* Extra byte for null-termination */ - struct symbol_table_elem *next_sym; + struct symbol_table_elem *next_sym = NULL; struct target *target = get_target_from_connection(connection); struct rtos *os = target->rtos; @@ -255,33 +250,60 @@ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_s size_t len = unhexify((uint8_t *)cur_sym, strchr(packet + 8, ':') + 1, strlen(strchr(packet + 8, ':') + 1)); cur_sym[len] = 0; + const char no_suffix[] = ""; + const char lto_suffix[] = ".lto_priv.0"; + const size_t lto_suffix_len = strlen(lto_suffix); + + const char *cur_suffix; + const char *next_suffix; + + /* Detect what suffix was used during the previous symbol lookup attempt, and + * speculatively determine the next suffix (only used for the unknown address case) */ + if (len > lto_suffix_len && !strcmp(cur_sym + len - lto_suffix_len, lto_suffix)) { + /* Trim the suffix from cur_sym for comparison purposes below */ + cur_sym[len - lto_suffix_len] = '\0'; + cur_suffix = lto_suffix; + next_suffix = NULL; + } else { + cur_suffix = no_suffix; + next_suffix = lto_suffix; + } + if ((strcmp(packet, "qSymbol::") != 0) && /* GDB is not offering symbol lookup for the first time */ - (!sscanf(packet, "qSymbol:%" SCNx64 ":", &addr)) && /* GDB did not find an address for a symbol */ - is_symbol_mandatory(os, cur_sym)) { /* the symbol is mandatory for this RTOS */ + (!sscanf(packet, "qSymbol:%" SCNx64 ":", &addr))) { /* GDB did not find an address for a symbol */ /* GDB could not find an address for the previous symbol */ - if (!target->rtos_auto_detect) { - LOG_WARNING("RTOS %s not detected. (GDB could not find symbol \'%s\')", os->type->name, cur_sym); - goto done; - } else { - /* Autodetecting RTOS - try next RTOS */ - if (!rtos_try_next(target)) { - LOG_WARNING("No RTOS could be auto-detected!"); + struct symbol_table_elem *sym = find_symbol(os, cur_sym); + + if (next_suffix) { + next_sym = sym; + } else if (sym && !sym->optional) { /* the symbol is mandatory for this RTOS */ + if (!target->rtos_auto_detect) { + LOG_WARNING("RTOS %s not detected. (GDB could not find symbol \'%s\')", os->type->name, cur_sym); goto done; - } + } else { + /* Autodetecting RTOS - try next RTOS */ + if (!rtos_try_next(target)) { + LOG_WARNING("No RTOS could be auto-detected!"); + goto done; + } - /* Next RTOS selected - invalidate current symbol */ - cur_sym[0] = '\x00'; + /* Next RTOS selected - invalidate current symbol */ + cur_sym[0] = '\x00'; + } } } - LOG_DEBUG("RTOS: Address of symbol '%s' is 0x%" PRIx64, cur_sym, addr); + LOG_DEBUG("RTOS: Address of symbol '%s%s' is 0x%" PRIx64, cur_sym, cur_suffix, addr); - next_sym = next_symbol(os, cur_sym, addr); + if (!next_sym) { + next_sym = next_symbol(os, cur_sym, addr); + next_suffix = no_suffix; + } /* Should never happen unless the debugger misbehaves */ if (!next_sym) { - LOG_WARNING("RTOS: Debugger sent us qSymbol with '%s' that we did not ask for", cur_sym); + LOG_WARNING("RTOS: Debugger sent us qSymbol with '%s%s' that we did not ask for", cur_sym, cur_suffix); goto done; } @@ -303,17 +325,26 @@ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_s } } - if (8 + (strlen(next_sym->symbol_name) * 2) + 1 > sizeof(reply)) { - LOG_ERROR("ERROR: RTOS symbol '%s' name is too long for GDB!", next_sym->symbol_name); + assert(next_suffix); + + reply_len = 8; /* snprintf(..., "qSymbol:") */ + reply_len += 2 * strlen(next_sym->symbol_name); /* hexify(..., next_sym->symbol_name, ...) */ + reply_len += 2 * strlen(next_suffix); /* hexify(..., next_suffix, ...) */ + reply_len += 1; /* Terminating NUL */ + if (reply_len > sizeof(reply)) { + LOG_ERROR("ERROR: RTOS symbol '%s%s' name is too long for GDB!", next_sym->symbol_name, next_suffix); goto done; } - LOG_DEBUG("RTOS: Requesting symbol lookup of '%s' from the debugger", next_sym->symbol_name); + LOG_DEBUG("RTOS: Requesting symbol lookup of '%s%s' from the debugger", next_sym->symbol_name, next_suffix); reply_len = snprintf(reply, sizeof(reply), "qSymbol:"); reply_len += hexify(reply + reply_len, (const uint8_t *)next_sym->symbol_name, strlen(next_sym->symbol_name), sizeof(reply) - reply_len); + reply_len += hexify(reply + reply_len, + (const uint8_t *)next_suffix, strlen(next_suffix), + sizeof(reply) - reply_len); done: gdb_put_packet(connection, reply, reply_len); diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h index 745bea7..6695915 100644 --- a/src/rtos/rtos.h +++ b/src/rtos/rtos.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Broadcom Corporation * * Evan Hunter - ehunter@broadcom.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_RTOS_RTOS_H diff --git a/src/rtos/rtos_chibios_stackings.c b/src/rtos/rtos_chibios_stackings.c index 77bcb86..e2fe0a2 100644 --- a/src/rtos/rtos_chibios_stackings.c +++ b/src/rtos/rtos_chibios_stackings.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2012 by Matthias Blaicher * * Matthias Blaicher - matthias@blaicher.com * * * * Copyright (C) 2011 by Broadcom Corporation * * Evan Hunter - ehunter@broadcom.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -43,7 +32,7 @@ static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets[ARM { ARMV7M_R13, -2, 32 }, /* sp */ { ARMV7M_R14, -1, 32 }, /* lr */ { ARMV7M_PC, 0x20, 32 }, /* pc */ - { ARMV7M_xPSR, -1, 32 }, /* xPSR */ + { ARMV7M_XPSR, -1, 32 }, /* xPSR */ }; const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking = { @@ -70,7 +59,7 @@ static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets_w_f { ARMV7M_R13, -2, 32 }, /* sp */ { ARMV7M_R14, -1, 32 }, /* lr */ { ARMV7M_PC, 0x60, 32 }, /* pc */ - { ARMV7M_xPSR, -1, 32 }, /* xPSR */ + { ARMV7M_XPSR, -1, 32 }, /* xPSR */ }; const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking_w_fpu = { diff --git a/src/rtos/rtos_chibios_stackings.h b/src/rtos/rtos_chibios_stackings.h index 130aaa1..23ad44a 100644 --- a/src/rtos/rtos_chibios_stackings.h +++ b/src/rtos/rtos_chibios_stackings.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Broadcom Corporation * * Evan Hunter - ehunter@broadcom.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H diff --git a/src/rtos/rtos_ecos_stackings.c b/src/rtos/rtos_ecos_stackings.c index 4745470..0f54e86 100644 --- a/src/rtos/rtos_ecos_stackings.c +++ b/src/rtos/rtos_ecos_stackings.c @@ -1,18 +1,4 @@ -/*************************************************************************** - * * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ +// SPDX-License-Identifier: GPL-2.0-or-later #ifdef HAVE_CONFIG_H #include "config.h" @@ -39,7 +25,7 @@ static const struct stack_register_offset rtos_ecos_cortex_m3_stack_offsets[ARMV { ARMV7M_R13, -2, 32 }, /* sp */ { ARMV7M_R14, -1, 32 }, /* lr */ { ARMV7M_PC, 0x40, 32 }, /* pc */ - { ARMV7M_xPSR, -1, 32 }, /* xPSR */ + { ARMV7M_XPSR, -1, 32 }, /* xPSR */ }; const struct rtos_register_stacking rtos_ecos_cortex_m3_stacking = { diff --git a/src/rtos/rtos_ecos_stackings.h b/src/rtos/rtos_ecos_stackings.h index d66d05f..0375e2d 100644 --- a/src/rtos/rtos_ecos_stackings.h +++ b/src/rtos/rtos_ecos_stackings.h @@ -1,18 +1,4 @@ -/*************************************************************************** - * * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H #define OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H diff --git a/src/rtos/rtos_embkernel_stackings.c b/src/rtos/rtos_embkernel_stackings.c index df1fc51..809b622 100644 --- a/src/rtos/rtos_embkernel_stackings.c +++ b/src/rtos/rtos_embkernel_stackings.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Broadcom Corporation * * Evan Hunter - ehunter@broadcom.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -41,7 +30,7 @@ static const struct stack_register_offset rtos_embkernel_cortex_m_stack_offsets[ { ARMV7M_R13, -2, 32 }, /* sp */ { ARMV7M_R14, 0x38, 32 }, /* lr */ { ARMV7M_PC, 0x3c, 32 }, /* pc */ - { ARMV7M_xPSR, 0x40, 32 }, /* xPSR */ + { ARMV7M_XPSR, 0x40, 32 }, /* xPSR */ }; const struct rtos_register_stacking rtos_embkernel_cortex_m_stacking = { diff --git a/src/rtos/rtos_embkernel_stackings.h b/src/rtos/rtos_embkernel_stackings.h index 7850beb..972bce6 100644 --- a/src/rtos/rtos_embkernel_stackings.h +++ b/src/rtos/rtos_embkernel_stackings.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Broadcom Corporation * * Evan Hunter - ehunter@broadcom.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H diff --git a/src/rtos/rtos_mqx_stackings.c b/src/rtos/rtos_mqx_stackings.c index f99190e..8c8fd20 100644 --- a/src/rtos/rtos_mqx_stackings.c +++ b/src/rtos/rtos_mqx_stackings.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2014 by Marian Cingel * * cingel.marian@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -67,7 +56,7 @@ static const struct stack_register_offset rtos_mqx_arm_v7m_stack_offsets[ARMV7M_ { ARMV7M_R13, -2, 32 }, /* sp */ { ARMV7M_R14, 0x28, 32 }, /* lr */ { ARMV7M_PC, 0x44, 32 }, /* pc */ - { ARMV7M_xPSR, 0x48, 32 }, /* xPSR */ + { ARMV7M_XPSR, 0x48, 32 }, /* xPSR */ }; const struct rtos_register_stacking rtos_mqx_arm_v7m_stacking = { diff --git a/src/rtos/rtos_mqx_stackings.h b/src/rtos/rtos_mqx_stackings.h index 6ebd287..f86c05a 100644 --- a/src/rtos/rtos_mqx_stackings.h +++ b/src/rtos/rtos_mqx_stackings.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2014 by Marian Cingel * * cingel.marian@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_RTOS_RTOS_MQX_STACKINGS_H diff --git a/src/rtos/rtos_riot_stackings.c b/src/rtos/rtos_riot_stackings.c index 84e1f7f..e717e8c 100644 --- a/src/rtos/rtos_riot_stackings.c +++ b/src/rtos/rtos_riot_stackings.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 by Daniel Krebs * * Daniel Krebs - github@daniel-krebs.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -54,7 +43,7 @@ static const struct stack_register_offset rtos_riot_cortex_m0_stack_offsets[ARMV { ARMV7M_R13, -2, 32 }, /* sp */ { ARMV7M_R14, 0x38, 32 }, /* lr */ { ARMV7M_PC, 0x3c, 32 }, /* pc */ - { ARMV7M_xPSR, 0x40, 32 }, /* xPSR */ + { ARMV7M_XPSR, 0x40, 32 }, /* xPSR */ }; const struct rtos_register_stacking rtos_riot_cortex_m0_stacking = { @@ -83,7 +72,7 @@ static const struct stack_register_offset rtos_riot_cortex_m34_stack_offsets[ARM { ARMV7M_R13, -2, 32 }, /* sp */ { ARMV7M_R14, 0x38, 32 }, /* lr */ { ARMV7M_PC, 0x3c, 32 }, /* pc */ - { ARMV7M_xPSR, 0x40, 32 }, /* xPSR */ + { ARMV7M_XPSR, 0x40, 32 }, /* xPSR */ }; const struct rtos_register_stacking rtos_riot_cortex_m34_stacking = { diff --git a/src/rtos/rtos_riot_stackings.h b/src/rtos/rtos_riot_stackings.h index c5b8f59..3b6c5f4 100644 --- a/src/rtos/rtos_riot_stackings.h +++ b/src/rtos/rtos_riot_stackings.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2015 by Daniel Krebs * * Daniel Krebs - github@daniel-krebs.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_RTOS_RTOS_RIOT_STACKINGS_H diff --git a/src/rtos/rtos_standard_stackings.c b/src/rtos/rtos_standard_stackings.c index d338a47..f2b4e15 100644 --- a/src/rtos/rtos_standard_stackings.c +++ b/src/rtos/rtos_standard_stackings.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Broadcom Corporation * * Evan Hunter - ehunter@broadcom.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -41,7 +30,7 @@ static const struct stack_register_offset rtos_standard_cortex_m3_stack_offsets[ { ARMV7M_R13, -2, 32 }, /* sp */ { ARMV7M_R14, 0x34, 32 }, /* lr */ { ARMV7M_PC, 0x38, 32 }, /* pc */ - { ARMV7M_xPSR, 0x3c, 32 }, /* xPSR */ + { ARMV7M_XPSR, 0x3c, 32 }, /* xPSR */ }; static const struct stack_register_offset rtos_standard_cortex_m4f_stack_offsets[] = { @@ -61,7 +50,7 @@ static const struct stack_register_offset rtos_standard_cortex_m4f_stack_offsets { ARMV7M_R13, -2, 32 }, /* sp */ { ARMV7M_R14, 0x38, 32 }, /* lr */ { ARMV7M_PC, 0x3c, 32 }, /* pc */ - { ARMV7M_xPSR, 0x40, 32 }, /* xPSR */ + { ARMV7M_XPSR, 0x40, 32 }, /* xPSR */ }; static const struct stack_register_offset rtos_standard_cortex_m4f_fpu_stack_offsets[] = { @@ -81,7 +70,7 @@ static const struct stack_register_offset rtos_standard_cortex_m4f_fpu_stack_off { ARMV7M_R13, -2, 32 }, /* sp */ { ARMV7M_R14, 0x78, 32 }, /* lr */ { ARMV7M_PC, 0x7c, 32 }, /* pc */ - { ARMV7M_xPSR, 0x80, 32 }, /* xPSR */ + { ARMV7M_XPSR, 0x80, 32 }, /* xPSR */ }; diff --git a/src/rtos/rtos_standard_stackings.h b/src/rtos/rtos_standard_stackings.h index 71118fd..455acc4 100644 --- a/src/rtos/rtos_standard_stackings.h +++ b/src/rtos/rtos_standard_stackings.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Broadcom Corporation * * Evan Hunter - ehunter@broadcom.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H diff --git a/src/rtos/rtos_ucos_iii_stackings.c b/src/rtos/rtos_ucos_iii_stackings.c index 0d533b5..9ba5288 100644 --- a/src/rtos/rtos_ucos_iii_stackings.c +++ b/src/rtos/rtos_ucos_iii_stackings.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2017 by Square, Inc. * * Steven Stallion <stallion@squareup.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -43,7 +32,7 @@ static const struct stack_register_offset rtos_ucos_iii_cortex_m_stack_offsets[] { ARMV7M_R13, -2, 32 }, /* sp */ { ARMV7M_R14, 0x34, 32 }, /* lr */ { ARMV7M_PC, 0x38, 32 }, /* pc */ - { ARMV7M_xPSR, 0x3c, 32 }, /* xPSR */ + { ARMV7M_XPSR, 0x3c, 32 }, /* xPSR */ }; static const struct stack_register_offset rtos_ucos_iii_esi_risc_stack_offsets[] = { diff --git a/src/rtos/rtos_ucos_iii_stackings.h b/src/rtos/rtos_ucos_iii_stackings.h index f2f120f..831c68e 100644 --- a/src/rtos/rtos_ucos_iii_stackings.h +++ b/src/rtos/rtos_ucos_iii_stackings.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2017 by Square, Inc. * * Steven Stallion <stallion@squareup.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_RTOS_RTOS_UCOS_III_STACKINGS_H diff --git a/src/rtos/uCOS-III.c b/src/rtos/uCOS-III.c index 385c8d8..21be8ff 100644 --- a/src/rtos/uCOS-III.c +++ b/src/rtos/uCOS-III.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2017 by Square, Inc. * * Steven Stallion <stallion@squareup.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/rtos/zephyr.c b/src/rtos/zephyr.c index 7f3325f..b00b4b3 100644 --- a/src/rtos/zephyr.c +++ b/src/rtos/zephyr.c @@ -1,11 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2017 by Intel Corporation * Leandro Pereira <leandro.pereira@intel.com> * Daniel Glöckner <dg@emlix.com>* * Copyright (C) 2021 by Synopsys, Inc. * Evgeniy Didin <didin@synopsys.com> - * * - * SPDX-License-Identifier: GPL-2.0-or-later * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -136,7 +136,7 @@ static const struct stack_register_offset arm_cpu_saved[] = { { ARMV7M_R13, -2, 32 }, { ARMV7M_R14, 20, 32 }, { ARMV7M_PC, 24, 32 }, - { ARMV7M_xPSR, 28, 32 }, + { ARMV7M_XPSR, 28, 32 }, }; static struct stack_register_offset arc_cpu_saved[] = { diff --git a/src/rtt/Makefile.am b/src/rtt/Makefile.am index e3fcefd..9968554 100644 --- a/src/rtt/Makefile.am +++ b/src/rtt/Makefile.am @@ -1,2 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/librtt.la %C%_librtt_la_SOURCES = %D%/rtt.c %D%/rtt.h %D%/tcl.c diff --git a/src/rtt/rtt.c b/src/rtt/rtt.c index 3da3cce..e31e754 100644 --- a/src/rtt/rtt.c +++ b/src/rtt/rtt.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de> - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H diff --git a/src/rtt/rtt.h b/src/rtt/rtt.h index bc21bd0..a5630a9 100644 --- a/src/rtt/rtt.h +++ b/src/rtt/rtt.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de> - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifndef OPENOCD_RTT_RTT_H diff --git a/src/rtt/tcl.c b/src/rtt/tcl.c index 4a34d8b..7cbdccf 100644 --- a/src/rtt/tcl.c +++ b/src/rtt/tcl.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright (C) 2019-2020 by Marc Schink <dev@zapb.de> - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H diff --git a/src/server/Makefile.am b/src/server/Makefile.am index e3699f1..13a5914 100644 --- a/src/server/Makefile.am +++ b/src/server/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libserver.la %C%_libserver_la_SOURCES = \ %D%/server.c \ diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index e5bf74f..956a347 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -19,19 +21,6 @@ * * * Copyright (C) 2013 Franck Jullien * * elec4fun@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -1362,6 +1351,8 @@ static int gdb_set_registers_packet(struct connection *connection, packet_p = packet; for (i = 0; i < reg_list_size; i++) { uint8_t *bin_buf; + if (!reg_list[i] || !reg_list[i]->exist || reg_list[i]->hidden) + continue; int chars = (DIV_ROUND_UP(reg_list[i]->size, 8) * 2); if (packet_p + chars > packet + packet_size) @@ -1414,7 +1405,8 @@ static int gdb_get_register_packet(struct connection *connection, if (retval != ERROR_OK) return gdb_error(connection, retval); - if (reg_list_size <= reg_num) { + if ((reg_list_size <= reg_num) || !reg_list[reg_num] || + !reg_list[reg_num]->exist || reg_list[reg_num]->hidden) { LOG_ERROR("gdb requested a non-existing register (reg_num=%d)", reg_num); return ERROR_SERVER_REMOTE_CLOSED; } @@ -1476,7 +1468,8 @@ static int gdb_set_register_packet(struct connection *connection, return gdb_error(connection, retval); } - if (reg_list_size <= reg_num) { + if ((reg_list_size <= reg_num) || !reg_list[reg_num] || + !reg_list[reg_num]->exist || reg_list[reg_num]->hidden) { LOG_ERROR("gdb requested a non-existing register (reg_num=%d)", reg_num); free(bin_buf); free(reg_list); @@ -1814,8 +1807,11 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection, if (!bp_target) return ERROR_FAIL; } - retval = breakpoint_add(bp_target, address, size, bp_type); - if (retval != ERROR_OK) { + retval = breakpoint_add(target, address, size, bp_type); + if (retval == ERROR_NOT_IMPLEMENTED) { + /* Send empty reply to report that breakpoints of this type are not supported */ + gdb_put_packet(connection, "", 0); + } else if (retval != ERROR_OK) { retval = gdb_error(connection, retval); if (retval != ERROR_OK) return retval; @@ -1832,7 +1828,10 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection, { if (packet[0] == 'Z') { retval = watchpoint_add(target, address, size, wp_type, 0, 0xffffffffu); - if (retval != ERROR_OK) { + if (retval == ERROR_NOT_IMPLEMENTED) { + /* Send empty reply to report that watchpoints of this type are not supported */ + gdb_put_packet(connection, "", 0); + } else if (retval != ERROR_OK) { retval = gdb_error(connection, retval); if (retval != ERROR_OK) return retval; @@ -3002,6 +3001,11 @@ static int gdb_query_packet(struct connection *connection, gdb_connection->noack_mode = 1; gdb_put_packet(connection, "OK", 2); return ERROR_OK; + } else if (target->type->gdb_query_custom) { + char *buffer = NULL; + int ret = target->type->gdb_query_custom(target, packet, &buffer); + gdb_put_packet(connection, buffer, strlen(buffer)); + return ret; } gdb_put_packet(connection, "", 0); @@ -3062,139 +3066,138 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p gdb_running_type = 's'; bool fake_step = false; - if (strncmp(parse, "s:", 2) == 0) { - struct target *ct = target; - int current_pc = 1; - int64_t thread_id; + struct target *ct = target; + int current_pc = 1; + int64_t thread_id; + parse++; + packet_size--; + if (parse[0] == ':') { char *endp; - - parse += 2; - packet_size -= 2; - + parse++; + packet_size--; thread_id = strtoll(parse, &endp, 16); if (endp) { packet_size -= endp - parse; parse = endp; } + } else { + thread_id = 0; + } - if (target->rtos) { - /* FIXME: why is this necessary? rtos state should be up-to-date here already! */ - - /* Sometimes this results in picking a different thread than - * gdb just requested to step. Then we fake it, and now there's - * a different thread selected than gdb expects, so register - * accesses go to the wrong one! - * E.g.: - * Hg1$ - * P8=72101ce197869329$ # write r8 on thread 1 - * g$ - * vCont?$ - * vCont;s:1;c$ # rtos_update_threads changes to other thread - * g$ - * qXfer:threads:read::0,fff$ - * P8=cc060607eb89ca7f$ # write r8 on other thread - * g$ - * */ - /* rtos_update_threads(target); */ - - target->rtos->gdb_target_for_threadid(connection, thread_id, &ct); - - /* - * check if the thread to be stepped is the current rtos thread - * if not, we must fake the step - */ - fake_step = rtos_needs_fake_step(target, thread_id); - } + if (target->rtos) { + /* FIXME: why is this necessary? rtos state should be up-to-date here already! */ + + /* Sometimes this results in picking a different thread than + * gdb just requested to step. Then we fake it, and now there's + * a different thread selected than gdb expects, so register + * accesses go to the wrong one! + * E.g.: + * Hg1$ + * P8=72101ce197869329$ # write r8 on thread 1 + * g$ + * vCont?$ + * vCont;s:1;c$ # rtos_update_threads changes to other thread + * g$ + * qXfer:threads:read::0,fff$ + * P8=cc060607eb89ca7f$ # write r8 on other thread + * g$ + * */ + /* rtos_update_threads(target); */ + + target->rtos->gdb_target_for_threadid(connection, thread_id, &ct); + + /* + * check if the thread to be stepped is the current rtos thread + * if not, we must fake the step + */ + fake_step = rtos_needs_fake_step(target, thread_id); + } + + if (parse[0] == ';') { + ++parse; + --packet_size; - if (parse[0] == ';') { - ++parse; - --packet_size; + if (parse[0] == 'c') { + parse += 1; - if (parse[0] == 'c') { + /* check if thread-id follows */ + if (parse[0] == ':') { + int64_t tid; parse += 1; - /* check if thread-id follows */ - if (parse[0] == ':') { - int64_t tid; - parse += 1; - - tid = strtoll(parse, &endp, 16); - if (tid == thread_id) { - /* - * Special case: only step a single thread (core), - * keep the other threads halted. Currently, only - * aarch64 target understands it. Other target types don't - * care (nobody checks the actual value of 'current') - * and it doesn't really matter. This deserves - * a symbolic constant and a formal interface documentation - * at a later time. - */ - LOG_DEBUG("request to step current core only"); - /* uncomment after checking that indeed other targets are safe */ - /*current_pc = 2;*/ - } + tid = strtoll(parse, NULL, 16); + if (tid == thread_id) { + /* + * Special case: only step a single thread (core), + * keep the other threads halted. Currently, only + * aarch64 target understands it. Other target types don't + * care (nobody checks the actual value of 'current') + * and it doesn't really matter. This deserves + * a symbolic constant and a formal interface documentation + * at a later time. + */ + LOG_DEBUG("request to step current core only"); + /* uncomment after checking that indeed other targets are safe */ + /*current_pc = 2;*/ } } } + } - LOG_DEBUG("target %s single-step thread %"PRIx64, target_name(ct), thread_id); - gdb_connection->output_flag = GDB_OUTPUT_ALL; - target_call_event_callbacks(ct, TARGET_EVENT_GDB_START); - - if (fake_step) { - /* We just fake the step to not trigger an internal error in - * gdb. See https://sourceware.org/bugzilla/show_bug.cgi?id=22925 - * for details. */ - int sig_reply_len; - char sig_reply[128]; - - LOG_DEBUG("fake step thread %"PRIx64, thread_id); - target->rtos->current_threadid = thread_id; + LOG_DEBUG("target %s single-step thread %"PRIx64, target_name(ct), thread_id); + gdb_connection->output_flag = GDB_OUTPUT_ALL; + target_call_event_callbacks(ct, TARGET_EVENT_GDB_START); - sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), - "T05thread:%016"PRIx64";", thread_id); + if (fake_step) { + /* We just fake the step to not trigger an internal error in + * gdb. See https://sourceware.org/bugzilla/show_bug.cgi?id=22925 + * for details. */ + int sig_reply_len; + char sig_reply[128]; - gdb_put_packet(connection, sig_reply, sig_reply_len); - gdb_connection->output_flag = GDB_OUTPUT_NO; + LOG_DEBUG("fake step thread %"PRIx64, thread_id); + target->rtos->current_threadid = thread_id; - return true; - } + sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), + "T05thread:%016"PRIx64";", thread_id); - /* support for gdb_sync command */ - if (gdb_connection->sync) { - gdb_connection->sync = false; - if (ct->state == TARGET_HALTED) { - LOG_DEBUG("stepi ignored. GDB will now fetch the register state " - "from the target."); - gdb_sig_halted(connection); - gdb_connection->output_flag = GDB_OUTPUT_NO; - } else - gdb_connection->frontend_state = TARGET_RUNNING; - return true; - } + gdb_put_packet(connection, sig_reply, sig_reply_len); + gdb_connection->output_flag = GDB_OUTPUT_NO; - retval = target_step(ct, current_pc, 0, 0); - if (retval == ERROR_TARGET_NOT_HALTED) - LOG_INFO("target %s was not halted when step was requested", target_name(ct)); + return true; + } - /* if step was successful send a reply back to gdb */ - if (retval == ERROR_OK) { - retval = target_poll(ct); - if (retval != ERROR_OK) - LOG_DEBUG("error polling target %s after successful step", target_name(ct)); - /* send back signal information */ - gdb_signal_reply(ct, connection); - /* stop forwarding log packets! */ + /* support for gdb_sync command */ + if (gdb_connection->sync) { + gdb_connection->sync = false; + if (ct->state == TARGET_HALTED) { + LOG_DEBUG("stepi ignored. GDB will now fetch the register state " + "from the target."); + gdb_sig_halted(connection); gdb_connection->output_flag = GDB_OUTPUT_NO; } else gdb_connection->frontend_state = TARGET_RUNNING; - } else { - LOG_ERROR("Unknown vCont packet"); - return false; + return true; } + + retval = target_step(ct, current_pc, 0, 0); + if (retval == ERROR_TARGET_NOT_HALTED) + LOG_INFO("target %s was not halted when step was requested", target_name(ct)); + + /* if step was successful send a reply back to gdb */ + if (retval == ERROR_OK) { + retval = target_poll(ct); + if (retval != ERROR_OK) + LOG_DEBUG("error polling target %s after successful step", target_name(ct)); + /* send back signal information */ + gdb_signal_reply(ct, connection); + /* stop forwarding log packets! */ + gdb_connection->output_flag = GDB_OUTPUT_NO; + } else + gdb_connection->frontend_state = TARGET_RUNNING; return true; } - + LOG_ERROR("Unknown vCont packet"); return false; } diff --git a/src/server/gdb_server.h b/src/server/gdb_server.h index 0c50836..6821e36 100644 --- a/src/server/gdb_server.h +++ b/src/server/gdb_server.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -10,19 +12,6 @@ * * * Copyright (C) 2011 by Broadcom Corporation * * Evan Hunter - ehunter@broadcom.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_SERVER_GDB_SERVER_H diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c index 3bbcf07..f4a6f6c 100644 --- a/src/server/ipdbg.c +++ b/src/server/ipdbg.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later /* Copyright (C) 2020 by Daniel Anselmi <danselmi@gmx.ch> */ #ifdef HAVE_CONFIG_H diff --git a/src/server/rtt_server.c b/src/server/rtt_server.c index 3850c26..df2247b 100644 --- a/src/server/rtt_server.c +++ b/src/server/rtt_server.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright (C) 2016-2017 by Marc Schink <dev@zapb.de> - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H diff --git a/src/server/rtt_server.h b/src/server/rtt_server.h index aec6f22..5cea25a 100644 --- a/src/server/rtt_server.h +++ b/src/server/rtt_server.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * Copyright (C) 2016-2017 by Marc Schink <dev@zapb.de> - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifndef OPENOCD_SERVER_RTT_SERVER_H diff --git a/src/server/server.c b/src/server/server.c index 082febb..4da31ae 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -484,7 +473,7 @@ int server_loop(struct command_context *command_context) tv.tv_usec = 0; retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv); } else { - /* Every 100ms, can be changed with "poll_period" command */ + /* Timeout socket_select() when a target timer expires or every polling_period */ int timeout_ms = next_event - timeval_ms(); if (timeout_ms < 0) timeout_ms = 0; @@ -519,9 +508,12 @@ int server_loop(struct command_context *command_context) } if (retval == 0) { - /* We only execute these callbacks when there was nothing to do or we timed - *out */ - target_call_timer_callbacks_now(); + /* Execute callbacks of expired timers when + * - there was nothing to do if poll_ok was true + * - socket_select() timed out if poll_ok was false, now one or more + * timers expired or the polling period elapsed + */ + target_call_timer_callbacks(); next_event = target_timer_next_event(); process_jim_events(command_context); @@ -756,6 +748,11 @@ int connection_read(struct connection *connection, void *data, int len) return read(connection->fd, data, len); } +bool openocd_is_shutdown_pending(void) +{ + return shutdown_openocd != CONTINUE_MAIN_LOOP; +} + /* tell the server we want to shut down */ COMMAND_HANDLER(handle_shutdown_command) { diff --git a/src/server/server.h b/src/server/server.h index a6b1963..c9d4698 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_SERVER_SERVER_H @@ -115,6 +104,8 @@ int server_register_commands(struct command_context *context); int connection_write(struct connection *connection, const void *data, int len); int connection_read(struct connection *connection, void *data, int len); +bool openocd_is_shutdown_pending(void); + /** * Defines an extended command handler function declaration to enable * access to (and manipulation of) the server port number. diff --git a/src/server/startup.tcl b/src/server/startup.tcl index 447b57c..1d30b1d 100644 --- a/src/server/startup.tcl +++ b/src/server/startup.tcl @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + # Defines basic Tcl procs for OpenOCD server modules # Handle GDB 'R' packet. Can be overridden by configuration script, diff --git a/src/server/tcl_server.c b/src/server/tcl_server.c index 458d7ea..16cbedc 100644 --- a/src/server/tcl_server.c +++ b/src/server/tcl_server.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2010 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/server/tcl_server.h b/src/server/tcl_server.h index 6ce3ab9..bee562c 100644 --- a/src/server/tcl_server.h +++ b/src/server/tcl_server.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2008 * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_SERVER_TCL_SERVER_H diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c index 8e79626..938bc5b 100644 --- a/src/server/telnet_server.c +++ b/src/server/telnet_server.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/server/telnet_server.h b/src/server/telnet_server.h index 27148d7..313b529 100644 --- a/src/server/telnet_server.h +++ b/src/server/telnet_server.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_SERVER_TELNET_SERVER_H diff --git a/src/svf/Makefile.am b/src/svf/Makefile.am index 5603d53..5fcb02c 100644 --- a/src/svf/Makefile.am +++ b/src/svf/Makefile.am @@ -1,2 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libsvf.la %C%_libsvf_la_SOURCES = %D%/svf.c %D%/svf.h diff --git a/src/svf/svf.c b/src/svf/svf.c index 3021dcb..a537431 100644 --- a/src/svf/svf.c +++ b/src/svf/svf.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by Simon Qian * * SimonQian@SimonQian.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* The specification for SVF is available here: diff --git a/src/svf/svf.h b/src/svf/svf.h index 4101a3f..74f7d9c 100644 --- a/src/svf/svf.h +++ b/src/svf/svf.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 by Simon Qian * * SimonQian@SimonQian.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_SVF_SVF_H diff --git a/src/target/Makefile.am b/src/target/Makefile.am index 799c3dd..4687092 100644 --- a/src/target/Makefile.am +++ b/src/target/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + %C%_libtarget_la_LIBADD = %D%/openrisc/libopenrisc.la \ %D%/riscv/libriscv.la \ %D%/xtensa/libxtensa.la \ diff --git a/src/target/a64_disassembler.c b/src/target/a64_disassembler.c index 58ddf60..ca3d3ea 100644 --- a/src/target/a64_disassembler.c +++ b/src/target/a64_disassembler.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2019 by Mete Balci * * metebalci@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/a64_disassembler.h b/src/target/a64_disassembler.h index 5c58bbf..28fcf4b 100644 --- a/src/target/a64_disassembler.h +++ b/src/target/a64_disassembler.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2019 by Mete Balci * * metebalci@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_AARCH64_DISASSEMBLER_H diff --git a/src/target/aarch64.c b/src/target/aarch64.c index ecd9324..8592daa 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -1,20 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 by David Ung * * * - * 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., * - * * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -1849,7 +1837,7 @@ static int aarch64_remove_watchpoint(struct target *target, * find out which watchpoint hits * get exception address and compare the address to watchpoints */ -int aarch64_hit_watchpoint(struct target *target, +static int aarch64_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint) { if (target->debug_reason != DBG_REASON_WATCHPOINT) @@ -1942,7 +1930,7 @@ static int aarch64_assert_reset(struct target *target) else if (reset_config & RESET_HAS_SRST) { bool srst_asserted = false; - if (target->reset_halt) { + if (target->reset_halt && !(reset_config & RESET_SRST_PULLS_TRST)) { if (target_was_examined(target)) { if (reset_config & RESET_SRST_NO_GATING) { @@ -1952,12 +1940,12 @@ static int aarch64_assert_reset(struct target *target) */ adapter_assert_reset(); srst_asserted = true; - - /* make sure to clear all sticky errors */ - mem_ap_write_atomic_u32(armv8->debug_ap, - armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE); } + /* make sure to clear all sticky errors */ + mem_ap_write_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE); + /* set up Reset Catch debug event to halt the CPU after reset */ retval = aarch64_enable_reset_catch(target, true); if (retval != ERROR_OK) @@ -2558,15 +2546,24 @@ static int aarch64_examine_first(struct target *target) if (!pc) return ERROR_FAIL; + if (armv8->debug_ap) { + dap_put_ap(armv8->debug_ap); + armv8->debug_ap = NULL; + } + if (pc->adiv5_config.ap_num == DP_APSEL_INVALID) { /* Search for the APB-AB */ - retval = dap_find_ap(swjdp, AP_TYPE_APB_AP, &armv8->debug_ap); + retval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &armv8->debug_ap); if (retval != ERROR_OK) { LOG_ERROR("Could not find APB-AP for debug access"); return retval; } } else { - armv8->debug_ap = dap_ap(swjdp, pc->adiv5_config.ap_num); + armv8->debug_ap = dap_get_ap(swjdp, pc->adiv5_config.ap_num); + if (!armv8->debug_ap) { + LOG_ERROR("Cannot get AP"); + return ERROR_FAIL; + } } retval = mem_ap_init(armv8->debug_ap); @@ -2755,6 +2752,9 @@ static void aarch64_deinit_target(struct target *target) struct armv8_common *armv8 = &aarch64->armv8_common; struct arm_dpm *dpm = &armv8->dpm; + if (armv8->debug_ap) + dap_put_ap(armv8->debug_ap); + armv8_free_reg_cache(target); free(aarch64->brp_list); free(dpm->dbp); @@ -3144,8 +3144,6 @@ static const struct command_registration aarch64_exec_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -extern const struct command_registration semihosting_common_handlers[]; - static const struct command_registration aarch64_command_handlers[] = { { .name = "arm", diff --git a/src/target/aarch64.h b/src/target/aarch64.h index b57361f..2721fe7 100644 --- a/src/target/aarch64.h +++ b/src/target/aarch64.h @@ -1,19 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2015 by David Ung * - * * - * 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., * ***************************************************************************/ #ifndef OPENOCD_TARGET_AARCH64_H @@ -21,7 +9,7 @@ #include "armv8.h" -#define AARCH64_COMMON_MAGIC 0x411fc082 +#define AARCH64_COMMON_MAGIC 0x41413634U #define CPUDBG_CPUID 0xD00 #define CPUDBG_CTYPR 0xD04 @@ -50,7 +38,9 @@ struct aarch64_brp { }; struct aarch64_common { - int common_magic; + unsigned int common_magic; + + struct armv8_common armv8_common; /* Context information */ uint32_t system_control_reg; @@ -67,8 +57,6 @@ struct aarch64_common { int wp_num_available; struct aarch64_brp *wp_list; - struct armv8_common armv8_common; - enum aarch64_isrmasking_mode isrmasking_mode; }; diff --git a/src/target/adi_v5_dapdirect.c b/src/target/adi_v5_dapdirect.c index c0deee1..e1c00b7 100644 --- a/src/target/adi_v5_dapdirect.c +++ b/src/target/adi_v5_dapdirect.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright (C) 2019, STMicroelectronics - All Rights Reserved * Author(s): Antonio Borneo <borneo.antonio@gmail.com> for STMicroelectronics - * - * 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, see <http://www.gnu.org/licenses/>. */ /** diff --git a/src/target/adi_v5_jtag.c b/src/target/adi_v5_jtag.c index 94ee8cf..eeb796b 100644 --- a/src/target/adi_v5_jtag.c +++ b/src/target/adi_v5_jtag.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Magnus Lundin * lundin@mlu.mine.nu @@ -10,24 +12,13 @@ * * Copyright (C) 2009-2010 by David Brownell * - * 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, see <http://www.gnu.org/licenses/>. + * Copyright (C) 2020-2021, Ampere Computing LLC * ***************************************************************************/ /** * @file * This file implements JTAG transport support for cores implementing - the ARM Debug Interface version 5 (ADIv5). + the ARM Debug Interface version 5 (ADIv5) and version 6 (ADIv6). */ #ifdef HAVE_CONFIG_H @@ -49,13 +40,15 @@ #define JTAG_DP_IDCODE 0xFE /* three-bit ACK values for DPACC and APACC reads */ -#define JTAG_ACK_OK_FAULT 0x2 -#define JTAG_ACK_WAIT 0x1 +#define JTAG_ACK_WAIT 0x1 /* ADIv5 and ADIv6 */ +#define JTAG_ACK_OK_FAULT 0x2 /* ADIv5 */ +#define JTAG_ACK_FAULT 0x2 /* ADIv6 */ +#define JTAG_ACK_OK 0x4 /* ADIV6 */ static int jtag_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack); #ifdef DEBUG_WAIT -static const char *dap_reg_name(int instr, int reg_addr) +static const char *dap_reg_name(struct adiv5_dap *dap, uint8_t instr, uint16_t reg_addr) { char *reg_name = "UNK"; @@ -83,41 +76,32 @@ static const char *dap_reg_name(int instr, int reg_addr) } if (instr == JTAG_DP_APACC) { - switch (reg_addr) { - case MEM_AP_REG_CSW: + if (reg_addr == MEM_AP_REG_CSW(dap)) reg_name = "CSW"; - break; - case MEM_AP_REG_TAR: + else if (reg_addr == MEM_AP_REG_TAR(dap)) reg_name = "TAR"; - break; - case MEM_AP_REG_DRW: + else if (reg_addr == MEM_AP_REG_TAR64(dap)) + reg_name = "TAR64"; + else if (reg_addr == MEM_AP_REG_DRW(dap)) reg_name = "DRW"; - break; - case MEM_AP_REG_BD0: + else if (reg_addr == MEM_AP_REG_BD0(dap)) reg_name = "BD0"; - break; - case MEM_AP_REG_BD1: + else if (reg_addr == MEM_AP_REG_BD1(dap)) reg_name = "BD1"; - break; - case MEM_AP_REG_BD2: + else if (reg_addr == MEM_AP_REG_BD2(dap)) reg_name = "BD2"; - break; - case MEM_AP_REG_BD3: + else if (reg_addr == MEM_AP_REG_BD3(dap)) reg_name = "BD3"; - break; - case MEM_AP_REG_CFG: + else if (reg_addr == MEM_AP_REG_CFG(dap)) reg_name = "CFG"; - break; - case MEM_AP_REG_BASE: + else if (reg_addr == MEM_AP_REG_BASE(dap)) reg_name = "BASE"; - break; - case AP_REG_IDR: + else if (reg_addr == MEM_AP_REG_BASE64(dap)) + reg_name = "BASE64"; + else if (reg_addr == AP_REG_IDR(dap)) reg_name = "IDR"; - break; - default: + else reg_name = "UNK"; - break; - } } return reg_name; @@ -127,12 +111,12 @@ static const char *dap_reg_name(int instr, int reg_addr) struct dap_cmd { struct list_head lh; uint8_t instr; - uint8_t reg_addr; + uint16_t reg_addr; uint8_t rnw; uint8_t *invalue; uint8_t ack; uint32_t memaccess_tck; - uint32_t dp_select; + uint64_t dp_select; struct scan_field fields[2]; uint8_t out_addr_buf; @@ -147,17 +131,38 @@ struct dap_cmd_pool { struct dap_cmd cmd; }; -static void log_dap_cmd(const char *header, struct dap_cmd *el) +static void log_dap_cmd(struct adiv5_dap *dap, const char *header, struct dap_cmd *el) { #ifdef DEBUG_WAIT + const char *ack; + switch (el->ack) { + case JTAG_ACK_WAIT: /* ADIv5 and ADIv6 */ + ack = "WAIT"; + break; + case JTAG_ACK_OK_FAULT: /* ADIv5, same value as JTAG_ACK_FAULT */ + /* case JTAG_ACK_FAULT: */ /* ADIv6 */ + if (is_adiv6(dap)) + ack = "FAULT"; + else + ack = "OK"; + break; + case JTAG_ACK_OK: /* ADIv6 */ + if (is_adiv6(dap)) { + ack = "OK"; + break; + } + /* fall-through */ + default: + ack = "INVAL"; + break; + } LOG_DEBUG("%s: %2s %6s %5s 0x%08x 0x%08x %2s", header, el->instr == JTAG_DP_APACC ? "AP" : "DP", - dap_reg_name(el->instr, el->reg_addr), + dap_reg_name(dap, el->instr, el->reg_addr), el->rnw == DPAP_READ ? "READ" : "WRITE", buf_get_u32(el->outvalue_buf, 0, 32), buf_get_u32(el->invalue, 0, 32), - el->ack == JTAG_ACK_OK_FAULT ? "OK" : - (el->ack == JTAG_ACK_WAIT ? "WAIT" : "INVAL")); + ack); #endif } @@ -170,7 +175,7 @@ static int jtag_limit_queue_size(struct adiv5_dap *dap) } static struct dap_cmd *dap_cmd_new(struct adiv5_dap *dap, uint8_t instr, - uint8_t reg_addr, uint8_t rnw, + uint16_t reg_addr, uint8_t rnw, uint8_t *outvalue, uint8_t *invalue, uint32_t memaccess_tck) { @@ -268,17 +273,14 @@ static int adi_jtag_dp_scan_cmd(struct adiv5_dap *dap, struct dap_cmd *cmd, uint jtag_add_dr_scan(tap, 2, cmd->fields, TAP_IDLE); - /* Add specified number of tck clocks after starting memory bus - * access, giving the hardware time to complete the access. + /* Add specified number of tck clocks after starting AP register + * access or memory bus access, giving the hardware time to complete + * the access. * They provide more time for the (MEM) AP to complete the read ... - * See "Minimum Response Time" for JTAG-DP, in the ADIv5 spec. + * See "Minimum Response Time" for JTAG-DP, in the ADIv5/ADIv6 spec. */ - if (cmd->instr == JTAG_DP_APACC) { - if (((cmd->reg_addr == MEM_AP_REG_DRW) - || ((cmd->reg_addr & 0xF0) == MEM_AP_REG_BD0)) - && (cmd->memaccess_tck != 0)) - jtag_add_runtest(cmd->memaccess_tck, TAP_IDLE); - } + if (cmd->instr == JTAG_DP_APACC && cmd->memaccess_tck != 0) + jtag_add_runtest(cmd->memaccess_tck, TAP_IDLE); return ERROR_OK; } @@ -296,7 +298,7 @@ static int adi_jtag_dp_scan_cmd_sync(struct adiv5_dap *dap, struct dap_cmd *cmd, /** * Scan DPACC or APACC using target ordered uint8_t buffers. No endianness - * conversions are performed. See section 4.4.3 of the ADIv5 spec, which + * conversions are performed. See section 4.4.3 of the ADIv5/ADIv6 spec, which * discusses operations which access these registers. * * Note that only one scan is performed. If rnw is set, a separate scan @@ -315,7 +317,7 @@ static int adi_jtag_dp_scan_cmd_sync(struct adiv5_dap *dap, struct dap_cmd *cmd, */ static int adi_jtag_dp_scan(struct adiv5_dap *dap, - uint8_t instr, uint8_t reg_addr, uint8_t rnw, + uint8_t instr, uint16_t reg_addr, uint8_t rnw, uint8_t *outvalue, uint8_t *invalue, uint32_t memaccess_tck, uint8_t *ack) { @@ -342,13 +344,27 @@ static int adi_jtag_dp_scan(struct adiv5_dap *dap, * must be different). */ static int adi_jtag_dp_scan_u32(struct adiv5_dap *dap, - uint8_t instr, uint8_t reg_addr, uint8_t rnw, + uint8_t instr, uint16_t reg_addr, uint8_t rnw, uint32_t outvalue, uint32_t *invalue, uint32_t memaccess_tck, uint8_t *ack) { uint8_t out_value_buf[4]; int retval; - + uint64_t sel = (reg_addr >> 4) & 0xf; + + /* No need to change SELECT or RDBUFF as they are not banked */ + if (instr == JTAG_DP_DPACC && reg_addr != DP_SELECT && reg_addr != DP_RDBUFF && + sel != (dap->select & 0xf)) { + if (dap->select != DP_SELECT_INVALID) + sel |= dap->select & ~0xfull; + dap->select = sel; + LOG_DEBUG("DP BANKSEL: %x", (uint32_t)sel); + buf_set_u32(out_value_buf, 0, 32, (uint32_t)sel); + retval = adi_jtag_dp_scan(dap, JTAG_DP_DPACC, + DP_SELECT, DPAP_WRITE, out_value_buf, NULL, 0, NULL); + if (retval != ERROR_OK) + return retval; + } buf_set_u32(out_value_buf, 0, 32, outvalue); retval = adi_jtag_dp_scan(dap, instr, reg_addr, rnw, @@ -377,7 +393,7 @@ static int adi_jtag_finish_read(struct adiv5_dap *dap) } static int adi_jtag_scan_inout_check_u32(struct adiv5_dap *dap, - uint8_t instr, uint8_t reg_addr, uint8_t rnw, + uint8_t instr, uint16_t reg_addr, uint8_t rnw, uint32_t outvalue, uint32_t *invalue, uint32_t memaccess_tck) { int retval; @@ -416,14 +432,19 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) /* skip all completed transactions up to the first WAIT */ list_for_each_entry(el, &dap->cmd_journal, lh) { - if (el->ack == JTAG_ACK_OK_FAULT) { - log_dap_cmd("LOG", el); + /* + * JTAG_ACK_OK_FAULT (ADIv5) and JTAG_ACK_FAULT (ADIv6) are equal so + * the following statement is checking to see if an acknowledgment of + * OK or FAULT is generated for ADIv5 or ADIv6 + */ + if (el->ack == JTAG_ACK_OK_FAULT || (is_adiv6(dap) && el->ack == JTAG_ACK_OK)) { + log_dap_cmd(dap, "LOG", el); } else if (el->ack == JTAG_ACK_WAIT) { found_wait = 1; break; } else { LOG_ERROR("Invalid ACK (%1x) in DAP response", el->ack); - log_dap_cmd("ERR", el); + log_dap_cmd(dap, "ERR", el); retval = ERROR_JTAG_DEVICE_ERROR; goto done; } @@ -436,14 +457,15 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) if (found_wait && el != list_first_entry(&dap->cmd_journal, struct dap_cmd, lh)) { prev = list_entry(el->lh.prev, struct dap_cmd, lh); if (prev->rnw == DPAP_READ) { - log_dap_cmd("PND", prev); + log_dap_cmd(dap, "PND", prev); /* search for the next OK transaction, it contains * the result of the previous READ */ tmp = el; list_for_each_entry_from(tmp, &dap->cmd_journal, lh) { - if (tmp->ack == JTAG_ACK_OK_FAULT) { + /* The following check covers OK and FAULT ACKs for both ADIv5 and ADIv6 */ + if (tmp->ack == JTAG_ACK_OK_FAULT || (is_adiv6(dap) && tmp->ack == JTAG_ACK_OK)) { /* recover the read value */ - log_dap_cmd("FND", tmp); + log_dap_cmd(dap, "FND", tmp); if (el->invalue != el->invalue_buf) { uint32_t invalue = le_to_h_u32(tmp->invalue); memcpy(el->invalue, &invalue, sizeof(uint32_t)); @@ -454,7 +476,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) } if (prev) { - log_dap_cmd("LST", el); + log_dap_cmd(dap, "LST", el); /* * At this point we're sure that no previous @@ -476,8 +498,9 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) retval = adi_jtag_dp_scan_cmd_sync(dap, tmp, NULL); if (retval != ERROR_OK) break; - if (tmp->ack == JTAG_ACK_OK_FAULT) { - log_dap_cmd("FND", tmp); + /* The following check covers OK and FAULT ACKs for both ADIv5 and ADIv6 */ + if (tmp->ack == JTAG_ACK_OK_FAULT || (is_adiv6(dap) && tmp->ack == JTAG_ACK_OK)) { + log_dap_cmd(dap, "FND", tmp); if (el->invalue != el->invalue_buf) { uint32_t invalue = le_to_h_u32(tmp->invalue); memcpy(el->invalue, &invalue, sizeof(uint32_t)); @@ -486,7 +509,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) } if (tmp->ack != JTAG_ACK_WAIT) { LOG_ERROR("Invalid ACK (%1x) in DAP response", tmp->ack); - log_dap_cmd("ERR", tmp); + log_dap_cmd(dap, "ERR", tmp); retval = ERROR_JTAG_DEVICE_ERROR; break; } @@ -495,7 +518,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) if (retval == ERROR_OK) { /* timeout happened */ - if (tmp->ack != JTAG_ACK_OK_FAULT) { + if (tmp->ack == JTAG_ACK_WAIT) { LOG_ERROR("Timeout during WAIT recovery"); dap->select = DP_SELECT_INVALID; jtag_ap_q_abort(dap, NULL); @@ -523,7 +546,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) /* move all remaining transactions over to the replay list */ list_for_each_entry_safe_from(el, tmp, &dap->cmd_journal, lh) { - log_dap_cmd("REP", el); + log_dap_cmd(dap, "REP", el); list_move_tail(&el->lh, &replay_list); } @@ -560,8 +583,8 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) retval = adi_jtag_dp_scan_cmd_sync(dap, el, NULL); if (retval != ERROR_OK) break; - log_dap_cmd("REC", el); - if (el->ack == JTAG_ACK_OK_FAULT) { + log_dap_cmd(dap, "REC", el); + if (el->ack == JTAG_ACK_OK_FAULT || (is_adiv6(dap) && el->ack == JTAG_ACK_OK)) { if (el->invalue != el->invalue_buf) { uint32_t invalue = le_to_h_u32(el->invalue); memcpy(el->invalue, &invalue, sizeof(uint32_t)); @@ -570,7 +593,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) } if (el->ack != JTAG_ACK_WAIT) { LOG_ERROR("Invalid ACK (%1x) in DAP response", el->ack); - log_dap_cmd("ERR", el); + log_dap_cmd(dap, "ERR", el); retval = ERROR_JTAG_DEVICE_ERROR; break; } @@ -584,7 +607,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) } while (timeval_ms() - time_now < 1000); if (retval == ERROR_OK) { - if (el->ack != JTAG_ACK_OK_FAULT) { + if (el->ack == JTAG_ACK_WAIT) { LOG_ERROR("Timeout during WAIT recovery"); dap->select = DP_SELECT_INVALID; jtag_ap_q_abort(dap, NULL); @@ -640,10 +663,10 @@ static int jtagdp_transaction_endcheck(struct adiv5_dap *dap) if (ctrlstat & SSTICKYORUN) LOG_DEBUG("JTAG-DP STICKY OVERRUN"); - /* Clear Sticky Error Bits */ + /* Clear Sticky Error and Sticky Overrun Bits */ retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC, DP_CTRL_STAT, DPAP_WRITE, - dap->dp_ctrl_stat | SSTICKYERR, NULL, 0); + dap->dp_ctrl_stat | SSTICKYERR | SSTICKYORUN, NULL, 0); if (retval != ERROR_OK) goto done; @@ -722,15 +745,38 @@ static int jtag_dp_q_write(struct adiv5_dap *dap, unsigned reg, /** Select the AP register bank matching bits 7:4 of reg. */ static int jtag_ap_q_bankselect(struct adiv5_ap *ap, unsigned reg) { + int retval; struct adiv5_dap *dap = ap->dap; - uint32_t sel = ((uint32_t)ap->ap_num << 24) | (reg & 0x000000F0); + uint64_t sel; + + if (is_adiv6(dap)) { + sel = ap->ap_num | (reg & 0x00000FF0); + if (sel == (dap->select & ~0xfull)) + return ERROR_OK; + + if (dap->select != DP_SELECT_INVALID) + sel |= dap->select & 0xf; + dap->select = sel; + LOG_DEBUG("AP BANKSEL: %" PRIx64, sel); + + retval = jtag_dp_q_write(dap, DP_SELECT, (uint32_t)sel); + if (retval != ERROR_OK) + return retval; + + if (dap->asize > 32) + return jtag_dp_q_write(dap, DP_SELECT1, (uint32_t)(sel >> 32)); + return ERROR_OK; + } + + /* ADIv5 */ + sel = (ap->ap_num << 24) | (reg & 0x000000F0); if (sel == dap->select) return ERROR_OK; dap->select = sel; - return jtag_dp_q_write(dap, DP_SELECT, sel); + return jtag_dp_q_write(dap, DP_SELECT, (uint32_t)sel); } static int jtag_ap_q_read(struct adiv5_ap *ap, unsigned reg, diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index 6835042..979c643 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * * Copyright (C) 2010 by David Brownell - * - * 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, see <http://www.gnu.org/licenses/>. ***************************************************************************/ /** @@ -29,6 +18,7 @@ * for details, see "ARM IHI 0031A" * ARM Debug Interface v5 Architecture Specification * especially section 5.3 for SWD protocol + * and "ARM IHI 0074C" ARM Debug Interface Architecture Specification ADIv6.0 * * On many chips (most current Cortex-M3 parts) SWD is a run-time alternative * to JTAG. Boards may support one or both. There are also SWD-only chips, @@ -112,20 +102,20 @@ static inline int check_sync(struct adiv5_dap *dap) /** Select the DP register bank matching bits 7:4 of reg. */ static int swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned int reg) { - /* Only register address 4 is banked. */ - if ((reg & 0xf) != 4) + /* Only register address 0 and 4 are banked. */ + if ((reg & 0xf) > 4) return ERROR_OK; - uint32_t select_dp_bank = (reg & 0x000000F0) >> 4; - uint32_t sel = select_dp_bank - | (dap->select & (DP_SELECT_APSEL | DP_SELECT_APBANK)); + uint64_t sel = (reg & 0x000000F0) >> 4; + if (dap->select != DP_SELECT_INVALID) + sel |= dap->select & ~0xfULL; if (sel == dap->select) return ERROR_OK; dap->select = sel; - int retval = swd_queue_dp_write_inner(dap, DP_SELECT, sel); + int retval = swd_queue_dp_write_inner(dap, DP_SELECT, (uint32_t)sel); if (retval != ERROR_OK) dap->select = DP_SELECT_INVALID; @@ -326,6 +316,21 @@ static int swd_connect_single(struct adiv5_dap *dap) dap->do_reconnect = false; dap_invalidate_cache(dap); + /* The sequences to enter in SWD (JTAG_TO_SWD and DORMANT_TO_SWD) end + * with a SWD line reset sequence (50 clk with SWDIO high). + * From ARM IHI 0074C ADIv6.0, chapter B4.3.3 "Connection and line reset + * sequence": + * - line reset sets DP_SELECT_DPBANK to zero; + * - read of DP_DPIDR takes the connection out of reset; + * - write of DP_TARGETSEL keeps the connection in reset; + * - other accesses return protocol error (SWDIO not driven by target). + * + * Read DP_DPIDR to get out of reset. Initialize dap->select to zero to + * skip the write to DP_SELECT, avoiding the protocol error. Set again + * dap->select to DP_SELECT_INVALID because the rest of the register is + * unknown after line reset. + */ + dap->select = 0; retval = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr); if (retval == ERROR_OK) { retval = swd_run_inner(dap); @@ -337,6 +342,7 @@ static int swd_connect_single(struct adiv5_dap *dap) dap->switch_through_dormant = !dap->switch_through_dormant; } while (timeval_ms() < timeout); + dap->select = DP_SELECT_INVALID; if (retval != ERROR_OK) { LOG_ERROR("Error connecting DP: cannot read IDR"); @@ -473,17 +479,42 @@ static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg, /** Select the AP register bank matching bits 7:4 of reg. */ static int swd_queue_ap_bankselect(struct adiv5_ap *ap, unsigned reg) { + int retval; struct adiv5_dap *dap = ap->dap; - uint32_t sel = ((uint32_t)ap->ap_num << 24) - | (reg & 0x000000F0) - | (dap->select & DP_SELECT_DPBANK); + uint64_t sel; + + if (is_adiv6(dap)) { + sel = ap->ap_num | (reg & 0x00000FF0); + if (sel == (dap->select & ~0xfULL)) + return ERROR_OK; + + if (dap->select != DP_SELECT_INVALID) + sel |= dap->select & 0xf; + dap->select = sel; + LOG_DEBUG("AP BANKSEL: %" PRIx64, sel); + + retval = swd_queue_dp_write(dap, DP_SELECT, (uint32_t)sel); + + if (retval == ERROR_OK && dap->asize > 32) + retval = swd_queue_dp_write(dap, DP_SELECT1, (uint32_t)(sel >> 32)); + + if (retval != ERROR_OK) + dap->select = DP_SELECT_INVALID; + + return retval; + } + + /* ADIv5 */ + sel = (ap->ap_num << 24) | (reg & 0x000000F0); + if (dap->select != DP_SELECT_INVALID) + sel |= dap->select & DP_SELECT_DPBANK; if (sel == dap->select) return ERROR_OK; dap->select = sel; - int retval = swd_queue_dp_write_inner(dap, DP_SELECT, sel); + retval = swd_queue_dp_write_inner(dap, DP_SELECT, sel); if (retval != ERROR_OK) dap->select = DP_SELECT_INVALID; diff --git a/src/target/algorithm.c b/src/target/algorithm.c index 9fc9386..64abffc 100644 --- a/src/target/algorithm.c +++ b/src/target/algorithm.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/algorithm.h b/src/target/algorithm.h index 0fc49d0..25f1a66 100644 --- a/src/target/algorithm.h +++ b/src/target/algorithm.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ALGORITHM_H diff --git a/src/target/arc.c b/src/target/arc.c index 471f16a..9ae3ae6 100644 --- a/src/target/arc.c +++ b/src/target/arc.c @@ -1,11 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013-2015,2019-2020 Synopsys, Inc. * * Frank Dols <frank.dols@synopsys.com> * * Mischa Jonker <mischa.jonker@synopsys.com> * * Anton Kolesov <anton.kolesov@synopsys.com> * * Evgeniy Didin <didin@synopsys.com> * - * * - * SPDX-License-Identifier: GPL-2.0-or-later * ***************************************************************************/ @@ -93,7 +93,7 @@ struct reg *arc_reg_get_by_name(struct reg_cache *first, * * @param target Target for which to reset caches states. */ -int arc_reset_caches_states(struct target *target) +static int arc_reset_caches_states(struct target *target) { struct arc_common *arc = target_to_arc(target); @@ -283,7 +283,7 @@ static int arc_set_register(struct reg *reg, uint8_t *buf) return ERROR_OK; } -const struct reg_arch_type arc_reg_type = { +static const struct reg_arch_type arc_reg_type = { .get = arc_get_register, .set = arc_set_register, }; @@ -1401,7 +1401,7 @@ static int arc_target_create(struct target *target, Jim_Interp *interp) * little endian, so different type of conversion should be done. * Middle endian: instruction "aabbccdd", stored as "bbaaddcc" */ -int arc_write_instruction_u32(struct target *target, uint32_t address, +static int arc_write_instruction_u32(struct target *target, uint32_t address, uint32_t instr) { uint8_t value_buf[4]; @@ -1428,7 +1428,7 @@ int arc_write_instruction_u32(struct target *target, uint32_t address, * case of little endian ARC instructions are in middle endian format, so * different type of conversion should be done. */ -int arc_read_instruction_u32(struct target *target, uint32_t address, +static int arc_read_instruction_u32(struct target *target, uint32_t address, uint32_t *value) { uint8_t value_buf[4]; @@ -1694,7 +1694,7 @@ static int arc_remove_breakpoint(struct target *target, return ERROR_OK; } -void arc_reset_actionpoints(struct target *target) +static void arc_reset_actionpoints(struct target *target) { struct arc_common *arc = target_to_arc(target); struct arc_actionpoint *ap_list = arc->actionpoints_list; @@ -1965,7 +1965,7 @@ static int arc_hit_watchpoint(struct target *target, struct watchpoint **hit_wat /* Helper function which switches core to single_step mode by * doing aux r/w operations. */ -int arc_config_step(struct target *target, int enable_step) +static int arc_config_step(struct target *target, int enable_step) { uint32_t value; @@ -2001,7 +2001,7 @@ int arc_config_step(struct target *target, int enable_step) return ERROR_OK; } -int arc_step(struct target *target, int current, target_addr_t address, +static int arc_step(struct target *target, int current, target_addr_t address, int handle_breakpoints) { /* get pointers to arch-specific information */ @@ -2165,7 +2165,7 @@ int arc_cache_invalidate(struct target *target) * values directly from memory, bypassing cache, so if there are unflushed * lines debugger will read invalid values, which will cause a lot of troubles. * */ -int arc_dcache_flush(struct target *target) +static int arc_dcache_flush(struct target *target) { uint32_t value, dc_ctrl_value; bool has_to_set_dc_ctrl_im; diff --git a/src/target/arc.h b/src/target/arc.h index f0351bd..bb70a59 100644 --- a/src/target/arc.h +++ b/src/target/arc.h @@ -1,11 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013-2015,2019-2020 Synopsys, Inc. * * Frank Dols <frank.dols@synopsys.com> * * Mischa Jonker <mischa.jonker@synopsys.com> * * Anton Kolesov <anton.kolesov@synopsys.com> * * Evgeniy Didin <didin@synopsys.com> * - * * - * SPDX-License-Identifier: GPL-2.0-or-later * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARC_H @@ -27,7 +27,7 @@ #include "arc_cmd.h" #include "arc_mem.h" -#define ARC_COMMON_MAGIC 0xB32EB324 /* just a unique number */ +#define ARC_COMMON_MAGIC 0xB32EB324U /* just a unique number */ #define AUX_DEBUG_REG 0x5 #define AUX_PC_REG 0x6 @@ -183,7 +183,7 @@ struct arc_actionpoint { }; struct arc_common { - uint32_t common_magic; + unsigned int common_magic; struct arc_jtag jtag_info; diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c index 26c67c6..7a80046 100644 --- a/src/target/arc_cmd.c +++ b/src/target/arc_cmd.c @@ -1,11 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013-2015,2019-2020 Synopsys, Inc. * * Frank Dols <frank.dols@synopsys.com> * * Mischa Jonker <mischa.jonker@synopsys.com> * * Anton Kolesov <anton.kolesov@synopsys.com> * * Evgeniy Didin <didin@synopsys.com> * - * * - * SPDX-License-Identifier: GPL-2.0-or-later * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -975,7 +975,7 @@ static int jim_handle_actionpoints_num(Jim_Interp *interp, int argc, /* ----- Exported target commands ------------------------------------------ */ -const struct command_registration arc_l2_cache_group_handlers[] = { +static const struct command_registration arc_l2_cache_group_handlers[] = { { .name = "auto", .handler = arc_l2_cache_disable_auto_cmd, @@ -986,7 +986,7 @@ const struct command_registration arc_l2_cache_group_handlers[] = { COMMAND_REGISTRATION_DONE }; -const struct command_registration arc_cache_group_handlers[] = { +static const struct command_registration arc_cache_group_handlers[] = { { .name = "auto", .handler = arc_l1_cache_disable_auto_cmd, diff --git a/src/target/arc_cmd.h b/src/target/arc_cmd.h index b2264eb..f728bd5 100644 --- a/src/target/arc_cmd.h +++ b/src/target/arc_cmd.h @@ -1,11 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. * * Frank Dols <frank.dols@synopsys.com> * * Mischa Jonker <mischa.jonker@synopsys.com> * * Anton Kolesov <anton.kolesov@synopsys.com> * * Evgeniy Didin <didin@synopsys.com> * - * * - * SPDX-License-Identifier: GPL-2.0-or-later * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARC_CMD_H diff --git a/src/target/arc_jtag.c b/src/target/arc_jtag.c index ca1a096..ddb4f62 100644 --- a/src/target/arc_jtag.c +++ b/src/target/arc_jtag.c @@ -1,11 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. * * Frank Dols <frank.dols@synopsys.com> * * Mischa Jonker <mischa.jonker@synopsys.com> * * Anton Kolesov <anton.kolesov@synopsys.com> * * Evgeniy Didin <didin@synopsys.com> * - * * - * SPDX-License-Identifier: GPL-2.0-or-later * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arc_jtag.h b/src/target/arc_jtag.h index 99795f5..c2dc7b7 100644 --- a/src/target/arc_jtag.h +++ b/src/target/arc_jtag.h @@ -1,11 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. * * Frank Dols <frank.dols@synopsys.com> * * Mischa Jonker <mischa.jonker@synopsys.com> * * Anton Kolesov <anton.kolesov@synopsys.com> * * Evgeniy Didin <didin@synopsys.com> * - * * - * SPDX-License-Identifier: GPL-2.0-or-later * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARC_JTAG_H diff --git a/src/target/arc_mem.c b/src/target/arc_mem.c index 81d1ab2..c4814d2 100644 --- a/src/target/arc_mem.c +++ b/src/target/arc_mem.c @@ -1,11 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. * * Frank Dols <frank.dols@synopsys.com> * * Mischa Jonker <mischa.jonker@synopsys.com> * * Anton Kolesov <anton.kolesov@synopsys.com> * * Evgeniy Didin <didin@synopsys.com> * - * * - * SPDX-License-Identifier: GPL-2.0-or-later * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arc_mem.h b/src/target/arc_mem.h index 06e1c88..861823d 100644 --- a/src/target/arc_mem.h +++ b/src/target/arc_mem.h @@ -1,10 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. * * Frank Dols <frank.dols@synopsys.com> * * Anton Kolesov <anton.kolesov@synopsys.com> * * Evgeniy Didin <didin@synopsys.com> * - * * - * SPDX-License-Identifier: GPL-2.0-or-later * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARC_MEM_H diff --git a/src/target/arm.h b/src/target/arm.h index 1732789..de46ffb 100644 --- a/src/target/arm.h +++ b/src/target/arm.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * Copyright (C) 2005 by Dominic Rath * Dominic.Rath@gmx.de @@ -10,19 +12,6 @@ * * Copyright (C) 2018 by Liviu Ionescu * <ilg@livius.net> - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifndef OPENOCD_TARGET_ARM_H @@ -166,7 +155,7 @@ enum arm_vfp_version { ARM_VFP_V3, }; -#define ARM_COMMON_MAGIC 0x0A450A45 +#define ARM_COMMON_MAGIC 0x0A450A45U /** * Represents a generic ARM core, with standard application registers. @@ -176,7 +165,8 @@ enum arm_vfp_version { * registers as traditional ARM cores, and only support Thumb2 instructions. */ struct arm { - int common_magic; + unsigned int common_magic; + struct reg_cache *core_cache; /** Handle to the PC; valid in all core modes. */ @@ -263,7 +253,7 @@ static inline bool is_arm(struct arm *arm) } struct arm_algorithm { - int common_magic; + unsigned int common_magic; enum arm_mode core_mode; enum arm_state core_state; @@ -283,6 +273,7 @@ void arm_free_reg_cache(struct arm *arm); struct reg_cache *armv8_build_reg_cache(struct target *target); extern const struct command_registration arm_command_handlers[]; +extern const struct command_registration arm_all_profiles_command_handlers[]; int arm_arch_state(struct target *target); const char *arm_get_gdb_arch(struct target *target); @@ -319,7 +310,4 @@ void arm_set_cpsr(struct arm *arm, uint32_t cpsr); struct reg *arm_reg_current(struct arm *arm, unsigned regnum); struct reg *armv8_reg_current(struct arm *arm, unsigned regnum); -extern struct reg arm_gdb_dummy_fp_reg; -extern struct reg arm_gdb_dummy_fps_reg; - #endif /* OPENOCD_TARGET_ARM_H */ diff --git a/src/target/arm11.c b/src/target/arm11.c index e3b0975..e48bcf3 100644 --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2008 digenius technology GmbH. * * Michael Bruck * @@ -7,19 +9,6 @@ * Copyright (C) 2008 Georg Acher <acher@in.tum.de> * * * * Copyright (C) 2009 David Brownell * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arm11.h b/src/target/arm11.h index 77cc223..1f56f7b 100644 --- a/src/target/arm11.h +++ b/src/target/arm11.h @@ -1,21 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2008 digenius technology GmbH. * * Michael Bruck * * * * Copyright (C) 2008 Georg Acher <acher@in.tum.de> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM11_H diff --git a/src/target/arm11_dbgtap.c b/src/target/arm11_dbgtap.c index fc35414..b670bd7 100644 --- a/src/target/arm11_dbgtap.c +++ b/src/target/arm11_dbgtap.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2008 digenius technology GmbH. * * Michael Bruck * * * * Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arm11_dbgtap.h b/src/target/arm11_dbgtap.h index c6b20a8..eeb174a 100644 --- a/src/target/arm11_dbgtap.h +++ b/src/target/arm11_dbgtap.h @@ -1,21 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2008 digenius technology GmbH. * * Michael Bruck * * * * Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM11_DBGTAP_H diff --git a/src/target/arm720t.c b/src/target/arm720t.c index db75011..c330dff 100644 --- a/src/target/arm720t.c +++ b/src/target/arm720t.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2009 by Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arm720t.h b/src/target/arm720t.h index 31dad9c..65bd78f 100644 --- a/src/target/arm720t.h +++ b/src/target/arm720t.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM720T_H @@ -22,11 +11,12 @@ #include "arm7tdmi.h" #include "armv4_5_mmu.h" -#define ARM720T_COMMON_MAGIC 0xa720a720 +#define ARM720T_COMMON_MAGIC 0xa720a720U struct arm720t_common { + unsigned int common_magic; + struct arm7_9_common arm7_9_common; - uint32_t common_magic; struct armv4_5_mmu_common armv4_5_mmu; uint32_t cp15_control_reg; uint32_t fsr_reg; diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index da047c3..8f87d9c 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -12,19 +14,6 @@ * hontor@126.com * * * * Copyright (C) 2009 by David Brownell * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h index 4961212..92d0fd5 100644 --- a/src/target/arm7_9_common.h +++ b/src/target/arm7_9_common.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -10,19 +12,6 @@ * * * Copyright (C) 2008 by Hongtao Zheng * * hontor@126.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM7_9_COMMON_H @@ -31,14 +20,15 @@ #include "arm.h" #include "arm_jtag.h" -#define ARM7_9_COMMON_MAGIC 0x0a790a79 /**< */ +#define ARM7_9_COMMON_MAGIC 0x0a790a79U /**< */ /** * Structure for items that are common between both ARM7 and ARM9 targets. */ struct arm7_9_common { + unsigned int common_magic; + struct arm arm; - uint32_t common_magic; struct arm_jtag jtag_info; /**< JTAG information for target */ struct reg_cache *eice_cache; /**< Embedded ICE register cache */ diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c index b034839..393d3b4 100644 --- a/src/target/arm7tdmi.c +++ b/src/target/arm7tdmi.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arm7tdmi.h b/src/target/arm7tdmi.h index 3cc3d4a..369a514 100644 --- a/src/target/arm7tdmi.h +++ b/src/target/arm7tdmi.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM7TDMI_H diff --git a/src/target/arm920t.c b/src/target/arm920t.c index a6d626e..f4c3f42 100644 --- a/src/target/arm920t.c +++ b/src/target/arm920t.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arm920t.h b/src/target/arm920t.h index 2e3b08c..eba768f 100644 --- a/src/target/arm920t.h +++ b/src/target/arm920t.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM920T_H @@ -22,11 +11,12 @@ #include "arm9tdmi.h" #include "armv4_5_mmu.h" -#define ARM920T_COMMON_MAGIC 0xa920a920 +#define ARM920T_COMMON_MAGIC 0xa920a920U struct arm920t_common { + unsigned int common_magic; + struct arm7_9_common arm7_9_common; - uint32_t common_magic; struct armv4_5_mmu_common armv4_5_mmu; uint32_t cp15_control_reg; uint32_t d_fsr; diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c index ea0927b..807d211 100644 --- a/src/target/arm926ejs.c +++ b/src/target/arm926ejs.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008,2009 by Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arm926ejs.h b/src/target/arm926ejs.h index 0cd523a..479128e 100644 --- a/src/target/arm926ejs.h +++ b/src/target/arm926ejs.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM926EJS_H @@ -22,11 +11,12 @@ #include "arm9tdmi.h" #include "armv4_5_mmu.h" -#define ARM926EJS_COMMON_MAGIC 0xa926a926 +#define ARM926EJS_COMMON_MAGIC 0xa926a926U struct arm926ejs_common { + unsigned int common_magic; + struct arm7_9_common arm7_9_common; - uint32_t common_magic; struct armv4_5_mmu_common armv4_5_mmu; int (*read_cp15)(struct target *target, uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint32_t *value); diff --git a/src/target/arm946e.c b/src/target/arm946e.c index 036e8ba..06dab4e 100644 --- a/src/target/arm946e.c +++ b/src/target/arm946e.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2010 by Drasko DRASKOVIC * * drasko.draskovic@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -55,7 +44,7 @@ static int arm946e_post_debug_entry(struct target *target); static void arm946e_pre_restore_context(struct target *target); static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *value); -int arm946e_init_arch_info(struct target *target, +static int arm946e_init_arch_info(struct target *target, struct arm946e_common *arm946e, struct jtag_tap *tap) { @@ -184,7 +173,7 @@ static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *valu return ERROR_OK; } -int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value) +static int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value) { int retval = ERROR_OK; struct arm7_9_common *arm7_9 = target_to_arm7_9(target); @@ -731,7 +720,7 @@ static const struct command_registration arm946e_exec_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -const struct command_registration arm946e_command_handlers[] = { +static const struct command_registration arm946e_command_handlers[] = { { .chain = arm9tdmi_command_handlers, }, diff --git a/src/target/arm946e.h b/src/target/arm946e.h index ee1ef32..0196c2b 100644 --- a/src/target/arm946e.h +++ b/src/target/arm946e.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2010 by Drasko DRASKOVIC * * drasko.draskovic@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM946E_H @@ -27,11 +16,12 @@ #include "arm9tdmi.h" -#define ARM946E_COMMON_MAGIC 0x20f920f9 +#define ARM946E_COMMON_MAGIC 0x20f920f9U struct arm946e_common { + unsigned int common_magic; + struct arm7_9_common arm7_9_common; - int common_magic; uint32_t cp15_control_reg; uint32_t cp15_cache_info; }; @@ -42,10 +32,4 @@ static inline struct arm946e_common *target_to_arm946(struct target *target) arm7_9_common.arm); } -int arm946e_init_arch_info(struct target *target, - struct arm946e_common *arm946e, struct jtag_tap *tap); -int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value); - -extern const struct command_registration arm946e_command_handlers[]; - #endif /* OPENOCD_TARGET_ARM946E_H */ diff --git a/src/target/arm966e.c b/src/target/arm966e.c index b6d3e50..3e60172 100644 --- a/src/target/arm966e.c +++ b/src/target/arm966e.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arm966e.h b/src/target/arm966e.h index aa2e9bb..be2b339 100644 --- a/src/target/arm966e.h +++ b/src/target/arm966e.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM966E_H @@ -24,11 +13,12 @@ #include "arm9tdmi.h" -#define ARM966E_COMMON_MAGIC 0x20f920f9 +#define ARM966E_COMMON_MAGIC 0x20f920f9U struct arm966e_common { + unsigned int common_magic; + struct arm7_9_common arm7_9_common; - int common_magic; uint32_t cp15_control_reg; }; diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c index 2a32f11..805330f 100644 --- a/src/target/arm9tdmi.c +++ b/src/target/arm9tdmi.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Hongtao Zheng * * hontor@126.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arm9tdmi.h b/src/target/arm9tdmi.h index 56946f7..d2a2784 100644 --- a/src/target/arm9tdmi.h +++ b/src/target/arm9tdmi.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM9TDMI_H diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 4d5f02b..c446428 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Magnus Lundin * * lundin@mlu.mine.nu * @@ -14,19 +16,6 @@ * andreas.fritiofson@gmail.com * * * * Copyright (C) 2019-2021, Ampere Computing LLC * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /** @@ -107,7 +96,7 @@ static int mem_ap_setup_csw(struct adiv5_ap *ap, uint32_t csw) if (csw != ap->csw_value) { /* LOG_DEBUG("DAP: Set CSW %x",csw); */ - int retval = dap_queue_ap_write(ap, MEM_AP_REG_CSW, csw); + int retval = dap_queue_ap_write(ap, MEM_AP_REG_CSW(ap->dap), csw); if (retval != ERROR_OK) { ap->csw_value = 0; return retval; @@ -121,11 +110,11 @@ static int mem_ap_setup_tar(struct adiv5_ap *ap, target_addr_t tar) { if (!ap->tar_valid || tar != ap->tar_value) { /* LOG_DEBUG("DAP: Set TAR %x",tar); */ - int retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR, (uint32_t)(tar & 0xffffffffUL)); + int retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR(ap->dap), (uint32_t)(tar & 0xffffffffUL)); if (retval == ERROR_OK && is_64bit_ap(ap)) { /* See if bits 63:32 of tar is different from last setting */ if ((ap->tar_value >> 32) != (tar >> 32)) - retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR64, (uint32_t)(tar >> 32)); + retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR64(ap->dap), (uint32_t)(tar >> 32)); } if (retval != ERROR_OK) { ap->tar_valid = false; @@ -142,9 +131,9 @@ static int mem_ap_read_tar(struct adiv5_ap *ap, target_addr_t *tar) uint32_t lower; uint32_t upper = 0; - int retval = dap_queue_ap_read(ap, MEM_AP_REG_TAR, &lower); + int retval = dap_queue_ap_read(ap, MEM_AP_REG_TAR(ap->dap), &lower); if (retval == ERROR_OK && is_64bit_ap(ap)) - retval = dap_queue_ap_read(ap, MEM_AP_REG_TAR64, &upper); + retval = dap_queue_ap_read(ap, MEM_AP_REG_TAR64(ap->dap), &upper); if (retval != ERROR_OK) { ap->tar_valid = false; @@ -252,7 +241,7 @@ int mem_ap_read_u32(struct adiv5_ap *ap, target_addr_t address, if (retval != ERROR_OK) return retval; - return dap_queue_ap_read(ap, MEM_AP_REG_BD0 | (address & 0xC), value); + return dap_queue_ap_read(ap, MEM_AP_REG_BD0(ap->dap) | (address & 0xC), value); } /** @@ -304,7 +293,7 @@ int mem_ap_write_u32(struct adiv5_ap *ap, target_addr_t address, if (retval != ERROR_OK) return retval; - return dap_queue_ap_write(ap, MEM_AP_REG_BD0 | (address & 0xC), + return dap_queue_ap_write(ap, MEM_AP_REG_BD0(ap->dap) | (address & 0xC), value); } @@ -420,6 +409,26 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz outvalue |= (uint32_t)*buffer++ << 8 * (0 ^ (drw_byte_idx & 3) ^ addr_xor); break; } + } else if (dap->nu_npcx_quirks) { + switch (this_size) { + case 4: + outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3); + outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3); + outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3); + outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3); + break; + case 2: + outvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3); + outvalue |= (uint32_t)*(buffer+1) << 8 * (drw_byte_idx++ & 3); + outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3); + outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3); + break; + case 1: + outvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3); + outvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3); + outvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3); + outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3); + } } else { switch (this_size) { case 4: @@ -436,7 +445,7 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz nbytes -= this_size; - retval = dap_queue_ap_write(ap, MEM_AP_REG_DRW, outvalue); + retval = dap_queue_ap_write(ap, MEM_AP_REG_DRW(dap), outvalue); if (retval != ERROR_OK) break; @@ -533,7 +542,7 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint if (retval != ERROR_OK) break; - retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW, read_ptr++); + retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW(dap), read_ptr++); if (retval != ERROR_OK) break; @@ -780,7 +789,7 @@ int mem_ap_init(struct adiv5_ap *ap) /* Set ap->cfg_reg before calling mem_ap_setup_transfer(). */ /* mem_ap_setup_transfer() needs to know if the MEM_AP supports LPAE. */ - retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG, &cfg); + retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG(dap), &cfg); if (retval != ERROR_OK) return retval; @@ -795,7 +804,7 @@ int mem_ap_init(struct adiv5_ap *ap) if (retval != ERROR_OK) return retval; - retval = dap_queue_ap_read(ap, MEM_AP_REG_CSW, &csw); + retval = dap_queue_ap_read(ap, MEM_AP_REG_CSW(dap), &csw); if (retval != ERROR_OK) return retval; @@ -928,7 +937,9 @@ static const struct { }; #define DEVARCH_ID_MASK (ARM_CS_C9_DEVARCH_ARCHITECT_MASK | ARM_CS_C9_DEVARCH_ARCHID_MASK) +#define DEVARCH_MEM_AP ARCH_ID(ARM_ID, 0x0A17) #define DEVARCH_ROM_C_0X9 ARCH_ID(ARM_ID, 0x0AF7) +#define DEVARCH_UNKNOWN_V2 ARCH_ID(ARM_ID, 0x0A47) static const char *class0x9_devarch_description(uint32_t devarch) { @@ -966,22 +977,57 @@ static const char *ap_type_to_description(enum ap_type type) return "Unknown"; } +bool is_ap_num_valid(struct adiv5_dap *dap, uint64_t ap_num) +{ + if (!dap) + return false; + + /* no autodetection, by now, so uninitialized is equivalent to ADIv5 for + * backward compatibility */ + if (!is_adiv6(dap)) { + if (ap_num > DP_APSEL_MAX) + return false; + return true; + } + + if (is_adiv6(dap)) { + if (ap_num & 0x0fffULL) + return false; + if (dap->asize != 0) + if (ap_num & ((~0ULL) << dap->asize)) + return false; + return true; + } + + return false; +} + /* * This function checks the ID for each access port to find the requested Access Port type + * It also calls dap_get_ap() to increment the AP refcount */ -int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out) +int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out) { - int ap_num; + if (is_adiv6(dap)) { + /* TODO: scan the ROM table and detect the AP available */ + LOG_DEBUG("On ADIv6 we cannot scan all the possible AP"); + return ERROR_FAIL; + } /* Maximum AP number is 255 since the SELECT register is 8 bits */ - for (ap_num = 0; ap_num <= DP_APSEL_MAX; ap_num++) { + for (unsigned int ap_num = 0; ap_num <= DP_APSEL_MAX; ap_num++) { + struct adiv5_ap *ap = dap_get_ap(dap, ap_num); + if (!ap) + continue; /* read the IDR register of the Access Port */ uint32_t id_val = 0; - int retval = dap_queue_ap_read(dap_ap(dap, ap_num), AP_REG_IDR, &id_val); - if (retval != ERROR_OK) + int retval = dap_queue_ap_read(ap, AP_REG_IDR(dap), &id_val); + if (retval != ERROR_OK) { + dap_put_ap(ap); return retval; + } retval = dap_run(dap); @@ -993,15 +1039,96 @@ int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_a ap_type_to_description(type_to_find), ap_num, id_val); - *ap_out = &dap->ap[ap_num]; + *ap_out = ap; return ERROR_OK; } + dap_put_ap(ap); } LOG_DEBUG("No %s found", ap_type_to_description(type_to_find)); return ERROR_FAIL; } +static inline bool is_ap_in_use(struct adiv5_ap *ap) +{ + return ap->refcount > 0 || ap->config_ap_never_release; +} + +static struct adiv5_ap *_dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num) +{ + if (!is_ap_num_valid(dap, ap_num)) { + LOG_ERROR("Invalid AP#0x%" PRIx64, ap_num); + return NULL; + } + if (is_adiv6(dap)) { + for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) { + struct adiv5_ap *ap = &dap->ap[i]; + if (is_ap_in_use(ap) && ap->ap_num == ap_num) { + ++ap->refcount; + return ap; + } + } + for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) { + struct adiv5_ap *ap = &dap->ap[i]; + if (!is_ap_in_use(ap)) { + ap->ap_num = ap_num; + ++ap->refcount; + return ap; + } + } + LOG_ERROR("No more AP available!"); + return NULL; + } + + /* ADIv5 */ + struct adiv5_ap *ap = &dap->ap[ap_num]; + ap->ap_num = ap_num; + ++ap->refcount; + return ap; +} + +/* Return AP with specified ap_num. Increment AP refcount */ +struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num) +{ + struct adiv5_ap *ap = _dap_get_ap(dap, ap_num); + if (ap) + LOG_DEBUG("refcount AP#0x%" PRIx64 " get %u", ap_num, ap->refcount); + return ap; +} + +/* Return AP with specified ap_num. Increment AP refcount and keep it non-zero */ +struct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, uint64_t ap_num) +{ + struct adiv5_ap *ap = _dap_get_ap(dap, ap_num); + if (ap) { + ap->config_ap_never_release = true; + LOG_DEBUG("refcount AP#0x%" PRIx64 " get_config %u", ap_num, ap->refcount); + } + return ap; +} + +/* Decrement AP refcount and release the AP when refcount reaches zero */ +int dap_put_ap(struct adiv5_ap *ap) +{ + if (ap->refcount == 0) { + LOG_ERROR("BUG: refcount AP#0x%" PRIx64 " put underflow", ap->ap_num); + return ERROR_FAIL; + } + + --ap->refcount; + + LOG_DEBUG("refcount AP#0x%" PRIx64 " put %u", ap->ap_num, ap->refcount); + if (!is_ap_in_use(ap)) { + /* defaults from dap_instance_init() */ + ap->ap_num = DP_APSEL_INVALID; + ap->memaccess_tck = 255; + ap->tar_autoincr_block = (1 << 10); + ap->csw_default = CSW_AHB_DEFAULT; + ap->cfg_reg = MEM_AP_REG_CFG_INVALID; + } + return ERROR_OK; +} + static int dap_get_debugbase(struct adiv5_ap *ap, target_addr_t *dbgbase, uint32_t *apid) { @@ -1010,19 +1137,19 @@ static int dap_get_debugbase(struct adiv5_ap *ap, uint32_t baseptr_upper, baseptr_lower; if (ap->cfg_reg == MEM_AP_REG_CFG_INVALID) { - retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG, &ap->cfg_reg); + retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG(dap), &ap->cfg_reg); if (retval != ERROR_OK) return retval; } - retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, &baseptr_lower); + retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE(dap), &baseptr_lower); if (retval != ERROR_OK) return retval; - retval = dap_queue_ap_read(ap, AP_REG_IDR, apid); + retval = dap_queue_ap_read(ap, AP_REG_IDR(dap), apid); if (retval != ERROR_OK) return retval; /* MEM_AP_REG_BASE64 is defined as 'RES0'; can be read and then ignored on 32 bits AP */ if (ap->cfg_reg == MEM_AP_REG_CFG_INVALID || is_64bit_ap(ap)) { - retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64, &baseptr_upper); + retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64(dap), &baseptr_upper); if (retval != ERROR_OK) return retval; } @@ -1038,6 +1165,43 @@ static int dap_get_debugbase(struct adiv5_ap *ap, return ERROR_OK; } +int adiv6_dap_read_baseptr(struct command_invocation *cmd, struct adiv5_dap *dap, uint64_t *baseptr) +{ + uint32_t baseptr_lower, baseptr_upper = 0; + int retval; + + if (dap->asize > 32) { + retval = dap_queue_dp_read(dap, DP_BASEPTR1, &baseptr_upper); + if (retval != ERROR_OK) + return retval; + } + + retval = dap_dp_read_atomic(dap, DP_BASEPTR0, &baseptr_lower); + if (retval != ERROR_OK) + return retval; + + if ((baseptr_lower & DP_BASEPTR0_VALID) != DP_BASEPTR0_VALID) { + command_print(cmd, "System root table not present"); + return ERROR_FAIL; + } + + baseptr_lower &= ~0x0fff; + *baseptr = (((uint64_t)baseptr_upper) << 32) | baseptr_lower; + + return ERROR_OK; +} + +/** + * Method to access the CoreSight component. + * On ADIv5, CoreSight components are on the bus behind a MEM-AP. + * On ADIv6, CoreSight components can either be on the bus behind a MEM-AP + * or directly in the AP. + */ +enum coresight_access_mode { + CS_ACCESS_AP, + CS_ACCESS_MEM_AP, +}; + /** Holds registers and coordinates of a CoreSight component */ struct cs_component_vals { struct adiv5_ap *ap; @@ -1047,19 +1211,43 @@ struct cs_component_vals { uint32_t devarch; uint32_t devid; uint32_t devtype_memtype; + enum coresight_access_mode mode; }; /** + * Helper to read CoreSight component's registers, either on the bus + * behind a MEM-AP or directly in the AP. + * + * @param mode Method to access the component (AP or MEM-AP). + * @param ap Pointer to AP containing the component. + * @param component_base On MEM-AP access method, base address of the component. + * @param reg Offset of the component's register to read. + * @param value Pointer to the store the read value. + * + * @return ERROR_OK on success, else a fault code. + */ +static int dap_queue_read_reg(enum coresight_access_mode mode, struct adiv5_ap *ap, + uint64_t component_base, unsigned int reg, uint32_t *value) +{ + if (mode == CS_ACCESS_AP) + return dap_queue_ap_read(ap, reg, value); + + /* mode == CS_ACCESS_MEM_AP */ + return mem_ap_read_u32(ap, component_base + reg, value); +} + +/** * Read the CoreSight registers needed during ROM Table Parsing (RTP). * + * @param mode Method to access the component (AP or MEM-AP). * @param ap Pointer to AP containing the component. * @param component_base On MEM-AP access method, base address of the component. * @param v Pointer to the struct holding the value of registers. * * @return ERROR_OK on success, else a fault code. */ -static int rtp_read_cs_regs(struct adiv5_ap *ap, target_addr_t component_base, - struct cs_component_vals *v) +static int rtp_read_cs_regs(enum coresight_access_mode mode, struct adiv5_ap *ap, + target_addr_t component_base, struct cs_component_vals *v) { assert(IS_ALIGNED(component_base, ARM_CS_ALIGN)); assert(ap && v); @@ -1070,6 +1258,7 @@ static int rtp_read_cs_regs(struct adiv5_ap *ap, target_addr_t component_base, v->ap = ap; v->component_base = component_base; + v->mode = mode; /* sort by offset to gain speed */ @@ -1079,35 +1268,35 @@ static int rtp_read_cs_regs(struct adiv5_ap *ap, target_addr_t component_base, * without triggering error. Read them for eventual use on Class 0x9. */ if (retval == ERROR_OK) - retval = mem_ap_read_u32(ap, component_base + ARM_CS_C9_DEVARCH, &v->devarch); + retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_C9_DEVARCH, &v->devarch); if (retval == ERROR_OK) - retval = mem_ap_read_u32(ap, component_base + ARM_CS_C9_DEVID, &v->devid); + retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_C9_DEVID, &v->devid); /* Same address as ARM_CS_C1_MEMTYPE */ if (retval == ERROR_OK) - retval = mem_ap_read_u32(ap, component_base + ARM_CS_C9_DEVTYPE, &v->devtype_memtype); + retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_C9_DEVTYPE, &v->devtype_memtype); if (retval == ERROR_OK) - retval = mem_ap_read_u32(ap, component_base + ARM_CS_PIDR4, &pid4); + retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR4, &pid4); if (retval == ERROR_OK) - retval = mem_ap_read_u32(ap, component_base + ARM_CS_PIDR0, &pid0); + retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR0, &pid0); if (retval == ERROR_OK) - retval = mem_ap_read_u32(ap, component_base + ARM_CS_PIDR1, &pid1); + retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR1, &pid1); if (retval == ERROR_OK) - retval = mem_ap_read_u32(ap, component_base + ARM_CS_PIDR2, &pid2); + retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR2, &pid2); if (retval == ERROR_OK) - retval = mem_ap_read_u32(ap, component_base + ARM_CS_PIDR3, &pid3); + retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR3, &pid3); if (retval == ERROR_OK) - retval = mem_ap_read_u32(ap, component_base + ARM_CS_CIDR0, &cid0); + retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_CIDR0, &cid0); if (retval == ERROR_OK) - retval = mem_ap_read_u32(ap, component_base + ARM_CS_CIDR1, &cid1); + retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_CIDR1, &cid1); if (retval == ERROR_OK) - retval = mem_ap_read_u32(ap, component_base + ARM_CS_CIDR2, &cid2); + retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_CIDR2, &cid2); if (retval == ERROR_OK) - retval = mem_ap_read_u32(ap, component_base + ARM_CS_CIDR3, &cid3); + retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_CIDR3, &cid3); if (retval == ERROR_OK) retval = dap_run(ap->dap); @@ -1431,16 +1620,25 @@ static int dap_devtype_display(struct command_invocation *cmd, uint32_t devtype) */ struct rtp_ops { /** + * Executed at the start of a new AP, typically to print the AP header. + * @param ap Pointer to AP. + * @param depth The current depth level of ROM table. + * @param priv Pointer to private data. + * @return ERROR_OK on success, else a fault code. + */ + int (*ap_header)(struct adiv5_ap *ap, int depth, void *priv); + /** * Executed at the start of a new MEM-AP, typically to print the MEM-AP header. * @param retval Error encountered while reading AP. * @param ap Pointer to AP. * @param dbgbase Value of MEM-AP Debug Base Address register. * @param apid Value of MEM-AP IDR Identification Register. + * @param depth The current depth level of ROM table. * @param priv Pointer to private data. * @return ERROR_OK on success, else a fault code. */ int (*mem_ap_header)(int retval, struct adiv5_ap *ap, uint64_t dbgbase, - uint32_t apid, void *priv); + uint32_t apid, int depth, void *priv); /** * Executed when a CoreSight component is parsed, typically to print * information on the component. @@ -1470,16 +1668,28 @@ struct rtp_ops { }; /** + * Wrapper around struct rtp_ops::ap_header. + */ +static int rtp_ops_ap_header(const struct rtp_ops *ops, + struct adiv5_ap *ap, int depth) +{ + if (ops->ap_header) + return ops->ap_header(ap, depth, ops->priv); + + return ERROR_OK; +} + +/** * Wrapper around struct rtp_ops::mem_ap_header. * Input parameter @a retval is propagated. */ static int rtp_ops_mem_ap_header(const struct rtp_ops *ops, - int retval, struct adiv5_ap *ap, uint64_t dbgbase, uint32_t apid) + int retval, struct adiv5_ap *ap, uint64_t dbgbase, uint32_t apid, int depth) { if (!ops->mem_ap_header) return retval; - int retval1 = ops->mem_ap_header(retval, ap, dbgbase, apid, ops->priv); + int retval1 = ops->mem_ap_header(retval, ap, dbgbase, apid, depth, ops->priv); if (retval != ERROR_OK) return retval; return retval1; @@ -1528,13 +1738,18 @@ static int rtp_ops_rom_table_entry(const struct rtp_ops *ops, */ #define CORESIGHT_COMPONENT_FOUND (1) -static int rtp_cs_component(const struct rtp_ops *ops, - struct adiv5_ap *ap, target_addr_t dbgbase, int depth); +static int rtp_ap(const struct rtp_ops *ops, struct adiv5_ap *ap, int depth); +static int rtp_cs_component(enum coresight_access_mode mode, const struct rtp_ops *ops, + struct adiv5_ap *ap, target_addr_t dbgbase, bool *is_mem_ap, int depth); -static int rtp_rom_loop(const struct rtp_ops *ops, +static int rtp_rom_loop(enum coresight_access_mode mode, const struct rtp_ops *ops, struct adiv5_ap *ap, target_addr_t base_address, int depth, unsigned int width, unsigned int max_entries) { + /* ADIv6 AP ROM table provide offset from current AP */ + if (mode == CS_ACCESS_AP) + base_address = ap->ap_num; + assert(IS_ALIGNED(base_address, ARM_CS_ALIGN)); unsigned int offset = 0; @@ -1544,10 +1759,10 @@ static int rtp_rom_loop(const struct rtp_ops *ops, target_addr_t component_base; unsigned int saved_offset = offset; - int retval = mem_ap_read_u32(ap, base_address + offset, &romentry_low); + int retval = dap_queue_read_reg(mode, ap, base_address, offset, &romentry_low); offset += 4; if (retval == ERROR_OK && width == 64) { - retval = mem_ap_read_u32(ap, base_address + offset, &romentry_high); + retval = dap_queue_read_reg(mode, ap, base_address, offset, &romentry_high); offset += 4; } if (retval == ERROR_OK) @@ -1581,7 +1796,18 @@ static int rtp_rom_loop(const struct rtp_ops *ops, continue; /* Recurse */ - retval = rtp_cs_component(ops, ap, component_base, depth + 1); + if (mode == CS_ACCESS_AP) { + struct adiv5_ap *next_ap = dap_get_ap(ap->dap, component_base); + if (!next_ap) { + LOG_DEBUG("Wrong AP # 0x%" PRIx64, component_base); + continue; + } + retval = rtp_ap(ops, next_ap, depth + 1); + dap_put_ap(next_ap); + } else { + /* mode == CS_ACCESS_MEM_AP */ + retval = rtp_cs_component(mode, ops, ap, component_base, NULL, depth + 1); + } if (retval == CORESIGHT_COMPONENT_FOUND) return CORESIGHT_COMPONENT_FOUND; if (retval != ERROR_OK) { @@ -1594,18 +1820,21 @@ static int rtp_rom_loop(const struct rtp_ops *ops, return ERROR_OK; } -static int rtp_cs_component(const struct rtp_ops *ops, - struct adiv5_ap *ap, target_addr_t base_address, int depth) +static int rtp_cs_component(enum coresight_access_mode mode, const struct rtp_ops *ops, + struct adiv5_ap *ap, target_addr_t base_address, bool *is_mem_ap, int depth) { struct cs_component_vals v; int retval; assert(IS_ALIGNED(base_address, ARM_CS_ALIGN)); + if (is_mem_ap) + *is_mem_ap = false; + if (depth > ROM_TABLE_MAX_DEPTH) retval = ERROR_FAIL; else - retval = rtp_read_cs_regs(ap, base_address, &v); + retval = rtp_read_cs_regs(mode, ap, base_address, &v); retval = rtp_ops_cs_component(ops, retval, &v, depth); if (retval == CORESIGHT_COMPONENT_FOUND) @@ -1619,37 +1848,64 @@ static int rtp_cs_component(const struct rtp_ops *ops, const unsigned int class = ARM_CS_CIDR_CLASS(v.cid); if (class == ARM_CS_CLASS_0X1_ROM_TABLE) - return rtp_rom_loop(ops, ap, base_address, depth, 32, 960); + return rtp_rom_loop(mode, ops, ap, base_address, depth, 32, 960); if (class == ARM_CS_CLASS_0X9_CS_COMPONENT) { if ((v.devarch & ARM_CS_C9_DEVARCH_PRESENT) == 0) return ERROR_OK; + if (is_mem_ap) { + if ((v.devarch & DEVARCH_ID_MASK) == DEVARCH_MEM_AP) + *is_mem_ap = true; + + /* SoC-600 APv1 Adapter */ + if ((v.devarch & DEVARCH_ID_MASK) == DEVARCH_UNKNOWN_V2 && + ARM_CS_PIDR_DESIGNER(v.pid) == ARM_ID && + ARM_CS_PIDR_PART(v.pid) == 0x9e5) + *is_mem_ap = true; + } + /* quit if not ROM table */ if ((v.devarch & DEVARCH_ID_MASK) != DEVARCH_ROM_C_0X9) return ERROR_OK; if ((v.devid & ARM_CS_C9_DEVID_FORMAT_MASK) == ARM_CS_C9_DEVID_FORMAT_64BIT) - return rtp_rom_loop(ops, ap, base_address, depth, 64, 256); + return rtp_rom_loop(mode, ops, ap, base_address, depth, 64, 256); else - return rtp_rom_loop(ops, ap, base_address, depth, 32, 512); + return rtp_rom_loop(mode, ops, ap, base_address, depth, 32, 512); } /* Class other than 0x1 and 0x9 */ return ERROR_OK; } -static int rtp_ap(const struct rtp_ops *ops, struct adiv5_ap *ap) +static int rtp_ap(const struct rtp_ops *ops, struct adiv5_ap *ap, int depth) { - int retval; uint32_t apid; target_addr_t dbgbase, invalid_entry; + int retval = rtp_ops_ap_header(ops, ap, depth); + if (retval != ERROR_OK || depth > ROM_TABLE_MAX_DEPTH) + return ERROR_OK; /* Don't abort recursion */ + + if (is_adiv6(ap->dap)) { + bool is_mem_ap; + retval = rtp_cs_component(CS_ACCESS_AP, ops, ap, 0, &is_mem_ap, depth); + if (retval == CORESIGHT_COMPONENT_FOUND) + return CORESIGHT_COMPONENT_FOUND; + if (retval != ERROR_OK) + return ERROR_OK; /* Don't abort recursion */ + + if (!is_mem_ap) + return ERROR_OK; + /* Continue for an ADIv6 MEM-AP or SoC-600 APv1 Adapter */ + } + /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */ retval = dap_get_debugbase(ap, &dbgbase, &apid); if (retval != ERROR_OK) return retval; - retval = rtp_ops_mem_ap_header(ops, retval, ap, dbgbase, apid); + retval = rtp_ops_mem_ap_header(ops, retval, ap, dbgbase, apid, depth); if (retval != ERROR_OK) return retval; @@ -1668,7 +1924,8 @@ static int rtp_ap(const struct rtp_ops *ops, struct adiv5_ap *ap) invalid_entry = 0xFFFFFFFFul; if (dbgbase != invalid_entry && (dbgbase & 0x3) != 0x2) { - retval = rtp_cs_component(ops, ap, dbgbase & 0xFFFFFFFFFFFFF000ull, 0); + retval = rtp_cs_component(CS_ACCESS_MEM_AP, ops, ap, + dbgbase & 0xFFFFFFFFFFFFF000ull, NULL, depth); if (retval == CORESIGHT_COMPONENT_FOUND) return CORESIGHT_COMPONENT_FOUND; } @@ -1679,24 +1936,46 @@ static int rtp_ap(const struct rtp_ops *ops, struct adiv5_ap *ap) /* Actions for command "dap info" */ +static int dap_info_ap_header(struct adiv5_ap *ap, int depth, void *priv) +{ + struct command_invocation *cmd = priv; + + if (depth > ROM_TABLE_MAX_DEPTH) { + command_print(cmd, "\tTables too deep"); + return ERROR_FAIL; + } + + command_print(cmd, "%sAP # 0x%" PRIx64, (depth) ? "\t\t" : "", ap->ap_num); + return ERROR_OK; +} + static int dap_info_mem_ap_header(int retval, struct adiv5_ap *ap, - target_addr_t dbgbase, uint32_t apid, void *priv) + target_addr_t dbgbase, uint32_t apid, int depth, void *priv) { struct command_invocation *cmd = priv; target_addr_t invalid_entry; + char tabs[17] = ""; if (retval != ERROR_OK) { command_print(cmd, "\t\tCan't read MEM-AP, the corresponding core might be turned off"); return retval; } - command_print(cmd, "AP ID register 0x%8.8" PRIx32, apid); + if (depth > ROM_TABLE_MAX_DEPTH) { + command_print(cmd, "\tTables too deep"); + return ERROR_FAIL; + } + + if (depth) + snprintf(tabs, sizeof(tabs), "\t[L%02d] ", depth); + + command_print(cmd, "\t\tAP ID register 0x%8.8" PRIx32, apid); if (apid == 0) { - command_print(cmd, "No AP found at this ap 0x%x", ap->ap_num); + command_print(cmd, "\t\tNo AP found at this AP#0x%" PRIx64, ap->ap_num); return ERROR_FAIL; } - command_print(cmd, "\tType is %s", ap_type_to_description(apid & AP_TYPE_MASK)); + command_print(cmd, "\t\tType is %s", ap_type_to_description(apid & AP_TYPE_MASK)); /* NOTE: a MEM-AP may have a single CoreSight component that's * not a ROM table ... or have no such components at all. @@ -1709,15 +1988,15 @@ static int dap_info_mem_ap_header(int retval, struct adiv5_ap *ap, else invalid_entry = 0xFFFFFFFFul; - command_print(cmd, "MEM-AP BASE " TARGET_ADDR_FMT, dbgbase); + command_print(cmd, "%sMEM-AP BASE " TARGET_ADDR_FMT, tabs, dbgbase); if (dbgbase == invalid_entry || (dbgbase & 0x3) == 0x2) { - command_print(cmd, "\tNo ROM table present"); + command_print(cmd, "\t\tNo ROM table present"); } else { if (dbgbase & 0x01) - command_print(cmd, "\tValid ROM table present"); + command_print(cmd, "\t\tValid ROM table present"); else - command_print(cmd, "\tROM table in legacy format"); + command_print(cmd, "\t\tROM table in legacy format"); } } @@ -1733,7 +2012,8 @@ static int dap_info_cs_component(int retval, struct cs_component_vals *v, int de return ERROR_FAIL; } - command_print(cmd, "\t\tComponent base address " TARGET_ADDR_FMT, v->component_base); + if (v->mode == CS_ACCESS_MEM_AP) + command_print(cmd, "\t\tComponent base address " TARGET_ADDR_FMT, v->component_base); if (retval != ERROR_OK) { command_print(cmd, "\t\tCan't read component, the corresponding core might be turned off"); @@ -1844,13 +2124,14 @@ static int dap_info_rom_table_entry(int retval, int depth, int dap_info_command(struct command_invocation *cmd, struct adiv5_ap *ap) { struct rtp_ops dap_info_ops = { + .ap_header = dap_info_ap_header, .mem_ap_header = dap_info_mem_ap_header, .cs_component = dap_info_cs_component, .rom_table_entry = dap_info_rom_table_entry, .priv = cmd, }; - return rtp_ap(&dap_info_ops, ap); + return rtp_ap(&dap_info_ops, ap, 0); } /* Actions for dap_lookup_cs_component() */ @@ -1861,6 +2142,7 @@ struct dap_lookup_data { unsigned int type; /* output */ uint64_t component_base; + uint64_t ap_num; }; static int dap_lookup_cs_component_cs_component(int retval, @@ -1889,6 +2171,7 @@ static int dap_lookup_cs_component_cs_component(int retval, /* Found! */ lookup->component_base = v->component_base; + lookup->ap_num = v->ap->ap_num; return CORESIGHT_COMPONENT_FOUND; } @@ -1900,14 +2183,20 @@ int dap_lookup_cs_component(struct adiv5_ap *ap, uint8_t type, .idx = core_id, }; struct rtp_ops dap_lookup_cs_component_ops = { + .ap_header = NULL, .mem_ap_header = NULL, .cs_component = dap_lookup_cs_component_cs_component, .rom_table_entry = NULL, .priv = &lookup, }; - int retval = rtp_ap(&dap_lookup_cs_component_ops, ap); + int retval = rtp_ap(&dap_lookup_cs_component_ops, ap, 0); if (retval == CORESIGHT_COMPONENT_FOUND) { + if (lookup.ap_num != ap->ap_num) { + /* TODO: handle search from root ROM table */ + LOG_DEBUG("CS lookup ended in AP # 0x%" PRIx64 ". Ignore it", lookup.ap_num); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } LOG_DEBUG("CS lookup found at 0x%" PRIx64, lookup.component_base); *addr = lookup.component_base; return ERROR_OK; @@ -1936,7 +2225,7 @@ static const struct jim_nvp nvp_config_opts[] = { }; static int adiv5_jim_spot_configure(struct jim_getopt_info *goi, - struct adiv5_dap **dap_p, int *ap_num_p, uint32_t *base_p) + struct adiv5_dap **dap_p, uint64_t *ap_num_p, uint32_t *base_p) { assert(dap_p && ap_num_p); @@ -1991,11 +2280,13 @@ static int adiv5_jim_spot_configure(struct jim_getopt_info *goi, case CFG_AP_NUM: if (goi->isconfigure) { + /* jim_wide is a signed 64 bits int, ap_num is unsigned with max 52 bits */ jim_wide ap_num; e = jim_getopt_wide(goi, &ap_num); if (e != JIM_OK) return e; - if (ap_num < 0 || ap_num > DP_APSEL_MAX) { + /* we still don't know dap->adi_version */ + if (ap_num < 0 || (ap_num > DP_APSEL_MAX && (ap_num & 0xfff))) { Jim_SetResultString(goi->interp, "Invalid AP number!", -1); return JIM_ERR; } @@ -2100,15 +2391,27 @@ int adiv5_mem_ap_spot_init(struct adiv5_mem_ap_spot *p) COMMAND_HANDLER(handle_dap_info_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); - uint32_t apsel; + uint64_t apsel; switch (CMD_ARGC) { case 0: apsel = dap->apsel; break; case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - if (apsel > DP_APSEL_MAX) { + if (!strcmp(CMD_ARGV[0], "root")) { + if (!is_adiv6(dap)) { + command_print(CMD, "Option \"root\" not allowed with ADIv5 DAP"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + int retval = adiv6_dap_read_baseptr(CMD, dap, &apsel); + if (retval != ERROR_OK) { + command_print(CMD, "Failed reading DAP baseptr"); + return retval; + } + break; + } + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel); + if (!is_ap_num_valid(dap, apsel)) { command_print(CMD, "Invalid AP number"); return ERROR_COMMAND_ARGUMENT_INVALID; } @@ -2117,13 +2420,22 @@ COMMAND_HANDLER(handle_dap_info_command) return ERROR_COMMAND_SYNTAX_ERROR; } - return dap_info_command(CMD, &dap->ap[apsel]); + struct adiv5_ap *ap = dap_get_ap(dap, apsel); + if (!ap) { + command_print(CMD, "Cannot get AP"); + return ERROR_FAIL; + } + + int retval = dap_info_command(CMD, ap); + dap_put_ap(ap); + return retval; } COMMAND_HANDLER(dap_baseaddr_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); - uint32_t apsel, baseaddr_lower, baseaddr_upper; + uint64_t apsel; + uint32_t baseaddr_lower, baseaddr_upper; struct adiv5_ap *ap; target_addr_t baseaddr; int retval; @@ -2135,9 +2447,8 @@ COMMAND_HANDLER(dap_baseaddr_command) apsel = dap->apsel; break; case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel > DP_APSEL_MAX) { + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel); + if (!is_ap_num_valid(dap, apsel)) { command_print(CMD, "Invalid AP number"); return ERROR_COMMAND_ARGUMENT_INVALID; } @@ -2152,19 +2463,25 @@ COMMAND_HANDLER(dap_baseaddr_command) * use the ID register to verify it's a MEM-AP. */ - ap = dap_ap(dap, apsel); - retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, &baseaddr_lower); + ap = dap_get_ap(dap, apsel); + if (!ap) { + command_print(CMD, "Cannot get AP"); + return ERROR_FAIL; + } + + retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE(dap), &baseaddr_lower); if (retval == ERROR_OK && ap->cfg_reg == MEM_AP_REG_CFG_INVALID) - retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG, &ap->cfg_reg); + retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG(dap), &ap->cfg_reg); if (retval == ERROR_OK && (ap->cfg_reg == MEM_AP_REG_CFG_INVALID || is_64bit_ap(ap))) { /* MEM_AP_REG_BASE64 is defined as 'RES0'; can be read and then ignored on 32 bits AP */ - retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64, &baseaddr_upper); + retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64(dap), &baseaddr_upper); } if (retval == ERROR_OK) retval = dap_run(dap); + dap_put_ap(ap); if (retval != ERROR_OK) return retval; @@ -2180,22 +2497,35 @@ COMMAND_HANDLER(dap_baseaddr_command) COMMAND_HANDLER(dap_memaccess_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); + struct adiv5_ap *ap; uint32_t memaccess_tck; switch (CMD_ARGC) { case 0: - memaccess_tck = dap->ap[dap->apsel].memaccess_tck; + ap = dap_get_ap(dap, dap->apsel); + if (!ap) { + command_print(CMD, "Cannot get AP"); + return ERROR_FAIL; + } + memaccess_tck = ap->memaccess_tck; break; case 1: + ap = dap_get_config_ap(dap, dap->apsel); + if (!ap) { + command_print(CMD, "Cannot get AP"); + return ERROR_FAIL; + } COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], memaccess_tck); + ap->memaccess_tck = memaccess_tck; break; default: return ERROR_COMMAND_SYNTAX_ERROR; } - dap->ap[dap->apsel].memaccess_tck = memaccess_tck; + + dap_put_ap(ap); command_print(CMD, "memory bus access delay set to %" PRIu32 " tck", - dap->ap[dap->apsel].memaccess_tck); + memaccess_tck); return ERROR_OK; } @@ -2203,16 +2533,15 @@ COMMAND_HANDLER(dap_memaccess_command) COMMAND_HANDLER(dap_apsel_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); - uint32_t apsel; + uint64_t apsel; switch (CMD_ARGC) { case 0: - command_print(CMD, "%" PRIu32, dap->apsel); + command_print(CMD, "0x%" PRIx64, dap->apsel); return ERROR_OK; case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel > DP_APSEL_MAX) { + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel); + if (!is_ap_num_valid(dap, apsel)) { command_print(CMD, "Invalid AP number"); return ERROR_COMMAND_ARGUMENT_INVALID; } @@ -2228,14 +2557,19 @@ COMMAND_HANDLER(dap_apsel_command) COMMAND_HANDLER(dap_apcsw_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); - uint32_t apcsw = dap->ap[dap->apsel].csw_default; + struct adiv5_ap *ap; uint32_t csw_val, csw_mask; switch (CMD_ARGC) { case 0: - command_print(CMD, "ap %" PRIu32 " selected, csw 0x%8.8" PRIx32, - dap->apsel, apcsw); - return ERROR_OK; + ap = dap_get_ap(dap, dap->apsel); + if (!ap) { + command_print(CMD, "Cannot get AP"); + return ERROR_FAIL; + } + command_print(CMD, "AP#0x%" PRIx64 " selected, csw 0x%8.8" PRIx32, + dap->apsel, ap->csw_default); + break; case 1: if (strcmp(CMD_ARGV[0], "default") == 0) csw_val = CSW_AHB_DEFAULT; @@ -2246,7 +2580,12 @@ COMMAND_HANDLER(dap_apcsw_command) LOG_ERROR("CSW value cannot include 'Size' and 'AddrInc' bit-fields"); return ERROR_COMMAND_ARGUMENT_INVALID; } - apcsw = csw_val; + ap = dap_get_config_ap(dap, dap->apsel); + if (!ap) { + command_print(CMD, "Cannot get AP"); + return ERROR_FAIL; + } + ap->csw_default = csw_val; break; case 2: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], csw_val); @@ -2255,14 +2594,19 @@ COMMAND_HANDLER(dap_apcsw_command) LOG_ERROR("CSW mask cannot include 'Size' and 'AddrInc' bit-fields"); return ERROR_COMMAND_ARGUMENT_INVALID; } - apcsw = (apcsw & ~csw_mask) | (csw_val & csw_mask); + ap = dap_get_config_ap(dap, dap->apsel); + if (!ap) { + command_print(CMD, "Cannot get AP"); + return ERROR_FAIL; + } + ap->csw_default = (ap->csw_default & ~csw_mask) | (csw_val & csw_mask); break; default: return ERROR_COMMAND_SYNTAX_ERROR; } - dap->ap[dap->apsel].csw_default = apcsw; + dap_put_ap(ap); - return 0; + return ERROR_OK; } @@ -2270,7 +2614,8 @@ COMMAND_HANDLER(dap_apcsw_command) COMMAND_HANDLER(dap_apid_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); - uint32_t apsel, apid; + uint64_t apsel; + uint32_t apid; int retval; switch (CMD_ARGC) { @@ -2278,9 +2623,8 @@ COMMAND_HANDLER(dap_apid_command) apsel = dap->apsel; break; case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel > DP_APSEL_MAX) { + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel); + if (!is_ap_num_valid(dap, apsel)) { command_print(CMD, "Invalid AP number"); return ERROR_COMMAND_ARGUMENT_INVALID; } @@ -2289,10 +2633,18 @@ COMMAND_HANDLER(dap_apid_command) return ERROR_COMMAND_SYNTAX_ERROR; } - retval = dap_queue_ap_read(dap_ap(dap, apsel), AP_REG_IDR, &apid); - if (retval != ERROR_OK) + struct adiv5_ap *ap = dap_get_ap(dap, apsel); + if (!ap) { + command_print(CMD, "Cannot get AP"); + return ERROR_FAIL; + } + retval = dap_queue_ap_read(ap, AP_REG_IDR(dap), &apid); + if (retval != ERROR_OK) { + dap_put_ap(ap); return retval; + } retval = dap_run(dap); + dap_put_ap(ap); if (retval != ERROR_OK) return retval; @@ -2304,38 +2656,47 @@ COMMAND_HANDLER(dap_apid_command) COMMAND_HANDLER(dap_apreg_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); - uint32_t apsel, reg, value; - struct adiv5_ap *ap; + uint64_t apsel; + uint32_t reg, value; int retval; if (CMD_ARGC < 2 || CMD_ARGC > 3) return ERROR_COMMAND_SYNTAX_ERROR; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel > DP_APSEL_MAX) { + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel); + if (!is_ap_num_valid(dap, apsel)) { command_print(CMD, "Invalid AP number"); return ERROR_COMMAND_ARGUMENT_INVALID; } - ap = dap_ap(dap, apsel); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg); - if (reg >= 256 || (reg & 3)) { - command_print(CMD, "Invalid reg value (should be less than 256 and 4 bytes aligned)"); - return ERROR_COMMAND_ARGUMENT_INVALID; + if (is_adiv6(dap)) { + if (reg >= 4096 || (reg & 3)) { + command_print(CMD, "Invalid reg value (should be less than 4096 and 4 bytes aligned)"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + } else { /* ADI version 5 */ + if (reg >= 256 || (reg & 3)) { + command_print(CMD, "Invalid reg value (should be less than 256 and 4 bytes aligned)"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + } + + struct adiv5_ap *ap = dap_get_ap(dap, apsel); + if (!ap) { + command_print(CMD, "Cannot get AP"); + return ERROR_FAIL; } if (CMD_ARGC == 3) { COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value); - switch (reg) { - case MEM_AP_REG_CSW: + /* see if user supplied register address is a match for the CSW or TAR register */ + if (reg == MEM_AP_REG_CSW(dap)) { ap->csw_value = 0; /* invalid, in case write fails */ retval = dap_queue_ap_write(ap, reg, value); if (retval == ERROR_OK) ap->csw_value = value; - break; - case MEM_AP_REG_TAR: + } else if (reg == MEM_AP_REG_TAR(dap)) { retval = dap_queue_ap_write(ap, reg, value); if (retval == ERROR_OK) ap->tar_value = (ap->tar_value & ~0xFFFFFFFFull) | value; @@ -2346,8 +2707,7 @@ COMMAND_HANDLER(dap_apreg_command) /* if tar_valid is false. */ ap->tar_valid = false; } - break; - case MEM_AP_REG_TAR64: + } else if (reg == MEM_AP_REG_TAR64(dap)) { retval = dap_queue_ap_write(ap, reg, value); if (retval == ERROR_OK) ap->tar_value = (ap->tar_value & 0xFFFFFFFFull) | (((target_addr_t)value) << 32); @@ -2355,10 +2715,8 @@ COMMAND_HANDLER(dap_apreg_command) /* See above comment for the MEM_AP_REG_TAR failed write case */ ap->tar_valid = false; } - break; - default: + } else { retval = dap_queue_ap_write(ap, reg, value); - break; } } else { retval = dap_queue_ap_read(ap, reg, &value); @@ -2366,6 +2724,8 @@ COMMAND_HANDLER(dap_apreg_command) if (retval == ERROR_OK) retval = dap_run(dap); + dap_put_ap(ap); + if (retval != ERROR_OK) return retval; @@ -2415,14 +2775,21 @@ COMMAND_HANDLER(dap_ti_be_32_quirks_command) "TI BE-32 quirks mode"); } +COMMAND_HANDLER(dap_nu_npcx_quirks_command) +{ + struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); + return CALL_COMMAND_HANDLER(handle_command_parse_bool, &dap->nu_npcx_quirks, + "Nuvoton NPCX quirks mode"); +} + const struct command_registration dap_instance_commands[] = { { .name = "info", .handler = handle_dap_info_command, .mode = COMMAND_EXEC, - .help = "display ROM table for MEM-AP " - "(default currently selected AP)", - .usage = "[ap_num]", + .help = "display ROM table for specified MEM-AP (default currently selected AP) " + "or the ADIv6 root ROM table", + .usage = "[ap_num | 'root']", }, { .name = "apsel", @@ -2487,5 +2854,12 @@ const struct command_registration dap_instance_commands[] = { .help = "set/get quirks mode for TI TMS450/TMS570 processors", .usage = "[enable]", }, + { + .name = "nu_npcx_quirks", + .handler = dap_nu_npcx_quirks_command, + .mode = COMMAND_CONFIG, + .help = "set/get quirks mode for Nuvoton NPCX controllers", + .usage = "[enable]", + }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index 8c9a60f..3eddbc0 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2006 by Magnus Lundin * * lundin@mlu.mine.nu * @@ -5,18 +7,7 @@ * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * * * - * 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, see <http://www.gnu.org/licenses/>. * + * Copyright (C) 2019-2021, Ampere Computing LLC * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM_ADI_V5_H @@ -53,11 +44,15 @@ */ #define DP_DPIDR BANK_REG(0x0, 0x0) /* DPv1+: ro */ #define DP_ABORT BANK_REG(0x0, 0x0) /* DPv1+: SWD: wo */ +#define DP_DPIDR1 BANK_REG(0x1, 0x0) /* DPv3: ro */ +#define DP_BASEPTR0 BANK_REG(0x2, 0x0) /* DPv3: ro */ +#define DP_BASEPTR1 BANK_REG(0x3, 0x0) /* DPv3: ro */ #define DP_CTRL_STAT BANK_REG(0x0, 0x4) /* DPv0+: rw */ #define DP_DLCR BANK_REG(0x1, 0x4) /* DPv1+: SWD: rw */ #define DP_TARGETID BANK_REG(0x2, 0x4) /* DPv2: ro */ #define DP_DLPIDR BANK_REG(0x3, 0x4) /* DPv2: ro */ #define DP_EVENTSTAT BANK_REG(0x4, 0x4) /* DPv2: ro */ +#define DP_SELECT1 BANK_REG(0x5, 0x4) /* DPv3: ro */ #define DP_RESEND BANK_REG(0x0, 0x8) /* DPv1+: SWD: ro */ #define DP_SELECT BANK_REG(0x0, 0x8) /* DPv0+: JTAG: rw; SWD: wo */ #define DP_RDBUFF BANK_REG(0x0, 0xC) /* DPv0+: ro */ @@ -76,6 +71,13 @@ #define WDERRCLR (1UL << 3) /* SWD-only */ #define ORUNERRCLR (1UL << 4) /* SWD-only */ +/* Fields of register DP_DPIDR1 */ +#define DP_DPIDR1_ASIZE_MASK (0x7F) +#define DP_DPIDR1_ERRMODE BIT(7) + +/* Fields of register DP_BASEPTR0 */ +#define DP_BASEPTR0_VALID BIT(0) + /* Fields of the DP's CTRL/STAT register */ #define CORUNDETECT (1UL << 0) #define SSTICKYORUN (1UL << 1) @@ -100,8 +102,8 @@ #define DP_SELECT_DPBANK 0x0000000F #define DP_SELECT_INVALID 0x00FFFF00 /* Reserved bits one */ -#define DP_APSEL_MAX (255) -#define DP_APSEL_INVALID (-1) +#define DP_APSEL_MAX (255) /* for ADIv5 only */ +#define DP_APSEL_INVALID 0xF00 /* more than DP_APSEL_MAX and not ADIv6 aligned 4k */ #define DP_TARGETSEL_INVALID 0xFFFFFFFFU #define DP_TARGETSEL_DPID_MASK 0x0FFFFFFFU @@ -110,20 +112,49 @@ /* MEM-AP register addresses */ -#define MEM_AP_REG_CSW 0x00 -#define MEM_AP_REG_TAR 0x04 -#define MEM_AP_REG_TAR64 0x08 /* RW: Large Physical Address Extension */ -#define MEM_AP_REG_DRW 0x0C /* RW: Data Read/Write register */ -#define MEM_AP_REG_BD0 0x10 /* RW: Banked Data register 0-3 */ -#define MEM_AP_REG_BD1 0x14 -#define MEM_AP_REG_BD2 0x18 -#define MEM_AP_REG_BD3 0x1C -#define MEM_AP_REG_MBT 0x20 /* --: Memory Barrier Transfer register */ -#define MEM_AP_REG_BASE64 0xF0 /* RO: Debug Base Address (LA) register */ -#define MEM_AP_REG_CFG 0xF4 /* RO: Configuration register */ -#define MEM_AP_REG_BASE 0xF8 /* RO: Debug Base Address register */ +#define ADIV5_MEM_AP_REG_CSW (0x00) +#define ADIV5_MEM_AP_REG_TAR (0x04) +#define ADIV5_MEM_AP_REG_TAR64 (0x08) /* RW: Large Physical Address Extension */ +#define ADIV5_MEM_AP_REG_DRW (0x0C) /* RW: Data Read/Write register */ +#define ADIV5_MEM_AP_REG_BD0 (0x10) /* RW: Banked Data register 0-3 */ +#define ADIV5_MEM_AP_REG_BD1 (0x14) +#define ADIV5_MEM_AP_REG_BD2 (0x18) +#define ADIV5_MEM_AP_REG_BD3 (0x1C) +#define ADIV5_MEM_AP_REG_MBT (0x20) /* --: Memory Barrier Transfer register */ +#define ADIV5_MEM_AP_REG_BASE64 (0xF0) /* RO: Debug Base Address (LA) register */ +#define ADIV5_MEM_AP_REG_CFG (0xF4) /* RO: Configuration register */ +#define ADIV5_MEM_AP_REG_BASE (0xF8) /* RO: Debug Base Address register */ + +#define ADIV6_MEM_AP_REG_CSW (0xD00 + ADIV5_MEM_AP_REG_CSW) +#define ADIV6_MEM_AP_REG_TAR (0xD00 + ADIV5_MEM_AP_REG_TAR) +#define ADIV6_MEM_AP_REG_TAR64 (0xD00 + ADIV5_MEM_AP_REG_TAR64) +#define ADIV6_MEM_AP_REG_DRW (0xD00 + ADIV5_MEM_AP_REG_DRW) +#define ADIV6_MEM_AP_REG_BD0 (0xD00 + ADIV5_MEM_AP_REG_BD0) +#define ADIV6_MEM_AP_REG_BD1 (0xD00 + ADIV5_MEM_AP_REG_BD1) +#define ADIV6_MEM_AP_REG_BD2 (0xD00 + ADIV5_MEM_AP_REG_BD2) +#define ADIV6_MEM_AP_REG_BD3 (0xD00 + ADIV5_MEM_AP_REG_BD3) +#define ADIV6_MEM_AP_REG_MBT (0xD00 + ADIV5_MEM_AP_REG_MBT) +#define ADIV6_MEM_AP_REG_BASE64 (0xD00 + ADIV5_MEM_AP_REG_BASE64) +#define ADIV6_MEM_AP_REG_CFG (0xD00 + ADIV5_MEM_AP_REG_CFG) +#define ADIV6_MEM_AP_REG_BASE (0xD00 + ADIV5_MEM_AP_REG_BASE) + +#define MEM_AP_REG_CSW(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_CSW : ADIV5_MEM_AP_REG_CSW) +#define MEM_AP_REG_TAR(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_TAR : ADIV5_MEM_AP_REG_TAR) +#define MEM_AP_REG_TAR64(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_TAR64 : ADIV5_MEM_AP_REG_TAR64) +#define MEM_AP_REG_DRW(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_DRW : ADIV5_MEM_AP_REG_DRW) +#define MEM_AP_REG_BD0(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD0 : ADIV5_MEM_AP_REG_BD0) +#define MEM_AP_REG_BD1(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD1 : ADIV5_MEM_AP_REG_BD1) +#define MEM_AP_REG_BD2(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD2 : ADIV5_MEM_AP_REG_BD2) +#define MEM_AP_REG_BD3(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD3 : ADIV5_MEM_AP_REG_BD3) +#define MEM_AP_REG_MBT(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_MBT : ADIV5_MEM_AP_REG_MBT) +#define MEM_AP_REG_BASE64(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BASE64 : ADIV5_MEM_AP_REG_BASE64) +#define MEM_AP_REG_CFG(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_CFG : ADIV5_MEM_AP_REG_CFG) +#define MEM_AP_REG_BASE(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BASE : ADIV5_MEM_AP_REG_BASE) + /* Generic AP register address */ -#define AP_REG_IDR 0xFC /* RO: Identification Register */ +#define ADIV5_AP_REG_IDR (0xFC) /* RO: Identification Register */ +#define ADIV6_AP_REG_IDR (0xD00 + ADIV5_AP_REG_IDR) +#define AP_REG_IDR(dap) (is_adiv6(dap) ? ADIV6_AP_REG_IDR : ADIV5_AP_REG_IDR) /* Fields of the MEM-AP's CSW register */ #define CSW_SIZE_MASK 7 @@ -216,9 +247,11 @@ struct adiv5_ap { struct adiv5_dap *dap; /** - * Number of this AP. + * ADIv5: Number of this AP (0~255) + * ADIv6: Base address of this AP (4k aligned) + * TODO: to be more coherent, it should be renamed apsel */ - uint8_t ap_num; + uint64_t ap_num; /** * Default value for (MEM-AP) AP_REG_CSW register. @@ -259,6 +292,12 @@ struct adiv5_ap { /* MEM AP configuration register indicating LPAE support */ uint32_t cfg_reg; + + /* references counter */ + unsigned int refcount; + + /* AP referenced during config. Never put it, even when refcount reaches zero */ + bool config_ap_never_release; }; @@ -297,13 +336,13 @@ struct adiv5_dap { struct adiv5_ap ap[DP_APSEL_MAX + 1]; /* The current manually selected AP by the "dap apsel" command */ - uint32_t apsel; + uint64_t apsel; /** * Cache for DP_SELECT register. A value of DP_SELECT_INVALID * indicates no cached value and forces rewrite of the register. */ - uint32_t select; + uint64_t select; /* information about current pending SWjDP-AHBAP transaction */ uint8_t ack; @@ -320,6 +359,10 @@ struct adiv5_dap { * swizzle appropriately. */ bool ti_be_32_quirks; + /* The Nuvoton NPCX M4 has an issue with writing to non-4-byte-aligned mmios. + * The work around is to repeat the data in all 4 bytes of DRW */ + bool nu_npcx_quirks; + /** * STLINK adapter need to know if last AP operation was read or write, and * in case of write has to flush it with a dummy read from DP_RDBUFF @@ -347,6 +390,12 @@ struct adiv5_dap { * Record if enter in SWD required passing through DORMANT */ bool switch_through_dormant; + + /** Indicates ADI version (5, 6 or 0 for unknown) being used */ + unsigned int adi_version; + + /* ADIv6 only field indicating ROM Table address size */ + unsigned int asize; }; /** @@ -421,6 +470,18 @@ static inline bool is_64bit_ap(struct adiv5_ap *ap) } /** + * Check if DAP is ADIv6 + * + * @param dap The DAP to test + * + * @return true for ADIv6, false for either ADIv5 or unknown version + */ +static inline bool is_adiv6(const struct adiv5_dap *dap) +{ + return dap->adi_version == 6; +} + +/** * Send an adi-v5 sequence to the DAP. * * @param dap The DAP used for reading. @@ -486,6 +547,10 @@ static inline int dap_queue_ap_read(struct adiv5_ap *ap, unsigned reg, uint32_t *data) { assert(ap->dap->ops); + if (ap->refcount == 0) { + ap->refcount = 1; + LOG_ERROR("BUG: refcount AP#0x%" PRIx64 " used without get", ap->ap_num); + } return ap->dap->ops->queue_ap_read(ap, reg, data); } @@ -502,6 +567,10 @@ static inline int dap_queue_ap_write(struct adiv5_ap *ap, unsigned reg, uint32_t data) { assert(ap->dap->ops); + if (ap->refcount == 0) { + ap->refcount = 1; + LOG_ERROR("BUG: refcount AP#0x%" PRIx64 " used without get", ap->ap_num); + } return ap->dap->ops->queue_ap_write(ap, reg, data); } @@ -619,15 +688,25 @@ int mem_ap_init(struct adiv5_ap *ap); /* Invalidate cached DP select and cached TAR and CSW of all APs */ void dap_invalidate_cache(struct adiv5_dap *dap); -/* Probe Access Ports to find a particular type */ -int dap_find_ap(struct adiv5_dap *dap, +/* read ADIv6 baseptr register */ +int adiv6_dap_read_baseptr(struct command_invocation *cmd, struct adiv5_dap *dap, target_addr_t *baseptr); + +/* test if ap_num is valid, based on current knowledge of dap */ +bool is_ap_num_valid(struct adiv5_dap *dap, uint64_t ap_num); + +/* Probe Access Ports to find a particular type. Increment AP refcount */ +int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out); -static inline struct adiv5_ap *dap_ap(struct adiv5_dap *dap, uint8_t ap_num) -{ - return &dap->ap[ap_num]; -} +/* Return AP with specified ap_num. Increment AP refcount */ +struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num); + +/* Return AP with specified ap_num. Increment AP refcount and keep it non-zero */ +struct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, uint64_t ap_num); + +/* Decrement AP refcount and release the AP when refcount reaches zero */ +int dap_put_ap(struct adiv5_ap *ap); /** Check if SWD multidrop configuration is valid */ static inline bool dap_is_multidrop(struct adiv5_dap *dap) @@ -660,7 +739,7 @@ extern const struct swd_driver *adiv5_dap_swd_driver(struct adiv5_dap *self); extern int dap_cleanup_all(void); struct adiv5_private_config { - int ap_num; + uint64_t ap_num; struct adiv5_dap *dap; }; @@ -669,7 +748,7 @@ extern int adiv5_jim_configure(struct target *target, struct jim_getopt_info *go struct adiv5_mem_ap_spot { struct adiv5_dap *dap; - int ap_num; + uint64_t ap_num; uint32_t base; }; diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c index 96927bf..3612874 100644 --- a/src/target/arm_cti.c +++ b/src/target/arm_cti.c @@ -1,20 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2016 by Matthias Welwarsky * * * - * 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., * - * * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -34,6 +22,7 @@ struct arm_cti { struct list_head lh; char *name; struct adiv5_mem_ap_spot spot; + struct adiv5_ap *ap; }; static LIST_HEAD(all_cti); @@ -65,7 +54,7 @@ struct arm_cti *cti_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o) static int arm_cti_mod_reg_bits(struct arm_cti *self, unsigned int reg, uint32_t mask, uint32_t value) { - struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num); + struct adiv5_ap *ap = self->ap; uint32_t tmp; /* Read register */ @@ -84,15 +73,14 @@ static int arm_cti_mod_reg_bits(struct arm_cti *self, unsigned int reg, uint32_t int arm_cti_enable(struct arm_cti *self, bool enable) { - struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num); uint32_t val = enable ? 1 : 0; - return mem_ap_write_atomic_u32(ap, self->spot.base + CTI_CTR, val); + return mem_ap_write_atomic_u32(self->ap, self->spot.base + CTI_CTR, val); } int arm_cti_ack_events(struct arm_cti *self, uint32_t event) { - struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num); + struct adiv5_ap *ap = self->ap; int retval; uint32_t tmp; @@ -134,19 +122,15 @@ int arm_cti_ungate_channel(struct arm_cti *self, uint32_t channel) int arm_cti_write_reg(struct arm_cti *self, unsigned int reg, uint32_t value) { - struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num); - - return mem_ap_write_atomic_u32(ap, self->spot.base + reg, value); + return mem_ap_write_atomic_u32(self->ap, self->spot.base + reg, value); } int arm_cti_read_reg(struct arm_cti *self, unsigned int reg, uint32_t *p_value) { - struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num); - if (!p_value) return ERROR_COMMAND_ARGUMENT_INVALID; - return mem_ap_read_atomic_u32(ap, self->spot.base + reg, p_value); + return mem_ap_read_atomic_u32(self->ap, self->spot.base + reg, p_value); } int arm_cti_pulse_channel(struct arm_cti *self, uint32_t channel) @@ -228,6 +212,8 @@ int arm_cti_cleanup_all(void) struct arm_cti *obj, *tmp; list_for_each_entry_safe(obj, tmp, &all_cti, lh) { + if (obj->ap) + dap_put_ap(obj->ap); free(obj->name); free(obj); } @@ -238,7 +224,7 @@ int arm_cti_cleanup_all(void) COMMAND_HANDLER(handle_cti_dump) { struct arm_cti *cti = CMD_DATA; - struct adiv5_ap *ap = dap_ap(cti->spot.dap, cti->spot.ap_num); + struct adiv5_ap *ap = cti->ap; int retval = ERROR_OK; for (int i = 0; (retval == ERROR_OK) && (i < (int)ARRAY_SIZE(cti_names)); i++) @@ -518,6 +504,12 @@ static int cti_create(struct jim_getopt_info *goi) list_add_tail(&cti->lh, &all_cti); + cti->ap = dap_get_ap(cti->spot.dap, cti->spot.ap_num); + if (!cti->ap) { + Jim_SetResultString(goi->interp, "Cannot get AP", -1); + return JIM_ERR; + } + return JIM_OK; } diff --git a/src/target/arm_cti.h b/src/target/arm_cti.h index 7c4f7eb..cfcde65 100644 --- a/src/target/arm_cti.h +++ b/src/target/arm_cti.h @@ -1,20 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2016 by Matthias Welwarsky * * * - * 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., * - * * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM_CTI_H diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index 2dba45d..e21136d 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -1,20 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2016 by Matthias Welwarsky * * * - * 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., * - * * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -50,7 +38,7 @@ static void dap_instance_init(struct adiv5_dap *dap) /* Set up with safe defaults */ for (i = 0; i <= DP_APSEL_MAX; i++) { dap->ap[i].dap = dap; - dap->ap[i].ap_num = i; + dap->ap[i].ap_num = DP_APSEL_INVALID; /* memaccess_tck max is 255 */ dap->ap[i].memaccess_tck = 255; /* Number of bits for tar autoincrement, impl. dep. at least 10 */ @@ -58,6 +46,8 @@ static void dap_instance_init(struct adiv5_dap *dap) /* default CSW value */ dap->ap[i].csw_default = CSW_AHB_DEFAULT; dap->ap[i].cfg_reg = MEM_AP_REG_CFG_INVALID; /* mem_ap configuration reg (large physical addr, etc.) */ + dap->ap[i].refcount = 0; + dap->ap[i].config_ap_never_release = false; } INIT_LIST_HEAD(&dap->cmd_journal); INIT_LIST_HEAD(&dap->cmd_pool); @@ -127,9 +117,34 @@ static int dap_init_all(void) } else dap->ops = &jtag_dp_ops; + if (dap->adi_version == 0) { + LOG_DEBUG("DAP %s configured by default to use ADIv5 protocol", jtag_tap_name(dap->tap)); + dap->adi_version = 5; + } else { + LOG_DEBUG("DAP %s configured to use %s protocol by user cfg file", jtag_tap_name(dap->tap), + is_adiv6(dap) ? "ADIv6" : "ADIv5"); + } + retval = dap->ops->connect(dap); if (retval != ERROR_OK) return retval; + + /* see if address size of ROM Table is greater than 32-bits */ + if (is_adiv6(dap)) { + uint32_t dpidr1; + + retval = dap->ops->queue_dp_read(dap, DP_DPIDR1, &dpidr1); + if (retval != ERROR_OK) { + LOG_ERROR("DAP read of DPIDR1 failed..."); + return retval; + } + retval = dap_run(dap); + if (retval != ERROR_OK) { + LOG_ERROR("DAP read of DPIDR1 failed..."); + return retval; + } + dap->asize = dpidr1 & DP_DPIDR1_ASIZE_MASK; + } } return ERROR_OK; @@ -142,6 +157,10 @@ int dap_cleanup_all(void) list_for_each_entry_safe(obj, tmp, &all_dap, lh) { dap = &obj->dap; + for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) { + if (dap->ap[i].refcount != 0) + LOG_ERROR("BUG: refcount AP#%u still %u at exit", i, dap->ap[i].refcount); + } if (dap->ops && dap->ops->quit) dap->ops->quit(dap); @@ -157,6 +176,8 @@ enum dap_cfg_param { CFG_IGNORE_SYSPWRUPACK, CFG_DP_ID, CFG_INSTANCE_ID, + CFG_ADIV6, + CFG_ADIV5, }; static const struct jim_nvp nvp_config_opts[] = { @@ -164,6 +185,8 @@ static const struct jim_nvp nvp_config_opts[] = { { .name = "-ignore-syspwrupack", .value = CFG_IGNORE_SYSPWRUPACK }, { .name = "-dp-id", .value = CFG_DP_ID }, { .name = "-instance-id", .value = CFG_INSTANCE_ID }, + { .name = "-adiv6", .value = CFG_ADIV6 }, + { .name = "-adiv5", .value = CFG_ADIV5 }, { .name = NULL, .value = -1 } }; @@ -243,6 +266,12 @@ static int dap_configure(struct jim_getopt_info *goi, struct arm_dap_object *dap dap->dap.multidrop_instance_id_valid = true; break; } + case CFG_ADIV6: + dap->dap.adi_version = 6; + break; + case CFG_ADIV5: + dap->dap.adi_version = 5; + break; default: break; } @@ -418,7 +447,7 @@ COMMAND_HANDLER(handle_dap_info_command) struct target *target = get_current_target(CMD_CTX); struct arm *arm = target_to_arm(target); struct adiv5_dap *dap = arm->dap; - uint32_t apsel; + uint64_t apsel; if (!dap) { LOG_ERROR("DAP instance not available. Probably a HLA target..."); @@ -430,15 +459,34 @@ COMMAND_HANDLER(handle_dap_info_command) apsel = dap->apsel; break; case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - if (apsel > DP_APSEL_MAX) + if (!strcmp(CMD_ARGV[0], "root")) { + if (!is_adiv6(dap)) { + command_print(CMD, "Option \"root\" not allowed with ADIv5 DAP"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + int retval = adiv6_dap_read_baseptr(CMD, dap, &apsel); + if (retval != ERROR_OK) { + command_print(CMD, "Failed reading DAP baseptr"); + return retval; + } + break; + } + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel); + if (!is_ap_num_valid(dap, apsel)) return ERROR_COMMAND_SYNTAX_ERROR; break; default: return ERROR_COMMAND_SYNTAX_ERROR; } - return dap_info_command(CMD, &dap->ap[apsel]); + struct adiv5_ap *ap = dap_get_ap(dap, apsel); + if (!ap) { + command_print(CMD, "Cannot get AP"); + return ERROR_FAIL; + } + int retval = dap_info_command(CMD, ap); + dap_put_ap(ap); + return retval; } static const struct command_registration dap_subcommand_handlers[] = { @@ -467,9 +515,9 @@ static const struct command_registration dap_subcommand_handlers[] = { .name = "info", .handler = handle_dap_info_command, .mode = COMMAND_EXEC, - .help = "display ROM table for MEM-AP of current target " - "(default currently selected AP)", - .usage = "[ap_num]", + .help = "display ROM table for specified MEM-AP (default MEM-AP of current target) " + "or the ADIv6 root ROM table of current target's DAP", + .usage = "[ap_num | 'root']", }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c index d3d27a9..749274f 100644 --- a/src/target/arm_disassembler.c +++ b/src/target/arm_disassembler.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2009 by David Brownell * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arm_disassembler.h b/src/target/arm_disassembler.h index 6f15f4b..1be5674 100644 --- a/src/target/arm_disassembler.h +++ b/src/target/arm_disassembler.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM_DISASSEMBLER_H diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c index e60ef22..5f7e929 100644 --- a/src/target/arm_dpm.c +++ b/src/target/arm_dpm.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright (C) 2009 by David Brownell - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H diff --git a/src/target/arm_dpm.h b/src/target/arm_dpm.h index 0172d9a..d35e9f6 100644 --- a/src/target/arm_dpm.h +++ b/src/target/arm_dpm.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * Copyright (C) 2009 by David Brownell - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifndef OPENOCD_TARGET_ARM_DPM_H diff --git a/src/target/arm_jtag.c b/src/target/arm_jtag.c index 6a27e32..c1ec473 100644 --- a/src/target/arm_jtag.c +++ b/src/target/arm_jtag.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arm_jtag.h b/src/target/arm_jtag.h index f3e0bc2..11b7c3e 100644 --- a/src/target/arm_jtag.h +++ b/src/target/arm_jtag.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007-2010 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM_JTAG_H diff --git a/src/target/arm_opcodes.h b/src/target/arm_opcodes.h index 00035f5..c182f41 100644 --- a/src/target/arm_opcodes.h +++ b/src/target/arm_opcodes.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * Copyright (C) 2005 by Dominic Rath * Dominic.Rath@gmx.de @@ -10,19 +12,6 @@ * * Copyright (C) 2009 by Øyvind Harboe * oyvind.harboe@zylin.com - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifndef OPENOCD_TARGET_ARM_OPCODES_H diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c index 507d1cd..b557589 100644 --- a/src/target/arm_semihosting.c +++ b/src/target/arm_semihosting.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by Marvell Technology Group Ltd. * * Written by Nicolas Pitre <nico@marvell.com> * @@ -10,19 +12,6 @@ * * * Copyright (C) 2018 by Liviu Ionescu * * <ilg@livius.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /** diff --git a/src/target/arm_semihosting.h b/src/target/arm_semihosting.h index cf1f8de..0a912a7 100644 --- a/src/target/arm_semihosting.h +++ b/src/target/arm_semihosting.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 by Marvell Technology Group Ltd. * * Written by Nicolas Pitre <nico@marvell.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM_SEMIHOSTING_H diff --git a/src/target/arm_simulator.c b/src/target/arm_simulator.c index 480d9bc..058e3d3 100644 --- a/src/target/arm_simulator.c +++ b/src/target/arm_simulator.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2008 by Hongtao Zheng * * hontor@126.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/arm_simulator.h b/src/target/arm_simulator.h index 5bdbf56..e4a25d8 100644 --- a/src/target/arm_simulator.h +++ b/src/target/arm_simulator.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM_SIMULATOR_H diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c index fba3fec..7096db3 100644 --- a/src/target/arm_tpiu_swo.c +++ b/src/target/arm_tpiu_swo.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later /** * @file @@ -90,6 +90,7 @@ struct arm_tpiu_swo_event_action { struct arm_tpiu_swo_object { struct list_head lh; struct adiv5_mem_ap_spot spot; + struct adiv5_ap *ap; char *name; struct arm_tpiu_swo_event_action *event_action; /* record enable before init */ @@ -233,6 +234,9 @@ int arm_tpiu_swo_cleanup_all(void) ea = next; } + if (obj->ap) + dap_put_ap(obj->ap); + free(obj->name); free(obj->out_filename); free(obj); @@ -596,7 +600,6 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const struct command *c = jim_to_command(interp); struct arm_tpiu_swo_object *obj = c->jim_handler_data; struct command_context *cmd_ctx = current_command_context(interp); - struct adiv5_ap *tpiu_ap = dap_ap(obj->spot.dap, obj->spot.ap_num); uint32_t value; int retval; @@ -614,8 +617,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const if (obj->enabled) return JIM_OK; - if (transport_is_hla() && obj->spot.ap_num > 0) { - LOG_ERROR("Invalid access port %d. Only AP#0 allowed with hla transport", obj->spot.ap_num); + if (transport_is_hla() && obj->spot.ap_num != 0) { + LOG_ERROR("Invalid access port 0x%" PRIx64 ". Only AP#0 allowed with hla transport", obj->spot.ap_num); return JIM_ERR; } @@ -644,21 +647,28 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const struct cortex_m_common *cm = target_to_cm(target); obj->recheck_ap_cur_target = false; obj->spot.ap_num = cm->armv7m.debug_ap->ap_num; - tpiu_ap = dap_ap(obj->spot.dap, obj->spot.ap_num); if (obj->spot.ap_num == 0) LOG_INFO(MSG "Confirmed TPIU %s is on AP 0", obj->name); else - LOG_INFO(MSG "Target %s is on AP %d. Revised command is " - "\'tpiu create %s -dap %s -ap-num %d\'", + LOG_INFO(MSG "Target %s is on AP#0x%" PRIx64 ". Revised command is " + "\'tpiu create %s -dap %s -ap-num 0x%" PRIx64 "\'", target_name(target), obj->spot.ap_num, obj->name, adiv5_dap_name(obj->spot.dap), obj->spot.ap_num); } /* END_DEPRECATED_TPIU */ + if (!obj->ap) { + obj->ap = dap_get_ap(obj->spot.dap, obj->spot.ap_num); + if (!obj->ap) { + LOG_ERROR("Cannot get AP"); + return JIM_ERR; + } + } + /* trigger the event before any attempt to R/W in the TPIU/SWO */ arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_ENABLE); - retval = wrap_read_u32(target, tpiu_ap, obj->spot.base + TPIU_DEVID_OFFSET, &value); + retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_DEVID_OFFSET, &value); if (retval != ERROR_OK) { LOG_ERROR("Unable to read %s", obj->name); return JIM_ERR; @@ -684,7 +694,7 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const } if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_SYNC) { - retval = wrap_read_u32(target, tpiu_ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value); + retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value); if (retval != ERROR_OK) { LOG_ERROR("Cannot read TPIU register SSPSR"); return JIM_ERR; @@ -759,26 +769,26 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const obj->swo_pin_freq = swo_pin_freq; } - retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_CSPSR_OFFSET, BIT(obj->port_width - 1)); + retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_CSPSR_OFFSET, BIT(obj->port_width - 1)); if (retval != ERROR_OK) goto error_exit; - retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_ACPR_OFFSET, prescaler - 1); + retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_ACPR_OFFSET, prescaler - 1); if (retval != ERROR_OK) goto error_exit; - retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_SPPR_OFFSET, obj->pin_protocol); + retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_SPPR_OFFSET, obj->pin_protocol); if (retval != ERROR_OK) goto error_exit; - retval = wrap_read_u32(target, tpiu_ap, obj->spot.base + TPIU_FFCR_OFFSET, &value); + retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_FFCR_OFFSET, &value); if (retval != ERROR_OK) goto error_exit; if (obj->en_formatter) value |= BIT(1); else value &= ~BIT(1); - retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_FFCR_OFFSET, value); + retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_FFCR_OFFSET, value); if (retval != ERROR_OK) goto error_exit; @@ -1037,7 +1047,7 @@ COMMAND_HANDLER(handle_tpiu_deprecated_config_command) struct cortex_m_common *cm = target_to_cm(target); struct adiv5_private_config *pc = target->private_config; struct adiv5_dap *dap = pc->dap; - int ap_num = pc->ap_num; + uint64_t ap_num = pc->ap_num; bool set_recheck_ap_cur_target = false; LOG_INFO(MSG "Adding a TPIU \'%s.tpiu\' in the configuration", target_name(target)); @@ -1055,10 +1065,10 @@ COMMAND_HANDLER(handle_tpiu_deprecated_config_command) set_recheck_ap_cur_target = true; } - LOG_INFO(MSG "Running: \'tpiu create %s.tpiu -dap %s -ap-num %d\'", + LOG_INFO(MSG "Running: \'tpiu create %s.tpiu -dap %s -ap-num 0x%" PRIx64 "\'", target_name(target), adiv5_dap_name(dap), ap_num); - retval = command_run_linef(CMD_CTX, "tpiu create %s.tpiu -dap %s -ap-num %d", + retval = command_run_linef(CMD_CTX, "tpiu create %s.tpiu -dap %s -ap-num 0x%" PRIx64, target_name(target), adiv5_dap_name(dap), ap_num); if (retval != ERROR_OK) return retval; diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index b861cf5..48af503 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -10,19 +12,6 @@ * * * Copyright (C) 2018 by Liviu Ionescu * * <ilg@livius.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -546,7 +535,7 @@ static struct reg_feature arm_gdb_dummy_fp_features = { * Modern ARM cores use Vector Floating Point (VFP), if they * have any floating point support. VFP is not FPA-compatible. */ -struct reg arm_gdb_dummy_fp_reg = { +static struct reg arm_gdb_dummy_fp_reg = { .name = "GDB dummy FPA register", .value = (uint8_t *) arm_gdb_dummy_fp_value, .valid = true, @@ -563,7 +552,7 @@ static const uint8_t arm_gdb_dummy_fps_value[4]; * Dummy FPA status registers are required to support GDB on ARM. * Register packets require an obsolete FPA status register. */ -struct reg arm_gdb_dummy_fps_reg = { +static struct reg arm_gdb_dummy_fps_reg = { .name = "GDB dummy FPA status register", .value = (uint8_t *) arm_gdb_dummy_fps_value, .valid = true, @@ -916,32 +905,33 @@ COMMAND_HANDLER(handle_armv4_5_reg_command) return ERROR_OK; } -COMMAND_HANDLER(handle_armv4_5_core_state_command) +COMMAND_HANDLER(handle_arm_core_state_command) { struct target *target = get_current_target(CMD_CTX); struct arm *arm = target_to_arm(target); + int ret = ERROR_OK; if (!is_arm(arm)) { command_print(CMD, "current target isn't an ARM"); return ERROR_FAIL; } - if (arm->core_type == ARM_CORE_TYPE_M_PROFILE) { - /* armv7m not supported */ - command_print(CMD, "Unsupported Command"); - return ERROR_OK; - } - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "arm") == 0) - arm->core_state = ARM_STATE_ARM; + if (strcmp(CMD_ARGV[0], "arm") == 0) { + if (arm->core_type == ARM_CORE_TYPE_M_PROFILE) { + command_print(CMD, "arm mode not supported on Cortex-M"); + ret = ERROR_FAIL; + } else { + arm->core_state = ARM_STATE_ARM; + } + } if (strcmp(CMD_ARGV[0], "thumb") == 0) arm->core_state = ARM_STATE_THUMB; } command_print(CMD, "core state: %s", arm_state_strings[arm->core_state]); - return ERROR_OK; + return ret; } COMMAND_HANDLER(handle_arm_disassemble_command) @@ -1127,8 +1117,6 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) return JIM_OK; } -extern const struct command_registration semihosting_common_handlers[]; - static const struct command_registration arm_exec_command_handlers[] = { { .name = "reg", @@ -1138,20 +1126,6 @@ static const struct command_registration arm_exec_command_handlers[] = { .usage = "", }, { - .name = "core_state", - .handler = handle_armv4_5_core_state_command, - .mode = COMMAND_EXEC, - .usage = "['arm'|'thumb']", - .help = "display/change ARM core state", - }, - { - .name = "disassemble", - .handler = handle_arm_disassemble_command, - .mode = COMMAND_EXEC, - .usage = "address [count ['thumb']]", - .help = "disassemble instructions", - }, - { .name = "mcr", .mode = COMMAND_EXEC, .jim_handler = &jim_mcrmrc, @@ -1166,10 +1140,32 @@ static const struct command_registration arm_exec_command_handlers[] = { .usage = "cpnum op1 CRn CRm op2", }, { + .chain = arm_all_profiles_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; + +const struct command_registration arm_all_profiles_command_handlers[] = { + { + .name = "core_state", + .handler = handle_arm_core_state_command, + .mode = COMMAND_EXEC, + .usage = "['arm'|'thumb']", + .help = "display/change ARM core state", + }, + { + .name = "disassemble", + .handler = handle_arm_disassemble_command, + .mode = COMMAND_EXEC, + .usage = "address [count ['thumb']]", + .help = "disassemble instructions", + }, + { .chain = semihosting_common_handlers, }, COMMAND_REGISTRATION_DONE }; + const struct command_registration arm_command_handlers[] = { { .name = "arm", diff --git a/src/target/armv4_5.h b/src/target/armv4_5.h index bef1cfe..250fa82 100644 --- a/src/target/armv4_5.h +++ b/src/target/armv4_5.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2009 by Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARMV4_5_H diff --git a/src/target/armv4_5_cache.c b/src/target/armv4_5_cache.c index eda8cb7..e12c43d 100644 --- a/src/target/armv4_5_cache.c +++ b/src/target/armv4_5_cache.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/armv4_5_cache.h b/src/target/armv4_5_cache.h index 985a3a7..3659941 100644 --- a/src/target/armv4_5_cache.h +++ b/src/target/armv4_5_cache.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARMV4_5_CACHE_H diff --git a/src/target/armv4_5_mmu.c b/src/target/armv4_5_mmu.c index 115a489..9942f49 100644 --- a/src/target/armv4_5_mmu.c +++ b/src/target/armv4_5_mmu.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/armv4_5_mmu.h b/src/target/armv4_5_mmu.h index 7beaf4e..774f105 100644 --- a/src/target/armv4_5_mmu.h +++ b/src/target/armv4_5_mmu.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARMV4_5_MMU_H diff --git a/src/target/armv7a.c b/src/target/armv7a.c index 1e425aa..82f4be5 100644 --- a/src/target/armv7a.c +++ b/src/target/armv7a.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by David Brownell * * * * Copyright (C) ST-Ericsson SA 2011 michel.jaouen@stericsson.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/armv7a.h b/src/target/armv7a.h index c282554..6b9c2a6 100644 --- a/src/target/armv7a.h +++ b/src/target/armv7a.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 by David Brownell * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARMV7A_H @@ -30,7 +19,7 @@ enum { ARM_CPSR = 16 }; -#define ARMV7_COMMON_MAGIC 0x0A450999 +#define ARMV7_COMMON_MAGIC 0x0A450999U /* VA to PA translation operations opc2 values*/ #define V2PCWPR 0 @@ -98,8 +87,9 @@ struct armv7a_mmu_common { }; struct armv7a_common { + unsigned int common_magic; + struct arm arm; - int common_magic; struct reg_cache *core_cache; /* Core Debug Unit */ diff --git a/src/target/armv7a_cache.c b/src/target/armv7a_cache.c index ba6f076..995a856 100644 --- a/src/target/armv7a_cache.c +++ b/src/target/armv7a_cache.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 by Oleksij Rempel * * linux@rempel-privat.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/armv7a_cache.h b/src/target/armv7a_cache.h index 8d8ca2d..17ec5e6 100644 --- a/src/target/armv7a_cache.h +++ b/src/target/armv7a_cache.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2015 Oleksij Rempel * * linux@rempel-privat.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM7A_CACHE_H diff --git a/src/target/armv7a_cache_l2x.c b/src/target/armv7a_cache_l2x.c index c26d051..39c503f 100644 --- a/src/target/armv7a_cache_l2x.c +++ b/src/target/armv7a_cache_l2x.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 by Oleksij Rempel * * linux@rempel-privat.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/armv7a_cache_l2x.h b/src/target/armv7a_cache_l2x.h index f98b554..d5f1a6f 100644 --- a/src/target/armv7a_cache_l2x.h +++ b/src/target/armv7a_cache_l2x.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2015 Oleksij Rempel * * linux@rempel-privat.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARM7A_CACHE_L2X_H diff --git a/src/target/armv7a_mmu.c b/src/target/armv7a_mmu.c index 98a0065..c4d294e 100644 --- a/src/target/armv7a_mmu.c +++ b/src/target/armv7a_mmu.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2016 by Matthias Welwarsky * * matthias.welwarsky@sysgo.com * * * * Copyright (C) ST-Ericsson SA 2011 michel.jaouen@stericsson.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/armv7a_mmu.h b/src/target/armv7a_mmu.h index 36cd9d1..d93d3c6 100644 --- a/src/target/armv7a_mmu.h +++ b/src/target/armv7a_mmu.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2016 by Matthias Welwarsky * * matthias.welwarsky@sysgo.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARMV7A_MMU_H diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 0a51ad4..2db2ce2 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -17,19 +19,6 @@ * Copyright (C) 2019 by Tomas Vanek * * vanekt@fbl.cz * * * - * 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, see <http://www.gnu.org/licenses/>. * - * * * ARMv7-M Architecture, Application Level Reference Manual * * ARM DDI 0405C (September 2008) * * * @@ -64,7 +53,7 @@ const int armv7m_psp_reg_map[ARMV7M_NUM_CORE_REGS] = { ARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7, ARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11, ARMV7M_R12, ARMV7M_PSP, ARMV7M_R14, ARMV7M_PC, - ARMV7M_xPSR, + ARMV7M_XPSR, }; /* MSP is used in handler and some thread modes */ @@ -73,7 +62,7 @@ const int armv7m_msp_reg_map[ARMV7M_NUM_CORE_REGS] = { ARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7, ARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11, ARMV7M_R12, ARMV7M_MSP, ARMV7M_R14, ARMV7M_PC, - ARMV7M_xPSR, + ARMV7M_XPSR, }; /* @@ -108,7 +97,7 @@ static const struct { { ARMV7M_R13, "sp", 32, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.arm.m-profile" }, { ARMV7M_R14, "lr", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, { ARMV7M_PC, "pc", 32, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_xPSR, "xPSR", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_XPSR, "xPSR", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, { ARMV7M_MSP, "msp", 32, REG_TYPE_DATA_PTR, "system", "org.gnu.gdb.arm.m-system" }, { ARMV7M_PSP, "psp", 32, REG_TYPE_DATA_PTR, "system", "org.gnu.gdb.arm.m-system" }, @@ -256,7 +245,7 @@ uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id) switch (arm_reg_id) { case ARMV7M_R0 ... ARMV7M_R14: case ARMV7M_PC: - case ARMV7M_xPSR: + case ARMV7M_XPSR: case ARMV7M_MSP: case ARMV7M_PSP: /* NOTE: we "know" here that the register identifiers @@ -590,7 +579,7 @@ int armv7m_start_algorithm(struct target *target, * Because xPSR.T is populated on reset from the vector table, * it might be 0 if the vector table has "bad" data in it. */ - struct reg *reg = &armv7m->arm.core_cache->reg_list[ARMV7M_xPSR]; + struct reg *reg = &armv7m->arm.core_cache->reg_list[ARMV7M_XPSR]; buf_set_u32(reg->value, 0, 32, 0x01000000); reg->valid = true; reg->dirty = true; @@ -814,7 +803,7 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target) LOG_ERROR("unable to allocate reg type list"); } - arm->cpsr = reg_list + ARMV7M_xPSR; + arm->cpsr = reg_list + ARMV7M_XPSR; arm->pc = reg_list + ARMV7M_PC; arm->core_cache = cache; @@ -865,6 +854,7 @@ int armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m) /* Enable stimulus port #0 by default */ armv7m->trace_config.itm_ter[0] = 1; + arm->core_state = ARM_STATE_THUMB; arm->core_type = ARM_CORE_TYPE_M_PROFILE; arm->arch_info = armv7m; arm->setup_semihosting = armv7m_setup_semihosting; @@ -1095,7 +1085,11 @@ int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found) const struct command_registration armv7m_command_handlers[] = { { - .chain = arm_command_handlers, + .name = "arm", + .mode = COMMAND_ANY, + .help = "ARM command group", + .usage = "", + .chain = arm_all_profiles_command_handlers, }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/armv7m.h b/src/target/armv7m.h index 9ac121a..188bd56 100644 --- a/src/target/armv7m.h +++ b/src/target/armv7m.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARMV7M_H @@ -57,7 +46,7 @@ enum { ARMV7M_REGSEL_R14, ARMV7M_REGSEL_PC = 15, - ARMV7M_REGSEL_xPSR = 16, + ARMV7M_REGSEL_XPSR = 16, ARMV7M_REGSEL_MSP, ARMV7M_REGSEL_PSP, @@ -135,7 +124,7 @@ enum { ARMV7M_R14 = ARMV7M_REGSEL_R14, ARMV7M_PC = ARMV7M_REGSEL_PC, - ARMV7M_xPSR = ARMV7M_REGSEL_xPSR, + ARMV7M_XPSR = ARMV7M_REGSEL_XPSR, ARMV7M_MSP = ARMV7M_REGSEL_MSP, ARMV7M_PSP = ARMV7M_REGSEL_PSP, @@ -210,7 +199,7 @@ enum { /* for convenience add registers' block delimiters */ ARMV7M_LAST_REG, ARMV7M_CORE_FIRST_REG = ARMV7M_R0, - ARMV7M_CORE_LAST_REG = ARMV7M_xPSR, + ARMV7M_CORE_LAST_REG = ARMV7M_XPSR, ARMV7M_FPU_FIRST_REG = ARMV7M_D0, ARMV7M_FPU_LAST_REG = ARMV7M_FPSCR, ARMV8M_FIRST_REG = ARMV8M_MSP_NS, @@ -226,12 +215,13 @@ enum { #define ARMV7M_NUM_CORE_REGS (ARMV7M_CORE_LAST_REG - ARMV7M_CORE_FIRST_REG + 1) -#define ARMV7M_COMMON_MAGIC 0x2A452A45 +#define ARMV7M_COMMON_MAGIC 0x2A452A45U struct armv7m_common { + unsigned int common_magic; + struct arm arm; - int common_magic; int exception_number; /* AP this processor is connected to in the DAP */ @@ -300,7 +290,7 @@ target_to_armv7m_safe(struct target *target) } struct armv7m_algorithm { - int common_magic; + unsigned int common_magic; enum arm_mode core_mode; diff --git a/src/target/armv7m_trace.c b/src/target/armv7m_trace.c index 74ffaf5..45117d2 100644 --- a/src/target/armv7m_trace.c +++ b/src/target/armv7m_trace.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 Paul Fertser <fercerpav@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/armv7m_trace.h b/src/target/armv7m_trace.h index 7e4977a..5abb0b9 100644 --- a/src/target/armv7m_trace.h +++ b/src/target/armv7m_trace.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2015 Paul Fertser <fercerpav@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARMV7M_TRACE_H diff --git a/src/target/armv8.c b/src/target/armv8.c index 2de1157..de0bddb 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -1,22 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2015 by David Ung * * * * Copyright (C) 2018 by Liviu Ionescu * * <ilg@livius.net> * - * * - * 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., * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -146,7 +134,7 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv retval = dpm->instr_read_data_r0_64(dpm, ARMV8_MRS_DLR(0), &value_64); break; - case ARMV8_xPSR: + case ARMV8_XPSR: retval = dpm->instr_read_data_r0(dpm, ARMV8_MRS_DSPSR(0), &value); value_64 = value; @@ -261,7 +249,7 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu ARMV8_MSR_DLR(0), value_64); break; - case ARMV8_xPSR: + case ARMV8_XPSR: value = value_64; retval = dpm->instr_write_data_r0(dpm, ARMV8_MSR_DSPSR(0), @@ -376,7 +364,7 @@ static int armv8_read_reg32(struct armv8_common *armv8, int regnum, uint64_t *re ARMV8_MRC_DLR(0), &value); break; - case ARMV8_xPSR: + case ARMV8_XPSR: retval = dpm->instr_read_data_r0(dpm, ARMV8_MRC_DSPSR(0), &value); @@ -411,17 +399,17 @@ static int armv8_read_reg32(struct armv8_common *armv8, int regnum, uint64_t *re break; case ARMV8_SPSR_EL1: /* mapped to SPSR_svc */ retval = dpm->instr_read_data_r0(dpm, - ARMV8_MRS_xPSR_T1(1, 0), + ARMV8_MRS_XPSR_T1(1, 0), &value); break; case ARMV8_SPSR_EL2: /* mapped to SPSR_hyp */ retval = dpm->instr_read_data_r0(dpm, - ARMV8_MRS_xPSR_T1(1, 0), + ARMV8_MRS_XPSR_T1(1, 0), &value); break; case ARMV8_SPSR_EL3: /* mapped to SPSR_mon */ retval = dpm->instr_read_data_r0(dpm, - ARMV8_MRS_xPSR_T1(1, 0), + ARMV8_MRS_XPSR_T1(1, 0), &value); break; case ARMV8_FPSR: @@ -512,7 +500,7 @@ static int armv8_write_reg32(struct armv8_common *armv8, int regnum, uint64_t va retval = dpm->instr_write_data_r0(dpm, ARMV8_MCR_DLR(0), value); break; - case ARMV8_xPSR: /* CPSR */ + case ARMV8_XPSR: /* CPSR */ /* read r0 from DCC, then "MCR r0, DSPSR" */ retval = dpm->instr_write_data_r0(dpm, ARMV8_MCR_DSPSR(0), value); @@ -547,17 +535,17 @@ static int armv8_write_reg32(struct armv8_common *armv8, int regnum, uint64_t va break; case ARMV8_SPSR_EL1: /* mapped to SPSR_svc */ retval = dpm->instr_write_data_r0(dpm, - ARMV8_MSR_GP_xPSR_T1(1, 0, 15), + ARMV8_MSR_GP_XPSR_T1(1, 0, 15), value); break; case ARMV8_SPSR_EL2: /* mapped to SPSR_hyp */ retval = dpm->instr_write_data_r0(dpm, - ARMV8_MSR_GP_xPSR_T1(1, 0, 15), + ARMV8_MSR_GP_XPSR_T1(1, 0, 15), value); break; case ARMV8_SPSR_EL3: /* mapped to SPSR_mon */ retval = dpm->instr_write_data_r0(dpm, - ARMV8_MSR_GP_xPSR_T1(1, 0, 15), + ARMV8_MSR_GP_XPSR_T1(1, 0, 15), value); break; case ARMV8_FPSR: @@ -1376,7 +1364,7 @@ static const struct { { ARMV8_SP, "sp", 64, ARM_MODE_ANY, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.aarch64.core", NULL}, { ARMV8_PC, "pc", 64, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.aarch64.core", NULL}, - { ARMV8_xPSR, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, + { ARMV8_XPSR, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "general", "org.gnu.gdb.aarch64.core", aarch64_flags_cpsr}, { ARMV8_V0, "v0", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v}, { ARMV8_V1, "v1", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v}, @@ -1461,7 +1449,7 @@ static const struct { { ARMV8_R13, 0, "sp", 32, ARM_MODE_ANY, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.arm.core" }, { ARMV8_R14, 0, "lr", 32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.core" }, { ARMV8_PC, 0, "pc", 32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.core" }, - { ARMV8_xPSR, 0, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" }, + { ARMV8_XPSR, 0, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" }, { ARMV8_V0, 0, "d0", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"}, { ARMV8_V0, 8, "d1", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"}, { ARMV8_V1, 0, "d2", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"}, @@ -1664,7 +1652,7 @@ struct reg_cache *armv8_build_reg_cache(struct target *target) LOG_ERROR("unable to allocate reg type list"); } - arm->cpsr = reg_list + ARMV8_xPSR; + arm->cpsr = reg_list + ARMV8_XPSR; arm->pc = reg_list + ARMV8_PC; arm->core_cache = cache; diff --git a/src/target/armv8.h b/src/target/armv8.h index c30739c..2ed3a65 100644 --- a/src/target/armv8.h +++ b/src/target/armv8.h @@ -1,19 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2015 by David Ung * - * * - * 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., * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARMV8_H @@ -61,7 +49,7 @@ enum { ARMV8_SP = 31, ARMV8_PC = 32, - ARMV8_xPSR = 33, + ARMV8_XPSR = 33, ARMV8_V0 = 34, ARMV8_V1, @@ -120,7 +108,7 @@ enum run_control_op { ARMV8_RUNCONTROL_STEP = 3, }; -#define ARMV8_COMMON_MAGIC 0x0A450AAA +#define ARMV8_COMMON_MAGIC 0x0A450AAAU /* VA to PA translation operations opc2 values*/ #define V2PCWPR 0 @@ -190,8 +178,9 @@ struct armv8_mmu_common { }; struct armv8_common { + unsigned int common_magic; + struct arm arm; - int common_magic; struct reg_cache *core_cache; /* Core Debug Unit */ diff --git a/src/target/armv8_cache.c b/src/target/armv8_cache.c index 5b58d3f..cf71119 100644 --- a/src/target/armv8_cache.c +++ b/src/target/armv8_cache.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2016 by Matthias Welwarsky * * matthias.welwarsky@sysgo.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/armv8_cache.h b/src/target/armv8_cache.h index fa46e16..7a12aa1 100644 --- a/src/target/armv8_cache.h +++ b/src/target/armv8_cache.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2016 by Matthias Welwarsky * * matthias.welwarsky@sysgo.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ARMV8_CACHE_H_ #define OPENOCD_TARGET_ARMV8_CACHE_H_ diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c index 765f1b7..f40beb8 100644 --- a/src/target/armv8_dpm.c +++ b/src/target/armv8_dpm.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright (C) 2009 by David Brownell - * - * 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. - * */ #ifdef HAVE_CONFIG_H @@ -610,7 +601,7 @@ int armv8_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode) /* load SPSR with the desired mode and execute DRPS */ LOG_DEBUG("SPSR = 0x%08"PRIx32, cpsr); retval = dpm->instr_write_data_r0(dpm, - ARMV8_MSR_GP_xPSR_T1(1, 0, 15), cpsr); + ARMV8_MSR_GP_XPSR_T1(1, 0, 15), cpsr); if (retval == ERROR_OK) retval = dpm->instr_execute(dpm, armv8_opcode(armv8, ARMV8_OPC_DRPS)); } @@ -926,7 +917,7 @@ int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp) if (!cache->reg_list[i].exist) continue; /* skip PC and CPSR */ - if (i == ARMV8_PC || i == ARMV8_xPSR) + if (i == ARMV8_PC || i == ARMV8_XPSR) continue; /* skip invalid */ if (!cache->reg_list[i].valid) @@ -948,7 +939,7 @@ int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp) /* flush CPSR and PC */ if (retval == ERROR_OK) - retval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_xPSR], ARMV8_xPSR); + retval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_XPSR], ARMV8_XPSR); if (retval == ERROR_OK) retval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_PC], ARMV8_PC); /* flush R0 -- it's *very* dirty by now */ @@ -1302,9 +1293,9 @@ void armv8_dpm_handle_exception(struct arm_dpm *dpm, bool do_restore) unsigned int el; static const int clobbered_regs_by_el[3][5] = { - { ARMV8_PC, ARMV8_xPSR, ARMV8_ELR_EL1, ARMV8_ESR_EL1, ARMV8_SPSR_EL1 }, - { ARMV8_PC, ARMV8_xPSR, ARMV8_ELR_EL2, ARMV8_ESR_EL2, ARMV8_SPSR_EL2 }, - { ARMV8_PC, ARMV8_xPSR, ARMV8_ELR_EL3, ARMV8_ESR_EL3, ARMV8_SPSR_EL3 }, + { ARMV8_PC, ARMV8_XPSR, ARMV8_ELR_EL1, ARMV8_ESR_EL1, ARMV8_SPSR_EL1 }, + { ARMV8_PC, ARMV8_XPSR, ARMV8_ELR_EL2, ARMV8_ESR_EL2, ARMV8_SPSR_EL2 }, + { ARMV8_PC, ARMV8_XPSR, ARMV8_ELR_EL3, ARMV8_ESR_EL3, ARMV8_SPSR_EL3 }, }; el = (dpm->dscr >> 8) & 3; @@ -1319,7 +1310,7 @@ void armv8_dpm_handle_exception(struct arm_dpm *dpm, bool do_restore) mem_ap_write_u32(armv8->debug_ap, armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE); - armv8->read_reg_u64(armv8, ARMV8_xPSR, &dlr); + armv8->read_reg_u64(armv8, ARMV8_XPSR, &dlr); dspsr = dlr; armv8->read_reg_u64(armv8, ARMV8_PC, &dlr); diff --git a/src/target/armv8_dpm.h b/src/target/armv8_dpm.h index c30b04f..19b33da 100644 --- a/src/target/armv8_dpm.h +++ b/src/target/armv8_dpm.h @@ -1,15 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * Copyright (C) 2009 by David Brownell - * - * 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. */ #ifndef OPENOCD_TARGET_ARMV8_DPM_H diff --git a/src/target/armv8_opcodes.c b/src/target/armv8_opcodes.c index 96db728..7afcc52 100644 --- a/src/target/armv8_opcodes.c +++ b/src/target/armv8_opcodes.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright (C) 2015 by Matthias Welwarsky <matthias.welwarsky@sysgo.com> - * - * 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. - * */ #ifdef HAVE_CONFIG_H diff --git a/src/target/armv8_opcodes.h b/src/target/armv8_opcodes.h index 8c213ef..8c9652b 100644 --- a/src/target/armv8_opcodes.h +++ b/src/target/armv8_opcodes.h @@ -1,17 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* - * Copyright (C) 2015 by pierrr kuo - * vichy.kuo@gmail.com - * 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. - * + * Copyright (C) 2015 by pierrr kuo <vichy.kuo@gmail.com> */ + #ifndef OPENOCD_TARGET_ARMV8_OPCODES_H #define OPENOCD_TARGET_ARMV8_OPCODES_H @@ -146,9 +138,9 @@ (0xd500401f | ((op1) << 16) | ((crm) << 8) | ((op2) << 5)) #define ARMV8_MRS_T1(r, m1, rd, m) (0xF3E08020 | (r << 20) | (m1 << 16) | (rd << 8) | (m << 4)) -#define ARMV8_MRS_xPSR_T1(r, rd) (0xF3EF8000 | (r << 20) | (rd << 8)) +#define ARMV8_MRS_XPSR_T1(r, rd) (0xF3EF8000 | (r << 20) | (rd << 8)) #define ARMV8_MSR_GP_T1(r, m1, rd, m) (0xF3808020 | (r << 20) | (m1 << 8) | (rd << 16) | (m << 4)) -#define ARMV8_MSR_GP_xPSR_T1(r, rn, mask) (0xF3808000 | (r << 20) | (rn << 16) | (mask << 8)) +#define ARMV8_MSR_GP_XPSR_T1(r, rn, mask) (0xF3808000 | (r << 20) | (rn << 16) | (mask << 8)) #define ARMV8_BKPT(im) (0xD4200000 | ((im & 0xffff) << 5)) #define ARMV8_HLT(im) (0x0D4400000 | ((im & 0xffff) << 5)) diff --git a/src/target/avr32_ap7k.c b/src/target/avr32_ap7k.c index 4cf0276..bf1445b 100644 --- a/src/target/avr32_ap7k.c +++ b/src/target/avr32_ap7k.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> * * Based on mips_m4k code: * * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> * * Copyright (C) 2008 by David T.L. Wong * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/avr32_ap7k.h b/src/target/avr32_ap7k.h index 65b856e..ac35754 100644 --- a/src/target/avr32_ap7k.h +++ b/src/target/avr32_ap7k.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_AVR32_AP7K_H @@ -20,9 +9,11 @@ struct target; -#define AP7K_COMMON_MAGIC 0x4150374b +#define AP7K_COMMON_MAGIC 0x4150374bU + struct avr32_ap7k_common { - int common_magic; + unsigned int common_magic; + struct avr32_jtag jtag; struct reg_cache *core_cache; uint32_t core_regs[AVR32NUMCOREREGS]; diff --git a/src/target/avr32_jtag.c b/src/target/avr32_jtag.c index a23ddf7..a9c4f8d 100644 --- a/src/target/avr32_jtag.c +++ b/src/target/avr32_jtag.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/avr32_jtag.h b/src/target/avr32_jtag.h index b431ef4..382b245 100644 --- a/src/target/avr32_jtag.h +++ b/src/target/avr32_jtag.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_AVR32_JTAG_H diff --git a/src/target/avr32_mem.c b/src/target/avr32_mem.c index 8f38a18..835a501 100644 --- a/src/target/avr32_mem.c +++ b/src/target/avr32_mem.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/avr32_mem.h b/src/target/avr32_mem.h index f60a121..4a8019a 100644 --- a/src/target/avr32_mem.h +++ b/src/target/avr32_mem.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_AVR32_MEM_H diff --git a/src/target/avr32_regs.c b/src/target/avr32_regs.c index 7273822..d6fd0e0 100644 --- a/src/target/avr32_regs.c +++ b/src/target/avr32_regs.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/avr32_regs.h b/src/target/avr32_regs.h index cb492a9..9004657 100644 --- a/src/target/avr32_regs.h +++ b/src/target/avr32_regs.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_AVR32_REGS_H diff --git a/src/target/avrt.c b/src/target/avrt.c index feceec6..61bef32 100644 --- a/src/target/avrt.c +++ b/src/target/avrt.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by Simon Qian * * SimonQian@SimonQian.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/avrt.h b/src/target/avrt.h index 3610eb5..615cb8a 100644 --- a/src/target/avrt.h +++ b/src/target/avrt.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 by Simon Qian * * SimonQian@SimonQian.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_AVRT_H diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c index 1055ed9..7bdb2a6 100644 --- a/src/target/breakpoints.c +++ b/src/target/breakpoints.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) ST-Ericsson SA 2011 * * michel.jaouen@stericsson.com : smp minimum support * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -404,7 +393,7 @@ struct breakpoint *breakpoint_find(struct target *target, target_addr_t address) return NULL; } -int watchpoint_add_internal(struct target *target, target_addr_t address, +static int watchpoint_add_internal(struct target *target, target_addr_t address, uint32_t length, enum watchpoint_rw rw, uint32_t value, uint32_t mask) { struct watchpoint *watchpoint = target->watchpoints; @@ -514,7 +503,7 @@ static void watchpoint_free(struct target *target, struct watchpoint *watchpoint free(watchpoint); } -int watchpoint_remove_internal(struct target *target, target_addr_t address) +static int watchpoint_remove_internal(struct target *target, target_addr_t address) { struct watchpoint *watchpoint = target->watchpoints; diff --git a/src/target/breakpoints.h b/src/target/breakpoints.h index fc5b50b..8a3fbb2 100644 --- a/src/target/breakpoints.h +++ b/src/target/breakpoints.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_BREAKPOINTS_H diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 20b2e51..7286a30 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -26,19 +28,6 @@ * Copyright (C) 2016 Chengyu Zheng * * chengyu.zheng@polimi.it : watchpoint support * * * - * 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, see <http://www.gnu.org/licenses/>. * - * * * Cortex-A8(tm) TRM, ARM DDI 0344H * * Cortex-A9(tm) TRM, ARM DDI 0407F * * Cortex-A4(tm) TRM, ARM DDI 0363E * @@ -818,11 +807,11 @@ static int cortex_a_internal_restore(struct target *target, int current, armv7m->core_cache->reg_list[ARMV7M_PRIMASK].valid = true; /* Make sure we are in Thumb mode */ - buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32, - buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, + buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_XPSR].value, 0, 32, + buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_XPSR].value, 0, 32) | (1 << 24)); - armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = true; - armv7m->core_cache->reg_list[ARMV7M_xPSR].valid = true; + armv7m->core_cache->reg_list[ARMV7M_XPSR].dirty = true; + armv7m->core_cache->reg_list[ARMV7M_XPSR].valid = true; } #endif @@ -2885,15 +2874,24 @@ static int cortex_a_examine_first(struct target *target) int retval = ERROR_OK; uint32_t didr, cpuid, dbg_osreg, dbg_idpfr1; + if (armv7a->debug_ap) { + dap_put_ap(armv7a->debug_ap); + armv7a->debug_ap = NULL; + } + if (pc->ap_num == DP_APSEL_INVALID) { /* Search for the APB-AP - it is needed for access to debug registers */ - retval = dap_find_ap(swjdp, AP_TYPE_APB_AP, &armv7a->debug_ap); + retval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &armv7a->debug_ap); if (retval != ERROR_OK) { LOG_ERROR("Could not find APB-AP for debug access"); return retval; } } else { - armv7a->debug_ap = dap_ap(swjdp, pc->ap_num); + armv7a->debug_ap = dap_get_ap(swjdp, pc->ap_num); + if (!armv7a->debug_ap) { + LOG_ERROR("Cannot get AP"); + return ERROR_FAIL; + } } retval = mem_ap_init(armv7a->debug_ap); @@ -3172,6 +3170,9 @@ static void cortex_a_deinit_target(struct target *target) dscr & ~DSCR_HALT_DBG_MODE); } + if (armv7a->debug_ap) + dap_put_ap(armv7a->debug_ap); + free(cortex_a->wrp_list); free(cortex_a->brp_list); arm_free_reg_cache(dpm->arm); diff --git a/src/target/cortex_a.h b/src/target/cortex_a.h index 685621c..37fba1a 100644 --- a/src/target/cortex_a.h +++ b/src/target/cortex_a.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -10,19 +12,6 @@ * * * Copyright (C) 2009 by Dirk Behme * * dirk.behme@gmail.com - copy from cortex_m3 * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_CORTEX_A_H @@ -30,8 +19,7 @@ #include "armv7a.h" -#define CORTEX_A_COMMON_MAGIC 0x411fc082 -#define CORTEX_A15_COMMON_MAGIC 0x413fc0f1 +#define CORTEX_A_COMMON_MAGIC 0x411fc082U #define CORTEX_A5_PARTNUM 0xc05 #define CORTEX_A7_PARTNUM 0xc07 @@ -79,7 +67,9 @@ struct cortex_a_wrp { }; struct cortex_a_common { - int common_magic; + unsigned int common_magic; + + struct armv7a_common armv7a_common; /* Context information */ uint32_t cpudbg_dscr; @@ -108,9 +98,6 @@ struct cortex_a_common { enum cortex_a_isrmasking_mode isrmasking_mode; enum cortex_a_dacrfixup_mode dacrfixup_mode; - - struct armv7a_common armv7a_common; - }; static inline struct cortex_a_common * diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 344cfcf..23d9065 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -8,19 +10,6 @@ * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * * * - * 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, see <http://www.gnu.org/licenses/>. * - * * * * * Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) * * * @@ -114,6 +103,12 @@ static const struct cortex_m_part_info cortex_m_parts[] = { .arch = ARM_ARCH_V8M, .flags = CORTEX_M_F_HAS_FPV5, }, + { + .partno = STAR_MC1_PARTNO, + .name = "STAR-MC1", + .arch = ARM_ARCH_V8M, + .flags = CORTEX_M_F_HAS_FPV5, + }, }; /* forward declarations */ @@ -663,6 +658,11 @@ static int cortex_m_endreset_event(struct target *target) register_cache_invalidate(armv7m->arm.core_cache); + /* TODO: invalidate also working areas (needed in the case of detected reset). + * Doing so will require flash drivers to test if working area + * is still valid in all target algo calling loops. + */ + /* make sure we have latest dhcsr flags */ retval = cortex_m_read_dhcsr_atomic_sticky(target); if (retval != ERROR_OK) @@ -775,7 +775,7 @@ static int cortex_m_examine_exception_reason(struct target *target) static int cortex_m_debug_entry(struct target *target) { - uint32_t xPSR; + uint32_t xpsr; int retval; struct cortex_m_common *cortex_m = target_to_cm(target); struct armv7m_common *armv7m = &cortex_m->armv7m; @@ -826,11 +826,11 @@ static int cortex_m_debug_entry(struct target *target) return retval; r = arm->cpsr; - xPSR = buf_get_u32(r->value, 0, 32); + xpsr = buf_get_u32(r->value, 0, 32); /* Are we in an exception handler */ - if (xPSR & 0x1FF) { - armv7m->exception_number = (xPSR & 0x1FF); + if (xpsr & 0x1FF) { + armv7m->exception_number = (xpsr & 0x1FF); arm->core_mode = ARM_MODE_HANDLER; arm->map = armv7m_msp_reg_map; @@ -879,6 +879,16 @@ static int cortex_m_poll(struct target *target) struct cortex_m_common *cortex_m = target_to_cm(target); struct armv7m_common *armv7m = &cortex_m->armv7m; + /* Check if debug_ap is available to prevent segmentation fault. + * If the re-examination after an error does not find a MEM-AP + * (e.g. the target stopped communicating), debug_ap pointer + * can suddenly become NULL. + */ + if (!armv7m->debug_ap) { + target->state = TARGET_UNKNOWN; + return ERROR_TARGET_NOT_EXAMINED; + } + /* Read from Debug Halting Control and Status Register */ retval = cortex_m_read_dhcsr_atomic_sticky(target); if (retval != ERROR_OK) { @@ -1904,7 +1914,7 @@ int cortex_m_remove_watchpoint(struct target *target, struct watchpoint *watchpo return ERROR_OK; } -int cortex_m_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint) +static int cortex_m_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint) { if (target->debug_reason != DBG_REASON_WATCHPOINT) return ERROR_FAIL; @@ -1984,6 +1994,10 @@ static int cortex_m_init_target(struct command_context *cmd_ctx, void cortex_m_deinit_target(struct target *target) { struct cortex_m_common *cortex_m = target_to_cm(target); + struct armv7m_common *armv7m = target_to_armv7m(target); + + if (!armv7m->is_hla_target && armv7m->debug_ap) + dap_put_ap(armv7m->debug_ap); free(cortex_m->fp_comparator_list); @@ -2262,10 +2276,10 @@ static void cortex_m_dwt_free(struct target *target) static int cortex_m_find_mem_ap(struct adiv5_dap *swjdp, struct adiv5_ap **debug_ap) { - if (dap_find_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK) + if (dap_find_get_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK) return ERROR_OK; - return dap_find_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap); + return dap_find_get_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap); } int cortex_m_examine(struct target *target) @@ -2279,6 +2293,11 @@ int cortex_m_examine(struct target *target) /* hla_target shares the examine handler but does not support * all its calls */ if (!armv7m->is_hla_target) { + if (armv7m->debug_ap) { + dap_put_ap(armv7m->debug_ap); + armv7m->debug_ap = NULL; + } + if (cortex_m->apsel == DP_APSEL_INVALID) { /* Search for the MEM-AP */ retval = cortex_m_find_mem_ap(swjdp, &armv7m->debug_ap); @@ -2287,7 +2306,11 @@ int cortex_m_examine(struct target *target) return retval; } } else { - armv7m->debug_ap = dap_ap(swjdp, cortex_m->apsel); + armv7m->debug_ap = dap_get_ap(swjdp, cortex_m->apsel); + if (!armv7m->debug_ap) { + LOG_ERROR("Cannot get AP"); + return ERROR_FAIL; + } } armv7m->debug_ap->memaccess_tck = 8; @@ -2384,6 +2407,20 @@ int cortex_m_examine(struct target *target) retval = target_read_u32(target, DCB_DHCSR, &cortex_m->dcb_dhcsr); if (retval != ERROR_OK) return retval; + + /* Don't cumulate sticky S_RESET_ST at the very first read of DHCSR + * as S_RESET_ST may indicate a reset that happened long time ago + * (most probably the power-on reset before OpenOCD was started). + * As we are just initializing the debug system we do not need + * to call cortex_m_endreset_event() in the following poll. + */ + if (!cortex_m->dcb_dhcsr_sticky_is_recent) { + cortex_m->dcb_dhcsr_sticky_is_recent = true; + if (cortex_m->dcb_dhcsr & S_RESET_ST) { + LOG_TARGET_DEBUG(target, "reset happened some time ago, ignore"); + cortex_m->dcb_dhcsr &= ~S_RESET_ST; + } + } cortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr); if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) { diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 5554014..b1de26e 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_CORTEX_M_H @@ -28,7 +17,7 @@ #include "armv7m.h" #include "helper/bits.h" -#define CORTEX_M_COMMON_MAGIC 0x1A451A45 +#define CORTEX_M_COMMON_MAGIC 0x1A451A45U #define SYSTEM_CONTROL_BASE 0x400FE000 @@ -47,6 +36,7 @@ enum cortex_m_partno { CORTEX_M_PARTNO_INVALID, + STAR_MC1_PARTNO = 0x132, CORTEX_M0_PARTNO = 0xC20, CORTEX_M1_PARTNO = 0xC21, CORTEX_M3_PARTNO = 0xC23, @@ -210,11 +200,15 @@ enum cortex_m_isrmasking_mode { }; struct cortex_m_common { - int common_magic; + unsigned int common_magic; + + struct armv7m_common armv7m; /* Context information */ uint32_t dcb_dhcsr; uint32_t dcb_dhcsr_cumulated_sticky; + /* DCB DHCSR has been at least once read, so the sticky bits have been reset */ + bool dcb_dhcsr_sticky_is_recent; uint32_t nvic_dfsr; /* Debug Fault Status Register - shows reason for debug halt */ uint32_t nvic_icsr; /* Interrupt Control State Register - shows active and pending IRQ */ @@ -237,11 +231,10 @@ struct cortex_m_common { enum cortex_m_isrmasking_mode isrmasking_mode; const struct cortex_m_part_info *core_info; - struct armv7m_common armv7m; bool slow_register_read; /* A register has not been ready, poll S_REGRDY */ - int apsel; + uint64_t apsel; /* Whether this target has the erratum that makes C_MASKINTS not apply to * already pending interrupts */ diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c index fdec95f..9db54fb 100644 --- a/src/target/dsp563xx.c +++ b/src/target/dsp563xx.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009-2011 by Mathias Kuester * * mkdorg@users.sourceforge.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -2151,7 +2140,7 @@ COMMAND_HANDLER(dsp563xx_mem_command) COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], count); } - buffer = calloc(count, sizeof(uint32_t)); + buffer = calloc(count, 4); if (read_mem == 1) { err = dsp563xx_read_memory(target, mem_type, address, sizeof(uint32_t), diff --git a/src/target/dsp563xx.h b/src/target/dsp563xx.h index 5c3e1d3..9468bf3 100644 --- a/src/target/dsp563xx.h +++ b/src/target/dsp563xx.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009-2011 by Mathias Kuester * * mkdorg@users.sourceforge.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_DSP563XX_H diff --git a/src/target/dsp563xx_once.c b/src/target/dsp563xx_once.c index 624474d..2244506 100644 --- a/src/target/dsp563xx_once.c +++ b/src/target/dsp563xx_once.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by Mathias Kuester * * mkdorg@users.sourceforge.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/dsp563xx_once.h b/src/target/dsp563xx_once.h index 811c086..8715488 100644 --- a/src/target/dsp563xx_once.h +++ b/src/target/dsp563xx_once.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2009 by Mathias Kuester * * mkdorg@users.sourceforge.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_DSP563XX_ONCE_H diff --git a/src/target/dsp5680xx.c b/src/target/dsp5680xx.c index 939b09d..37cf059 100644 --- a/src/target/dsp5680xx.c +++ b/src/target/dsp5680xx.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Rodrigo L. Rosa * * rodrigorosa.LG@gmail.com * * * * Based on dsp563xx_once.h written by Mathias Kuester * * mkdorg@users.sourceforge.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -27,7 +16,7 @@ #include "target_type.h" #include "dsp5680xx.h" -struct dsp5680xx_common dsp5680xx_context; +static struct dsp5680xx_common dsp5680xx_context; #define _E "DSP5680XX_ERROR:%d\nAt:%s:%d:%s" #define err_check(r, c, m) if (r != ERROR_OK) {LOG_ERROR(_E, c, __func__, __LINE__, m); return r; } diff --git a/src/target/dsp5680xx.h b/src/target/dsp5680xx.h index b969417..152f446 100644 --- a/src/target/dsp5680xx.h +++ b/src/target/dsp5680xx.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Rodrigo L. Rosa * * rodrigorosa.LG@gmail.com * * * * Based on dsp563xx_once.h written by Mathias Kuester * * mkdorg@users.sourceforge.net * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_DSP5680XX_H @@ -289,8 +278,6 @@ struct dsp5680xx_common { bool debug_mode_enabled; }; -extern struct dsp5680xx_common dsp5680xx_context; - static inline struct dsp5680xx_common *target_to_dsp5680xx(struct target *target) { diff --git a/src/target/embeddedice.c b/src/target/embeddedice.c index a29508b..7aef153 100644 --- a/src/target/embeddedice.c +++ b/src/target/embeddedice.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/embeddedice.h b/src/target/embeddedice.h index f57f141..32acd70 100644 --- a/src/target/embeddedice.h +++ b/src/target/embeddedice.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005, 2006 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_EMBEDDEDICE_H diff --git a/src/target/esirisc.c b/src/target/esirisc.c index aadd111..f86d28d 100644 --- a/src/target/esirisc.c +++ b/src/target/esirisc.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2018 by Square, Inc. * * Steven Stallion <stallion@squareup.com> * * James Zhao <hjz@squareup.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/esirisc.h b/src/target/esirisc.h index ad14223..7496b1e 100644 --- a/src/target/esirisc.h +++ b/src/target/esirisc.h @@ -1,20 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2018 by Square, Inc. * * Steven Stallion <stallion@squareup.com> * * James Zhao <hjz@squareup.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ESIRISC_H diff --git a/src/target/esirisc_jtag.c b/src/target/esirisc_jtag.c index dd5cd5a..54abc40 100644 --- a/src/target/esirisc_jtag.c +++ b/src/target/esirisc_jtag.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2018 by Square, Inc. * * Steven Stallion <stallion@squareup.com> * * James Zhao <hjz@squareup.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/esirisc_jtag.h b/src/target/esirisc_jtag.h index 5f8fe66..98ec8af 100644 --- a/src/target/esirisc_jtag.h +++ b/src/target/esirisc_jtag.h @@ -1,20 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2018 by Square, Inc. * * Steven Stallion <stallion@squareup.com> * * James Zhao <hjz@squareup.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ESIRISC_JTAG_H diff --git a/src/target/esirisc_regs.h b/src/target/esirisc_regs.h index 6ccda50..51e7e61 100644 --- a/src/target/esirisc_regs.h +++ b/src/target/esirisc_regs.h @@ -1,20 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2018 by Square, Inc. * * Steven Stallion <stallion@squareup.com> * * James Zhao <hjz@squareup.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ESIRISC_REGS_H diff --git a/src/target/esirisc_trace.c b/src/target/esirisc_trace.c index d17a65d..376ea1d 100644 --- a/src/target/esirisc_trace.c +++ b/src/target/esirisc_trace.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2018 by Square, Inc. * * Steven Stallion <stallion@squareup.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/esirisc_trace.h b/src/target/esirisc_trace.h index c3cc6e9..9c08d96 100644 --- a/src/target/esirisc_trace.h +++ b/src/target/esirisc_trace.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2018 by Square, Inc. * * Steven Stallion <stallion@squareup.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ESIRISC_TRACE_H diff --git a/src/target/espressif/Makefile.am b/src/target/espressif/Makefile.am index c681e09..8367a38 100644 --- a/src/target/espressif/Makefile.am +++ b/src/target/espressif/Makefile.am @@ -1,6 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libespressif.la %C%_libespressif_la_SOURCES = \ %D%/esp_xtensa.c \ %D%/esp_xtensa.h \ + %D%/esp_xtensa_smp.c \ + %D%/esp_xtensa_smp.h \ + %D%/esp_xtensa_semihosting.c \ + %D%/esp_xtensa_semihosting.h \ + %D%/esp32.c \ %D%/esp32s2.c \ - %D%/esp32s2.h + %D%/esp32s3.c \ + %D%/esp_semihosting.c \ + %D%/esp_semihosting.h diff --git a/src/target/espressif/esp32.c b/src/target/espressif/esp32.c new file mode 100644 index 0000000..63055cf --- /dev/null +++ b/src/target/espressif/esp32.c @@ -0,0 +1,503 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * ESP32 target API for OpenOCD * + * Copyright (C) 2016-2019 Espressif Systems Ltd. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <helper/time_support.h> +#include <target/target.h> +#include <target/target_type.h> +#include <target/smp.h> +#include <target/semihosting_common.h> +#include "assert.h" +#include "esp_xtensa_smp.h" + +/* +This is a JTAG driver for the ESP32, the are two Tensilica cores inside +the ESP32 chip. For more information please have a look into ESP32 target +implementation. +*/ + +/* ESP32 memory map */ +#define ESP32_DRAM_LOW 0x3ffae000 +#define ESP32_DRAM_HIGH 0x40000000 +#define ESP32_IROM_MASK_LOW 0x40000000 +#define ESP32_IROM_MASK_HIGH 0x40064f00 +#define ESP32_IRAM_LOW 0x40070000 +#define ESP32_IRAM_HIGH 0x400a0000 +#define ESP32_RTC_IRAM_LOW 0x400c0000 +#define ESP32_RTC_IRAM_HIGH 0x400c2000 +#define ESP32_RTC_DRAM_LOW 0x3ff80000 +#define ESP32_RTC_DRAM_HIGH 0x3ff82000 +#define ESP32_RTC_DATA_LOW 0x50000000 +#define ESP32_RTC_DATA_HIGH 0x50002000 +#define ESP32_EXTRAM_DATA_LOW 0x3f800000 +#define ESP32_EXTRAM_DATA_HIGH 0x3fc00000 +#define ESP32_DR_REG_LOW 0x3ff00000 +#define ESP32_DR_REG_HIGH 0x3ff71000 +#define ESP32_SYS_RAM_LOW 0x60000000UL +#define ESP32_SYS_RAM_HIGH (ESP32_SYS_RAM_LOW + 0x20000000UL) +#define ESP32_RTC_SLOW_MEM_BASE ESP32_RTC_DATA_LOW + +/* ESP32 WDT */ +#define ESP32_WDT_WKEY_VALUE 0x50d83aa1 +#define ESP32_TIMG0_BASE 0x3ff5f000 +#define ESP32_TIMG1_BASE 0x3ff60000 +#define ESP32_TIMGWDT_CFG0_OFF 0x48 +#define ESP32_TIMGWDT_PROTECT_OFF 0x64 +#define ESP32_TIMG0WDT_CFG0 (ESP32_TIMG0_BASE + ESP32_TIMGWDT_CFG0_OFF) +#define ESP32_TIMG1WDT_CFG0 (ESP32_TIMG1_BASE + ESP32_TIMGWDT_CFG0_OFF) +#define ESP32_TIMG0WDT_PROTECT (ESP32_TIMG0_BASE + ESP32_TIMGWDT_PROTECT_OFF) +#define ESP32_TIMG1WDT_PROTECT (ESP32_TIMG1_BASE + ESP32_TIMGWDT_PROTECT_OFF) +#define ESP32_RTCCNTL_BASE 0x3ff48000 +#define ESP32_RTCWDT_CFG_OFF 0x8C +#define ESP32_RTCWDT_PROTECT_OFF 0xA4 +#define ESP32_RTCWDT_CFG (ESP32_RTCCNTL_BASE + ESP32_RTCWDT_CFG_OFF) +#define ESP32_RTCWDT_PROTECT (ESP32_RTCCNTL_BASE + ESP32_RTCWDT_PROTECT_OFF) + +#define ESP32_TRACEMEM_BLOCK_SZ 0x4000 + +/* ESP32 dport regs */ +#define ESP32_DR_REG_DPORT_BASE ESP32_DR_REG_LOW +#define ESP32_DPORT_APPCPU_CTRL_B_REG (ESP32_DR_REG_DPORT_BASE + 0x030) +#define ESP32_DPORT_APPCPU_CLKGATE_EN BIT(0) +/* ESP32 RTC regs */ +#define ESP32_RTC_CNTL_SW_CPU_STALL_REG (ESP32_RTCCNTL_BASE + 0xac) +#define ESP32_RTC_CNTL_SW_CPU_STALL_DEF 0x0 + +/* 0 - don't care, 1 - TMS low, 2 - TMS high */ +enum esp32_flash_bootstrap { + FBS_DONTCARE = 0, + FBS_TMSLOW, + FBS_TMSHIGH, +}; + +struct esp32_common { + struct esp_xtensa_smp_common esp_xtensa_smp; + enum esp32_flash_bootstrap flash_bootstrap; +}; + +static inline struct esp32_common *target_to_esp32(struct target *target) +{ + return container_of(target->arch_info, struct esp32_common, esp_xtensa_smp); +} + +/* Reset ESP32 peripherals. + * Postconditions: all peripherals except RTC_CNTL are reset, CPU's PC is undefined, PRO CPU is halted, + * APP CPU is in reset + * How this works: + * 0. make sure target is halted; if not, try to halt it; if that fails, try to reset it (via OCD) and then halt + * 1. set CPU initial PC to 0x50000000 (ESP32_SMP_RTC_DATA_LOW) by clearing RTC_CNTL_{PRO,APP}CPU_STAT_VECTOR_SEL + * 2. load stub code into ESP32_SMP_RTC_DATA_LOW; once executed, stub code will disable watchdogs and + * make CPU spin in an idle loop. + * 3. trigger SoC reset using RTC_CNTL_SW_SYS_RST bit + * 4. wait for the OCD to be reset + * 5. halt the target and wait for it to be halted (at this point CPU is in the idle loop) + * 6. restore initial PC and the contents of ESP32_SMP_RTC_DATA_LOW + * TODO: some state of RTC_CNTL is not reset during SW_SYS_RST. Need to reset that manually. */ + +static const uint8_t esp32_reset_stub_code[] = { +#include "../../../contrib/loaders/reset/espressif/esp32/cpu_reset_handler_code.inc" +}; + +static int esp32_soc_reset(struct target *target) +{ + int res; + struct target_list *head; + struct xtensa *xtensa; + + LOG_DEBUG("start"); + /* In order to write to peripheral registers, target must be halted first */ + if (target->state != TARGET_HALTED) { + LOG_DEBUG("Target not halted before SoC reset, trying to halt it first"); + xtensa_halt(target); + res = target_wait_state(target, TARGET_HALTED, 1000); + if (res != ERROR_OK) { + LOG_DEBUG("Couldn't halt target before SoC reset, trying to do reset-halt"); + res = xtensa_assert_reset(target); + if (res != ERROR_OK) { + LOG_ERROR( + "Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)", + res); + return res; + } + alive_sleep(10); + xtensa_poll(target); + bool reset_halt_save = target->reset_halt; + target->reset_halt = true; + res = xtensa_deassert_reset(target); + target->reset_halt = reset_halt_save; + if (res != ERROR_OK) { + LOG_ERROR( + "Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)", + res); + return res; + } + alive_sleep(10); + xtensa_poll(target); + xtensa_halt(target); + res = target_wait_state(target, TARGET_HALTED, 1000); + if (res != ERROR_OK) { + LOG_ERROR("Couldn't halt target before SoC reset"); + return res; + } + } + } + + if (target->smp) { + foreach_smp_target(head, target->smp_targets) { + xtensa = target_to_xtensa(head->target); + /* if any of the cores is stalled unstall them */ + if (xtensa_dm_core_is_stalled(&xtensa->dbg_mod)) { + LOG_TARGET_DEBUG(head->target, "Unstall CPUs before SW reset!"); + res = target_write_u32(target, + ESP32_RTC_CNTL_SW_CPU_STALL_REG, + ESP32_RTC_CNTL_SW_CPU_STALL_DEF); + if (res != ERROR_OK) { + LOG_TARGET_ERROR(head->target, "Failed to unstall CPUs before SW reset!"); + return res; + } + break; /* both cores are unstalled now, so exit the loop */ + } + } + } + + LOG_DEBUG("Loading stub code into RTC RAM"); + uint8_t slow_mem_save[sizeof(esp32_reset_stub_code)]; + + /* Save contents of RTC_SLOW_MEM which we are about to overwrite */ + res = target_read_buffer(target, ESP32_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save); + if (res != ERROR_OK) { + LOG_ERROR("Failed to save contents of RTC_SLOW_MEM (%d)!", res); + return res; + } + + /* Write stub code into RTC_SLOW_MEM */ + res = target_write_buffer(target, ESP32_RTC_SLOW_MEM_BASE, sizeof(esp32_reset_stub_code), esp32_reset_stub_code); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write stub (%d)!", res); + return res; + } + + LOG_DEBUG("Resuming the target"); + xtensa = target_to_xtensa(target); + xtensa->suppress_dsr_errors = true; + res = xtensa_resume(target, 0, ESP32_RTC_SLOW_MEM_BASE + 4, 0, 0); + xtensa->suppress_dsr_errors = false; + if (res != ERROR_OK) { + LOG_ERROR("Failed to run stub (%d)!", res); + return res; + } + LOG_DEBUG("resume done, waiting for the target to come alive"); + + /* Wait for SoC to reset */ + alive_sleep(100); + int64_t timeout = timeval_ms() + 100; + bool get_timeout = false; + while (target->state != TARGET_RESET && target->state != TARGET_RUNNING) { + alive_sleep(10); + xtensa_poll(target); + if (timeval_ms() >= timeout) { + LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be reset, target state=%d", + target->state); + get_timeout = true; + break; + } + } + + /* Halt the CPU again */ + LOG_DEBUG("halting the target"); + xtensa_halt(target); + res = target_wait_state(target, TARGET_HALTED, 1000); + if (res == ERROR_OK) { + LOG_DEBUG("restoring RTC_SLOW_MEM"); + res = target_write_buffer(target, ESP32_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save); + if (res != ERROR_OK) + LOG_TARGET_ERROR(target, "Failed to restore contents of RTC_SLOW_MEM (%d)!", res); + } else { + LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be halted after SoC reset"); + } + + return get_timeout ? ERROR_TARGET_TIMEOUT : res; +} + +static int esp32_disable_wdts(struct target *target) +{ + /* TIMG1 WDT */ + int res = target_write_u32(target, ESP32_TIMG0WDT_PROTECT, ESP32_WDT_WKEY_VALUE); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_TIMG0WDT_PROTECT (%d)!", res); + return res; + } + res = target_write_u32(target, ESP32_TIMG0WDT_CFG0, 0); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_TIMG0WDT_CFG0 (%d)!", res); + return res; + } + /* TIMG2 WDT */ + res = target_write_u32(target, ESP32_TIMG1WDT_PROTECT, ESP32_WDT_WKEY_VALUE); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_TIMG1WDT_PROTECT (%d)!", res); + return res; + } + res = target_write_u32(target, ESP32_TIMG1WDT_CFG0, 0); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_TIMG1WDT_CFG0 (%d)!", res); + return res; + } + /* RTC WDT */ + res = target_write_u32(target, ESP32_RTCWDT_PROTECT, ESP32_WDT_WKEY_VALUE); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_RTCWDT_PROTECT (%d)!", res); + return res; + } + res = target_write_u32(target, ESP32_RTCWDT_CFG, 0); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_RTCWDT_CFG (%d)!", res); + return res; + } + return ERROR_OK; +} + +static int esp32_on_halt(struct target *target) +{ + return esp32_disable_wdts(target); +} + +static int esp32_arch_state(struct target *target) +{ + return ERROR_OK; +} + +static int esp32_virt2phys(struct target *target, + target_addr_t virtual, target_addr_t *physical) +{ + if (physical) { + *physical = virtual; + return ERROR_OK; + } + return ERROR_FAIL; +} + +/* The TDI pin is also used as a flash Vcc bootstrap pin. If we reset the CPU externally, the last state of the TDI pin + * can allow the power to an 1.8V flash chip to be raised to 3.3V, or the other way around. Users can use the + * esp32 flashbootstrap command to set a level, and this routine will make sure the tdi line will return to + * that when the jtag port is idle. */ + +static void esp32_queue_tdi_idle(struct target *target) +{ + struct esp32_common *esp32 = target_to_esp32(target); + static uint32_t value; + uint8_t t[4] = { 0, 0, 0, 0 }; + + if (esp32->flash_bootstrap == FBS_TMSLOW) + /* Make sure tdi is 0 at the exit of queue execution */ + value = 0; + else if (esp32->flash_bootstrap == FBS_TMSHIGH) + /* Make sure tdi is 1 at the exit of queue execution */ + value = 1; + else + return; + + /* Scan out 1 bit, do not move from IRPAUSE after we're done. */ + buf_set_u32(t, 0, 1, value); + jtag_add_plain_ir_scan(1, t, NULL, TAP_IRPAUSE); +} + +static int esp32_target_init(struct command_context *cmd_ctx, struct target *target) +{ + return esp_xtensa_smp_target_init(cmd_ctx, target); +} + +static const struct xtensa_debug_ops esp32_dbg_ops = { + .queue_enable = xtensa_dm_queue_enable, + .queue_reg_read = xtensa_dm_queue_reg_read, + .queue_reg_write = xtensa_dm_queue_reg_write +}; + +static const struct xtensa_power_ops esp32_pwr_ops = { + .queue_reg_read = xtensa_dm_queue_pwr_reg_read, + .queue_reg_write = xtensa_dm_queue_pwr_reg_write +}; + +static const struct esp_xtensa_smp_chip_ops esp32_chip_ops = { + .reset = esp32_soc_reset, + .on_halt = esp32_on_halt +}; + +static const struct esp_semihost_ops esp32_semihost_ops = { + .prepare = esp32_disable_wdts +}; + +static int esp32_target_create(struct target *target, Jim_Interp *interp) +{ + struct xtensa_debug_module_config esp32_dm_cfg = { + .dbg_ops = &esp32_dbg_ops, + .pwr_ops = &esp32_pwr_ops, + .tap = target->tap, + .queue_tdi_idle = esp32_queue_tdi_idle, + .queue_tdi_idle_arg = target + }; + + struct esp32_common *esp32 = calloc(1, sizeof(struct esp32_common)); + if (!esp32) { + LOG_ERROR("Failed to alloc memory for arch info!"); + return ERROR_FAIL; + } + + int ret = esp_xtensa_smp_init_arch_info(target, &esp32->esp_xtensa_smp, + &esp32_dm_cfg, &esp32_chip_ops, &esp32_semihost_ops); + if (ret != ERROR_OK) { + LOG_ERROR("Failed to init arch info!"); + free(esp32); + return ret; + } + esp32->flash_bootstrap = FBS_DONTCARE; + + /* Assume running target. If different, the first poll will fix this. */ + target->state = TARGET_RUNNING; + target->debug_reason = DBG_REASON_NOTHALTED; + return ERROR_OK; +} + +static COMMAND_HELPER(esp32_cmd_flashbootstrap_do, struct esp32_common *esp32) +{ + int state = -1; + + if (CMD_ARGC < 1) { + const char *st; + state = esp32->flash_bootstrap; + if (state == FBS_DONTCARE) + st = "Don't care"; + else if (state == FBS_TMSLOW) + st = "Low (3.3V)"; + else if (state == FBS_TMSHIGH) + st = "High (1.8V)"; + else + st = "None"; + command_print(CMD, "Current idle tms state: %s", st); + return ERROR_OK; + } + + if (!strcasecmp(CMD_ARGV[0], "none")) + state = FBS_DONTCARE; + else if (!strcasecmp(CMD_ARGV[0], "1.8")) + state = FBS_TMSHIGH; + else if (!strcasecmp(CMD_ARGV[0], "3.3")) + state = FBS_TMSLOW; + else if (!strcasecmp(CMD_ARGV[0], "high")) + state = FBS_TMSHIGH; + else if (!strcasecmp(CMD_ARGV[0], "low")) + state = FBS_TMSLOW; + + if (state == -1) { + command_print(CMD, + "Argument unknown. Please pick one of none, high, low, 1.8 or 3.3"); + return ERROR_FAIL; + } + esp32->flash_bootstrap = state; + return ERROR_OK; +} + +COMMAND_HANDLER(esp32_cmd_flashbootstrap) +{ + struct target *target = get_current_target(CMD_CTX); + + if (target->smp) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(esp32_cmd_flashbootstrap_do, + target_to_esp32(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(esp32_cmd_flashbootstrap_do, + target_to_esp32(target)); +} + +static const struct command_registration esp32_any_command_handlers[] = { + { + .name = "flashbootstrap", + .handler = esp32_cmd_flashbootstrap, + .mode = COMMAND_ANY, + .help = + "Set the idle state of the TMS pin, which at reset also is the voltage selector for the flash chip.", + .usage = "none|1.8|3.3|high|low", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration esp32_command_handlers[] = { + { + .chain = esp_xtensa_smp_command_handlers, + }, + { + .name = "esp32", + .usage = "", + .chain = smp_command_handlers, + }, + { + .name = "esp32", + .usage = "", + .chain = esp32_any_command_handlers, + }, + { + .name = "arm", + .mode = COMMAND_ANY, + .help = "ARM Command Group", + .usage = "", + .chain = semihosting_common_handlers + }, + COMMAND_REGISTRATION_DONE +}; + +/** Holds methods for Xtensa targets. */ +struct target_type esp32_target = { + .name = "esp32", + + .poll = esp_xtensa_smp_poll, + .arch_state = esp32_arch_state, + + .halt = xtensa_halt, + .resume = esp_xtensa_smp_resume, + .step = esp_xtensa_smp_step, + + .assert_reset = esp_xtensa_smp_assert_reset, + .deassert_reset = esp_xtensa_smp_deassert_reset, + .soft_reset_halt = esp_xtensa_smp_soft_reset_halt, + + .virt2phys = esp32_virt2phys, + .mmu = xtensa_mmu_is_enabled, + .read_memory = xtensa_read_memory, + .write_memory = xtensa_write_memory, + + .read_buffer = xtensa_read_buffer, + .write_buffer = xtensa_write_buffer, + + .checksum_memory = xtensa_checksum_memory, + + .get_gdb_arch = xtensa_get_gdb_arch, + .get_gdb_reg_list = xtensa_get_gdb_reg_list, + + .add_breakpoint = esp_xtensa_breakpoint_add, + .remove_breakpoint = esp_xtensa_breakpoint_remove, + + .add_watchpoint = esp_xtensa_smp_watchpoint_add, + .remove_watchpoint = esp_xtensa_smp_watchpoint_remove, + + .target_create = esp32_target_create, + .init_target = esp32_target_init, + .examine = xtensa_examine, + .deinit_target = esp_xtensa_target_deinit, + + .commands = esp32_command_handlers, +}; diff --git a/src/target/espressif/esp32s2.c b/src/target/espressif/esp32s2.c index 212533f..62d1ddb 100644 --- a/src/target/espressif/esp32s2.c +++ b/src/target/espressif/esp32s2.c @@ -1,31 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * ESP32-S2 target for OpenOCD * * Copyright (C) 2019 Espressif Systems Ltd. * - * Author: Alexey Gerenkov <alexey@espressif.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include <helper/time_support.h> #include "assert.h" #include <target/target.h> #include <target/target_type.h> +#include <target/semihosting_common.h> #include "esp_xtensa.h" -#include "esp32s2.h" +#include "esp_xtensa_semihosting.h" /* Overall memory map * TODO: read memory configuration from target registers */ @@ -100,190 +90,6 @@ #define ESP32_S2_DR_REG_UART_BASE 0x3f400000 #define ESP32_S2_REG_UART_BASE(i) (ESP32_S2_DR_REG_UART_BASE + (i) * 0x10000) #define ESP32_S2_UART_DATE_REG(i) (ESP32_S2_REG_UART_BASE(i) + 0x74) - -/* this should map local reg IDs to GDB reg mapping as defined in xtensa-config.c 'rmap' in - * xtensa-overlay */ -static const unsigned int esp32s2_gdb_regs_mapping[ESP32_S2_NUM_REGS] = { - XT_REG_IDX_PC, - XT_REG_IDX_AR0, XT_REG_IDX_AR1, XT_REG_IDX_AR2, XT_REG_IDX_AR3, - XT_REG_IDX_AR4, XT_REG_IDX_AR5, XT_REG_IDX_AR6, XT_REG_IDX_AR7, - XT_REG_IDX_AR8, XT_REG_IDX_AR9, XT_REG_IDX_AR10, XT_REG_IDX_AR11, - XT_REG_IDX_AR12, XT_REG_IDX_AR13, XT_REG_IDX_AR14, XT_REG_IDX_AR15, - XT_REG_IDX_AR16, XT_REG_IDX_AR17, XT_REG_IDX_AR18, XT_REG_IDX_AR19, - XT_REG_IDX_AR20, XT_REG_IDX_AR21, XT_REG_IDX_AR22, XT_REG_IDX_AR23, - XT_REG_IDX_AR24, XT_REG_IDX_AR25, XT_REG_IDX_AR26, XT_REG_IDX_AR27, - XT_REG_IDX_AR28, XT_REG_IDX_AR29, XT_REG_IDX_AR30, XT_REG_IDX_AR31, - XT_REG_IDX_AR32, XT_REG_IDX_AR33, XT_REG_IDX_AR34, XT_REG_IDX_AR35, - XT_REG_IDX_AR36, XT_REG_IDX_AR37, XT_REG_IDX_AR38, XT_REG_IDX_AR39, - XT_REG_IDX_AR40, XT_REG_IDX_AR41, XT_REG_IDX_AR42, XT_REG_IDX_AR43, - XT_REG_IDX_AR44, XT_REG_IDX_AR45, XT_REG_IDX_AR46, XT_REG_IDX_AR47, - XT_REG_IDX_AR48, XT_REG_IDX_AR49, XT_REG_IDX_AR50, XT_REG_IDX_AR51, - XT_REG_IDX_AR52, XT_REG_IDX_AR53, XT_REG_IDX_AR54, XT_REG_IDX_AR55, - XT_REG_IDX_AR56, XT_REG_IDX_AR57, XT_REG_IDX_AR58, XT_REG_IDX_AR59, - XT_REG_IDX_AR60, XT_REG_IDX_AR61, XT_REG_IDX_AR62, XT_REG_IDX_AR63, - XT_REG_IDX_SAR, - XT_REG_IDX_WINDOWBASE, XT_REG_IDX_WINDOWSTART, XT_REG_IDX_CONFIGID0, XT_REG_IDX_CONFIGID1, - XT_REG_IDX_PS, XT_REG_IDX_THREADPTR, - ESP32_S2_REG_IDX_GPIOOUT, - XT_REG_IDX_MMID, XT_REG_IDX_IBREAKENABLE, XT_REG_IDX_OCD_DDR, - XT_REG_IDX_IBREAKA0, XT_REG_IDX_IBREAKA1, XT_REG_IDX_DBREAKA0, XT_REG_IDX_DBREAKA1, - XT_REG_IDX_DBREAKC0, XT_REG_IDX_DBREAKC1, - XT_REG_IDX_EPC1, XT_REG_IDX_EPC2, XT_REG_IDX_EPC3, XT_REG_IDX_EPC4, - XT_REG_IDX_EPC5, XT_REG_IDX_EPC6, XT_REG_IDX_EPC7, XT_REG_IDX_DEPC, - XT_REG_IDX_EPS2, XT_REG_IDX_EPS3, XT_REG_IDX_EPS4, XT_REG_IDX_EPS5, - XT_REG_IDX_EPS6, XT_REG_IDX_EPS7, - XT_REG_IDX_EXCSAVE1, XT_REG_IDX_EXCSAVE2, XT_REG_IDX_EXCSAVE3, XT_REG_IDX_EXCSAVE4, - XT_REG_IDX_EXCSAVE5, XT_REG_IDX_EXCSAVE6, XT_REG_IDX_EXCSAVE7, XT_REG_IDX_CPENABLE, - XT_REG_IDX_INTERRUPT, XT_REG_IDX_INTSET, XT_REG_IDX_INTCLEAR, XT_REG_IDX_INTENABLE, - XT_REG_IDX_VECBASE, XT_REG_IDX_EXCCAUSE, XT_REG_IDX_DEBUGCAUSE, XT_REG_IDX_CCOUNT, - XT_REG_IDX_PRID, XT_REG_IDX_ICOUNT, XT_REG_IDX_ICOUNTLEVEL, XT_REG_IDX_EXCVADDR, - XT_REG_IDX_CCOMPARE0, XT_REG_IDX_CCOMPARE1, XT_REG_IDX_CCOMPARE2, - XT_REG_IDX_MISC0, XT_REG_IDX_MISC1, XT_REG_IDX_MISC2, XT_REG_IDX_MISC3, - XT_REG_IDX_A0, XT_REG_IDX_A1, XT_REG_IDX_A2, XT_REG_IDX_A3, - XT_REG_IDX_A4, XT_REG_IDX_A5, XT_REG_IDX_A6, XT_REG_IDX_A7, - XT_REG_IDX_A8, XT_REG_IDX_A9, XT_REG_IDX_A10, XT_REG_IDX_A11, - XT_REG_IDX_A12, XT_REG_IDX_A13, XT_REG_IDX_A14, XT_REG_IDX_A15, - XT_REG_IDX_PWRCTL, XT_REG_IDX_PWRSTAT, XT_REG_IDX_ERISTAT, - XT_REG_IDX_CS_ITCTRL, XT_REG_IDX_CS_CLAIMSET, XT_REG_IDX_CS_CLAIMCLR, - XT_REG_IDX_CS_LOCKACCESS, XT_REG_IDX_CS_LOCKSTATUS, XT_REG_IDX_CS_AUTHSTATUS, - XT_REG_IDX_FAULT_INFO, - XT_REG_IDX_TRAX_ID, XT_REG_IDX_TRAX_CTRL, XT_REG_IDX_TRAX_STAT, - XT_REG_IDX_TRAX_DATA, XT_REG_IDX_TRAX_ADDR, XT_REG_IDX_TRAX_PCTRIGGER, - XT_REG_IDX_TRAX_PCMATCH, XT_REG_IDX_TRAX_DELAY, XT_REG_IDX_TRAX_MEMSTART, - XT_REG_IDX_TRAX_MEMEND, - XT_REG_IDX_PMG, XT_REG_IDX_PMPC, XT_REG_IDX_PM0, XT_REG_IDX_PM1, - XT_REG_IDX_PMCTRL0, XT_REG_IDX_PMCTRL1, XT_REG_IDX_PMSTAT0, XT_REG_IDX_PMSTAT1, - XT_REG_IDX_OCD_ID, XT_REG_IDX_OCD_DCRCLR, XT_REG_IDX_OCD_DCRSET, XT_REG_IDX_OCD_DSR, -}; - -static const struct xtensa_user_reg_desc esp32s2_user_regs[ESP32_S2_NUM_REGS - XT_NUM_REGS] = { - { "gpio_out", 0x00, 0, 32, &xtensa_user_reg_u32_type }, -}; - -static const struct xtensa_config esp32s2_xtensa_cfg = { - .density = true, - .aregs_num = XT_AREGS_NUM_MAX, - .windowed = true, - .coproc = true, - .miscregs_num = 4, - .reloc_vec = true, - .proc_id = true, - .threadptr = true, - .user_regs_num = ARRAY_SIZE(esp32s2_user_regs), - .user_regs = esp32s2_user_regs, - .fetch_user_regs = xtensa_fetch_user_regs_u32, - .queue_write_dirty_user_regs = xtensa_queue_write_dirty_user_regs_u32, - .gdb_general_regs_num = ESP32_S2_NUM_REGS_G_COMMAND, - .gdb_regs_mapping = esp32s2_gdb_regs_mapping, - .irom = { - .count = 2, - .regions = { - { - .base = ESP32_S2_IROM_LOW, - .size = ESP32_S2_IROM_HIGH - ESP32_S2_IROM_LOW, - .access = XT_MEM_ACCESS_READ, - }, - { - .base = ESP32_S2_IROM_MASK_LOW, - .size = ESP32_S2_IROM_MASK_HIGH - ESP32_S2_IROM_MASK_LOW, - .access = XT_MEM_ACCESS_READ, - }, - } - }, - .iram = { - .count = 2, - .regions = { - { - .base = ESP32_S2_IRAM_LOW, - .size = ESP32_S2_IRAM_HIGH - ESP32_S2_IRAM_LOW, - .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE, - }, - { - .base = ESP32_S2_RTC_IRAM_LOW, - .size = ESP32_S2_RTC_IRAM_HIGH - ESP32_S2_RTC_IRAM_LOW, - .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE, - }, - } - }, - .drom = { - .count = 2, - .regions = { - { - .base = ESP32_S2_DROM0_LOW, - .size = ESP32_S2_DROM0_HIGH - ESP32_S2_DROM0_LOW, - .access = XT_MEM_ACCESS_READ, - }, - { - .base = ESP32_S2_DROM1_LOW, - .size = ESP32_S2_DROM1_HIGH - ESP32_S2_DROM1_LOW, - .access = XT_MEM_ACCESS_READ, - }, - } - }, - .dram = { - .count = 6, - .regions = { - { - .base = ESP32_S2_DRAM_LOW, - .size = ESP32_S2_DRAM_HIGH - ESP32_S2_DRAM_LOW, - .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE, - }, - { - .base = ESP32_S2_RTC_DRAM_LOW, - .size = ESP32_S2_RTC_DRAM_HIGH - ESP32_S2_RTC_DRAM_LOW, - .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE, - }, - { - .base = ESP32_S2_RTC_DATA_LOW, - .size = ESP32_S2_RTC_DATA_HIGH - ESP32_S2_RTC_DATA_LOW, - .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE, - }, - { - .base = ESP32_S2_EXTRAM_DATA_LOW, - .size = ESP32_S2_EXTRAM_DATA_HIGH - ESP32_S2_EXTRAM_DATA_LOW, - .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE, - }, - { - .base = ESP32_S2_DR_REG_LOW, - .size = ESP32_S2_DR_REG_HIGH - ESP32_S2_DR_REG_LOW, - .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE, - }, - { - .base = ESP32_S2_SYS_RAM_LOW, - .size = ESP32_S2_SYS_RAM_HIGH - ESP32_S2_SYS_RAM_LOW, - .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE, - }, - } - }, - .exc = { - .enabled = true, - }, - .irq = { - .enabled = true, - .irq_num = 32, - }, - .high_irq = { - .enabled = true, - .excm_level = 3, - .nmi_num = 1, - }, - .tim_irq = { - .enabled = true, - .comp_num = 3, - }, - .debug = { - .enabled = true, - .irq_level = 6, - .ibreaks_num = 2, - .dbreaks_num = 2, - .icount_sz = 32, - }, - .trace = { - .enabled = true, - .mem_sz = ESP32_S2_TRACEMEM_BLOCK_SZ, - }, -}; - struct esp32s2_common { struct esp_xtensa_common esp_xtensa; }; @@ -316,7 +122,7 @@ static int esp32s2_deassert_reset(struct target *target) return ERROR_OK; } -int esp32s2_soft_reset_halt(struct target *target) +static int esp32s2_soft_reset_halt(struct target *target) { LOG_TARGET_DEBUG(target, "begin"); @@ -324,7 +130,7 @@ int esp32s2_soft_reset_halt(struct target *target) int res = esp32s2_soc_reset(target); if (res != ERROR_OK) return res; - return xtensa_assert_reset(target); + return xtensa_soft_reset_halt(target); } static int esp32s2_set_peri_reg_mask(struct target *target, @@ -474,7 +280,7 @@ static int esp32s2_soc_reset(struct target *target) res = esp32s2_set_peri_reg_mask(target, ESP32_S2_OPTIONS0, ESP32_S2_SW_SYS_RST_M, - 1U << ESP32_S2_SW_SYS_RST_S); + BIT(ESP32_S2_SW_SYS_RST_S)); xtensa->suppress_dsr_errors = false; if (res != ERROR_OK) { LOG_ERROR("Failed to write ESP32_S2_OPTIONS0 (%d)!", res); @@ -482,15 +288,17 @@ static int esp32s2_soc_reset(struct target *target) } /* Wait for SoC to reset */ alive_sleep(100); - int timeout = 100; - while (target->state != TARGET_RESET && target->state != TARGET_RUNNING && --timeout > 0) { + int64_t timeout = timeval_ms() + 100; + while (target->state != TARGET_RESET && target->state != TARGET_RUNNING) { alive_sleep(10); xtensa_poll(target); + if (timeval_ms() >= timeout) { + LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be reset, target state=%d", + target->state); + return ERROR_TARGET_TIMEOUT; + } } - if (timeout == 0) { - LOG_ERROR("Timed out waiting for CPU to be reset, target->state=%d", target->state); - return ERROR_TARGET_TIMEOUT; - } + xtensa_halt(target); res = target_wait_state(target, TARGET_HALTED, 1000); if (res != ERROR_OK) { @@ -600,6 +408,19 @@ static int esp32s2_poll(struct target *target) if (old_state == TARGET_DEBUG_RUNNING) { target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); } else { + if (esp_xtensa_semihosting(target, &ret) == SEMIHOSTING_HANDLED) { + struct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target); + if (ret == ERROR_OK && esp_xtensa->semihost.need_resume) { + esp_xtensa->semihost.need_resume = false; + /* Resume xtensa_resume will handle BREAK instruction. */ + ret = target_resume(target, 1, 0, 1, 0); + if (ret != ERROR_OK) { + LOG_ERROR("Failed to resume target"); + return ret; + } + } + return ret; + } esp32s2_on_halt(target); target_call_event_callbacks(target, TARGET_EVENT_HALTED); } @@ -617,7 +438,11 @@ static int esp32s2_virt2phys(struct target *target, static int esp32s2_target_init(struct command_context *cmd_ctx, struct target *target) { - return esp_xtensa_target_init(cmd_ctx, target); + int ret = esp_xtensa_target_init(cmd_ctx, target); + if (ret != ERROR_OK) + return ret; + + return esp_xtensa_semihosting_init(target); } static const struct xtensa_debug_ops esp32s2_dbg_ops = { @@ -631,6 +456,10 @@ static const struct xtensa_power_ops esp32s2_pwr_ops = { .queue_reg_write = xtensa_dm_queue_pwr_reg_write }; +static const struct esp_semihost_ops esp32s2_semihost_ops = { + .prepare = esp32s2_disable_wdts +}; + static int esp32s2_target_create(struct target *target, Jim_Interp *interp) { struct xtensa_debug_module_config esp32s2_dm_cfg = { @@ -648,7 +477,7 @@ static int esp32s2_target_create(struct target *target, Jim_Interp *interp) return ERROR_FAIL; } - int ret = esp_xtensa_init_arch_info(target, &esp32->esp_xtensa, &esp32s2_xtensa_cfg, &esp32s2_dm_cfg); + int ret = esp_xtensa_init_arch_info(target, &esp32->esp_xtensa, &esp32s2_dm_cfg, &esp32s2_semihost_ops); if (ret != ERROR_OK) { LOG_ERROR("Failed to init arch info!"); free(esp32); @@ -663,11 +492,14 @@ static int esp32s2_target_create(struct target *target, Jim_Interp *interp) static const struct command_registration esp32s2_command_handlers[] = { { - .name = "xtensa", + .chain = xtensa_command_handlers, + }, + { + .name = "arm", .mode = COMMAND_ANY, - .help = "Xtensa commands group", + .help = "ARM Command Group", .usage = "", - .chain = xtensa_command_handlers, + .chain = semihosting_common_handlers }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/espressif/esp32s2.h b/src/target/espressif/esp32s2.h deleted file mode 100644 index 2c43e3e..0000000 --- a/src/target/espressif/esp32s2.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * ESP32-S2 target for OpenOCD * - * Copyright (C) 2019 Espressif Systems Ltd. * - * Author: Alexey Gerenkov <alexey@espressif.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ESP32S2_H -#define OPENOCD_TARGET_ESP32S2_H - -#include <target/xtensa/xtensa_regs.h> - -#define ESP32_S2_DROM_LOW 0x3f000000 -#define ESP32_S2_DROM_HIGH 0x3ff80000 -#define ESP32_S2_IROM_LOW 0x40080000 -#define ESP32_S2_IROM_HIGH 0x40800000 - -/* Number of registers returned directly by the G command - * Corresponds to the amount of regs listed in regformats/reg-xtensa.dat in the gdb source */ -#define ESP32_S2_NUM_REGS_G_COMMAND 72 - -enum esp32s2_reg_id { - /* chip specific registers that extend ISA go after ISA-defined ones */ - ESP32_S2_REG_IDX_GPIOOUT = XT_USR_REG_START, - ESP32_S2_NUM_REGS, -}; - -#endif /* OPENOCD_TARGET_ESP32S2_H */ diff --git a/src/target/espressif/esp32s3.c b/src/target/espressif/esp32s3.c new file mode 100644 index 0000000..62b22b1 --- /dev/null +++ b/src/target/espressif/esp32s3.c @@ -0,0 +1,422 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * ESP32-S3 target API for OpenOCD * + * Copyright (C) 2020 Espressif Systems Ltd. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <helper/time_support.h> +#include <target/target.h> +#include <target/target_type.h> +#include <target/smp.h> +#include <target/semihosting_common.h> +#include "assert.h" +#include "esp_xtensa_smp.h" + +/* +This is a JTAG driver for the ESP32_S3, the are two Tensilica cores inside +the ESP32_S3 chip. For more information please have a look into ESP32_S3 target +implementation. +*/ + +/* ESP32_S3 memory map */ +#define ESP32_S3_IRAM_LOW 0x40370000 +#define ESP32_S3_IRAM_HIGH 0x403E0000 +#define ESP32_S3_IROM_MASK_LOW 0x40000000 +#define ESP32_S3_IROM_MASK_HIGH 0x40060000 +#define ESP32_S3_DRAM_LOW 0x3FC88000 +#define ESP32_S3_DRAM_HIGH 0x3FD00000 +#define ESP32_S3_RTC_IRAM_LOW 0x600FE000 +#define ESP32_S3_RTC_IRAM_HIGH 0x60100000 +#define ESP32_S3_RTC_DRAM_LOW 0x600FE000 +#define ESP32_S3_RTC_DRAM_HIGH 0x60100000 +#define ESP32_S3_RTC_DATA_LOW 0x50000000 +#define ESP32_S3_RTC_DATA_HIGH 0x50002000 +#define ESP32_S3_EXTRAM_DATA_LOW 0x3D000000 +#define ESP32_S3_EXTRAM_DATA_HIGH 0x3E000000 +#define ESP32_S3_SYS_RAM_LOW 0x60000000UL +#define ESP32_S3_SYS_RAM_HIGH (ESP32_S3_SYS_RAM_LOW + 0x10000000UL) +#define ESP32_S3_RTC_SLOW_MEM_BASE ESP32_S3_RTC_DATA_LOW + +/* ESP32_S3 WDT */ +#define ESP32_S3_WDT_WKEY_VALUE 0x50D83AA1 +#define ESP32_S3_TIMG0_BASE 0x6001F000 +#define ESP32_S3_TIMG1_BASE 0x60020000 +#define ESP32_S3_TIMGWDT_CFG0_OFF 0x48 +#define ESP32_S3_TIMGWDT_PROTECT_OFF 0x64 +#define ESP32_S3_TIMG0WDT_CFG0 (ESP32_S3_TIMG0_BASE + ESP32_S3_TIMGWDT_CFG0_OFF) +#define ESP32_S3_TIMG1WDT_CFG0 (ESP32_S3_TIMG1_BASE + ESP32_S3_TIMGWDT_CFG0_OFF) +#define ESP32_S3_TIMG0WDT_PROTECT (ESP32_S3_TIMG0_BASE + ESP32_S3_TIMGWDT_PROTECT_OFF) +#define ESP32_S3_TIMG1WDT_PROTECT (ESP32_S3_TIMG1_BASE + ESP32_S3_TIMGWDT_PROTECT_OFF) +#define ESP32_S3_RTCCNTL_BASE 0x60008000 +#define ESP32_S3_RTCWDT_CFG_OFF 0x98 +#define ESP32_S3_RTCWDT_PROTECT_OFF 0xB0 +#define ESP32_S3_SWD_CONF_OFF 0xB0 +#define ESP32_S3_SWD_WPROTECT_OFF 0xB4 +#define ESP32_S3_RTCWDT_CFG (ESP32_S3_RTCCNTL_BASE + ESP32_S3_RTCWDT_CFG_OFF) +#define ESP32_S3_RTCWDT_PROTECT (ESP32_S3_RTCCNTL_BASE + ESP32_S3_RTCWDT_PROTECT_OFF) +#define ESP32_S3_SWD_CONF_REG (ESP32_S3_RTCCNTL_BASE + ESP32_S3_SWD_CONF_OFF) +#define ESP32_S3_SWD_WPROTECT_REG (ESP32_S3_RTCCNTL_BASE + ESP32_S3_SWD_WPROTECT_OFF) +#define ESP32_S3_SWD_AUTO_FEED_EN_M BIT(31) +#define ESP32_S3_SWD_WKEY_VALUE 0x8F1D312AU + +#define ESP32_S3_TRACEMEM_BLOCK_SZ 0x4000 + +/* ESP32_S3 dport regs */ +#define ESP32_S3_DR_REG_SYSTEM_BASE 0x600c0000 +#define ESP32_S3_SYSTEM_CORE_1_CONTROL_0_REG (ESP32_S3_DR_REG_SYSTEM_BASE + 0x014) +#define ESP32_S3_SYSTEM_CONTROL_CORE_1_CLKGATE_EN BIT(1) + +/* ESP32_S3 RTC regs */ +#define ESP32_S3_RTC_CNTL_SW_CPU_STALL_REG (ESP32_S3_RTCCNTL_BASE + 0xBC) +#define ESP32_S3_RTC_CNTL_SW_CPU_STALL_DEF 0x0 + +struct esp32s3_common { + struct esp_xtensa_smp_common esp_xtensa_smp; +}; + +/* Reset ESP32-S3's peripherals. + * 1. OpenOCD makes sure the target is halted; if not, tries to halt it. + * If that fails, tries to reset it (via OCD) and then halt. + * 2. OpenOCD loads the stub code into RTC_SLOW_MEM. + * 3. Executes the stub code from address 0x50000004. + * 4. The stub code changes the reset vector to 0x50000000, and triggers + * a system reset using RTC_CNTL_SW_SYS_RST bit. + * 5. Once the PRO CPU is out of reset, it executes the stub code from address 0x50000000. + * The stub code disables the watchdog, re-enables JTAG and the APP CPU, + * restores the reset vector, and enters an infinite loop. + * 6. OpenOCD waits until it can talk to the OCD module again, then halts the target. + * 7. OpenOCD restores the contents of RTC_SLOW_MEM. + * + * End result: all the peripherals except RTC_CNTL are reset, CPU's PC is undefined, + * PRO CPU is halted, APP CPU is in reset. + */ + +static const uint8_t esp32s3_reset_stub_code[] = { +#include "../../../contrib/loaders/reset/espressif/esp32s3/cpu_reset_handler_code.inc" +}; + +static int esp32s3_soc_reset(struct target *target) +{ + int res; + struct target_list *head; + struct xtensa *xtensa; + + LOG_DEBUG("start"); + /* In order to write to peripheral registers, target must be halted first */ + if (target->state != TARGET_HALTED) { + LOG_DEBUG("Target not halted before SoC reset, trying to halt it first"); + xtensa_halt(target); + res = target_wait_state(target, TARGET_HALTED, 1000); + if (res != ERROR_OK) { + LOG_DEBUG("Couldn't halt target before SoC reset, trying to do reset-halt"); + res = xtensa_assert_reset(target); + if (res != ERROR_OK) { + LOG_ERROR( + "Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)", + res); + return res; + } + alive_sleep(10); + xtensa_poll(target); + bool reset_halt_save = target->reset_halt; + target->reset_halt = true; + res = xtensa_deassert_reset(target); + target->reset_halt = reset_halt_save; + if (res != ERROR_OK) { + LOG_ERROR( + "Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)", + res); + return res; + } + alive_sleep(10); + xtensa_poll(target); + xtensa_halt(target); + res = target_wait_state(target, TARGET_HALTED, 1000); + if (res != ERROR_OK) { + LOG_ERROR("Couldn't halt target before SoC reset"); + return res; + } + } + } + + if (target->smp) { + foreach_smp_target(head, target->smp_targets) { + xtensa = target_to_xtensa(head->target); + /* if any of the cores is stalled unstall them */ + if (xtensa_dm_core_is_stalled(&xtensa->dbg_mod)) { + LOG_TARGET_DEBUG(head->target, "Unstall CPUs before SW reset!"); + res = target_write_u32(target, + ESP32_S3_RTC_CNTL_SW_CPU_STALL_REG, + ESP32_S3_RTC_CNTL_SW_CPU_STALL_DEF); + if (res != ERROR_OK) { + LOG_TARGET_ERROR(head->target, "Failed to unstall CPUs before SW reset!"); + return res; + } + break; /* both cores are unstalled now, so exit the loop */ + } + } + } + + LOG_DEBUG("Loading stub code into RTC RAM"); + uint8_t slow_mem_save[sizeof(esp32s3_reset_stub_code)]; + + /* Save contents of RTC_SLOW_MEM which we are about to overwrite */ + res = target_read_buffer(target, ESP32_S3_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save); + if (res != ERROR_OK) { + LOG_ERROR("Failed to save contents of RTC_SLOW_MEM (%d)!", res); + return res; + } + + /* Write stub code into RTC_SLOW_MEM */ + res = target_write_buffer(target, + ESP32_S3_RTC_SLOW_MEM_BASE, + sizeof(esp32s3_reset_stub_code), + esp32s3_reset_stub_code); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write stub (%d)!", res); + return res; + } + + LOG_DEBUG("Resuming the target"); + xtensa = target_to_xtensa(target); + xtensa->suppress_dsr_errors = true; + res = xtensa_resume(target, 0, ESP32_S3_RTC_SLOW_MEM_BASE + 4, 0, 0); + xtensa->suppress_dsr_errors = false; + if (res != ERROR_OK) { + LOG_ERROR("Failed to run stub (%d)!", res); + return res; + } + LOG_DEBUG("resume done, waiting for the target to come alive"); + + /* Wait for SoC to reset */ + alive_sleep(100); + int64_t timeout = timeval_ms() + 100; + bool get_timeout = false; + while (target->state != TARGET_RESET && target->state != TARGET_RUNNING) { + alive_sleep(10); + xtensa_poll(target); + if (timeval_ms() >= timeout) { + LOG_TARGET_ERROR(target, + "Timed out waiting for CPU to be reset, target state=%d", + target->state); + get_timeout = true; + break; + } + } + + /* Halt the CPU again */ + LOG_DEBUG("halting the target"); + xtensa_halt(target); + res = target_wait_state(target, TARGET_HALTED, 1000); + if (res == ERROR_OK) { + LOG_DEBUG("restoring RTC_SLOW_MEM"); + res = target_write_buffer(target, ESP32_S3_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save); + if (res != ERROR_OK) + LOG_TARGET_ERROR(target, "Failed to restore contents of RTC_SLOW_MEM (%d)!", res); + } else { + LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be halted after SoC reset"); + } + + return get_timeout ? ERROR_TARGET_TIMEOUT : res; +} + +static int esp32s3_disable_wdts(struct target *target) +{ + /* TIMG1 WDT */ + int res = target_write_u32(target, ESP32_S3_TIMG0WDT_PROTECT, ESP32_S3_WDT_WKEY_VALUE); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_S3_TIMG0WDT_PROTECT (%d)!", res); + return res; + } + res = target_write_u32(target, ESP32_S3_TIMG0WDT_CFG0, 0); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_S3_TIMG0WDT_CFG0 (%d)!", res); + return res; + } + /* TIMG2 WDT */ + res = target_write_u32(target, ESP32_S3_TIMG1WDT_PROTECT, ESP32_S3_WDT_WKEY_VALUE); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_S3_TIMG1WDT_PROTECT (%d)!", res); + return res; + } + res = target_write_u32(target, ESP32_S3_TIMG1WDT_CFG0, 0); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_S3_TIMG1WDT_CFG0 (%d)!", res); + return res; + } + /* RTC WDT */ + res = target_write_u32(target, ESP32_S3_RTCWDT_PROTECT, ESP32_S3_WDT_WKEY_VALUE); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_S3_RTCWDT_PROTECT (%d)!", res); + return res; + } + res = target_write_u32(target, ESP32_S3_RTCWDT_CFG, 0); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_S3_RTCWDT_CFG (%d)!", res); + return res; + } + /* Enable SWD auto-feed */ + res = target_write_u32(target, ESP32_S3_SWD_WPROTECT_REG, ESP32_S3_SWD_WKEY_VALUE); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_S3_SWD_WPROTECT_REG (%d)!", res); + return res; + } + uint32_t swd_conf_reg = 0; + res = target_read_u32(target, ESP32_S3_SWD_CONF_REG, &swd_conf_reg); + if (res != ERROR_OK) { + LOG_ERROR("Failed to read ESP32_S3_SWD_CONF_REG (%d)!", res); + return res; + } + swd_conf_reg |= ESP32_S3_SWD_AUTO_FEED_EN_M; + res = target_write_u32(target, ESP32_S3_SWD_CONF_REG, swd_conf_reg); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write ESP32_S3_SWD_CONF_REG (%d)!", res); + return res; + } + return ERROR_OK; +} + +static int esp32s3_on_halt(struct target *target) +{ + return esp32s3_disable_wdts(target); +} + +static int esp32s3_arch_state(struct target *target) +{ + return ERROR_OK; +} + +static int esp32s3_virt2phys(struct target *target, + target_addr_t virtual, target_addr_t *physical) +{ + if (physical) { + *physical = virtual; + return ERROR_OK; + } + return ERROR_FAIL; +} + +static int esp32s3_target_init(struct command_context *cmd_ctx, struct target *target) +{ + return esp_xtensa_smp_target_init(cmd_ctx, target); +} + +static const struct xtensa_debug_ops esp32s3_dbg_ops = { + .queue_enable = xtensa_dm_queue_enable, + .queue_reg_read = xtensa_dm_queue_reg_read, + .queue_reg_write = xtensa_dm_queue_reg_write +}; + +static const struct xtensa_power_ops esp32s3_pwr_ops = { + .queue_reg_read = xtensa_dm_queue_pwr_reg_read, + .queue_reg_write = xtensa_dm_queue_pwr_reg_write +}; + +static const struct esp_xtensa_smp_chip_ops esp32s3_chip_ops = { + .reset = esp32s3_soc_reset, + .on_halt = esp32s3_on_halt +}; + +static const struct esp_semihost_ops esp32s3_semihost_ops = { + .prepare = esp32s3_disable_wdts +}; + +static int esp32s3_target_create(struct target *target, Jim_Interp *interp) +{ + struct xtensa_debug_module_config esp32s3_dm_cfg = { + .dbg_ops = &esp32s3_dbg_ops, + .pwr_ops = &esp32s3_pwr_ops, + .tap = target->tap, + .queue_tdi_idle = NULL, + .queue_tdi_idle_arg = NULL + }; + + struct esp32s3_common *esp32s3 = calloc(1, sizeof(struct esp32s3_common)); + if (!esp32s3) { + LOG_ERROR("Failed to alloc memory for arch info!"); + return ERROR_FAIL; + } + + int ret = esp_xtensa_smp_init_arch_info(target, + &esp32s3->esp_xtensa_smp, + &esp32s3_dm_cfg, + &esp32s3_chip_ops, + &esp32s3_semihost_ops); + if (ret != ERROR_OK) { + LOG_ERROR("Failed to init arch info!"); + free(esp32s3); + return ret; + } + + /* Assume running target. If different, the first poll will fix this. */ + target->state = TARGET_RUNNING; + target->debug_reason = DBG_REASON_NOTHALTED; + return ERROR_OK; +} + +static const struct command_registration esp32s3_command_handlers[] = { + { + .usage = "", + .chain = esp_xtensa_smp_command_handlers, + }, + { + .name = "esp32", + .usage = "", + .chain = smp_command_handlers, + }, + { + .name = "arm", + .mode = COMMAND_ANY, + .help = "ARM Command Group", + .usage = "", + .chain = semihosting_common_handlers + }, + COMMAND_REGISTRATION_DONE +}; + +/** Holds methods for Xtensa targets. */ +struct target_type esp32s3_target = { + .name = "esp32s3", + + .poll = esp_xtensa_smp_poll, + .arch_state = esp32s3_arch_state, + + .halt = xtensa_halt, + .resume = esp_xtensa_smp_resume, + .step = esp_xtensa_smp_step, + + .assert_reset = esp_xtensa_smp_assert_reset, + .deassert_reset = esp_xtensa_smp_deassert_reset, + .soft_reset_halt = esp_xtensa_smp_soft_reset_halt, + + .virt2phys = esp32s3_virt2phys, + .mmu = xtensa_mmu_is_enabled, + .read_memory = xtensa_read_memory, + .write_memory = xtensa_write_memory, + + .read_buffer = xtensa_read_buffer, + .write_buffer = xtensa_write_buffer, + + .checksum_memory = xtensa_checksum_memory, + + .get_gdb_arch = xtensa_get_gdb_arch, + .get_gdb_reg_list = xtensa_get_gdb_reg_list, + + .add_breakpoint = esp_xtensa_breakpoint_add, + .remove_breakpoint = esp_xtensa_breakpoint_remove, + + .add_watchpoint = esp_xtensa_smp_watchpoint_add, + .remove_watchpoint = esp_xtensa_smp_watchpoint_remove, + + .target_create = esp32s3_target_create, + .init_target = esp32s3_target_init, + .examine = xtensa_examine, + .deinit_target = esp_xtensa_target_deinit, + + .commands = esp32s3_command_handlers, +}; diff --git a/src/target/espressif/esp_semihosting.c b/src/target/espressif/esp_semihosting.c new file mode 100644 index 0000000..5e9cb94 --- /dev/null +++ b/src/target/espressif/esp_semihosting.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * Semihosting API for Espressif chips * + * Copyright (C) 2022 Espressif Systems Ltd. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <helper/log.h> +#include <target/target.h> +#include <target/semihosting_common.h> +#include "esp_semihosting.h" +#include "esp_xtensa.h" + +static struct esp_semihost_data __attribute__((unused)) *target_to_esp_semihost_data(struct target *target) +{ + const char *arch = target_get_gdb_arch(target); + if (arch) { + if (strncmp(arch, "xtensa", 6) == 0) + return &target_to_esp_xtensa(target)->semihost; + /* TODO: add riscv */ + } + LOG_ERROR("Unknown target arch!"); + return NULL; +} + +static int esp_semihosting_sys_seek(struct target *target, uint64_t fd, uint32_t pos, size_t whence) +{ + struct semihosting *semihosting = target->semihosting; + + semihosting->result = lseek(fd, pos, whence); + semihosting->sys_errno = errno; + LOG_TARGET_DEBUG(target, "lseek(%" PRIx64 ", %" PRIu32 " %" PRId64 ")=%d", fd, pos, semihosting->result, errno); + return ERROR_OK; +} + +int esp_semihosting_common(struct target *target) +{ + struct semihosting *semihosting = target->semihosting; + if (!semihosting) + /* Silently ignore if the semihosting field was not set. */ + return ERROR_OK; + + int retval = ERROR_NOT_IMPLEMENTED; + + /* Enough space to hold 4 long words. */ + uint8_t fields[4 * 8]; + + /* + * By default return an error. + * The actual result must be set by each function + */ + semihosting->result = -1; + semihosting->sys_errno = EIO; + + LOG_TARGET_DEBUG(target, "op=0x%x, param=0x%" PRIx64, semihosting->op, semihosting->param); + + switch (semihosting->op) { + case ESP_SEMIHOSTING_SYS_DRV_INFO: + /* Return success to make esp-idf application happy */ + retval = ERROR_OK; + semihosting->result = 0; + semihosting->sys_errno = 0; + break; + + case ESP_SEMIHOSTING_SYS_SEEK: + retval = semihosting_read_fields(target, 3, fields); + if (retval == ERROR_OK) { + uint64_t fd = semihosting_get_field(target, 0, fields); + uint32_t pos = semihosting_get_field(target, 1, fields); + size_t whence = semihosting_get_field(target, 2, fields); + retval = esp_semihosting_sys_seek(target, fd, pos, whence); + } + break; + + case ESP_SEMIHOSTING_SYS_APPTRACE_INIT: + case ESP_SEMIHOSTING_SYS_DEBUG_STUBS_INIT: + case ESP_SEMIHOSTING_SYS_BREAKPOINT_SET: + case ESP_SEMIHOSTING_SYS_WATCHPOINT_SET: + /* For the time being only riscv chips support these commands + * TODO: invoke riscv custom command handler */ + break; + } + + return retval; +} + +int esp_semihosting_basedir_command(struct command_invocation *cmd) +{ + struct target *target = get_current_target(CMD_CTX); + + if (!target) { + LOG_ERROR("No target selected"); + return ERROR_FAIL; + } + + struct semihosting *semihosting = target->semihosting; + if (!semihosting) { + command_print(CMD, "semihosting not supported for current target"); + return ERROR_FAIL; + } + + if (!semihosting->is_active) { + if (semihosting->setup(target, true) != ERROR_OK) { + LOG_ERROR("Failed to Configure semihosting"); + return ERROR_FAIL; + } + semihosting->is_active = true; + } + + if (CMD_ARGC > 0) { + free(semihosting->basedir); + semihosting->basedir = strdup(CMD_ARGV[0]); + if (!semihosting->basedir) { + command_print(CMD, "semihosting failed to allocate memory for basedir!"); + return ERROR_FAIL; + } + } + + command_print(CMD, "DEPRECATED! semihosting base dir: %s", + semihosting->basedir ? semihosting->basedir : ""); + + return ERROR_OK; +} diff --git a/src/target/espressif/esp_semihosting.h b/src/target/espressif/esp_semihosting.h new file mode 100644 index 0000000..bd2c079 --- /dev/null +++ b/src/target/espressif/esp_semihosting.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/*************************************************************************** + * Semihosting API for Espressif chips * + * Copyright (C) 2022 Espressif Systems Ltd. * + ***************************************************************************/ + +#ifndef OPENOCD_TARGET_ESP_SEMIHOSTING_H +#define OPENOCD_TARGET_ESP_SEMIHOSTING_H + +/* Legacy syscalls */ +#define ESP_SYS_DRV_INFO_LEGACY 0xE0 + +/* syscalls compatible to ARM standard */ +#define ESP_SEMIHOSTING_SYS_DRV_INFO 0x100 +#define ESP_SEMIHOSTING_SYS_APPTRACE_INIT 0x101 +#define ESP_SEMIHOSTING_SYS_DEBUG_STUBS_INIT 0x102 +#define ESP_SEMIHOSTING_SYS_BREAKPOINT_SET 0x103 +#define ESP_SEMIHOSTING_SYS_WATCHPOINT_SET 0x104 +#define ESP_SEMIHOSTING_SYS_SEEK 0x105 /* custom lseek with whence */ +/* not implemented yet */ +#define ESP_SEMIHOSTING_SYS_MKDIR 0x106 +#define ESP_SEMIHOSTING_SYS_OPENDIR 0x107 +#define ESP_SEMIHOSTING_SYS_READDIR 0x108 +#define ESP_SEMIHOSTING_SYS_READDIR_R 0x109 +#define ESP_SEMIHOSTING_SYS_SEEKDIR 0x10A +#define ESP_SEMIHOSTING_SYS_TELLDIR 0x10B +#define ESP_SEMIHOSTING_SYS_CLOSEDIR 0x10C +#define ESP_SEMIHOSTING_SYS_RMDIR 0x10D +#define ESP_SEMIHOSTING_SYS_ACCESS 0x10E +#define ESP_SEMIHOSTING_SYS_TRUNCATE 0x10F +#define ESP_SEMIHOSTING_SYS_UTIME 0x110 +#define ESP_SEMIHOSTING_SYS_FSTAT 0x111 +#define ESP_SEMIHOSTING_SYS_STAT 0x112 +#define ESP_SEMIHOSTING_SYS_FSYNC 0x113 +#define ESP_SEMIHOSTING_SYS_LINK 0x114 +#define ESP_SEMIHOSTING_SYS_UNLINK 0x115 + +/** + * Semihost calls handling operations. + */ +struct esp_semihost_ops { + /** Callback called before handling semihost call */ + int (*prepare)(struct target *target); +}; + +struct esp_semihost_data { + bool need_resume; + struct esp_semihost_ops *ops; +}; + +int esp_semihosting_common(struct target *target); +int esp_semihosting_basedir_command(struct command_invocation *cmd); + +#endif /* OPENOCD_TARGET_ESP_SEMIHOSTING_H */ diff --git a/src/target/espressif/esp_xtensa.c b/src/target/espressif/esp_xtensa.c index 89393f4..fcc340c 100644 --- a/src/target/espressif/esp_xtensa.c +++ b/src/target/espressif/esp_xtensa.c @@ -1,20 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Espressif Xtensa target API for OpenOCD * * Copyright (C) 2019 Espressif Systems Ltd. * - * Author: Alexey Gerenkov <alexey@espressif.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -24,15 +12,20 @@ #include <stdbool.h> #include <stdint.h> #include <target/smp.h> -#include "esp_xtensa.h" #include <target/register.h> +#include "esp_xtensa.h" +#include "esp_semihosting.h" int esp_xtensa_init_arch_info(struct target *target, struct esp_xtensa_common *esp_xtensa, - const struct xtensa_config *xtensa_cfg, - struct xtensa_debug_module_config *dm_cfg) + struct xtensa_debug_module_config *dm_cfg, + const struct esp_semihost_ops *semihost_ops) { - return xtensa_init_arch_info(target, &esp_xtensa->xtensa, xtensa_cfg, dm_cfg); + int ret = xtensa_init_arch_info(target, &esp_xtensa->xtensa, dm_cfg); + if (ret != ERROR_OK) + return ret; + esp_xtensa->semihost.ops = (struct esp_semihost_ops *)semihost_ops; + return ERROR_OK; } int esp_xtensa_target_init(struct command_context *cmd_ctx, struct target *target) diff --git a/src/target/espressif/esp_xtensa.h b/src/target/espressif/esp_xtensa.h index 6badb1b..1ad6c37 100644 --- a/src/target/espressif/esp_xtensa.h +++ b/src/target/espressif/esp_xtensa.h @@ -1,31 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Generic ESP xtensa target implementation for OpenOCD * * Copyright (C) 2019 Espressif Systems Ltd. * - * Author: Alexey Gerenkov <alexey@espressif.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ESP_XTENSA_H #define OPENOCD_TARGET_ESP_XTENSA_H -#include <helper/command.h> #include <target/target.h> #include <target/xtensa/xtensa.h> +#include "esp_xtensa.h" +#include "esp_semihosting.h" struct esp_xtensa_common { struct xtensa xtensa; /* must be the first element */ + struct esp_semihost_data semihost; }; static inline struct esp_xtensa_common *target_to_esp_xtensa(struct target *target) @@ -35,8 +25,8 @@ static inline struct esp_xtensa_common *target_to_esp_xtensa(struct target *targ int esp_xtensa_init_arch_info(struct target *target, struct esp_xtensa_common *esp_xtensa, - const struct xtensa_config *xtensa_cfg, - struct xtensa_debug_module_config *dm_cfg); + struct xtensa_debug_module_config *dm_cfg, + const struct esp_semihost_ops *semihost_ops); int esp_xtensa_target_init(struct command_context *cmd_ctx, struct target *target); void esp_xtensa_target_deinit(struct target *target); int esp_xtensa_arch_state(struct target *target); diff --git a/src/target/espressif/esp_xtensa_semihosting.c b/src/target/espressif/esp_xtensa_semihosting.c new file mode 100644 index 0000000..54e9c4b --- /dev/null +++ b/src/target/espressif/esp_xtensa_semihosting.c @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * Copyright (c) 2020 Espressif Systems (Shanghai) Co. Ltd. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <target/semihosting_common.h> +#include <target/xtensa/xtensa_regs.h> +#include <target/xtensa/xtensa.h> +#include "esp_xtensa.h" +#include "esp_xtensa_semihosting.h" + +#define ESP_XTENSA_SYSCALL 0x41E0 /* XT_INS_BREAK(1, 14) */ +#define ESP_XTENSA_SYSCALL_SZ 3 + +#define XTENSA_SYSCALL_OP_REG XT_REG_IDX_A2 +#define XTENSA_SYSCALL_RETVAL_REG XT_REG_IDX_A2 +#define XTENSA_SYSCALL_ERRNO_REG XT_REG_IDX_A3 + +static int esp_xtensa_semihosting_setup(struct target *target, int enable) +{ + LOG_TARGET_DEBUG(target, "semihosting enable=%d", enable); + + return ERROR_OK; +} + +static int esp_xtensa_semihosting_post_result(struct target *target) +{ + /* Even with the v2 and later, errno will not retrieved from A3 reg, it is safe to set */ + xtensa_reg_set(target, XTENSA_SYSCALL_RETVAL_REG, target->semihosting->result); + xtensa_reg_set(target, XTENSA_SYSCALL_ERRNO_REG, target->semihosting->sys_errno); + return ERROR_OK; +} + +/** + * Checks and processes an ESP Xtensa semihosting request. This is meant + * to be called when the target is stopped due to a debug mode entry. + * If the value 0 is returned then there was nothing to process. A non-zero + * return value signifies that a request was processed and the target resumed, + * or an error was encountered, in which case the caller must return immediately. + * + * @param target Pointer to the ESP Xtensa target to process. + * @param retval Pointer to a location where the return code will be stored + * @return SEMIHOSTING_HANDLED if a request was processed or SEMIHOSTING_NONE with the proper retval + */ +int esp_xtensa_semihosting(struct target *target, int *retval) +{ + struct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target); + + xtensa_reg_val_t dbg_cause = xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE); + if ((dbg_cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)) == 0) + return SEMIHOSTING_NONE; + + uint8_t brk_insn_buf[sizeof(uint32_t)] = { 0 }; + xtensa_reg_val_t pc = xtensa_reg_get(target, XT_REG_IDX_PC); + *retval = target_read_memory(target, pc, ESP_XTENSA_SYSCALL_SZ, 1, brk_insn_buf); + if (*retval != ERROR_OK) { + LOG_TARGET_ERROR(target, "Failed to read break instruction!"); + return SEMIHOSTING_NONE; + } + + uint32_t syscall_ins = buf_get_u32(brk_insn_buf, 0, 32); + if (syscall_ins != ESP_XTENSA_SYSCALL) { + *retval = ERROR_OK; + return SEMIHOSTING_NONE; + } + + if (esp_xtensa->semihost.ops && esp_xtensa->semihost.ops->prepare) + esp_xtensa->semihost.ops->prepare(target); + + xtensa_reg_val_t a2 = xtensa_reg_get(target, XT_REG_IDX_A2); + xtensa_reg_val_t a3 = xtensa_reg_get(target, XT_REG_IDX_A3); + LOG_TARGET_DEBUG(target, "Semihosting call 0x%" PRIx32 " 0x%" PRIx32 " Base dir '%s'", + a2, + a3, + target->semihosting->basedir ? target->semihosting->basedir : ""); + + target->semihosting->op = a2; + target->semihosting->param = a3; + + *retval = semihosting_common(target); + + /* Most operations are resumable, except the two exit calls. */ + if (*retval != ERROR_OK) { + LOG_TARGET_ERROR(target, "Semihosting operation (op: 0x%x) error! Code: %d", + target->semihosting->op, + *retval); + } + + /* Resume if target it is resumable and we are not waiting on a fileio operation to complete. */ + if (target->semihosting->is_resumable && !target->semihosting->hit_fileio) + target_to_esp_xtensa(target)->semihost.need_resume = true; + + return SEMIHOSTING_HANDLED; +} + +static int xtensa_semihosting_init(struct target *target) +{ + return semihosting_common_init(target, esp_xtensa_semihosting_setup, esp_xtensa_semihosting_post_result); +} + +int esp_xtensa_semihosting_init(struct target *target) +{ + int retval = xtensa_semihosting_init(target); + if (retval != ERROR_OK) + return retval; + target->semihosting->word_size_bytes = 4; /* 32 bits */ + target->semihosting->user_command_extension = esp_semihosting_common; + return ERROR_OK; +} diff --git a/src/target/espressif/esp_xtensa_semihosting.h b/src/target/espressif/esp_xtensa_semihosting.h new file mode 100644 index 0000000..1da3115 --- /dev/null +++ b/src/target/espressif/esp_xtensa_semihosting.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/*************************************************************************** + * Copyright (c) 2020 Espressif Systems (Shanghai) Co. Ltd. * + ***************************************************************************/ + +#ifndef OPENOCD_TARGET_ESP_XTENSA_SEMIHOSTING_H +#define OPENOCD_TARGET_ESP_XTENSA_SEMIHOSTING_H + +#include <target/target.h> + +int esp_xtensa_semihosting_init(struct target *target); +int esp_xtensa_semihosting(struct target *target, int *retval); + +#endif /* OPENOCD_TARGET_ESP_XTENSA_SEMIHOSTING_H */ diff --git a/src/target/espressif/esp_xtensa_smp.c b/src/target/espressif/esp_xtensa_smp.c new file mode 100644 index 0000000..1d03774 --- /dev/null +++ b/src/target/espressif/esp_xtensa_smp.c @@ -0,0 +1,931 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * ESP Xtensa SMP target API for OpenOCD * + * Copyright (C) 2020 Espressif Systems Ltd. Co * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "assert.h" +#include <target/target.h> +#include <target/target_type.h> +#include <target/smp.h> +#include <target/semihosting_common.h> +#include "esp_xtensa_smp.h" +#include "esp_xtensa_semihosting.h" + +/* +Multiprocessor stuff common: + +The ESP Xtensa chip can have several cores in it, which can run in SMP-mode if an +SMP-capable OS is running. The hardware has a few features which makes +SMP debugging much easier. + +First of all, there's something called a 'break network', consisting of a +BreakIn input and a BreakOut output on each CPU. The idea is that as soon +as a CPU goes into debug mode for whatever reason, it'll signal that using +its DebugOut pin. This signal is connected to the other CPU's DebugIn +input, causing this CPU also to go into debugging mode. To resume execution +when using only this break network, we will need to manually resume both +CPUs. + +An alternative to this is the XOCDMode output and the RunStall (or DebugStall) +input. When these are cross-connected, a CPU that goes into debug mode will +halt execution entirely on the other CPU. Execution on the other CPU can be +resumed by either the first CPU going out of debug mode, or the second CPU +going into debug mode: the stall is temporarily lifted as long as the stalled +CPU is in debug mode. + +A third, separate, signal is CrossTrigger. This is connected in the same way +as the breakIn/breakOut network, but is for the TRAX (trace memory) feature; +it does not affect OCD in any way. +*/ + +/* +Multiprocessor stuff: + +The ESP Xtensa chip has several Xtensa cores inside, but represent themself to the OCD +as one chip that works in multithreading mode under FreeRTOS OS. +The core that initiate the stop condition will be defined as an active cpu. +When one core stops, then other core will be stopped automatically by smpbreak. +The core that initiates stop condition will be defined as an active core, and +registers of this core will be transferred. +*/ + +#define ESP_XTENSA_SMP_EXAMINE_OTHER_CORES 5 + +static int esp_xtensa_smp_update_halt_gdb(struct target *target, bool *need_resume); + +static inline struct esp_xtensa_smp_common *target_to_esp_xtensa_smp(struct target *target) +{ + return container_of(target->arch_info, struct esp_xtensa_smp_common, esp_xtensa); +} + +int esp_xtensa_smp_assert_reset(struct target *target) +{ + return ERROR_OK; +} + +int esp_xtensa_smp_deassert_reset(struct target *target) +{ + LOG_TARGET_DEBUG(target, "begin"); + + int ret = xtensa_deassert_reset(target); + if (ret != ERROR_OK) + return ret; + /* in SMP mode when chip was running single-core app the other core can be left un-examined, + because examination is done before SOC reset. But after SOC reset it is functional and should be handled. + So try to examine un-examined core just after SOC reset */ + if (target->smp && !target_was_examined(target)) + ret = xtensa_examine(target); + return ret; +} + +int esp_xtensa_smp_soft_reset_halt(struct target *target) +{ + int res; + struct target_list *head; + struct esp_xtensa_smp_common *esp_xtensa_smp = target_to_esp_xtensa_smp(target); + + LOG_TARGET_DEBUG(target, "begin"); + /* in SMP mode we need to ensure that at first we reset SOC on PRO-CPU + and then call xtensa_assert_reset() for all cores */ + if (target->smp && target->coreid != 0) + return ERROR_OK; + /* Reset the SoC first */ + if (esp_xtensa_smp->chip_ops->reset) { + res = esp_xtensa_smp->chip_ops->reset(target); + if (res != ERROR_OK) + return res; + } + if (!target->smp) + return xtensa_assert_reset(target); + + foreach_smp_target(head, target->smp_targets) { + res = xtensa_assert_reset(head->target); + if (res != ERROR_OK) + return res; + } + return ERROR_OK; +} + +static struct target *get_halted_esp_xtensa_smp(struct target *target, int32_t coreid) +{ + struct target_list *head; + struct target *curr; + + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + if ((curr->coreid == coreid) && (curr->state == TARGET_HALTED)) + return curr; + } + + return target; +} + +int esp_xtensa_smp_poll(struct target *target) +{ + enum target_state old_state = target->state; + struct esp_xtensa_smp_common *esp_xtensa_smp = target_to_esp_xtensa_smp(target); + struct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target); + struct target_list *head; + struct target *curr; + bool other_core_resume_req = false; + + if (target->state == TARGET_HALTED && target->smp && target->gdb_service && !target->gdb_service->target) { + target->gdb_service->target = get_halted_esp_xtensa_smp(target, target->gdb_service->core[1]); + LOG_INFO("Switch GDB target to '%s'", target_name(target->gdb_service->target)); + if (esp_xtensa_smp->chip_ops->on_halt) + esp_xtensa_smp->chip_ops->on_halt(target); + target_call_event_callbacks(target, TARGET_EVENT_HALTED); + return ERROR_OK; + } + + int ret = esp_xtensa_poll(target); + if (ret != ERROR_OK) + return ret; + + if (target->smp) { + if (target->state == TARGET_RESET) { + esp_xtensa_smp->examine_other_cores = ESP_XTENSA_SMP_EXAMINE_OTHER_CORES; + } else if (esp_xtensa_smp->examine_other_cores > 0 && + (target->state == TARGET_RUNNING || target->state == TARGET_HALTED)) { + LOG_TARGET_DEBUG(target, "Check for unexamined cores after reset"); + bool all_examined = true; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + if (curr == target) + continue; + if (!target_was_examined(curr)) { + if (target_examine_one(curr) != ERROR_OK) { + LOG_DEBUG("Failed to examine!"); + all_examined = false; + } + } + } + if (all_examined) + esp_xtensa_smp->examine_other_cores = 0; + else + esp_xtensa_smp->examine_other_cores--; + } + } + + if (old_state != TARGET_HALTED && target->state == TARGET_HALTED) { + if (target->smp) { + ret = esp_xtensa_smp_update_halt_gdb(target, &other_core_resume_req); + if (ret != ERROR_OK) + return ret; + } + /* Call any event callbacks that are applicable */ + if (old_state == TARGET_DEBUG_RUNNING) { + target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); + } else { + if (esp_xtensa_semihosting(target, &ret) == SEMIHOSTING_HANDLED) { + if (ret == ERROR_OK && esp_xtensa->semihost.need_resume && + !esp_xtensa_smp->other_core_does_resume) { + esp_xtensa->semihost.need_resume = false; + /* Resume xtensa_resume will handle BREAK instruction. */ + ret = target_resume(target, 1, 0, 1, 0); + if (ret != ERROR_OK) { + LOG_ERROR("Failed to resume target"); + return ret; + } + } + return ret; + } + /* check whether any core polled by esp_xtensa_smp_update_halt_gdb() requested resume */ + if (target->smp && other_core_resume_req) { + /* Resume xtensa_resume will handle BREAK instruction. */ + ret = target_resume(target, 1, 0, 1, 0); + if (ret != ERROR_OK) { + LOG_ERROR("Failed to resume target"); + return ret; + } + return ERROR_OK; + } + if (esp_xtensa_smp->chip_ops->on_halt) + esp_xtensa_smp->chip_ops->on_halt(target); + target_call_event_callbacks(target, TARGET_EVENT_HALTED); + } + } + + return ERROR_OK; +} + +static int esp_xtensa_smp_update_halt_gdb(struct target *target, bool *need_resume) +{ + struct esp_xtensa_smp_common *esp_xtensa_smp; + struct target *gdb_target = NULL; + struct target_list *head; + struct target *curr; + int ret = ERROR_OK; + + *need_resume = false; + + if (target->gdb_service && target->gdb_service->target) + LOG_DEBUG("GDB target '%s'", target_name(target->gdb_service->target)); + + if (target->gdb_service && target->gdb_service->core[0] == -1) { + target->gdb_service->target = target; + target->gdb_service->core[0] = target->coreid; + LOG_INFO("Set GDB target to '%s'", target_name(target)); + } + + if (target->gdb_service) + gdb_target = target->gdb_service->target; + + /* due to smpbreak config other cores can also go to HALTED state */ + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + LOG_DEBUG("Check target '%s'", target_name(curr)); + /* skip calling context */ + if (curr == target) + continue; + if (!target_was_examined(curr)) { + curr->state = TARGET_HALTED; + continue; + } + /* skip targets that were already halted */ + if (curr->state == TARGET_HALTED) + continue; + /* Skip gdb_target; it alerts GDB so has to be polled as last one */ + if (curr == gdb_target) + continue; + LOG_DEBUG("Poll target '%s'", target_name(curr)); + + esp_xtensa_smp = target_to_esp_xtensa_smp(curr); + /* avoid auto-resume after syscall, it will be done later */ + esp_xtensa_smp->other_core_does_resume = true; + /* avoid recursion in esp_xtensa_smp_poll() */ + curr->smp = 0; + if (esp_xtensa_smp->chip_ops->poll) + ret = esp_xtensa_smp->chip_ops->poll(curr); + else + ret = esp_xtensa_smp_poll(curr); + curr->smp = 1; + if (ret != ERROR_OK) + return ret; + esp_xtensa_smp->other_core_does_resume = false; + struct esp_xtensa_common *curr_esp_xtensa = target_to_esp_xtensa(curr); + if (curr_esp_xtensa->semihost.need_resume) { + curr_esp_xtensa->semihost.need_resume = false; + *need_resume = true; + } + } + + /* after all targets were updated, poll the gdb serving target */ + if (gdb_target && gdb_target != target) { + esp_xtensa_smp = target_to_esp_xtensa_smp(gdb_target); + if (esp_xtensa_smp->chip_ops->poll) + ret = esp_xtensa_smp->chip_ops->poll(gdb_target); + else + ret = esp_xtensa_smp_poll(gdb_target); + } + + LOG_DEBUG("exit"); + + return ret; +} + +static inline int esp_xtensa_smp_smpbreak_disable(struct target *target, uint32_t *smp_break) +{ + int res = xtensa_smpbreak_get(target, smp_break); + if (res != ERROR_OK) + return res; + return xtensa_smpbreak_set(target, 0); +} + +static inline int esp_xtensa_smp_smpbreak_restore(struct target *target, uint32_t smp_break) +{ + return xtensa_smpbreak_set(target, smp_break); +} + +static int esp_xtensa_smp_resume_cores(struct target *target, + int handle_breakpoints, + int debug_execution) +{ + struct target_list *head; + struct target *curr; + + LOG_TARGET_DEBUG(target, "begin"); + + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + /* in single-core mode disabled core cannot be examined, but need to be resumed too*/ + if ((curr != target) && (curr->state != TARGET_RUNNING) && target_was_examined(curr)) { + /* resume current address, not in SMP mode */ + curr->smp = 0; + int res = esp_xtensa_smp_resume(curr, 1, 0, handle_breakpoints, debug_execution); + curr->smp = 1; + if (res != ERROR_OK) + return res; + } + } + return ERROR_OK; +} + +int esp_xtensa_smp_resume(struct target *target, + int current, + target_addr_t address, + int handle_breakpoints, + int debug_execution) +{ + int res; + uint32_t smp_break; + + xtensa_smpbreak_get(target, &smp_break); + LOG_TARGET_DEBUG(target, "smp_break=0x%" PRIx32, smp_break); + + /* dummy resume for smp toggle in order to reduce gdb impact */ + if ((target->smp) && (target->gdb_service) && (target->gdb_service->core[1] != -1)) { + /* simulate a start and halt of target */ + target->gdb_service->target = NULL; + target->gdb_service->core[0] = target->gdb_service->core[1]; + /* fake resume at next poll we play the target core[1], see poll*/ + LOG_TARGET_DEBUG(target, "Fake resume"); + target_call_event_callbacks(target, TARGET_EVENT_RESUMED); + return ERROR_OK; + } + + /* xtensa_prepare_resume() can step over breakpoint/watchpoint and generate signals on BreakInOut circuit for + * other cores. So disconnect this core from BreakInOut circuit and do xtensa_prepare_resume(). */ + res = esp_xtensa_smp_smpbreak_disable(target, &smp_break); + if (res != ERROR_OK) + return res; + res = xtensa_prepare_resume(target, current, address, handle_breakpoints, debug_execution); + /* restore configured BreakInOut signals config */ + int ret = esp_xtensa_smp_smpbreak_restore(target, smp_break); + if (ret != ERROR_OK) + return ret; + if (res != ERROR_OK) { + LOG_TARGET_ERROR(target, "Failed to prepare for resume!"); + return res; + } + + if (target->smp) { + if (target->gdb_service) + target->gdb_service->core[0] = -1; + res = esp_xtensa_smp_resume_cores(target, handle_breakpoints, debug_execution); + if (res != ERROR_OK) + return res; + } + + res = xtensa_do_resume(target); + if (res != ERROR_OK) { + LOG_TARGET_ERROR(target, "Failed to resume!"); + return res; + } + + target->debug_reason = DBG_REASON_NOTHALTED; + if (!debug_execution) + target->state = TARGET_RUNNING; + else + target->state = TARGET_DEBUG_RUNNING; + + target_call_event_callbacks(target, TARGET_EVENT_RESUMED); + return ERROR_OK; +} + +int esp_xtensa_smp_step(struct target *target, + int current, + target_addr_t address, + int handle_breakpoints) +{ + int res; + uint32_t smp_break = 0; + struct esp_xtensa_smp_common *esp_xtensa_smp = target_to_esp_xtensa_smp(target); + + if (target->smp) { + res = esp_xtensa_smp_smpbreak_disable(target, &smp_break); + if (res != ERROR_OK) + return res; + } + res = xtensa_step(target, current, address, handle_breakpoints); + + if (res == ERROR_OK) { + if (esp_xtensa_smp->chip_ops->on_halt) + esp_xtensa_smp->chip_ops->on_halt(target); + target_call_event_callbacks(target, TARGET_EVENT_HALTED); + } + + if (target->smp) { + int ret = esp_xtensa_smp_smpbreak_restore(target, smp_break); + if (ret != ERROR_OK) + return ret; + } + + return res; +} + +int esp_xtensa_smp_watchpoint_add(struct target *target, struct watchpoint *watchpoint) +{ + int res = xtensa_watchpoint_add(target, watchpoint); + if (res != ERROR_OK) + return res; + + if (!target->smp) + return ERROR_OK; + + struct target_list *head; + foreach_smp_target(head, target->smp_targets) { + struct target *curr = head->target; + if (curr == target || !target_was_examined(curr)) + continue; + /* Need to use high level API here because every target for core contains list of watchpoints. + * GDB works with active core only, so we need to duplicate every watchpoint on other cores, + * otherwise watchpoint_free() on active core can fail if WP has been initially added on another core. */ + curr->smp = 0; + res = watchpoint_add(curr, watchpoint->address, watchpoint->length, + watchpoint->rw, watchpoint->value, watchpoint->mask); + curr->smp = 1; + if (res != ERROR_OK) + return res; + } + return ERROR_OK; +} + +int esp_xtensa_smp_watchpoint_remove(struct target *target, struct watchpoint *watchpoint) +{ + int res = xtensa_watchpoint_remove(target, watchpoint); + if (res != ERROR_OK) + return res; + + if (!target->smp) + return ERROR_OK; + + struct target_list *head; + foreach_smp_target(head, target->smp_targets) { + struct target *curr = head->target; + if (curr == target) + continue; + /* see big comment in esp_xtensa_smp_watchpoint_add() */ + curr->smp = 0; + watchpoint_remove(curr, watchpoint->address); + curr->smp = 1; + } + return ERROR_OK; +} + +int esp_xtensa_smp_init_arch_info(struct target *target, + struct esp_xtensa_smp_common *esp_xtensa_smp, + struct xtensa_debug_module_config *dm_cfg, + const struct esp_xtensa_smp_chip_ops *chip_ops, + const struct esp_semihost_ops *semihost_ops) +{ + int ret = esp_xtensa_init_arch_info(target, &esp_xtensa_smp->esp_xtensa, dm_cfg, semihost_ops); + if (ret != ERROR_OK) + return ret; + esp_xtensa_smp->chip_ops = chip_ops; + esp_xtensa_smp->examine_other_cores = ESP_XTENSA_SMP_EXAMINE_OTHER_CORES; + return ERROR_OK; +} + +int esp_xtensa_smp_target_init(struct command_context *cmd_ctx, struct target *target) +{ + int ret = esp_xtensa_target_init(cmd_ctx, target); + if (ret != ERROR_OK) + return ret; + + if (target->smp) { + struct target_list *head; + foreach_smp_target(head, target->smp_targets) { + struct target *curr = head->target; + ret = esp_xtensa_semihosting_init(curr); + if (ret != ERROR_OK) + return ret; + } + } else { + ret = esp_xtensa_semihosting_init(target); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_xtdef) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp && CMD_ARGC > 0) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtdef_do, + target_to_xtensa(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_xtdef_do, + target_to_xtensa(target)); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_xtopt) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp && CMD_ARGC > 0) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtopt_do, + target_to_xtensa(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_xtopt_do, + target_to_xtensa(target)); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_xtmem) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp && CMD_ARGC > 0) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtmem_do, + target_to_xtensa(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_xtmem_do, + target_to_xtensa(target)); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_xtmpu) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp && CMD_ARGC > 0) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtmpu_do, + target_to_xtensa(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_xtmpu_do, + target_to_xtensa(target)); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_xtmmu) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp && CMD_ARGC > 0) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtmmu_do, + target_to_xtensa(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_xtmmu_do, + target_to_xtensa(target)); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_xtreg) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp && CMD_ARGC > 0) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtreg_do, + target_to_xtensa(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_xtreg_do, + target_to_xtensa(target)); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_xtregfmt) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp && CMD_ARGC > 0) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtregfmt_do, + target_to_xtensa(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_xtregfmt_do, + target_to_xtensa(target)); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_permissive_mode) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp && CMD_ARGC > 0) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_permissive_mode_do, + target_to_xtensa(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_permissive_mode_do, + target_to_xtensa(target)); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_smpbreak) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp && CMD_ARGC > 0) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_smpbreak_do, curr); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_smpbreak_do, target); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_mask_interrupts) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp && CMD_ARGC > 0) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_mask_interrupts_do, + target_to_xtensa(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_mask_interrupts_do, + target_to_xtensa(target)); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_perfmon_enable) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp && CMD_ARGC > 0) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_enable_do, + target_to_xtensa(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_enable_do, + target_to_xtensa(target)); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_perfmon_dump) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + LOG_INFO("CPU%d:", curr->coreid); + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_dump_do, + target_to_xtensa(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_dump_do, + target_to_xtensa(target)); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_tracestart) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_tracestart_do, + target_to_xtensa(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_tracestart_do, + target_to_xtensa(target)); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_tracestop) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_tracestop_do, + target_to_xtensa(curr)); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_tracestop_do, + target_to_xtensa(target)); +} + +COMMAND_HANDLER(esp_xtensa_smp_cmd_tracedump) +{ + struct target *target = get_current_target(CMD_CTX); + if (target->smp) { + struct target_list *head; + struct target *curr; + int32_t cores_max_id = 0; + /* assume that core IDs are assigned to SMP targets sequentially: 0,1,2... */ + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + if (cores_max_id < curr->coreid) + cores_max_id = curr->coreid; + } + if (CMD_ARGC < ((uint32_t)cores_max_id + 1)) { + command_print(CMD, + "Need %d filenames to dump to as output!", + cores_max_id + 1); + return ERROR_FAIL; + } + foreach_smp_target(head, target->smp_targets) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(xtensa_cmd_tracedump_do, + target_to_xtensa(curr), CMD_ARGV[curr->coreid]); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(xtensa_cmd_tracedump_do, + target_to_xtensa(target), CMD_ARGV[0]); +} + +const struct command_registration esp_xtensa_smp_xtensa_command_handlers[] = { + { + .name = "xtdef", + .handler = esp_xtensa_smp_cmd_xtdef, + .mode = COMMAND_CONFIG, + .help = "Configure Xtensa core type", + .usage = "<type>", + }, + { + .name = "xtopt", + .handler = esp_xtensa_smp_cmd_xtopt, + .mode = COMMAND_CONFIG, + .help = "Configure Xtensa core option", + .usage = "<name> <value>", + }, + { + .name = "xtmem", + .handler = esp_xtensa_smp_cmd_xtmem, + .mode = COMMAND_CONFIG, + .help = "Configure Xtensa memory/cache option", + .usage = "<type> [parameters]", + }, + { + .name = "xtmmu", + .handler = esp_xtensa_smp_cmd_xtmmu, + .mode = COMMAND_CONFIG, + .help = "Configure Xtensa MMU option", + .usage = "<NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56>", + }, + { + .name = "xtmpu", + .handler = esp_xtensa_smp_cmd_xtmpu, + .mode = COMMAND_CONFIG, + .help = "Configure Xtensa MPU option", + .usage = "<num FG seg> <min seg size> <lockable> <executeonly>", + }, + { + .name = "xtreg", + .handler = esp_xtensa_smp_cmd_xtreg, + .mode = COMMAND_CONFIG, + .help = "Configure Xtensa register", + .usage = "<regname> <regnum>", + }, + { + .name = "xtregs", + .handler = esp_xtensa_smp_cmd_xtreg, + .mode = COMMAND_CONFIG, + .help = "Configure number of Xtensa registers", + .usage = "<numregs>", + }, + { + .name = "xtregfmt", + .handler = esp_xtensa_smp_cmd_xtregfmt, + .mode = COMMAND_CONFIG, + .help = "Configure format of Xtensa register map", + .usage = "<numgregs>", + }, + { + .name = "set_permissive", + .handler = esp_xtensa_smp_cmd_permissive_mode, + .mode = COMMAND_ANY, + .help = "When set to 1, enable Xtensa permissive mode (less client-side checks)", + .usage = "[0|1]", + }, + { + .name = "maskisr", + .handler = esp_xtensa_smp_cmd_mask_interrupts, + .mode = COMMAND_ANY, + .help = "mask Xtensa interrupts at step", + .usage = "['on'|'off']", + }, + { + .name = "smpbreak", + .handler = esp_xtensa_smp_cmd_smpbreak, + .mode = COMMAND_ANY, + .help = "Set the way the CPU chains OCD breaks", + .usage = + "[none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]", + }, + { + .name = "perfmon_enable", + .handler = esp_xtensa_smp_cmd_perfmon_enable, + .mode = COMMAND_EXEC, + .help = "Enable and start performance counter", + .usage = "<counter_id> <select> [mask] [kernelcnt] [tracelevel]", + }, + { + .name = "perfmon_dump", + .handler = esp_xtensa_smp_cmd_perfmon_dump, + .mode = COMMAND_EXEC, + .help = + "Dump performance counter value. If no argument specified, dumps all counters.", + .usage = "[counter_id]", + }, + { + .name = "tracestart", + .handler = esp_xtensa_smp_cmd_tracestart, + .mode = COMMAND_EXEC, + .help = + "Tracing: Set up and start a trace. Optionally set stop trigger address and amount of data captured after.", + .usage = "[pc <pcval>/[maskbitcount]] [after <n> [ins|words]]", + }, + { + .name = "tracestop", + .handler = esp_xtensa_smp_cmd_tracestop, + .mode = COMMAND_EXEC, + .help = "Tracing: Stop current trace as started by the tracestart command", + .usage = "", + }, + { + .name = "tracedump", + .handler = esp_xtensa_smp_cmd_tracedump, + .mode = COMMAND_EXEC, + .help = "Tracing: Dump trace memory to a files. One file per core.", + .usage = "<outfile1> <outfile2>", + }, + COMMAND_REGISTRATION_DONE +}; + +const struct command_registration esp_xtensa_smp_command_handlers[] = { + { + .name = "xtensa", + .usage = "", + .chain = esp_xtensa_smp_xtensa_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; diff --git a/src/target/espressif/esp_xtensa_smp.h b/src/target/espressif/esp_xtensa_smp.h new file mode 100644 index 0000000..aeb1d61 --- /dev/null +++ b/src/target/espressif/esp_xtensa_smp.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/*************************************************************************** + * ESP Xtensa SMP target for OpenOCD * + * Copyright (C) 2020 Espressif Systems Ltd. Co * + ***************************************************************************/ + +#ifndef OPENOCD_TARGET_XTENSA_ESP_SMP_H +#define OPENOCD_TARGET_XTENSA_ESP_SMP_H + +#include "esp_xtensa.h" + +struct esp_xtensa_smp_chip_ops { + int (*poll)(struct target *target); + int (*reset)(struct target *target); + int (*on_halt)(struct target *target); +}; + +struct esp_xtensa_smp_common { + struct esp_xtensa_common esp_xtensa; + const struct esp_xtensa_smp_chip_ops *chip_ops; + bool other_core_does_resume; + /* number of attempts to examine other SMP cores, attempts are made after reset on target poll */ + int examine_other_cores; +}; + +int esp_xtensa_smp_poll(struct target *target); +int esp_xtensa_smp_resume(struct target *target, + int current, + target_addr_t address, + int handle_breakpoints, + int debug_execution); +int esp_xtensa_smp_step(struct target *target, + int current, + target_addr_t address, + int handle_breakpoints); +int esp_xtensa_smp_assert_reset(struct target *target); +int esp_xtensa_smp_deassert_reset(struct target *target); +int esp_xtensa_smp_soft_reset_halt(struct target *target); +int esp_xtensa_smp_watchpoint_add(struct target *target, struct watchpoint *watchpoint); +int esp_xtensa_smp_watchpoint_remove(struct target *target, struct watchpoint *watchpoint); +int esp_xtensa_smp_handle_target_event(struct target *target, enum target_event event, void *priv); +int esp_xtensa_smp_target_init(struct command_context *cmd_ctx, struct target *target); +int esp_xtensa_smp_init_arch_info(struct target *target, + struct esp_xtensa_smp_common *esp_xtensa_smp, + struct xtensa_debug_module_config *dm_cfg, + const struct esp_xtensa_smp_chip_ops *chip_ops, + const struct esp_semihost_ops *semihost_ops); + +extern const struct command_registration esp_xtensa_smp_command_handlers[]; +extern const struct command_registration esp_xtensa_smp_xtensa_command_handlers[]; +extern const struct command_registration esp_xtensa_smp_esp_command_handlers[]; + +#endif /* OPENOCD_TARGET_XTENSA_ESP_SMP_H */ diff --git a/src/target/etb.c b/src/target/etb.c index ce1bef9..3b9004b 100644 --- a/src/target/etb.c +++ b/src/target/etb.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/etb.h b/src/target/etb.h index 680c8a1..fa75600 100644 --- a/src/target/etb.h +++ b/src/target/etb.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ETB_H diff --git a/src/target/etm.c b/src/target/etm.c index 119c0df..57417c3 100644 --- a/src/target/etm.c +++ b/src/target/etm.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/target/etm.h b/src/target/etm.h index debe197..be5f2c7 100644 --- a/src/target/etm.h +++ b/src/target/etm.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005, 2007 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007 by Vincent Palatin * * vincent.palatin_openocd@m4x.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ETM_H diff --git a/src/target/etm_dummy.c b/src/target/etm_dummy.c index ba53c7a..8deccf5 100644 --- a/src/target/etm_dummy.c +++ b/src/target/etm_dummy.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/etm_dummy.h b/src/target/etm_dummy.h index 5a1955f..8df2000 100644 --- a/src/target/etm_dummy.h +++ b/src/target/etm_dummy.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_ETM_DUMMY_H diff --git a/src/target/fa526.c b/src/target/fa526.c index aa9e450..38b7ab2 100644 --- a/src/target/fa526.c +++ b/src/target/fa526.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 by Paulius Zaleckas * * paulius.zaleckas@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/target/feroceon.c b/src/target/feroceon.c index bbb793a..1e7eb09 100644 --- a/src/target/feroceon.c +++ b/src/target/feroceon.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2008-2009 by Marvell Semiconductors, Inc. * * Written by Nicolas Pitre <nico@marvell.com> * * * * Copyright (C) 2008 by Hongtao Zheng * * hontor@126.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* diff --git a/src/target/hla_target.c b/src/target/hla_target.c index 3e359b9..33126d6 100644 --- a/src/target/hla_target.c +++ b/src/target/hla_target.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Mathias Kuester * * Mathias Kuester <kesmtp@freenet.de> * @@ -6,19 +8,6 @@ * spen@spen-soft.co.uk * * * * revised: 4/25/13 by brent@mbari.org [DCC target request support] * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -203,7 +192,7 @@ static int adapter_target_create(struct target *target, { LOG_DEBUG("%s", __func__); struct adiv5_private_config *pc = target->private_config; - if (pc && pc->ap_num > 0) { + if (pc && pc->ap_num != DP_APSEL_INVALID && pc->ap_num != 0) { LOG_ERROR("hla_target: invalid parameter -ap-num (> 0)"); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -242,7 +231,7 @@ static int adapter_debug_entry(struct target *target) struct armv7m_common *armv7m = target_to_armv7m(target); struct arm *arm = &armv7m->arm; struct reg *r; - uint32_t xPSR; + uint32_t xpsr; int retval; /* preserve the DCRDR across halts */ @@ -260,11 +249,11 @@ static int adapter_debug_entry(struct target *target) adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA); r = arm->cpsr; - xPSR = buf_get_u32(r->value, 0, 32); + xpsr = buf_get_u32(r->value, 0, 32); /* Are we in an exception handler */ - if (xPSR & 0x1FF) { - armv7m->exception_number = (xPSR & 0x1FF); + if (xpsr & 0x1FF) { + armv7m->exception_number = (xpsr & 0x1FF); arm->core_mode = ARM_MODE_HANDLER; arm->map = armv7m_msp_reg_map; diff --git a/src/target/image.c b/src/target/image.c index 130ea6c..f8de7a2 100644 --- a/src/target/image.c +++ b/src/target/image.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -13,19 +15,6 @@ * * * Copyright (C) 2018 by Advantest * * florian.meister@advantest.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/image.h b/src/target/image.h index bf06064..03bc068 100644 --- a/src/target/image.h +++ b/src/target/image.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -10,19 +12,6 @@ * * * Copyright (C) 2018 by Advantest * * florian.meister@advantest.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_IMAGE_H diff --git a/src/target/lakemont.c b/src/target/lakemont.c index 230f53f..5035cdb 100644 --- a/src/target/lakemont.c +++ b/src/target/lakemont.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright(c) 2013-2016 Intel Corporation. * @@ -8,19 +10,6 @@ * Jeffrey Maxwell (jeffrey.r.maxwell@intel.com) * Jessica Gomez (jessica.gomez.hernandez@intel.com) * - * 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, see <http://www.gnu.org/licenses/>. - * * Contact Information: * Intel Corporation */ diff --git a/src/target/lakemont.h b/src/target/lakemont.h index 98efd44..ca6557f 100644 --- a/src/target/lakemont.h +++ b/src/target/lakemont.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * Copyright(c) 2013-2016 Intel Corporation. * @@ -7,19 +9,6 @@ * Julien Carreno (julien.carreno@intel.com) * Jeffrey Maxwell (jeffrey.r.maxwell@intel.com) * - * 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, see <http://www.gnu.org/licenses/>. - * * Contact Information: * Intel Corporation */ diff --git a/src/target/ls1_sap.c b/src/target/ls1_sap.c index c167224..9bd00c0 100644 --- a/src/target/ls1_sap.c +++ b/src/target/ls1_sap.c @@ -1,17 +1,8 @@ -/*************************************************************************** - * Copyright (C) 2015 by Esben Haabendal * - * eha@deif.com * - * * - * 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. * - ***************************************************************************/ +// SPDX-License-Identifier: GPL-2.0-or-later + +/* + * Copyright (C) 2015 by Esben Haabendal <eha@deif.com> + */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/target/mem_ap.c b/src/target/mem_ap.c index eef05b4..a662506 100644 --- a/src/target/mem_ap.c +++ b/src/target/mem_ap.c @@ -1,16 +1,8 @@ -/***************************************************************************** - * Copyright (C) 2016 by Matthias Welwarsky <matthias.welwarsky@sysgo.com> * - * * - * 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. * - ****************************************************************************/ +// SPDX-License-Identifier: GPL-2.0-or-later + +/* + * Copyright (C) 2016 by Matthias Welwarsky <matthias.welwarsky@sysgo.com> + */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -29,7 +21,7 @@ struct mem_ap { int common_magic; struct adiv5_dap *dap; struct adiv5_ap *ap; - int ap_num; + uint64_t ap_num; }; static int mem_ap_target_create(struct target *target, Jim_Interp *interp) @@ -74,8 +66,13 @@ static int mem_ap_init_target(struct command_context *cmd_ctx, struct target *ta static void mem_ap_deinit_target(struct target *target) { + struct mem_ap *mem_ap = target->arch_info; + LOG_DEBUG("%s", __func__); + if (mem_ap->ap) + dap_put_ap(mem_ap->ap); + free(target->private_config); free(target->arch_info); return; @@ -139,7 +136,16 @@ static int mem_ap_examine(struct target *target) struct mem_ap *mem_ap = target->arch_info; if (!target_was_examined(target)) { - mem_ap->ap = dap_ap(mem_ap->dap, mem_ap->ap_num); + if (mem_ap->ap) { + dap_put_ap(mem_ap->ap); + mem_ap->ap = NULL; + } + + mem_ap->ap = dap_get_ap(mem_ap->dap, mem_ap->ap_num); + if (!mem_ap->ap) { + LOG_ERROR("Cannot get AP"); + return ERROR_FAIL; + } target_set_examined(target); target->state = TARGET_UNKNOWN; target->debug_reason = DBG_REASON_UNDEFINED; @@ -179,7 +185,7 @@ static struct reg_arch_type mem_ap_reg_arch_type = { .set = mem_ap_reg_set, }; -const char *mem_ap_get_gdb_arch(struct target *target) +static const char *mem_ap_get_gdb_arch(struct target *target) { return "arm"; } diff --git a/src/target/mips32.c b/src/target/mips32.c index c825369..f593b5f 100644 --- a/src/target/mips32.c +++ b/src/target/mips32.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * @@ -9,19 +11,6 @@ * * * Copyright (C) 2011 by Drasko DRASKOVIC * * drasko.draskovic@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/mips32.h b/src/target/mips32.h index 5ca3b7e..8837da1 100644 --- a/src/target/mips32.h +++ b/src/target/mips32.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * @@ -6,19 +8,6 @@ * * * Copyright (C) 2011 by Drasko DRASKOVIC * * drasko.draskovic@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_MIPS32_H @@ -27,7 +16,7 @@ #include "target.h" #include "mips32_pracc.h" -#define MIPS32_COMMON_MAGIC 0xB320B320 +#define MIPS32_COMMON_MAGIC 0xB320B320U /** * Memory segments (32bit kernel mode addresses) @@ -93,7 +82,8 @@ struct mips32_comparator { }; struct mips32_common { - uint32_t common_magic; + unsigned int common_magic; + void *arch_info; struct reg_cache *core_cache; struct mips_ejtag ejtag_info; @@ -130,7 +120,7 @@ struct mips32_core_reg { }; struct mips32_algorithm { - int common_magic; + unsigned int common_magic; enum mips32_isa_mode isa_mode; }; diff --git a/src/target/mips32_dmaacc.c b/src/target/mips32_dmaacc.c index 220ea94..beffbf5 100644 --- a/src/target/mips32_dmaacc.c +++ b/src/target/mips32_dmaacc.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2008 by John McCarthy * * jgmcc@magma.ca * @@ -6,19 +8,6 @@ * spen@spen-soft.co.uk * * * * Copyright (C) 2008 by David T.L. Wong * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/mips32_dmaacc.h b/src/target/mips32_dmaacc.h index 70fe2a7..1725941 100644 --- a/src/target/mips32_dmaacc.h +++ b/src/target/mips32_dmaacc.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2008 by John McCarthy * * jgmcc@magma.ca * @@ -6,19 +8,6 @@ * spen@spen-soft.co.uk * * * * Copyright (C) 2008 by David T.L. Wong * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_MIPS32_DMAACC_H diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c index 9f8762e..c4704b5 100644 --- a/src/target/mips32_pracc.c +++ b/src/target/mips32_pracc.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * @@ -8,19 +10,6 @@ * * * Copyright (C) 2011 by Drasko DRASKOVIC * * drasko.draskovic@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* @@ -161,7 +150,7 @@ static int mips32_pracc_clean_text_jump(struct mips_ejtag *ejtag_info) return ERROR_OK; } -int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx, +static int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx, uint32_t *param_out, bool check_last) { int code_count = 0; @@ -334,7 +323,7 @@ void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr) ctx->store_count++; } -void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint32_t data, bool optimize) +static void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint32_t data, bool optimize) { if (LOWER16(data) == 0 && optimize) pracc_add(ctx, 0, MIPS32_LUI(ctx->isa, reg_num, UPPER16(data))); /* load only upper value */ diff --git a/src/target/mips32_pracc.h b/src/target/mips32_pracc.h index 30edaec..1b00768 100644 --- a/src/target/mips32_pracc.h +++ b/src/target/mips32_pracc.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * @@ -6,19 +8,6 @@ * * * Copyright (C) 2011 by Drasko DRASKOVIC * * drasko.draskovic@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_MIPS32_PRACC_H @@ -64,7 +53,6 @@ struct pracc_queue_info { void pracc_queue_init(struct pracc_queue_info *ctx); void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr); -void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint32_t data, bool optimize); void pracc_queue_free(struct pracc_queue_info *ctx); int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx, uint32_t *buf, bool check_last); @@ -79,9 +67,6 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs); int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs); -int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx, - uint32_t *param_out, bool check_last); - /** * \b mips32_cp0_read * diff --git a/src/target/mips64.c b/src/target/mips64.c index 347cdfc..773b92d 100644 --- a/src/target/mips64.c +++ b/src/target/mips64.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Support for processors implementing MIPS64 instruction set * @@ -10,8 +12,6 @@ * Copyright (C) 2008 by Spencer Oliver * Copyright (C) 2008 by David T.L. Wong * Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev - * - * SPDX-License-Identifier: GPL-2.0-or-later */ #ifdef HAVE_CONFIG_H diff --git a/src/target/mips64.h b/src/target/mips64.h index 3453e4e..9079c80 100644 --- a/src/target/mips64.h +++ b/src/target/mips64.h @@ -19,7 +19,7 @@ #include "register.h" #include "mips64_pracc.h" -#define MIPS64_COMMON_MAGIC 0xB640B640 +#define MIPS64_COMMON_MAGIC 0xB640B640U /* MIPS64 CP0 registers */ #define MIPS64_C0_INDEX 0 @@ -81,7 +81,8 @@ struct mips64_comparator { }; struct mips64_common { - uint32_t common_magic; + unsigned int common_magic; + void *arch_info; struct reg_cache *core_cache; struct mips_ejtag ejtag_info; diff --git a/src/target/mips64_pracc.c b/src/target/mips64_pracc.c index 81a4cfb..b083f5c 100644 --- a/src/target/mips64_pracc.c +++ b/src/target/mips64_pracc.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Support for processors implementing MIPS64 instruction set * @@ -9,8 +11,6 @@ * Copyright (C) 2008 by Spencer Oliver * Copyright (C) 2008 by David T.L. Wong * Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev - * - * SPDX-License-Identifier: GPL-2.0-or-later */ #ifdef HAVE_CONFIG_H diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c index b21a1bd..a1a1792 100644 --- a/src/target/mips_ejtag.c +++ b/src/target/mips_ejtag.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * @@ -5,19 +7,6 @@ * Copyright (C) 2008 by David T.L. Wong * * * * Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h index e50101b..eb80742 100644 --- a/src/target/mips_ejtag.h +++ b/src/target/mips_ejtag.h @@ -1,21 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * * * * Copyright (C) 2008 by David T.L. Wong * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_MIPS_EJTAG_H diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index 8601193..e85018c 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * @@ -8,19 +10,6 @@ * * * Copyright (C) 2011 by Drasko DRASKOVIC * * drasko.draskovic@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -1368,7 +1357,7 @@ static const struct command_registration mips_m4k_exec_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -const struct command_registration mips_m4k_command_handlers[] = { +static const struct command_registration mips_m4k_command_handlers[] = { { .chain = mips32_command_handlers, }, diff --git a/src/target/mips_m4k.h b/src/target/mips_m4k.h index ea09ae5..f63d72f 100644 --- a/src/target/mips_m4k.h +++ b/src/target/mips_m4k.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * @@ -6,19 +8,6 @@ * * * Copyright (C) 2011 by Drasko DRASKOVIC * * drasko.draskovic@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_MIPS_M4K_H @@ -26,12 +15,14 @@ struct target; -#define MIPSM4K_COMMON_MAGIC 0xB321B321 +#define MIPSM4K_COMMON_MAGIC 0xB321B321U struct mips_m4k_common { - uint32_t common_magic; - bool is_pic32mx; + unsigned int common_magic; + struct mips32_common mips32; + + bool is_pic32mx; }; static inline struct mips_m4k_common * @@ -52,6 +43,5 @@ static inline void mips_m4k_isa_filter(enum mips32_isa_imp isa_imp, target_addr_ } } } -extern const struct command_registration mips_m4k_command_handlers[]; #endif /* OPENOCD_TARGET_MIPS_M4K_H */ diff --git a/src/target/mips_mips64.c b/src/target/mips_mips64.c index 5d821d7..640b4c8 100644 --- a/src/target/mips_mips64.c +++ b/src/target/mips_mips64.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * MIPS64 generic target support * @@ -8,8 +10,6 @@ * Based on the work of: * Copyright (C) 2008 by Spencer Oliver * Copyright (C) 2008 by David T.L. Wong - * - * SPDX-License-Identifier: GPL-2.0-or-later */ #ifdef HAVE_CONFIG_H @@ -205,12 +205,6 @@ static int mips_mips64_deassert_reset(struct target *target) return ERROR_OK; } -static int mips_mips64_soft_reset_halt(struct target *target) -{ - /* TODO */ - return ERROR_OK; -} - static int mips_mips64_single_step_core(struct target *target) { struct mips64_common *mips64 = target->arch_info; @@ -1168,7 +1162,7 @@ struct target_type mips_mips64_target = { .assert_reset = mips_mips64_assert_reset, .deassert_reset = mips_mips64_deassert_reset, - .soft_reset_halt = mips_mips64_soft_reset_halt, + /* TODO: add .soft_reset_halt */ .get_gdb_reg_list = mips64_get_gdb_reg_list, diff --git a/src/target/mips_mips64.h b/src/target/mips_mips64.h index 69fb2a6..9841deb 100644 --- a/src/target/mips_mips64.h +++ b/src/target/mips_mips64.h @@ -17,7 +17,8 @@ #include "helper/types.h" struct mips_mips64_common { - int common_magic; + unsigned int common_magic; + struct mips64_common mips64_common; }; diff --git a/src/target/nds32.c b/src/target/nds32.c index f0fb74d..bd30976 100644 --- a/src/target/nds32.c +++ b/src/target/nds32.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/nds32.h b/src/target/nds32.h index c447673..d0b680a 100644 --- a/src/target/nds32.h +++ b/src/target/nds32.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_NDS32_H @@ -235,7 +224,8 @@ struct nds32_misc_config { * Represents a generic Andes core. */ struct nds32 { - uint32_t common_magic; + unsigned int common_magic; + struct reg_cache *core_cache; /** Handle for the debug module. */ diff --git a/src/target/nds32_aice.c b/src/target/nds32_aice.c index b01f8c0..8dc4d77 100644 --- a/src/target/nds32_aice.c +++ b/src/target/nds32_aice.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 Andes technology. * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/target/nds32_aice.h b/src/target/nds32_aice.h index 5ea3b16..2a6c879 100644 --- a/src/target/nds32_aice.h +++ b/src/target/nds32_aice.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 Andes technology. * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_NDS32_AICE_H diff --git a/src/target/nds32_cmd.c b/src/target/nds32_cmd.c index 69c28ac..37f7648 100644 --- a/src/target/nds32_cmd.c +++ b/src/target/nds32_cmd.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/nds32_cmd.h b/src/target/nds32_cmd.h index 543ba54..1593243 100644 --- a/src/target/nds32_cmd.h +++ b/src/target/nds32_cmd.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_NDS32_CMD_H diff --git a/src/target/nds32_disassembler.c b/src/target/nds32_disassembler.c index 0bf74e1..eebbfe1 100644 --- a/src/target/nds32_disassembler.c +++ b/src/target/nds32_disassembler.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/nds32_disassembler.h b/src/target/nds32_disassembler.h index 9117cbb..f2c8e85 100644 --- a/src/target/nds32_disassembler.h +++ b/src/target/nds32_disassembler.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_NDS32_DISASSEMBLER_H diff --git a/src/target/nds32_edm.h b/src/target/nds32_edm.h index 2b5067a..3213604 100644 --- a/src/target/nds32_edm.h +++ b/src/target/nds32_edm.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_NDS32_EDM_H diff --git a/src/target/nds32_insn.h b/src/target/nds32_insn.h index 4e0b2d5..25eb9ab 100644 --- a/src/target/nds32_insn.h +++ b/src/target/nds32_insn.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_NDS32_INSN_H diff --git a/src/target/nds32_reg.c b/src/target/nds32_reg.c index 034a075..1687e69 100644 --- a/src/target/nds32_reg.c +++ b/src/target/nds32_reg.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/target/nds32_reg.h b/src/target/nds32_reg.h index 8808cd2..30cd241 100644 --- a/src/target/nds32_reg.h +++ b/src/target/nds32_reg.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_NDS32_REG_H diff --git a/src/target/nds32_tlb.c b/src/target/nds32_tlb.c index 81734e0..a533e59 100644 --- a/src/target/nds32_tlb.c +++ b/src/target/nds32_tlb.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/target/nds32_tlb.h b/src/target/nds32_tlb.h index c22ed73..1edff29 100644 --- a/src/target/nds32_tlb.h +++ b/src/target/nds32_tlb.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_NDS32_TLB_H diff --git a/src/target/nds32_v2.c b/src/target/nds32_v2.c index 49a5758..2149291 100644 --- a/src/target/nds32_v2.c +++ b/src/target/nds32_v2.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/nds32_v2.h b/src/target/nds32_v2.h index dcc08c2..3c30108 100644 --- a/src/target/nds32_v2.h +++ b/src/target/nds32_v2.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_NDS32_V2_H diff --git a/src/target/nds32_v3.c b/src/target/nds32_v3.c index fde86d6..9d02e5a 100644 --- a/src/target/nds32_v3.c +++ b/src/target/nds32_v3.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/nds32_v3.h b/src/target/nds32_v3.h index a5df8fe..389838d 100644 --- a/src/target/nds32_v3.h +++ b/src/target/nds32_v3.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_NDS32_V3_H diff --git a/src/target/nds32_v3_common.c b/src/target/nds32_v3_common.c index 8ff8e30..f2efab4 100644 --- a/src/target/nds32_v3_common.c +++ b/src/target/nds32_v3_common.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/nds32_v3_common.h b/src/target/nds32_v3_common.h index 23393e5..a98988e 100644 --- a/src/target/nds32_v3_common.h +++ b/src/target/nds32_v3_common.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_NDS32_V3_COMMON_H diff --git a/src/target/nds32_v3m.c b/src/target/nds32_v3m.c index ffd646f..6bc549f 100644 --- a/src/target/nds32_v3m.c +++ b/src/target/nds32_v3m.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/nds32_v3m.h b/src/target/nds32_v3m.h index 1e7427c..f21dd62 100644 --- a/src/target/nds32_v3m.h +++ b/src/target/nds32_v3m.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 Andes Technology * * Hsiangkai Wang <hkwang@andestech.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_NDS32_V3M_H diff --git a/src/target/openrisc/Makefile.am b/src/target/openrisc/Makefile.am index 5a2549a..b9c0f83 100644 --- a/src/target/openrisc/Makefile.am +++ b/src/target/openrisc/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libopenrisc.la %C%_libopenrisc_la_SOURCES = \ %D%/or1k.c \ diff --git a/src/target/openrisc/jsp_server.c b/src/target/openrisc/jsp_server.c index 54c9694..185a506 100644 --- a/src/target/openrisc/jsp_server.c +++ b/src/target/openrisc/jsp_server.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2014 by Franck Jullien * * franck.jullien@gmail.com * * * * Based on ./src/server/telnet_server.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/openrisc/jsp_server.h b/src/target/openrisc/jsp_server.h index e5cfaa8..a522fa8 100644 --- a/src/target/openrisc/jsp_server.h +++ b/src/target/openrisc/jsp_server.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + #ifndef OPENOCD_TARGET_OPENRISC_JSP_SERVER_H #define OPENOCD_TARGET_OPENRISC_JSP_SERVER_H diff --git a/src/target/openrisc/or1k.c b/src/target/openrisc/or1k.c index 77fa15d..d73bca2 100644 --- a/src/target/openrisc/or1k.c +++ b/src/target/openrisc/or1k.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2011 by Julius Baxter * * julius@opencores.org * @@ -8,19 +10,6 @@ * Copyright (C) 2013 by Franck Jullien * * elec4fun@gmail.com * * * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/openrisc/or1k.h b/src/target/openrisc/or1k.h index c456ccb..8f76a06 100644 --- a/src/target/openrisc/or1k.h +++ b/src/target/openrisc/or1k.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2011 by Julius Baxter * * julius@opencores.org * @@ -8,19 +10,6 @@ * Copyright (C) 2013 by Franck Jullien * * elec4fun@gmail.com * * * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_OPENRISC_OR1K_H diff --git a/src/target/openrisc/or1k_du.h b/src/target/openrisc/or1k_du.h index 9828b0d..ae95376 100644 --- a/src/target/openrisc/or1k_du.h +++ b/src/target/openrisc/or1k_du.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2013 Franck Jullien * * elec4fun@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_OPENRISC_OR1K_DU_H diff --git a/src/target/openrisc/or1k_du_adv.c b/src/target/openrisc/or1k_du_adv.c index 885fcb9..cfb7d0e 100644 --- a/src/target/openrisc/or1k_du_adv.c +++ b/src/target/openrisc/or1k_du_adv.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013-2014 by Franck Jullien * * elec4fun@gmail.com * @@ -9,19 +11,6 @@ * And the Mohor interface version of this file which is: * * Copyright (C) 2011 by Julius Baxter * * julius@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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/openrisc/or1k_tap.h b/src/target/openrisc/or1k_tap.h index 2cf7da8..e06a5e0 100644 --- a/src/target/openrisc/or1k_tap.h +++ b/src/target/openrisc/or1k_tap.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2012 by Franck Jullien * * elec4fun@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_OPENRISC_OR1K_TAP_H diff --git a/src/target/openrisc/or1k_tap_mohor.c b/src/target/openrisc/or1k_tap_mohor.c index 1415e32..0dedb3e 100644 --- a/src/target/openrisc/or1k_tap_mohor.c +++ b/src/target/openrisc/or1k_tap_mohor.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 by Franck Jullien * * elec4fun@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/openrisc/or1k_tap_vjtag.c b/src/target/openrisc/or1k_tap_vjtag.c index 28366cf..783b4db 100644 --- a/src/target/openrisc/or1k_tap_vjtag.c +++ b/src/target/openrisc/or1k_tap_vjtag.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 by Franck Jullien * * elec4fun@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/openrisc/or1k_tap_xilinx_bscan.c b/src/target/openrisc/or1k_tap_xilinx_bscan.c index a77c65e..6b3df0e 100644 --- a/src/target/openrisc/or1k_tap_xilinx_bscan.c +++ b/src/target/openrisc/or1k_tap_xilinx_bscan.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2013 by Sergio Chico * * sergio.chico@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/quark_d20xx.c b/src/target/quark_d20xx.c index 211245d..d63a42a 100644 --- a/src/target/quark_d20xx.c +++ b/src/target/quark_d20xx.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright(c) 2015-2016 Intel Corporation. * * Jessica Gomez (jessica.gomez.hernandez@intel.com) * Ivan De Cesaris (ivan.de.cesaris@intel.com) * - * 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, see <http://www.gnu.org/licenses/>. - * * Contact Information: * Intel Corporation */ diff --git a/src/target/quark_x10xx.c b/src/target/quark_x10xx.c index 525d39a..0daa642 100644 --- a/src/target/quark_x10xx.c +++ b/src/target/quark_x10xx.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright(c) 2013-2016 Intel Corporation. * @@ -7,19 +9,6 @@ * Julien Carreno (julien.carreno@intel.com) * Jeffrey Maxwell (jeffrey.r.maxwell@intel.com) * - * 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, see <http://www.gnu.org/licenses/>. - * * Contact Information: * Intel Corporation */ diff --git a/src/target/register.c b/src/target/register.c index 6387475..2287125 100644 --- a/src/target/register.c +++ b/src/target/register.c @@ -1,22 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/register.h b/src/target/register.h index a7705f7..1e4f2e0 100644 --- a/src/target/register.h +++ b/src/target/register.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_REGISTER_H diff --git a/src/target/riscv/Makefile.am b/src/target/riscv/Makefile.am index 83f1a8c..4b6a74f 100644 --- a/src/target/riscv/Makefile.am +++ b/src/target/riscv/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libriscv.la %C%_libriscv_la_SOURCES = \ %D%/asm.h \ diff --git a/src/target/riscv/batch.c b/src/target/riscv/batch.c index 4c1667d..217c36d 100644 --- a/src/target/riscv/batch.c +++ b/src/target/riscv/batch.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/target/riscv/program.c b/src/target/riscv/program.c index 16baa4b..ce28026 100644 --- a/src/target/riscv/program.c +++ b/src/target/riscv/program.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c index e38d854..c6f4f84 100644 --- a/src/target/riscv/riscv-011.c +++ b/src/target/riscv/riscv-011.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Support for RISC-V, debug version 0.11. This was never an officially adopted @@ -229,10 +229,10 @@ static int get_register(struct target *target, riscv_reg_t *value, int regid); static riscv011_info_t *get_info(const struct target *target) { - riscv_info_t *info = (riscv_info_t *) target->arch_info; + struct riscv_info *info = target->arch_info; assert(info); assert(info->version_specific); - return (riscv011_info_t *) info->version_specific; + return info->version_specific; } static unsigned int slot_offset(const struct target *target, slot_t slot) @@ -1403,7 +1403,10 @@ static int halt(struct target *target) static void deinit_target(struct target *target) { LOG_DEBUG("riscv_deinit_target()"); - riscv_info_t *info = (riscv_info_t *) target->arch_info; + struct riscv_info *info = target->arch_info; + if (!info) + return; + free(info->version_specific); info->version_specific = NULL; } @@ -1544,7 +1547,7 @@ static int examine(struct target *target) uint32_t word0 = cache_get32(target, 0); uint32_t word1 = cache_get32(target, 1); - riscv_info_t *generic_info = (riscv_info_t *) target->arch_info; + struct riscv_info *generic_info = riscv_info(target); if (word0 == 1 && word1 == 0) { generic_info->xlen = 32; } else if (word0 == 0xffffffff && word1 == 3) { @@ -2288,7 +2291,7 @@ static int arch_state(struct target *target) return ERROR_OK; } -COMMAND_HELPER(riscv011_print_info, struct target *target) +static COMMAND_HELPER(riscv011_print_info, struct target *target) { /* Abstract description. */ riscv_print_info_line(CMD, "target", "memory.read_while_running8", 0); diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 3043b06..1842667 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Support for RISC-V, debug version 0.13, which is currently (2/4/17) the @@ -34,7 +34,7 @@ static int riscv013_step_or_resume_current_hart(struct target *target, bool step); static void riscv013_clear_abstract_error(struct target *target); -/* Implementations of the functions in riscv_info_t. */ +/* Implementations of the functions in struct riscv_info. */ static int riscv013_get_register(struct target *target, riscv_reg_t *value, int rid); static int riscv013_set_register(struct target *target, int regid, uint64_t value); @@ -209,14 +209,14 @@ typedef struct { bool selected; } riscv013_info_t; -LIST_HEAD(dm_list); +static LIST_HEAD(dm_list); static riscv013_info_t *get_info(const struct target *target) { - riscv_info_t *info = (riscv_info_t *) target->arch_info; + struct riscv_info *info = target->arch_info; assert(info); assert(info->version_specific); - return (riscv013_info_t *) info->version_specific; + return info->version_specific; } /** @@ -224,7 +224,7 @@ static riscv013_info_t *get_info(const struct target *target) * global list of DMs. If it's not in there, then create one and initialize it * to 0. */ -dm013_info_t *get_dm(struct target *target) +static dm013_info_t *get_dm(struct target *target) { RISCV013_INFO(info); if (info->dm) @@ -677,7 +677,7 @@ static int dmi_write_exec(struct target *target, uint32_t address, return dmi_op(target, NULL, NULL, DMI_OP_WRITE, address, value, true, ensure_success); } -int dmstatus_read_timeout(struct target *target, uint32_t *dmstatus, +static int dmstatus_read_timeout(struct target *target, uint32_t *dmstatus, bool authenticated, unsigned timeout_sec) { int result = dmi_op_timeout(target, dmstatus, NULL, DMI_OP_READ, @@ -699,7 +699,7 @@ int dmstatus_read_timeout(struct target *target, uint32_t *dmstatus, return ERROR_OK; } -int dmstatus_read(struct target *target, uint32_t *dmstatus, +static int dmstatus_read(struct target *target, uint32_t *dmstatus, bool authenticated) { int result = dmstatus_read_timeout(target, dmstatus, authenticated, @@ -721,7 +721,7 @@ static void increase_ac_busy_delay(struct target *target) info->ac_busy_delay); } -uint32_t abstract_register_size(unsigned width) +static uint32_t __attribute__((unused)) abstract_register_size(unsigned width) { switch (width) { case 32: @@ -1502,7 +1502,10 @@ static int wait_for_authbusy(struct target *target, uint32_t *dmstatus) static void deinit_target(struct target *target) { LOG_DEBUG("riscv_deinit_target()"); - riscv_info_t *info = (riscv_info_t *) target->arch_info; + struct riscv_info *info = target->arch_info; + if (!info) + return; + free(info->version_specific); /* TODO: free register arch_info */ info->version_specific = NULL; @@ -1870,7 +1873,7 @@ static unsigned riscv013_data_bits(struct target *target) return 32; } -COMMAND_HELPER(riscv013_print_info, struct target *target) +static COMMAND_HELPER(riscv013_print_info, struct target *target) { RISCV013_INFO(info); @@ -2427,9 +2430,7 @@ static int assert_reset(struct target *target) /* TODO: Try to use hasel in dmcontrol */ /* Set haltreq for each hart. */ - uint32_t control = control_base; - - control = set_dmcontrol_hartsel(control_base, info->index); + uint32_t control = set_dmcontrol_hartsel(control_base, info->index); control = set_field(control, DM_DMCONTROL_HALTREQ, target->reset_halt ? 1 : 0); dmi_write(target, DM_DMCONTROL, control); @@ -4235,7 +4236,7 @@ static int select_prepped_harts(struct target *target) unsigned int selected_index = 0; list_for_each_entry(entry, &dm->target_list, list) { struct target *t = entry->target; - riscv_info_t *info = riscv_info(t); + struct riscv_info *info = riscv_info(t); riscv013_info_t *info_013 = get_info(t); unsigned index = info_013->index; LOG_DEBUG("index=%d, coreid=%d, prepped=%d", index, t->coreid, info->prepped); diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index f5f2332..c64a98c 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later #include <assert.h> #include <stdlib.h> @@ -37,38 +37,38 @@ #define DBUS 0x11 -uint8_t ir_dtmcontrol[4] = {DTMCONTROL}; +static uint8_t ir_dtmcontrol[4] = {DTMCONTROL}; struct scan_field select_dtmcontrol = { .in_value = NULL, .out_value = ir_dtmcontrol }; -uint8_t ir_dbus[4] = {DBUS}; +static uint8_t ir_dbus[4] = {DBUS}; struct scan_field select_dbus = { .in_value = NULL, .out_value = ir_dbus }; -uint8_t ir_idcode[4] = {0x1}; +static uint8_t ir_idcode[4] = {0x1}; struct scan_field select_idcode = { .in_value = NULL, .out_value = ir_idcode }; -bscan_tunnel_type_t bscan_tunnel_type; +static bscan_tunnel_type_t bscan_tunnel_type; int bscan_tunnel_ir_width; /* if zero, then tunneling is not present/active */ static int bscan_tunnel_ir_id; /* IR ID of the JTAG TAP to access the tunnel. Valid when not 0 */ static const uint8_t bscan_zero[4] = {0}; static const uint8_t bscan_one[4] = {1}; -uint8_t ir_user4[4]; -struct scan_field select_user4 = { +static uint8_t ir_user4[4]; +static struct scan_field select_user4 = { .in_value = NULL, .out_value = ir_user4 }; -uint8_t bscan_tunneled_ir_width[4] = {5}; /* overridden by assignment in riscv_init_target */ -struct scan_field _bscan_tunnel_data_register_select_dmi[] = { +static uint8_t bscan_tunneled_ir_width[4] = {5}; /* overridden by assignment in riscv_init_target */ +static struct scan_field _bscan_tunnel_data_register_select_dmi[] = { { .num_bits = 3, .out_value = bscan_zero, @@ -91,7 +91,7 @@ struct scan_field _bscan_tunnel_data_register_select_dmi[] = { } }; -struct scan_field _bscan_tunnel_nested_tap_select_dmi[] = { +static struct scan_field _bscan_tunnel_nested_tap_select_dmi[] = { { .num_bits = 1, .out_value = bscan_zero, @@ -113,11 +113,11 @@ struct scan_field _bscan_tunnel_nested_tap_select_dmi[] = { .in_value = NULL, } }; -struct scan_field *bscan_tunnel_nested_tap_select_dmi = _bscan_tunnel_nested_tap_select_dmi; -uint32_t bscan_tunnel_nested_tap_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_nested_tap_select_dmi); +static struct scan_field *bscan_tunnel_nested_tap_select_dmi = _bscan_tunnel_nested_tap_select_dmi; +static uint32_t bscan_tunnel_nested_tap_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_nested_tap_select_dmi); -struct scan_field *bscan_tunnel_data_register_select_dmi = _bscan_tunnel_data_register_select_dmi; -uint32_t bscan_tunnel_data_register_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_data_register_select_dmi); +static struct scan_field *bscan_tunnel_data_register_select_dmi = _bscan_tunnel_data_register_select_dmi; +static uint32_t bscan_tunnel_data_register_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_data_register_select_dmi); struct trigger { uint64_t address; @@ -134,7 +134,7 @@ int riscv_command_timeout_sec = DEFAULT_COMMAND_TIMEOUT_SEC; /* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/ int riscv_reset_timeout_sec = DEFAULT_RESET_TIMEOUT_SEC; -bool riscv_enable_virt2phys = true; +static bool riscv_enable_virt2phys = true; bool riscv_ebreakm = true; bool riscv_ebreaks = true; bool riscv_ebreaku = true; @@ -146,7 +146,7 @@ static enum { RO_REVERSED } resume_order; -const virt2phys_info_t sv32 = { +static const virt2phys_info_t sv32 = { .name = "Sv32", .va_bits = 32, .level = 2, @@ -159,7 +159,7 @@ const virt2phys_info_t sv32 = { .pa_ppn_mask = {0x3ff, 0xfff}, }; -const virt2phys_info_t sv39 = { +static const virt2phys_info_t sv39 = { .name = "Sv39", .va_bits = 39, .level = 3, @@ -172,7 +172,7 @@ const virt2phys_info_t sv39 = { .pa_ppn_mask = {0x1ff, 0x1ff, 0x3ffffff}, }; -const virt2phys_info_t sv48 = { +static const virt2phys_info_t sv48 = { .name = "Sv48", .va_bits = 48, .level = 4, @@ -185,7 +185,12 @@ const virt2phys_info_t sv48 = { .pa_ppn_mask = {0x1ff, 0x1ff, 0x1ff, 0x1ffff}, }; -void riscv_sample_buf_maybe_add_timestamp(struct target *target, bool before) +static enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid); +static void riscv_info_init(struct target *target, struct riscv_info *r); +static void riscv_invalidate_register_cache(struct target *target); +static int riscv_step_rtos_hart(struct target *target); + +static void riscv_sample_buf_maybe_add_timestamp(struct target *target, bool before) { RISCV_INFO(r); uint32_t now = timeval_ms() & 0xffffffff; @@ -334,13 +339,12 @@ static uint32_t dtmcontrol_scan(struct target *target, uint32_t out) static struct target_type *get_target_type(struct target *target) { - riscv_info_t *info = (riscv_info_t *) target->arch_info; - - if (!info) { + if (!target->arch_info) { LOG_ERROR("Target has not been initialized"); return NULL; } + RISCV_INFO(info); switch (info->dtm_version) { case 0: return &riscv011_target; @@ -356,7 +360,7 @@ static struct target_type *get_target_type(struct target *target) static int riscv_create_target(struct target *target, Jim_Interp *interp) { LOG_DEBUG("riscv_create_target()"); - target->arch_info = calloc(1, sizeof(riscv_info_t)); + target->arch_info = calloc(1, sizeof(struct riscv_info)); if (!target->arch_info) { LOG_ERROR("Failed to allocate RISC-V target structure."); return ERROR_FAIL; @@ -383,10 +387,7 @@ static int riscv_init_target(struct command_context *cmd_ctx, assert(target->tap->ir_length >= 6); ir_user4_raw = 0x23 << (target->tap->ir_length - 6); } - ir_user4[0] = (uint8_t)ir_user4_raw; - ir_user4[1] = (uint8_t)(ir_user4_raw >>= 8); - ir_user4[2] = (uint8_t)(ir_user4_raw >>= 8); - ir_user4[3] = (uint8_t)(ir_user4_raw >>= 8); + h_u32_to_le(ir_user4, ir_user4_raw); select_user4.num_bits = target->tap->ir_length; bscan_tunneled_ir_width[0] = bscan_tunnel_ir_width; if (bscan_tunnel_type == BSCAN_TUNNEL_DATA_REGISTER) @@ -423,17 +424,20 @@ static void riscv_deinit_target(struct target *target) { LOG_DEBUG("riscv_deinit_target()"); - riscv_info_t *info = target->arch_info; + struct riscv_info *info = target->arch_info; struct target_type *tt = get_target_type(target); if (riscv_flush_registers(target) != ERROR_OK) LOG_ERROR("[%s] Failed to flush registers. Ignoring this error.", target_name(target)); - if (tt && info->version_specific) + if (tt && info && info->version_specific) tt->deinit_target(target); riscv_free_registers(target); + if (!info) + return; + range_list_t *entry, *tmp; list_for_each_entry_safe(entry, tmp, &info->hide_csr, list) { free(entry->name); @@ -1076,7 +1080,7 @@ int riscv_read_by_any_size(struct target *target, target_addr_t address, uint32_ return ERROR_FAIL; } -int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint) +static int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint) { LOG_TARGET_DEBUG(target, "@0x%" TARGET_PRIxADDR, breakpoint->address); assert(breakpoint); @@ -1158,7 +1162,7 @@ static int remove_trigger(struct target *target, int unique_id) return ERROR_OK; } -int riscv_remove_breakpoint(struct target *target, +static int riscv_remove_breakpoint(struct target *target, struct breakpoint *breakpoint) { if (breakpoint->type == BKPT_SOFT) { @@ -1306,7 +1310,7 @@ static int riscv_hit_trigger_hit_bit(struct target *target, uint32_t *unique_id) * The GDB server uses this information to tell GDB what data address has * been hit, which enables GDB to print the hit variable along with its old * and new value. */ -int riscv_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint) +static int riscv_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint) { RISCV_INFO(r); @@ -1474,7 +1478,7 @@ int riscv_flush_registers(struct target *target) } /* Convert: RISC-V hart's halt reason --> OpenOCD's generic debug reason */ -int set_debug_reason(struct target *target, enum riscv_halt_reason halt_reason) +static int set_debug_reason(struct target *target, enum riscv_halt_reason halt_reason) { RISCV_INFO(r); r->trigger_hit = -1; @@ -1510,7 +1514,7 @@ int set_debug_reason(struct target *target, enum riscv_halt_reason halt_reason) return ERROR_OK; } -int halt_prep(struct target *target) +static int halt_prep(struct target *target) { RISCV_INFO(r); @@ -1530,7 +1534,7 @@ int halt_prep(struct target *target) return ERROR_OK; } -int riscv_halt_go_all_harts(struct target *target) +static int riscv_halt_go_all_harts(struct target *target) { RISCV_INFO(r); @@ -1549,9 +1553,9 @@ int riscv_halt_go_all_harts(struct target *target) return ERROR_OK; } -int halt_go(struct target *target) +static int halt_go(struct target *target) { - riscv_info_t *r = riscv_info(target); + RISCV_INFO(r); int result; if (!r->get_hart_state) { struct target_type *tt = get_target_type(target); @@ -1592,7 +1596,7 @@ int riscv_halt(struct target *target) foreach_smp_target(tlist, target->smp_targets) { struct target *t = tlist->target; - riscv_info_t *i = riscv_info(t); + struct riscv_info *i = riscv_info(t); if (i->prepped) { if (halt_go(t) != ERROR_OK) result = ERROR_FAIL; @@ -1763,7 +1767,7 @@ static int resume_prep(struct target *target, int current, static int resume_go(struct target *target, int current, target_addr_t address, int handle_breakpoints, int debug_execution) { - riscv_info_t *r = riscv_info(target); + RISCV_INFO(r); int result; if (!r->get_hart_state) { struct target_type *tt = get_target_type(target); @@ -1790,7 +1794,7 @@ static int resume_finish(struct target *target, int debug_execution) * @par single_hart When true, only resume a single hart even if SMP is * configured. This is used to run algorithms on just one hart. */ -int riscv_resume( +static int riscv_resume( struct target *target, int current, target_addr_t address, @@ -1830,7 +1834,7 @@ int riscv_resume( foreach_smp_target_direction(resume_order == RO_NORMAL, tlist, targets) { struct target *t = tlist->target; - riscv_info_t *i = riscv_info(t); + struct riscv_info *i = riscv_info(t); if (i->prepped) { if (resume_go(t, current, address, handle_breakpoints, debug_execution) != ERROR_OK) @@ -1941,6 +1945,7 @@ static int riscv_address_translate(struct target *target, LOG_DEBUG("virtual=0x%" TARGET_PRIxADDR "; mode=%s", virtual, info->name); /* verify bits xlen-1:va_bits-1 are all equal */ + assert(xlen >= info->va_bits); target_addr_t mask = ((target_addr_t)1 << (xlen - (info->va_bits - 1))) - 1; target_addr_t masked_msbs = (virtual >> (info->va_bits - 1)) & mask; if (masked_msbs != 0 && masked_msbs != mask) { @@ -2067,7 +2072,7 @@ static int riscv_write_memory(struct target *target, target_addr_t address, return tt->write_memory(target, address, size, count, buffer); } -const char *riscv_get_gdb_arch(struct target *target) +static const char *riscv_get_gdb_arch(struct target *target) { switch (riscv_xlen(target)) { case 32: @@ -2522,7 +2527,7 @@ static int riscv_poll_hart(struct target *target, enum riscv_next_action *next_a return ERROR_OK; } -int sample_memory(struct target *target) +static int sample_memory(struct target *target) { RISCV_INFO(r); @@ -2873,7 +2878,7 @@ COMMAND_HANDLER(riscv_set_enable_virtual) return ERROR_OK; } -int parse_ranges(struct list_head *ranges, const char *tcl_arg, const char *reg_type, unsigned int max_val) +static int parse_ranges(struct list_head *ranges, const char *tcl_arg, const char *reg_type, unsigned int max_val) { char *args = strdup(tcl_arg); if (!args) @@ -3099,27 +3104,25 @@ COMMAND_HANDLER(riscv_authdata_write) uint32_t value; unsigned int index = 0; - if (CMD_ARGC == 0) { - /* nop */ - } else if (CMD_ARGC == 1) { + if (CMD_ARGC == 0 || CMD_ARGC > 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (CMD_ARGC == 1) { COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], value); - } else if (CMD_ARGC == 2) { + } else { COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], index); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); - } else { - LOG_ERROR("Command takes at most 2 arguments"); - return ERROR_COMMAND_SYNTAX_ERROR; } struct target *target = get_current_target(CMD_CTX); RISCV_INFO(r); - if (r->authdata_write) { - return r->authdata_write(target, value, index); - } else { + if (!r->authdata_write) { LOG_ERROR("authdata_write is not implemented for this target."); return ERROR_FAIL; } + + return r->authdata_write(target, value, index); } COMMAND_HANDLER(riscv_dmi_read) @@ -4077,9 +4080,8 @@ static const struct command_registration riscv_exec_command_handlers[] = { * protocol, then a command like `riscv semihosting enable` will make * sense, but for now all semihosting commands are prefixed with `arm`. */ -extern const struct command_registration semihosting_common_handlers[]; -const struct command_registration riscv_command_handlers[] = { +static const struct command_registration riscv_command_handlers[] = { { .name = "riscv", .mode = COMMAND_ANY, @@ -4161,9 +4163,13 @@ struct target_type riscv_target = { /*** RISC-V Interface ***/ -void riscv_info_init(struct target *target, riscv_info_t *r) +/* Initializes the shared RISC-V structure. */ +static void riscv_info_init(struct target *target, struct riscv_info *r) { memset(r, 0, sizeof(*r)); + + r->common_magic = RISCV_COMMON_MAGIC; + r->dtm_version = 1; r->version_specific = NULL; @@ -4251,7 +4257,7 @@ int riscv_interrupts_restore(struct target *target, uint64_t old_mstatus) return reg_mstatus->type->set(reg_mstatus, mstatus_bytes); } -int riscv_step_rtos_hart(struct target *target) +static int riscv_step_rtos_hart(struct target *target) { RISCV_INFO(r); LOG_DEBUG("[%s] stepping", target_name(target)); @@ -4290,7 +4296,7 @@ unsigned riscv_xlen(const struct target *target) return r->xlen; } -void riscv_invalidate_register_cache(struct target *target) +static void riscv_invalidate_register_cache(struct target *target) { /* Do not invalidate the register cache if it is not yet set up * (e.g. when the target failed to get examined). */ @@ -4466,7 +4472,7 @@ int riscv_save_register(struct target *target, enum gdb_regno regid) return ERROR_OK; } -int riscv_get_hart_state(struct target *target, enum riscv_hart_state *state) +static int riscv_get_hart_state(struct target *target, enum riscv_hart_state *state) { RISCV_INFO(r); assert(r->get_hart_state); diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index 6b4d577..591fb3f 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -10,8 +10,11 @@ struct riscv_program; #include "gdb_regs.h" #include "jtag/jtag.h" #include "target/register.h" +#include "target/semihosting_common.h" #include <helper/command.h> +#define RISCV_COMMON_MAGIC 0x52495356U + /* The register cache is statically allocated. */ #define RISCV_MAX_HARTS 1024 #define RISCV_MAX_REGISTERS 5000 @@ -106,7 +109,9 @@ typedef struct { char *name; } range_list_t; -typedef struct { +struct riscv_info { + unsigned int common_magic; + unsigned dtm_version; struct command_context *cmd_ctx; @@ -265,7 +270,7 @@ typedef struct { int64_t last_activity; yes_no_maybe_t vsew64_supported; -} riscv_info_t; +}; COMMAND_HELPER(riscv_print_info_line, const char *section, const char *key, unsigned int value); @@ -301,27 +306,27 @@ extern bool riscv_ebreaku; /* Everything needs the RISC-V specific info structure, so here's a nice macro * that provides that. */ -static inline riscv_info_t *riscv_info(const struct target *target) __attribute__((unused)); -static inline riscv_info_t *riscv_info(const struct target *target) +static inline struct riscv_info *riscv_info(const struct target *target) __attribute__((unused)); +static inline struct riscv_info *riscv_info(const struct target *target) { assert(target->arch_info); return target->arch_info; } -#define RISCV_INFO(R) riscv_info_t *R = riscv_info(target); +#define RISCV_INFO(R) struct riscv_info *R = riscv_info(target); + +static inline bool is_riscv(const struct riscv_info *riscv_info) +{ + return riscv_info->common_magic == RISCV_COMMON_MAGIC; +} -extern uint8_t ir_dtmcontrol[4]; extern struct scan_field select_dtmcontrol; -extern uint8_t ir_dbus[4]; extern struct scan_field select_dbus; -extern uint8_t ir_idcode[4]; extern struct scan_field select_idcode; -extern struct scan_field select_user4; extern struct scan_field *bscan_tunneled_select_dmi; extern uint32_t bscan_tunneled_select_dmi_num_fields; typedef enum { BSCAN_TUNNEL_NESTED_TAP, BSCAN_TUNNEL_DATA_REGISTER } bscan_tunnel_type_t; extern int bscan_tunnel_ir_width; -extern bscan_tunnel_type_t bscan_tunnel_type; uint32_t dtmcontrol_scan_via_bscan(struct target *target, uint32_t out); void select_dmi_via_bscan(struct target *target); @@ -331,15 +336,6 @@ int riscv_openocd_poll(struct target *target); int riscv_halt(struct target *target); -int riscv_resume( - struct target *target, - int current, - target_addr_t address, - int handle_breakpoints, - int debug_execution, - bool single_hart -); - int riscv_openocd_step( struct target *target, int current, @@ -352,13 +348,6 @@ int riscv_openocd_deassert_reset(struct target *target); /*** RISC-V Interface ***/ -/* Initializes the shared RISC-V structure. */ -void riscv_info_init(struct target *target, riscv_info_t *r); - -/* Steps the hart that's currently selected in the RTOS, or if there is no RTOS - * then the only hart. */ -int riscv_step_rtos_hart(struct target *target); - bool riscv_supports_extension(struct target *target, char letter); /* Returns XLEN for the given (or current) hart. */ @@ -407,29 +396,17 @@ void riscv_fill_dmi_write_u64(struct target *target, char *buf, int a, uint64_t void riscv_fill_dmi_read_u64(struct target *target, char *buf, int a); int riscv_dmi_write_u64_bits(struct target *target); -/* Invalidates the register cache. */ -void riscv_invalidate_register_cache(struct target *target); - int riscv_enumerate_triggers(struct target *target); -int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint); -int riscv_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint); int riscv_add_watchpoint(struct target *target, struct watchpoint *watchpoint); int riscv_remove_watchpoint(struct target *target, struct watchpoint *watchpoint); -int riscv_hit_watchpoint(struct target *target, struct watchpoint **hit_wp_address); int riscv_init_registers(struct target *target); void riscv_semihosting_init(struct target *target); -typedef enum { - SEMI_NONE, /* Not halted for a semihosting call. */ - SEMI_HANDLED, /* Call handled, and target was resumed. */ - SEMI_WAITING, /* Call handled, target is halted waiting until we can resume. */ - SEMI_ERROR /* Something went wrong. */ -} semihosting_result_t; -semihosting_result_t riscv_semihosting(struct target *target, int *retval); + +enum semihosting_result riscv_semihosting(struct target *target, int *retval); void riscv_add_bscan_tunneled_scan(struct target *target, struct scan_field *field, riscv_bscan_tunneled_scan_context_t *ctxt); diff --git a/src/target/riscv/riscv_semihosting.c b/src/target/riscv/riscv_semihosting.c index 2c53813..5e630c4 100644 --- a/src/target/riscv/riscv_semihosting.c +++ b/src/target/riscv/riscv_semihosting.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later /*************************************************************************** * Copyright (C) 2018 by Liviu Ionescu * @@ -12,19 +12,6 @@ * * * Copyright (C) 2016 by Square, Inc. * * Steven Stallion <stallion@squareup.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /** @@ -44,7 +31,6 @@ #include <helper/log.h> #include "target/target.h" -#include "target/semihosting_common.h" #include "riscv.h" static int riscv_semihosting_setup(struct target *target, int enable); @@ -67,23 +53,23 @@ void riscv_semihosting_init(struct target *target) * @param retval Pointer to a location where the return code will be stored * @return non-zero value if a request was processed or an error encountered */ -semihosting_result_t riscv_semihosting(struct target *target, int *retval) +enum semihosting_result riscv_semihosting(struct target *target, int *retval) { struct semihosting *semihosting = target->semihosting; if (!semihosting) { LOG_DEBUG(" -> NONE (!semihosting)"); - return SEMI_NONE; + return SEMIHOSTING_NONE; } if (!semihosting->is_active) { LOG_DEBUG(" -> NONE (!semihosting->is_active)"); - return SEMI_NONE; + return SEMIHOSTING_NONE; } riscv_reg_t pc; int result = riscv_get_register(target, &pc, GDB_REGNO_PC); if (result != ERROR_OK) - return SEMI_ERROR; + return SEMIHOSTING_ERROR; uint8_t tmp_buf[12]; @@ -92,7 +78,7 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval) /* Instruction memories may not support arbitrary read size. Use any size that will work. */ *retval = riscv_read_by_any_size(target, (pc - 4) + 4 * i, 4, tmp_buf + 4 * i); if (*retval != ERROR_OK) - return SEMI_ERROR; + return SEMIHOSTING_ERROR; } /* @@ -111,7 +97,7 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval) if (pre != 0x01f01013 || ebreak != 0x00100073 || post != 0x40705013) { /* Not the magic sequence defining semihosting. */ LOG_DEBUG(" -> NONE (no magic)"); - return SEMI_NONE; + return SEMIHOSTING_NONE; } /* @@ -126,13 +112,13 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval) result = riscv_get_register(target, &r0, GDB_REGNO_A0); if (result != ERROR_OK) { LOG_DEBUG(" -> ERROR (couldn't read a0)"); - return SEMI_ERROR; + return SEMIHOSTING_ERROR; } result = riscv_get_register(target, &r1, GDB_REGNO_A1); if (result != ERROR_OK) { LOG_DEBUG(" -> ERROR (couldn't read a1)"); - return SEMI_ERROR; + return SEMIHOSTING_ERROR; } semihosting->op = r0; @@ -146,12 +132,12 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval) *retval = semihosting_common(target); if (*retval != ERROR_OK) { LOG_ERROR("Failed semihosting operation (0x%02X)", semihosting->op); - return SEMI_ERROR; + return SEMIHOSTING_ERROR; } } else { /* Unknown operation number, not a semihosting call. */ LOG_DEBUG(" -> NONE (unknown operation number)"); - return SEMI_NONE; + return SEMIHOSTING_NONE; } } @@ -166,11 +152,11 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval) */ if (semihosting->is_resumable && !semihosting->hit_fileio) { LOG_DEBUG(" -> HANDLED"); - return SEMI_HANDLED; + return SEMIHOSTING_HANDLED; } LOG_DEBUG(" -> WAITING"); - return SEMI_WAITING; + return SEMIHOSTING_WAITING; } /* ------------------------------------------------------------------------- diff --git a/src/target/rtt.c b/src/target/rtt.c index 4183021..ef2c45d 100644 --- a/src/target/rtt.c +++ b/src/target/rtt.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de> - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H diff --git a/src/target/rtt.h b/src/target/rtt.h index 0122475..f3acda5 100644 --- a/src/target/rtt.h +++ b/src/target/rtt.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de> - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifndef OPENOCD_TARGET_RTT_H diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c index 2df6e38..dc0dae2 100644 --- a/src/target/semihosting_common.c +++ b/src/target/semihosting_common.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2018 by Liviu Ionescu * * <ilg@livius.net> * @@ -10,19 +12,6 @@ * * * Copyright (C) 2016 by Square, Inc. * * Steven Stallion <stallion@squareup.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /** @@ -103,16 +92,6 @@ static int semihosting_common_fileio_info(struct target *target, static int semihosting_common_fileio_end(struct target *target, int result, int fileio_errno, bool ctrl_c); -static int semihosting_read_fields(struct target *target, size_t number, - uint8_t *fields); -static int semihosting_write_fields(struct target *target, size_t number, - uint8_t *fields); -static uint64_t semihosting_get_field(struct target *target, size_t index, - uint8_t *fields); -static void semihosting_set_field(struct target *target, uint64_t value, - size_t index, - uint8_t *fields); - /* Attempts to include gdb_server.h failed. */ extern int gdb_actual_connections; @@ -166,6 +145,7 @@ int semihosting_common_init(struct target *target, void *setup, semihosting->setup = setup; semihosting->post_result = post_result; + semihosting->user_command_extension = NULL; target->semihosting = semihosting; @@ -426,7 +406,7 @@ int semihosting_common(struct target *target) } else { semihosting->result = close(fd); semihosting->sys_errno = errno; - LOG_DEBUG("close(%d)=%d", fd, (int)semihosting->result); + LOG_DEBUG("close(%d)=%" PRId64, fd, semihosting->result); } } break; @@ -651,10 +631,10 @@ int semihosting_common(struct target *target) semihosting->result = fstat(fd, &buf); if (semihosting->result == -1) { semihosting->sys_errno = errno; - LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result); + LOG_DEBUG("fstat(%d)=%" PRId64, fd, semihosting->result); break; } - LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result); + LOG_DEBUG("fstat(%d)=%" PRId64, fd, semihosting->result); semihosting->result = buf.st_size; } break; @@ -711,8 +691,7 @@ int semihosting_common(struct target *target) if (retval != ERROR_OK) return retval; } - LOG_DEBUG("SYS_GET_CMDLINE=[%s],%d", arg, - (int)semihosting->result); + LOG_DEBUG("SYS_GET_CMDLINE=[%s], %" PRId64, arg, semihosting->result); } break; @@ -804,7 +783,7 @@ int semihosting_common(struct target *target) int fd = semihosting_get_field(target, 0, fields); semihosting->result = isatty(fd); semihosting->sys_errno = errno; - LOG_DEBUG("isatty(%d)=%d", fd, (int)semihosting->result); + LOG_DEBUG("isatty(%d)=%" PRId64, fd, semihosting->result); } break; @@ -877,9 +856,11 @@ int semihosting_common(struct target *target) semihosting->result = -1; semihosting->sys_errno = ENOMEM; } else { - strncpy((char *)fn, semihosting->basedir, basedir_len); - if (fn[basedir_len - 1] != '/') - fn[basedir_len++] = '/'; + if (basedir_len > 0) { + strcpy((char *)fn, semihosting->basedir); + if (fn[basedir_len - 1] != '/') + fn[basedir_len++] = '/'; + } retval = target_read_memory(target, addr, 1, len, fn + basedir_len); if (retval != ERROR_OK) { free(fn); @@ -920,22 +901,19 @@ int semihosting_common(struct target *target) semihosting->result = fd; semihosting->stdin_fd = fd; semihosting->sys_errno = errno; - LOG_DEBUG("dup(STDIN)=%d", - (int)semihosting->result); + LOG_DEBUG("dup(STDIN)=%" PRId64, semihosting->result); } else if (mode < 8) { int fd = dup(STDOUT_FILENO); semihosting->result = fd; semihosting->stdout_fd = fd; semihosting->sys_errno = errno; - LOG_DEBUG("dup(STDOUT)=%d", - (int)semihosting->result); + LOG_DEBUG("dup(STDOUT)=%" PRId64, semihosting->result); } else { int fd = dup(STDERR_FILENO); semihosting->result = fd; semihosting->stderr_fd = fd; semihosting->sys_errno = errno; - LOG_DEBUG("dup(STDERR)=%d", - (int)semihosting->result); + LOG_DEBUG("dup(STDERR)=%" PRId64, semihosting->result); } } else { /* cygwin requires the permission setting @@ -945,8 +923,7 @@ int semihosting_common(struct target *target) open_host_modeflags[mode], 0644); semihosting->sys_errno = errno; - LOG_DEBUG("open('%s')=%d", fn, - (int)semihosting->result); + LOG_DEBUG("open('%s')=%" PRId64, fn, semihosting->result); } } free(fn); @@ -1009,11 +986,11 @@ int semihosting_common(struct target *target) semihosting->sys_errno = ENOMEM; } else { semihosting->result = semihosting_read(semihosting, fd, buf, len); - LOG_DEBUG("read(%d, 0x%" PRIx64 ", %zu)=%d", + LOG_DEBUG("read(%d, 0x%" PRIx64 ", %zu)=%" PRId64, fd, addr, len, - (int)semihosting->result); + semihosting->result); if (semihosting->result >= 0) { retval = target_write_buffer(target, addr, semihosting->result, @@ -1049,7 +1026,7 @@ int semihosting_common(struct target *target) return ERROR_FAIL; } semihosting->result = semihosting_getchar(semihosting, semihosting->stdin_fd); - LOG_DEBUG("getchar()=%d", (int)semihosting->result); + LOG_DEBUG("getchar()=%" PRId64, semihosting->result); break; case SEMIHOSTING_SYS_REMOVE: /* 0x0E */ @@ -1095,8 +1072,7 @@ int semihosting_common(struct target *target) fn[len] = 0; semihosting->result = remove((char *)fn); semihosting->sys_errno = errno; - LOG_DEBUG("remove('%s')=%d", fn, - (int)semihosting->result); + LOG_DEBUG("remove('%s')=%" PRId64, fn, semihosting->result); free(fn); } @@ -1165,9 +1141,7 @@ int semihosting_common(struct target *target) semihosting->result = rename((char *)fn1, (char *)fn2); semihosting->sys_errno = errno; - LOG_DEBUG("rename('%s', '%s')=%d", fn1, fn2, - (int)semihosting->result); - + LOG_DEBUG("rename('%s', '%s')=%" PRId64 " %d", fn1, fn2, semihosting->result, errno); free(fn1); free(fn2); } @@ -1212,8 +1186,7 @@ int semihosting_common(struct target *target) } else { semihosting->result = lseek(fd, pos, SEEK_SET); semihosting->sys_errno = errno; - LOG_DEBUG("lseek(%d, %d)=%d", fd, (int)pos, - (int)semihosting->result); + LOG_DEBUG("lseek(%d, %d)=%" PRId64, fd, (int)pos, semihosting->result); if (semihosting->result == pos) semihosting->result = 0; } @@ -1272,9 +1245,7 @@ int semihosting_common(struct target *target) cmd[len] = 0; semihosting->result = system( (const char *)cmd); - LOG_DEBUG("system('%s')=%d", - cmd, - (int)semihosting->result); + LOG_DEBUG("system('%s')=%" PRId64, cmd, semihosting->result); } free(cmd); @@ -1353,11 +1324,11 @@ int semihosting_common(struct target *target) } semihosting->result = semihosting_write(semihosting, fd, buf, len); semihosting->sys_errno = errno; - LOG_DEBUG("write(%d, 0x%" PRIx64 ", %zu)=%d", + LOG_DEBUG("write(%d, 0x%" PRIx64 ", %zu)=%" PRId64, fd, addr, len, - (int)semihosting->result); + semihosting->result); if (semihosting->result >= 0) { /* The number of bytes that are NOT written. * */ @@ -1446,7 +1417,7 @@ int semihosting_common(struct target *target) } break; - case SEMIHOSTING_USER_CMD_0x100 ... SEMIHOSTING_USER_CMD_0x107: + case SEMIHOSTING_USER_CMD_0X100 ... SEMIHOSTING_USER_CMD_0X107: /** * This is a user defined operation (while user cmds 0x100-0x1ff * are possible, only 0x100-0x107 are currently implemented). @@ -1465,9 +1436,14 @@ int semihosting_common(struct target *target) * Return * On exit, the RETURN REGISTER contains the return status. */ - { - assert(!semihosting_user_op_params); + if (semihosting->user_command_extension) { + retval = semihosting->user_command_extension(target); + if (retval != ERROR_NOT_IMPLEMENTED) + break; + /* If custom user command not handled, we are looking for the TCL handler */ + } + assert(!semihosting_user_op_params); retval = semihosting_read_fields(target, 2, fields); if (retval != ERROR_OK) { LOG_ERROR("Failed to read fields for user defined command" @@ -1505,11 +1481,8 @@ int semihosting_common(struct target *target) target_handle_event(target, semihosting->op); free(semihosting_user_op_params); semihosting_user_op_params = NULL; - semihosting->result = 0; break; - } - case SEMIHOSTING_SYS_ELAPSED: /* 0x30 */ /* @@ -1646,17 +1619,11 @@ static int semihosting_common_fileio_end(struct target *target, int result, */ switch (semihosting->op) { case SEMIHOSTING_SYS_WRITE: /* 0x05 */ + case SEMIHOSTING_SYS_READ: /* 0x06 */ if (result < 0) - semihosting->result = fileio_info->param_3; + semihosting->result = fileio_info->param_3; /* Zero bytes read/written. */ else - semihosting->result = 0; - break; - - case SEMIHOSTING_SYS_READ: /* 0x06 */ - if (result == (int)fileio_info->param_3) - semihosting->result = 0; - if (result <= 0) - semihosting->result = fileio_info->param_3; + semihosting->result = (int64_t)fileio_info->param_3 - result; break; case SEMIHOSTING_SYS_SEEK: /* 0x0a */ @@ -1668,10 +1635,13 @@ static int semihosting_common_fileio_end(struct target *target, int result, return semihosting->post_result(target); } +/* ------------------------------------------------------------------------- + * Utility functions. */ + /** * Read all fields of a command from target to buffer. */ -static int semihosting_read_fields(struct target *target, size_t number, +int semihosting_read_fields(struct target *target, size_t number, uint8_t *fields) { struct semihosting *semihosting = target->semihosting; @@ -1683,7 +1653,7 @@ static int semihosting_read_fields(struct target *target, size_t number, /** * Write all fields of a command from buffer to target. */ -static int semihosting_write_fields(struct target *target, size_t number, +int semihosting_write_fields(struct target *target, size_t number, uint8_t *fields) { struct semihosting *semihosting = target->semihosting; @@ -1695,7 +1665,7 @@ static int semihosting_write_fields(struct target *target, size_t number, /** * Extract a field from the buffer, considering register size and endianness. */ -static uint64_t semihosting_get_field(struct target *target, size_t index, +uint64_t semihosting_get_field(struct target *target, size_t index, uint8_t *fields) { struct semihosting *semihosting = target->semihosting; @@ -1708,7 +1678,7 @@ static uint64_t semihosting_get_field(struct target *target, size_t index, /** * Store a field in the buffer, considering register size and endianness. */ -static void semihosting_set_field(struct target *target, uint64_t value, +void semihosting_set_field(struct target *target, uint64_t value, size_t index, uint8_t *fields) { @@ -1832,7 +1802,7 @@ COMMAND_HANDLER(handle_common_semihosting_redirect_command) { struct target *target = get_current_target(CMD_CTX); - if (target == NULL) { + if (!target) { LOG_ERROR("No target selected"); return ERROR_FAIL; } diff --git a/src/target/semihosting_common.h b/src/target/semihosting_common.h index 404080f..7c5f748 100644 --- a/src/target/semihosting_common.h +++ b/src/target/semihosting_common.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2018 by Liviu Ionescu * * <ilg@livius.net> * * * * Copyright (C) 2009 by Marvell Technology Group Ltd. * * Written by Nicolas Pitre <nico@marvell.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_SEMIHOSTING_COMMON_H @@ -76,9 +65,9 @@ enum semihosting_operation_numbers { SEMIHOSTING_SYS_WRITE = 0x05, SEMIHOSTING_SYS_WRITEC = 0x03, SEMIHOSTING_SYS_WRITE0 = 0x04, - SEMIHOSTING_USER_CMD_0x100 = 0x100, /* First user cmd op code */ - SEMIHOSTING_USER_CMD_0x107 = 0x107, /* Last supported user cmd op code */ - SEMIHOSTING_USER_CMD_0x1FF = 0x1FF, /* Last user cmd op code */ + SEMIHOSTING_USER_CMD_0X100 = 0x100, /* First user cmd op code */ + SEMIHOSTING_USER_CMD_0X107 = 0x107, /* Last supported user cmd op code */ + SEMIHOSTING_USER_CMD_0X1FF = 0x1FF, /* Last user cmd op code */ }; /** Maximum allowed Tcl command segment length in bytes*/ @@ -103,6 +92,13 @@ enum semihosting_redirect_config { SEMIHOSTING_REDIRECT_CFG_ALL, }; +enum semihosting_result { + SEMIHOSTING_NONE, /* Not halted for a semihosting call. */ + SEMIHOSTING_HANDLED, /* Call handled, and target was resumed. */ + SEMIHOSTING_WAITING, /* Call handled, target is halted waiting until we can resume. */ + SEMIHOSTING_ERROR /* Something went wrong. */ +}; + struct target; /* @@ -179,6 +175,13 @@ struct semihosting { /** Base directory for semihosting I/O operations. */ char *basedir; + /** + * Target's extension of semihosting user commands. + * @returns ERROR_NOT_IMPLEMENTED when user command is not handled, otherwise + * sets semihosting->result and semihosting->sys_errno and returns ERROR_OK. + */ + int (*user_command_extension)(struct target *target); + int (*setup)(struct target *target, int enable); int (*post_result)(struct target *target); }; @@ -187,4 +190,17 @@ int semihosting_common_init(struct target *target, void *setup, void *post_result); int semihosting_common(struct target *target); +/* utility functions which may also be used by semihosting extensions (custom vendor-defined syscalls) */ +int semihosting_read_fields(struct target *target, size_t number, + uint8_t *fields); +int semihosting_write_fields(struct target *target, size_t number, + uint8_t *fields); +uint64_t semihosting_get_field(struct target *target, size_t index, + uint8_t *fields); +void semihosting_set_field(struct target *target, uint64_t value, + size_t index, + uint8_t *fields); + +extern const struct command_registration semihosting_common_handlers[]; + #endif /* OPENOCD_TARGET_SEMIHOSTING_COMMON_H */ diff --git a/src/target/smp.c b/src/target/smp.c index 569abd7..effc63f 100644 --- a/src/target/smp.c +++ b/src/target/smp.c @@ -1,19 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * * * Copyright (C) ST-Ericsson SA 2011 * * Author: Michel Jaouen <michel.jaouen@stericsson.com> for ST-Ericsson. * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/smp.h b/src/target/smp.h index d373c90..20835a0 100644 --- a/src/target/smp.h +++ b/src/target/smp.h @@ -1,19 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * * * Copyright (C) ST-Ericsson SA 2011 * * Author: Michel Jaouen <michel.jaouen@stericsson.com> for ST-Ericsson. * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_SMP_H diff --git a/src/target/startup.tcl b/src/target/startup.tcl index 0e46992..290e79d 100644 --- a/src/target/startup.tcl +++ b/src/target/startup.tcl @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + # Defines basic Tcl procs for OpenOCD target module proc new_target_name { } { diff --git a/src/target/stm8.c b/src/target/stm8.c index 4102082..aa934c9 100644 --- a/src/target/stm8.c +++ b/src/target/stm8.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * OpenOCD STM8 target driver * Copyright (C) 2017 Ake Rehnman * ake.rehnman(at)gmail.com -* -* 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, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H diff --git a/src/target/stm8.h b/src/target/stm8.h index b18ff58..55e1071 100644 --- a/src/target/stm8.h +++ b/src/target/stm8.h @@ -1,20 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * OpenOCD STM8 target driver * Copyright (C) 2017 Ake Rehnman * ake.rehnman(at)gmail.com -* -* 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, see <http://www.gnu.org/licenses/>. */ #ifndef OPENOCD_TARGET_STM8_H @@ -22,11 +11,12 @@ struct target; -#define STM8_COMMON_MAGIC 0x53544D38 +#define STM8_COMMON_MAGIC 0x53544D38U #define STM8_NUM_CORE_REGS 6 struct stm8_common { - uint32_t common_magic; + unsigned int common_magic; + void *arch_info; struct reg_cache *core_cache; uint32_t core_regs[STM8_NUM_CORE_REGS]; diff --git a/src/target/target.c b/src/target/target.c index a373848..f09c9a5 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -22,19 +24,6 @@ * * * Copyright (C) 2011 Andreas Fritiofson * * andreas.fritiofson@gmail.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -88,6 +77,7 @@ extern struct target_type fa526_target; extern struct target_type feroceon_target; extern struct target_type dragonite_target; extern struct target_type xscale_target; +extern struct target_type xtensa_chip_target; extern struct target_type cortexm_target; extern struct target_type cortexa_target; extern struct target_type aarch64_target; @@ -105,7 +95,9 @@ extern struct target_type hla_target; extern struct target_type nds32_v2_target; extern struct target_type nds32_v3_target; extern struct target_type nds32_v3m_target; +extern struct target_type esp32_target; extern struct target_type esp32s2_target; +extern struct target_type esp32s3_target; extern struct target_type or1k_target; extern struct target_type quark_x10xx_target; extern struct target_type quark_d20xx_target; @@ -127,6 +119,7 @@ static struct target_type *target_types[] = { &feroceon_target, &dragonite_target, &xscale_target, + &xtensa_chip_target, &cortexm_target, &cortexa_target, &cortexr4_target, @@ -142,7 +135,9 @@ static struct target_type *target_types[] = { &nds32_v2_target, &nds32_v3_target, &nds32_v3m_target, + &esp32_target, &esp32s2_target, + &esp32s3_target, &or1k_target, &quark_x10xx_target, &quark_d20xx_target, @@ -241,14 +236,14 @@ static const struct jim_nvp nvp_target_event[] = { { .value = TARGET_EVENT_TRACE_CONFIG, .name = "trace-config" }, - { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x100, .name = "semihosting-user-cmd-0x100" }, - { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x101, .name = "semihosting-user-cmd-0x101" }, - { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x102, .name = "semihosting-user-cmd-0x102" }, - { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x103, .name = "semihosting-user-cmd-0x103" }, - { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x104, .name = "semihosting-user-cmd-0x104" }, - { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x105, .name = "semihosting-user-cmd-0x105" }, - { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x106, .name = "semihosting-user-cmd-0x106" }, - { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x107, .name = "semihosting-user-cmd-0x107" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X100, .name = "semihosting-user-cmd-0x100" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X101, .name = "semihosting-user-cmd-0x101" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X102, .name = "semihosting-user-cmd-0x102" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X103, .name = "semihosting-user-cmd-0x103" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X104, .name = "semihosting-user-cmd-0x104" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X105, .name = "semihosting-user-cmd-0x105" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X106, .name = "semihosting-user-cmd-0x106" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X107, .name = "semihosting-user-cmd-0x107" }, { .name = NULL, .value = -1 } }; @@ -662,10 +657,10 @@ int target_resume(struct target *target, int current, target_addr_t address, * Disable polling during resume() to guarantee the execution of handlers * in the correct order. */ - bool save_poll = jtag_poll_get_enabled(); - jtag_poll_set_enabled(false); + bool save_poll_mask = jtag_poll_mask(); retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution); - jtag_poll_set_enabled(save_poll); + jtag_poll_unmask(save_poll_mask); + if (retval != ERROR_OK) return retval; @@ -693,14 +688,12 @@ static int target_process_reset(struct command_invocation *cmd, enum target_rese * more predictable, i.e. dr/irscan & pathmove in events will * not have JTAG operations injected into the middle of a sequence. */ - bool save_poll = jtag_poll_get_enabled(); - - jtag_poll_set_enabled(false); + bool save_poll_mask = jtag_poll_mask(); sprintf(buf, "ocd_process_reset %s", n->name); retval = Jim_Eval(cmd->ctx->interp, buf); - jtag_poll_set_enabled(save_poll); + jtag_poll_unmask(save_poll_mask); if (retval != JIM_OK) { Jim_MakeErrorMessage(cmd->ctx->interp); @@ -2088,7 +2081,7 @@ int target_alloc_working_area_try(struct target *target, uint32_t size, struct w struct working_area *new_wa = malloc(sizeof(*new_wa)); if (new_wa) { new_wa->next = NULL; - new_wa->size = target->working_area_size & ~3UL; /* 4-byte align */ + new_wa->size = ALIGN_DOWN(target->working_area_size, 4); /* 4-byte align */ new_wa->address = target->working_area; new_wa->backup = NULL; new_wa->user = NULL; @@ -2099,8 +2092,7 @@ int target_alloc_working_area_try(struct target *target, uint32_t size, struct w } /* only allocate multiples of 4 byte */ - if (size % 4) - size = (size + 3) & (~3UL); + size = ALIGN_UP(size, 4); struct working_area *c = target->working_areas; @@ -2254,7 +2246,7 @@ uint32_t target_get_working_area_avail(struct target *target) uint32_t max_size = 0; if (!c) - return target->working_area_size; + return ALIGN_DOWN(target->working_area_size, 4); while (c) { if (c->free && max_size < c->size) @@ -3337,7 +3329,7 @@ COMMAND_HANDLER(handle_soft_reset_halt_command) { struct target *target = get_current_target(CMD_CTX); - LOG_USER("requesting target halt and executing a soft reset"); + LOG_TARGET_INFO(target, "requesting target halt and executing a soft reset"); target_soft_reset_halt(target); @@ -4727,7 +4719,7 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc, break; } - char value_buf[11]; + char value_buf[19]; snprintf(value_buf, sizeof(value_buf), "0x%" PRIx64, v); Jim_ListAppendElement(interp, result_list, diff --git a/src/target/target.h b/src/target/target.h index e67016c..197890b 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -13,19 +15,6 @@ * * * Copyright (C) ST-Ericsson SA 2011 * * michel.jaouen@stericsson.com : smp minimum support * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_TARGET_H @@ -303,14 +292,14 @@ enum target_event { TARGET_EVENT_TRACE_CONFIG, - TARGET_EVENT_SEMIHOSTING_USER_CMD_0x100 = 0x100, /* semihosting allows user cmds from 0x100 to 0x1ff */ - TARGET_EVENT_SEMIHOSTING_USER_CMD_0x101 = 0x101, - TARGET_EVENT_SEMIHOSTING_USER_CMD_0x102 = 0x102, - TARGET_EVENT_SEMIHOSTING_USER_CMD_0x103 = 0x103, - TARGET_EVENT_SEMIHOSTING_USER_CMD_0x104 = 0x104, - TARGET_EVENT_SEMIHOSTING_USER_CMD_0x105 = 0x105, - TARGET_EVENT_SEMIHOSTING_USER_CMD_0x106 = 0x106, - TARGET_EVENT_SEMIHOSTING_USER_CMD_0x107 = 0x107, + TARGET_EVENT_SEMIHOSTING_USER_CMD_0X100 = 0x100, /* semihosting allows user cmds from 0x100 to 0x1ff */ + TARGET_EVENT_SEMIHOSTING_USER_CMD_0X101 = 0x101, + TARGET_EVENT_SEMIHOSTING_USER_CMD_0X102 = 0x102, + TARGET_EVENT_SEMIHOSTING_USER_CMD_0X103 = 0x103, + TARGET_EVENT_SEMIHOSTING_USER_CMD_0X104 = 0x104, + TARGET_EVENT_SEMIHOSTING_USER_CMD_0X105 = 0x105, + TARGET_EVENT_SEMIHOSTING_USER_CMD_0X106 = 0x106, + TARGET_EVENT_SEMIHOSTING_USER_CMD_0X107 = 0x107, }; struct target_event_action { diff --git a/src/target/target_request.c b/src/target/target_request.c index 562b046..72c8421 100644 --- a/src/target/target_request.c +++ b/src/target/target_request.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/target_request.h b/src/target/target_request.h index 1b13173..62d5c74 100644 --- a/src/target/target_request.h +++ b/src/target/target_request.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_TARGET_REQUEST_H diff --git a/src/target/target_type.h b/src/target/target_type.h index a26c2e7..9470803 100644 --- a/src/target/target_type.h +++ b/src/target/target_type.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_TARGET_TYPE_H @@ -297,6 +286,15 @@ struct target_type { */ int (*gdb_fileio_end)(struct target *target, int retcode, int fileio_errno, bool ctrl_c); + /* Parse target-specific GDB query commands. + * The string pointer "response_p" is always assigned by the called function + * to a pointer to a NULL-terminated string, even when the function returns + * an error. The string memory is not freed by the caller, so this function + * must pay attention for possible memory leaks if the string memory is + * dynamically allocated. + */ + int (*gdb_query_custom)(struct target *target, const char *packet, char **response_p); + /* do target profiling */ int (*profiling)(struct target *target, uint32_t *samples, diff --git a/src/target/testee.c b/src/target/testee.c index 236ac9a..6875652 100644 --- a/src/target/testee.c +++ b/src/target/testee.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/trace.c b/src/target/trace.c index f2ceb03..333a787 100644 --- a/src/target/trace.c +++ b/src/target/trace.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005, 2007 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/trace.h b/src/target/trace.h index 45308c0..e3d787e 100644 --- a/src/target/trace.h +++ b/src/target/trace.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_TRACE_H diff --git a/src/target/x86_32_common.c b/src/target/x86_32_common.c index d119be1..ecaf52b 100644 --- a/src/target/x86_32_common.c +++ b/src/target/x86_32_common.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright(c) 2013 Intel Corporation. * @@ -7,19 +9,6 @@ * Julien Carreno (julien.carreno@intel.com) * Jeffrey Maxwell (jeffrey.r.maxwell@intel.com) * - * 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, see <http://www.gnu.org/licenses/>. - * * Contact Information: * Intel Corporation */ diff --git a/src/target/x86_32_common.h b/src/target/x86_32_common.h index 14e6e35..7392447 100644 --- a/src/target/x86_32_common.h +++ b/src/target/x86_32_common.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * Copyright(c) 2013-2016 Intel Corporation. * @@ -7,19 +9,6 @@ * Julien Carreno (julien.carreno@intel.com) * Jeffrey Maxwell (jeffrey.r.maxwell@intel.com) * - * 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, see <http://www.gnu.org/licenses/>. - * * Contact Information: * Intel Corporation */ @@ -159,7 +148,7 @@ enum { PMCR, }; -#define X86_32_COMMON_MAGIC 0x86328632 +#define X86_32_COMMON_MAGIC 0x86328632U enum { /* memory read/write */ @@ -211,7 +200,8 @@ struct swbp_mem_patch { #define NUM_PM_REGS 18 /* regs used in save/restore */ struct x86_32_common { - uint32_t common_magic; + unsigned int common_magic; + void *arch_info; enum x86_core_type core_type; struct reg_cache *cache; diff --git a/src/target/xscale.c b/src/target/xscale.c index 78bd099..066ff8c 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2006, 2007 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -7,19 +9,6 @@ * * * Copyright (C) 2009 Michael Schwingen * * michael@schwingen.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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H diff --git a/src/target/xscale.h b/src/target/xscale.h index a86edb2..36a69bc 100644 --- a/src/target/xscale.h +++ b/src/target/xscale.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_XSCALE_H @@ -26,7 +15,7 @@ #include "armv4_5_mmu.h" #include "trace.h" -#define XSCALE_COMMON_MAGIC 0x58534341 +#define XSCALE_COMMON_MAGIC 0x58534341U /* These four JTAG instructions are architecturally defined. * Lengths are core-specific; originally 5 bits, later 7. @@ -82,11 +71,11 @@ struct xscale_trace { }; struct xscale_common { + unsigned int common_magic; + /* armv4/5 common stuff */ struct arm arm; - int common_magic; - /* XScale registers (CP15, DBG) */ struct reg_cache *reg_cache; diff --git a/src/target/xtensa/Makefile.am b/src/target/xtensa/Makefile.am index f6cee99..94c7c4a 100644 --- a/src/target/xtensa/Makefile.am +++ b/src/target/xtensa/Makefile.am @@ -1,7 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libxtensa.la %C%_libxtensa_la_SOURCES = \ %D%/xtensa.c \ %D%/xtensa.h \ + %D%/xtensa_chip.c \ + %D%/xtensa_chip.h \ %D%/xtensa_debug_module.c \ %D%/xtensa_debug_module.h \ %D%/xtensa_regs.h diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c index a955960..4dfff6a 100644 --- a/src/target/xtensa/xtensa.c +++ b/src/target/xtensa/xtensa.c @@ -1,24 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Generic Xtensa target API for OpenOCD * + * Copyright (C) 2020-2022 Cadence Design Systems, Inc. * * Copyright (C) 2016-2019 Espressif Systems Ltd. * * Derived from esp108.c * * Author: Angus Gratton gus@projectgus.com * - * Author: Jeroen Domburg <jeroen@espressif.com> * - * Author: Alexey Gerenkov <alexey@espressif.com> * - * Author: Andrey Gramakov <andrei.gramakov@espressif.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -30,325 +17,270 @@ #include <helper/align.h> #include <target/register.h> +#include "xtensa_chip.h" #include "xtensa.h" - -#define _XT_INS_FORMAT_RSR(OPCODE, SR, T) ((OPCODE) \ - | (((SR) & 0xFF) << 8) \ +/* Swap 4-bit Xtensa opcodes and fields */ +#define XT_NIBSWAP8(V) \ + ((((V) & 0x0F) << 4) \ + | (((V) & 0xF0) >> 4)) + +#define XT_NIBSWAP16(V) \ + ((((V) & 0x000F) << 12) \ + | (((V) & 0x00F0) << 4) \ + | (((V) & 0x0F00) >> 4) \ + | (((V) & 0xF000) >> 12)) + +#define XT_NIBSWAP24(V) \ + ((((V) & 0x00000F) << 20) \ + | (((V) & 0x0000F0) << 12) \ + | (((V) & 0x000F00) << 4) \ + | (((V) & 0x00F000) >> 4) \ + | (((V) & 0x0F0000) >> 12) \ + | (((V) & 0xF00000) >> 20)) + +/* _XT_INS_FORMAT_*() + * Instruction formatting converted from little-endian inputs + * and shifted to the MSB-side of DIR for BE systems. + */ +#define _XT_INS_FORMAT_RSR(X, OPCODE, SR, T) \ + (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \ + | (((T) & 0x0F) << 16) \ + | (((SR) & 0xFF) << 8)) << 8 \ + : (OPCODE) \ + | (((SR) & 0xFF) << 8) \ | (((T) & 0x0F) << 4)) -#define _XT_INS_FORMAT_RRR(OPCODE, ST, R) ((OPCODE) \ - | (((ST) & 0xFF) << 4) \ +#define _XT_INS_FORMAT_RRR(X, OPCODE, ST, R) \ + (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \ + | ((XT_NIBSWAP8((ST) & 0xFF)) << 12) \ + | (((R) & 0x0F) << 8)) << 8 \ + : (OPCODE) \ + | (((ST) & 0xFF) << 4) \ | (((R) & 0x0F) << 12)) -#define _XT_INS_FORMAT_RRRN(OPCODE, S, T, IMM4) ((OPCODE) \ - | (((T) & 0x0F) << 4) \ - | (((S) & 0x0F) << 8) \ +#define _XT_INS_FORMAT_RRRN(X, OPCODE, S, T, IMM4) \ + (XT_ISBE(X) ? (XT_NIBSWAP16(OPCODE) \ + | (((T) & 0x0F) << 8) \ + | (((S) & 0x0F) << 4) \ + | ((IMM4) & 0x0F)) << 16 \ + : (OPCODE) \ + | (((T) & 0x0F) << 4) \ + | (((S) & 0x0F) << 8) \ | (((IMM4) & 0x0F) << 12)) -#define _XT_INS_FORMAT_RRI8(OPCODE, R, S, T, IMM8) ((OPCODE) \ - | (((IMM8) & 0xFF) << 16) \ - | (((R) & 0x0F) << 12) \ - | (((S) & 0x0F) << 8) \ +#define _XT_INS_FORMAT_RRI8(X, OPCODE, R, S, T, IMM8) \ + (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \ + | (((T) & 0x0F) << 16) \ + | (((S) & 0x0F) << 12) \ + | (((R) & 0x0F) << 8) \ + | ((IMM8) & 0xFF)) << 8 \ + : (OPCODE) \ + | (((IMM8) & 0xFF) << 16) \ + | (((R) & 0x0F) << 12) \ + | (((S) & 0x0F) << 8) \ | (((T) & 0x0F) << 4)) -#define _XT_INS_FORMAT_RRI4(OPCODE, IMM4, R, S, T) ((OPCODE) \ - | (((IMM4) & 0x0F) << 20) \ - | (((R) & 0x0F) << 12) \ - | (((S) & 0x0F) << 8) \ +#define _XT_INS_FORMAT_RRI4(X, OPCODE, IMM4, R, S, T) \ + (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \ + | (((T) & 0x0F) << 16) \ + | (((S) & 0x0F) << 12) \ + | (((R) & 0x0F) << 8)) << 8 \ + | ((IMM4) & 0x0F) \ + : (OPCODE) \ + | (((IMM4) & 0x0F) << 20) \ + | (((R) & 0x0F) << 12) \ + | (((S) & 0x0F) << 8) \ | (((T) & 0x0F) << 4)) /* Xtensa processor instruction opcodes - * "Return From Debug Operation" to Normal */ -#define XT_INS_RFDO 0xf1e000 +*/ +/* "Return From Debug Operation" to Normal */ +#define XT_INS_RFDO(X) (XT_ISBE(X) ? 0x000e1f << 8 : 0xf1e000) /* "Return From Debug and Dispatch" - allow sw debugging stuff to take over */ -#define XT_INS_RFDD 0xf1e010 +#define XT_INS_RFDD(X) (XT_ISBE(X) ? 0x010e1f << 8 : 0xf1e010) /* Load to DDR register, increase addr register */ -#define XT_INS_LDDR32P(S) (0x0070E0 | ((S) << 8)) +#define XT_INS_LDDR32P(X, S) (XT_ISBE(X) ? (0x0E0700 | ((S) << 12)) << 8 : (0x0070E0 | ((S) << 8))) /* Store from DDR register, increase addr register */ -#define XT_INS_SDDR32P(S) (0x0070F0 | ((S) << 8)) - -/* Load 32-bit Indirect from A(S) + 4 * IMM8 to A(T) */ -#define XT_INS_L32I(S, T, IMM8) _XT_INS_FORMAT_RRI8(0x002002, 0, S, T, IMM8) -/* Load 16-bit Unsigned from A(S) + 2 * IMM8 to A(T) */ -#define XT_INS_L16UI(S, T, IMM8) _XT_INS_FORMAT_RRI8(0x001002, 0, S, T, IMM8) -/* Load 8-bit Unsigned from A(S) + IMM8 to A(T) */ -#define XT_INS_L8UI(S, T, IMM8) _XT_INS_FORMAT_RRI8(0x000002, 0, S, T, IMM8) - -/* Store 32-bit Indirect to A(S) + 4 * IMM8 from A(T) */ -#define XT_INS_S32I(S, T, IMM8) _XT_INS_FORMAT_RRI8(0x006002, 0, S, T, IMM8) -/* Store 16-bit to A(S) + 2 * IMM8 from A(T) */ -#define XT_INS_S16I(S, T, IMM8) _XT_INS_FORMAT_RRI8(0x005002, 0, S, T, IMM8) -/* Store 8-bit to A(S) + IMM8 from A(T) */ -#define XT_INS_S8I(S, T, IMM8) _XT_INS_FORMAT_RRI8(0x004002, 0, S, T, IMM8) +#define XT_INS_SDDR32P(X, S) (XT_ISBE(X) ? (0x0F0700 | ((S) << 12)) << 8 : (0x0070F0 | ((S) << 8))) + +/* Load 32-bit Indirect from A(S)+4*IMM8 to A(T) */ +#define XT_INS_L32I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x002002, 0, S, T, IMM8) +/* Load 16-bit Unsigned from A(S)+2*IMM8 to A(T) */ +#define XT_INS_L16UI(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x001002, 0, S, T, IMM8) +/* Load 8-bit Unsigned from A(S)+IMM8 to A(T) */ +#define XT_INS_L8UI(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x000002, 0, S, T, IMM8) + +/* Store 32-bit Indirect to A(S)+4*IMM8 from A(T) */ +#define XT_INS_S32I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x006002, 0, S, T, IMM8) +/* Store 16-bit to A(S)+2*IMM8 from A(T) */ +#define XT_INS_S16I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x005002, 0, S, T, IMM8) +/* Store 8-bit to A(S)+IMM8 from A(T) */ +#define XT_INS_S8I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x004002, 0, S, T, IMM8) + +/* Cache Instructions */ +#define XT_INS_IHI(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x0070E2, 0, S, 0, IMM8) +#define XT_INS_DHWBI(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x007052, 0, S, 0, IMM8) +#define XT_INS_DHWB(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x007042, 0, S, 0, IMM8) +#define XT_INS_ISYNC(X) (XT_ISBE(X) ? 0x000200 << 8 : 0x002000) + +/* Control Instructions */ +#define XT_INS_JX(X, S) (XT_ISBE(X) ? (0x050000 | ((S) << 12)) : (0x0000a0 | ((S) << 8))) +#define XT_INS_CALL0(X, IMM18) (XT_ISBE(X) ? (0x500000 | ((IMM18) & 0x3ffff)) : (0x000005 | (((IMM18) & 0x3ffff) << 6))) /* Read Special Register */ -#define XT_INS_RSR(SR, T) _XT_INS_FORMAT_RSR(0x030000, SR, T) +#define XT_INS_RSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x030000, SR, T) /* Write Special Register */ -#define XT_INS_WSR(SR, T) _XT_INS_FORMAT_RSR(0x130000, SR, T) +#define XT_INS_WSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x130000, SR, T) /* Swap Special Register */ -#define XT_INS_XSR(SR, T) _XT_INS_FORMAT_RSR(0x610000, SR, T) +#define XT_INS_XSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x610000, SR, T) /* Rotate Window by (-8..7) */ -#define XT_INS_ROTW(N) ((0x408000) | (((N) & 15) << 4)) +#define XT_INS_ROTW(X, N) (XT_ISBE(X) ? ((0x000804) | (((N) & 15) << 16)) << 8 : ((0x408000) | (((N) & 15) << 4))) /* Read User Register */ -#define XT_INS_RUR(UR, T) _XT_INS_FORMAT_RRR(0xE30000, UR, T) +#define XT_INS_RUR(X, UR, T) _XT_INS_FORMAT_RRR(X, 0xE30000, UR, T) /* Write User Register */ -#define XT_INS_WUR(UR, T) _XT_INS_FORMAT_RSR(0xF30000, UR, T) +#define XT_INS_WUR(X, UR, T) _XT_INS_FORMAT_RSR(X, 0xF30000, UR, T) /* Read Floating-Point Register */ -#define XT_INS_RFR(FR, T) _XT_INS_FORMAT_RRR(0xFA0000, (((FR) << 4) | 0x4), T) +#define XT_INS_RFR(X, FR, T) _XT_INS_FORMAT_RRR(X, 0xFA0000, ((FR << 4) | 0x4), T) /* Write Floating-Point Register */ -#define XT_INS_WFR(FR, T) _XT_INS_FORMAT_RRR(0xFA0000, (((FR) << 4) | 0x5), T) - -/* 32-bit break */ -#define XT_INS_BREAK(IMM1, IMM2) _XT_INS_FORMAT_RRR(0x000000, \ - (((IMM1) & 0x0F) << 4) | ((IMM2) & 0x0F), 0x4) -/* 16-bit break */ -#define XT_INS_BREAKN(IMM4) _XT_INS_FORMAT_RRRN(0x00000D, IMM4, 0x2, 0xF) +#define XT_INS_WFR(X, FR, T) _XT_INS_FORMAT_RRR(X, 0xFA0000, ((T << 4) | 0x5), FR) -#define XT_INS_L32E(R, S, T) _XT_INS_FORMAT_RRI4(0x90000, 0, R, S, T) -#define XT_INS_S32E(R, S, T) _XT_INS_FORMAT_RRI4(0x490000, 0, R, S, T) -#define XT_INS_L32E_S32E_MASK 0xFF000F +#define XT_INS_L32E(X, R, S, T) _XT_INS_FORMAT_RRI4(X, 0x090000, 0, R, S, T) +#define XT_INS_S32E(X, R, S, T) _XT_INS_FORMAT_RRI4(X, 0x490000, 0, R, S, T) +#define XT_INS_L32E_S32E_MASK(X) (XT_ISBE(X) ? 0xF000FF << 8 : 0xFF000F) -#define XT_INS_RFWO 0x3400 -#define XT_INS_RFWU 0x3500 -#define XT_INS_RFWO_RFWU_MASK 0xFFFFFF +#define XT_INS_RFWO(X) (XT_ISBE(X) ? 0x004300 << 8 : 0x003400) +#define XT_INS_RFWU(X) (XT_ISBE(X) ? 0x005300 << 8 : 0x003500) +#define XT_INS_RFWO_RFWU_MASK(X) (XT_ISBE(X) ? 0xFFFFFF << 8 : 0xFFFFFF) #define XT_WATCHPOINTS_NUM_MAX 2 -/* Special register number macro for DDR register. -* this gets used a lot so making a shortcut to it is -* useful. -*/ -#define XT_SR_DDR (xtensa_regs[XT_REG_IDX_OCD_DDR].reg_num) - -/*Same thing for A3/A4 */ +/* Special register number macro for DDR, PS, WB, A3, A4 registers. + * These get used a lot so making a shortcut is useful. + */ +#define XT_SR_DDR (xtensa_regs[XT_REG_IDX_DDR].reg_num) +#define XT_SR_PS (xtensa_regs[XT_REG_IDX_PS].reg_num) +#define XT_SR_WB (xtensa_regs[XT_REG_IDX_WINDOWBASE].reg_num) #define XT_REG_A3 (xtensa_regs[XT_REG_IDX_AR3].reg_num) #define XT_REG_A4 (xtensa_regs[XT_REG_IDX_AR4].reg_num) -#define XT_PC_REG_NUM_BASE (176) -#define XT_SW_BREAKPOINTS_MAX_NUM 32 - -const struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS] = { - { "pc", XT_PC_REG_NUM_BASE /*+XT_DEBUGLEVEL*/, XT_REG_SPECIAL, 0 }, /* actually epc[debuglevel] */ - { "ar0", 0x00, XT_REG_GENERAL, 0 }, - { "ar1", 0x01, XT_REG_GENERAL, 0 }, - { "ar2", 0x02, XT_REG_GENERAL, 0 }, - { "ar3", 0x03, XT_REG_GENERAL, 0 }, - { "ar4", 0x04, XT_REG_GENERAL, 0 }, - { "ar5", 0x05, XT_REG_GENERAL, 0 }, - { "ar6", 0x06, XT_REG_GENERAL, 0 }, - { "ar7", 0x07, XT_REG_GENERAL, 0 }, - { "ar8", 0x08, XT_REG_GENERAL, 0 }, - { "ar9", 0x09, XT_REG_GENERAL, 0 }, - { "ar10", 0x0A, XT_REG_GENERAL, 0 }, - { "ar11", 0x0B, XT_REG_GENERAL, 0 }, - { "ar12", 0x0C, XT_REG_GENERAL, 0 }, - { "ar13", 0x0D, XT_REG_GENERAL, 0 }, - { "ar14", 0x0E, XT_REG_GENERAL, 0 }, - { "ar15", 0x0F, XT_REG_GENERAL, 0 }, - { "ar16", 0x10, XT_REG_GENERAL, 0 }, - { "ar17", 0x11, XT_REG_GENERAL, 0 }, - { "ar18", 0x12, XT_REG_GENERAL, 0 }, - { "ar19", 0x13, XT_REG_GENERAL, 0 }, - { "ar20", 0x14, XT_REG_GENERAL, 0 }, - { "ar21", 0x15, XT_REG_GENERAL, 0 }, - { "ar22", 0x16, XT_REG_GENERAL, 0 }, - { "ar23", 0x17, XT_REG_GENERAL, 0 }, - { "ar24", 0x18, XT_REG_GENERAL, 0 }, - { "ar25", 0x19, XT_REG_GENERAL, 0 }, - { "ar26", 0x1A, XT_REG_GENERAL, 0 }, - { "ar27", 0x1B, XT_REG_GENERAL, 0 }, - { "ar28", 0x1C, XT_REG_GENERAL, 0 }, - { "ar29", 0x1D, XT_REG_GENERAL, 0 }, - { "ar30", 0x1E, XT_REG_GENERAL, 0 }, - { "ar31", 0x1F, XT_REG_GENERAL, 0 }, - { "ar32", 0x20, XT_REG_GENERAL, 0 }, - { "ar33", 0x21, XT_REG_GENERAL, 0 }, - { "ar34", 0x22, XT_REG_GENERAL, 0 }, - { "ar35", 0x23, XT_REG_GENERAL, 0 }, - { "ar36", 0x24, XT_REG_GENERAL, 0 }, - { "ar37", 0x25, XT_REG_GENERAL, 0 }, - { "ar38", 0x26, XT_REG_GENERAL, 0 }, - { "ar39", 0x27, XT_REG_GENERAL, 0 }, - { "ar40", 0x28, XT_REG_GENERAL, 0 }, - { "ar41", 0x29, XT_REG_GENERAL, 0 }, - { "ar42", 0x2A, XT_REG_GENERAL, 0 }, - { "ar43", 0x2B, XT_REG_GENERAL, 0 }, - { "ar44", 0x2C, XT_REG_GENERAL, 0 }, - { "ar45", 0x2D, XT_REG_GENERAL, 0 }, - { "ar46", 0x2E, XT_REG_GENERAL, 0 }, - { "ar47", 0x2F, XT_REG_GENERAL, 0 }, - { "ar48", 0x30, XT_REG_GENERAL, 0 }, - { "ar49", 0x31, XT_REG_GENERAL, 0 }, - { "ar50", 0x32, XT_REG_GENERAL, 0 }, - { "ar51", 0x33, XT_REG_GENERAL, 0 }, - { "ar52", 0x34, XT_REG_GENERAL, 0 }, - { "ar53", 0x35, XT_REG_GENERAL, 0 }, - { "ar54", 0x36, XT_REG_GENERAL, 0 }, - { "ar55", 0x37, XT_REG_GENERAL, 0 }, - { "ar56", 0x38, XT_REG_GENERAL, 0 }, - { "ar57", 0x39, XT_REG_GENERAL, 0 }, - { "ar58", 0x3A, XT_REG_GENERAL, 0 }, - { "ar59", 0x3B, XT_REG_GENERAL, 0 }, - { "ar60", 0x3C, XT_REG_GENERAL, 0 }, - { "ar61", 0x3D, XT_REG_GENERAL, 0 }, - { "ar62", 0x3E, XT_REG_GENERAL, 0 }, - { "ar63", 0x3F, XT_REG_GENERAL, 0 }, - { "lbeg", 0x00, XT_REG_SPECIAL, 0 }, - { "lend", 0x01, XT_REG_SPECIAL, 0 }, - { "lcount", 0x02, XT_REG_SPECIAL, 0 }, - { "sar", 0x03, XT_REG_SPECIAL, 0 }, - { "windowbase", 0x48, XT_REG_SPECIAL, 0 }, - { "windowstart", 0x49, XT_REG_SPECIAL, 0 }, - { "configid0", 0xB0, XT_REG_SPECIAL, 0 }, - { "configid1", 0xD0, XT_REG_SPECIAL, 0 }, - { "ps", 0xC6, XT_REG_SPECIAL, 0 }, /* actually EPS[debuglevel] */ - { "threadptr", 0xE7, XT_REG_USER, 0 }, - { "br", 0x04, XT_REG_SPECIAL, 0 }, - { "scompare1", 0x0C, XT_REG_SPECIAL, 0 }, - { "acclo", 0x10, XT_REG_SPECIAL, 0 }, - { "acchi", 0x11, XT_REG_SPECIAL, 0 }, - { "m0", 0x20, XT_REG_SPECIAL, 0 }, - { "m1", 0x21, XT_REG_SPECIAL, 0 }, - { "m2", 0x22, XT_REG_SPECIAL, 0 }, - { "m3", 0x23, XT_REG_SPECIAL, 0 }, - { "f0", 0x00, XT_REG_FR, XT_REGF_COPROC0 }, - { "f1", 0x01, XT_REG_FR, XT_REGF_COPROC0 }, - { "f2", 0x02, XT_REG_FR, XT_REGF_COPROC0 }, - { "f3", 0x03, XT_REG_FR, XT_REGF_COPROC0 }, - { "f4", 0x04, XT_REG_FR, XT_REGF_COPROC0 }, - { "f5", 0x05, XT_REG_FR, XT_REGF_COPROC0 }, - { "f6", 0x06, XT_REG_FR, XT_REGF_COPROC0 }, - { "f7", 0x07, XT_REG_FR, XT_REGF_COPROC0 }, - { "f8", 0x08, XT_REG_FR, XT_REGF_COPROC0 }, - { "f9", 0x09, XT_REG_FR, XT_REGF_COPROC0 }, - { "f10", 0x0A, XT_REG_FR, XT_REGF_COPROC0 }, - { "f11", 0x0B, XT_REG_FR, XT_REGF_COPROC0 }, - { "f12", 0x0C, XT_REG_FR, XT_REGF_COPROC0 }, - { "f13", 0x0D, XT_REG_FR, XT_REGF_COPROC0 }, - { "f14", 0x0E, XT_REG_FR, XT_REGF_COPROC0 }, - { "f15", 0x0F, XT_REG_FR, XT_REGF_COPROC0 }, - { "fcr", 0xE8, XT_REG_USER, XT_REGF_COPROC0 }, - { "fsr", 0xE9, XT_REG_USER, XT_REGF_COPROC0 }, - { "mmid", 0x59, XT_REG_SPECIAL, XT_REGF_NOREAD }, - { "ibreakenable", 0x60, XT_REG_SPECIAL, 0 }, - { "memctl", 0x61, XT_REG_SPECIAL, 0 }, - { "atomctl", 0x63, XT_REG_SPECIAL, 0 }, - { "ibreaka0", 0x80, XT_REG_SPECIAL, 0 }, - { "ibreaka1", 0x81, XT_REG_SPECIAL, 0 }, - { "dbreaka0", 0x90, XT_REG_SPECIAL, 0 }, - { "dbreaka1", 0x91, XT_REG_SPECIAL, 0 }, - { "dbreakc0", 0xA0, XT_REG_SPECIAL, 0 }, - { "dbreakc1", 0xA1, XT_REG_SPECIAL, 0 }, - { "epc1", 0xB1, XT_REG_SPECIAL, 0 }, - { "epc2", 0xB2, XT_REG_SPECIAL, 0 }, - { "epc3", 0xB3, XT_REG_SPECIAL, 0 }, - { "epc4", 0xB4, XT_REG_SPECIAL, 0 }, - { "epc5", 0xB5, XT_REG_SPECIAL, 0 }, - { "epc6", 0xB6, XT_REG_SPECIAL, 0 }, - { "epc7", 0xB7, XT_REG_SPECIAL, 0 }, - { "depc", 0xC0, XT_REG_SPECIAL, 0 }, - { "eps2", 0xC2, XT_REG_SPECIAL, 0 }, - { "eps3", 0xC3, XT_REG_SPECIAL, 0 }, - { "eps4", 0xC4, XT_REG_SPECIAL, 0 }, - { "eps5", 0xC5, XT_REG_SPECIAL, 0 }, - { "eps6", 0xC6, XT_REG_SPECIAL, 0 }, - { "eps7", 0xC7, XT_REG_SPECIAL, 0 }, - { "excsave1", 0xD1, XT_REG_SPECIAL, 0 }, - { "excsave2", 0xD2, XT_REG_SPECIAL, 0 }, - { "excsave3", 0xD3, XT_REG_SPECIAL, 0 }, - { "excsave4", 0xD4, XT_REG_SPECIAL, 0 }, - { "excsave5", 0xD5, XT_REG_SPECIAL, 0 }, - { "excsave6", 0xD6, XT_REG_SPECIAL, 0 }, - { "excsave7", 0xD7, XT_REG_SPECIAL, 0 }, - { "cpenable", 0xE0, XT_REG_SPECIAL, 0 }, - { "interrupt", 0xE2, XT_REG_SPECIAL, 0 }, - { "intset", 0xE2, XT_REG_SPECIAL, XT_REGF_NOREAD }, - { "intclear", 0xE3, XT_REG_SPECIAL, XT_REGF_NOREAD }, - { "intenable", 0xE4, XT_REG_SPECIAL, 0 }, - { "vecbase", 0xE7, XT_REG_SPECIAL, 0 }, - { "exccause", 0xE8, XT_REG_SPECIAL, 0 }, - { "debugcause", 0xE9, XT_REG_SPECIAL, 0 }, - { "ccount", 0xEA, XT_REG_SPECIAL, 0 }, - { "prid", 0xEB, XT_REG_SPECIAL, 0 }, - { "icount", 0xEC, XT_REG_SPECIAL, 0 }, - { "icountlevel", 0xED, XT_REG_SPECIAL, 0 }, - { "excvaddr", 0xEE, XT_REG_SPECIAL, 0 }, - { "ccompare0", 0xF0, XT_REG_SPECIAL, 0 }, - { "ccompare1", 0xF1, XT_REG_SPECIAL, 0 }, - { "ccompare2", 0xF2, XT_REG_SPECIAL, 0 }, - { "misc0", 0xF4, XT_REG_SPECIAL, 0 }, - { "misc1", 0xF5, XT_REG_SPECIAL, 0 }, - { "misc2", 0xF6, XT_REG_SPECIAL, 0 }, - { "misc3", 0xF7, XT_REG_SPECIAL, 0 }, - { "litbase", 0x05, XT_REG_SPECIAL, 0 }, - { "ptevaddr", 0x53, XT_REG_SPECIAL, 0 }, - { "rasid", 0x5A, XT_REG_SPECIAL, 0 }, - { "itlbcfg", 0x5B, XT_REG_SPECIAL, 0 }, - { "dtlbcfg", 0x5C, XT_REG_SPECIAL, 0 }, - { "mepc", 0x6A, XT_REG_SPECIAL, 0 }, - { "meps", 0x6B, XT_REG_SPECIAL, 0 }, - { "mesave", 0x6C, XT_REG_SPECIAL, 0 }, - { "mesr", 0x6D, XT_REG_SPECIAL, 0 }, - { "mecr", 0x6E, XT_REG_SPECIAL, 0 }, - { "mevaddr", 0x6F, XT_REG_SPECIAL, 0 }, - { "a0", XT_REG_IDX_AR0, XT_REG_RELGEN, 0 }, /* WARNING: For these registers, regnum points to the */ - { "a1", XT_REG_IDX_AR1, XT_REG_RELGEN, 0 }, /* index of the corresponding ARxregisters, NOT to */ - { "a2", XT_REG_IDX_AR2, XT_REG_RELGEN, 0 }, /* the processor register number! */ - { "a3", XT_REG_IDX_AR3, XT_REG_RELGEN, 0 }, - { "a4", XT_REG_IDX_AR4, XT_REG_RELGEN, 0 }, - { "a5", XT_REG_IDX_AR5, XT_REG_RELGEN, 0 }, - { "a6", XT_REG_IDX_AR6, XT_REG_RELGEN, 0 }, - { "a7", XT_REG_IDX_AR7, XT_REG_RELGEN, 0 }, - { "a8", XT_REG_IDX_AR8, XT_REG_RELGEN, 0 }, - { "a9", XT_REG_IDX_AR9, XT_REG_RELGEN, 0 }, - { "a10", XT_REG_IDX_AR10, XT_REG_RELGEN, 0 }, - { "a11", XT_REG_IDX_AR11, XT_REG_RELGEN, 0 }, - { "a12", XT_REG_IDX_AR12, XT_REG_RELGEN, 0 }, - { "a13", XT_REG_IDX_AR13, XT_REG_RELGEN, 0 }, - { "a14", XT_REG_IDX_AR14, XT_REG_RELGEN, 0 }, - { "a15", XT_REG_IDX_AR15, XT_REG_RELGEN, 0 }, - - { "pwrctl", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "pwrstat", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "eristat", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "cs_itctrl", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "cs_claimset", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "cs_claimclr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "cs_lockaccess", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "cs_lockstatus", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "cs_authstatus", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "fault_info", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "trax_id", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "trax_ctrl", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "trax_stat", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "trax_data", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "trax_addr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "trax_pctrigger", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "trax_pcmatch", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "trax_delay", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "trax_memstart", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "trax_memend", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "pmg", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "pmoc", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "pm0", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "pm1", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "pmctrl0", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "pmctrl1", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "pmstat0", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "pmstat1", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "ocd_id", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "ocd_dcrclr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "ocd_dcrset", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "ocd_dsr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, - { "ddr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD }, +#define XT_PS_REG_NUM_BASE (0xc0U) /* (EPS2 - 2), for adding DBGLEVEL */ +#define XT_PC_REG_NUM_BASE (0xb0U) /* (EPC1 - 1), for adding DBGLEVEL */ +#define XT_PC_REG_NUM_VIRTUAL (0xffU) /* Marker for computing PC (EPC[DBGLEVEL) */ +#define XT_PC_DBREG_NUM_BASE (0x20U) /* External (i.e., GDB) access */ + +#define XT_SW_BREAKPOINTS_MAX_NUM 32 +#define XT_HW_IBREAK_MAX_NUM 2 +#define XT_HW_DBREAK_MAX_NUM 2 + +struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS] = { + XT_MK_REG_DESC("pc", XT_PC_REG_NUM_VIRTUAL, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("ar0", 0x00, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar1", 0x01, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar2", 0x02, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar3", 0x03, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar4", 0x04, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar5", 0x05, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar6", 0x06, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar7", 0x07, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar8", 0x08, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar9", 0x09, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar10", 0x0A, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar11", 0x0B, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar12", 0x0C, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar13", 0x0D, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar14", 0x0E, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar15", 0x0F, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar16", 0x10, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar17", 0x11, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar18", 0x12, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar19", 0x13, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar20", 0x14, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar21", 0x15, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar22", 0x16, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar23", 0x17, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar24", 0x18, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar25", 0x19, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar26", 0x1A, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar27", 0x1B, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar28", 0x1C, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar29", 0x1D, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar30", 0x1E, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar31", 0x1F, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar32", 0x20, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar33", 0x21, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar34", 0x22, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar35", 0x23, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar36", 0x24, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar37", 0x25, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar38", 0x26, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar39", 0x27, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar40", 0x28, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar41", 0x29, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar42", 0x2A, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar43", 0x2B, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar44", 0x2C, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar45", 0x2D, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar46", 0x2E, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar47", 0x2F, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar48", 0x30, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar49", 0x31, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar50", 0x32, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar51", 0x33, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar52", 0x34, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar53", 0x35, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar54", 0x36, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar55", 0x37, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar56", 0x38, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar57", 0x39, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar58", 0x3A, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar59", 0x3B, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar60", 0x3C, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar61", 0x3D, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar62", 0x3E, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("ar63", 0x3F, XT_REG_GENERAL, 0), + XT_MK_REG_DESC("windowbase", 0x48, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("windowstart", 0x49, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("ps", 0xE6, XT_REG_SPECIAL, 0), /* PS (not mapped through EPS[]) */ + XT_MK_REG_DESC("ibreakenable", 0x60, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("ddr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD), + XT_MK_REG_DESC("ibreaka0", 0x80, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("ibreaka1", 0x81, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("dbreaka0", 0x90, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("dbreaka1", 0x91, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("dbreakc0", 0xA0, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("dbreakc1", 0xA1, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("cpenable", 0xE0, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("exccause", 0xE8, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("debugcause", 0xE9, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("icount", 0xEC, XT_REG_SPECIAL, 0), + XT_MK_REG_DESC("icountlevel", 0xED, XT_REG_SPECIAL, 0), + + /* WARNING: For these registers, regnum points to the + * index of the corresponding ARx registers, NOT to + * the processor register number! */ + XT_MK_REG_DESC("a0", XT_REG_IDX_AR0, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a1", XT_REG_IDX_AR1, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a2", XT_REG_IDX_AR2, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a3", XT_REG_IDX_AR3, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a4", XT_REG_IDX_AR4, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a5", XT_REG_IDX_AR5, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a6", XT_REG_IDX_AR6, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a7", XT_REG_IDX_AR7, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a8", XT_REG_IDX_AR8, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a9", XT_REG_IDX_AR9, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a10", XT_REG_IDX_AR10, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a11", XT_REG_IDX_AR11, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a12", XT_REG_IDX_AR12, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a13", XT_REG_IDX_AR13, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a14", XT_REG_IDX_AR14, XT_REG_RELGEN, 0), + XT_MK_REG_DESC("a15", XT_REG_IDX_AR15, XT_REG_RELGEN, 0), }; - /** * Types of memory used at xtensa target */ @@ -357,11 +289,27 @@ enum xtensa_mem_region_type { XTENSA_MEM_REG_IRAM, XTENSA_MEM_REG_DROM, XTENSA_MEM_REG_DRAM, - XTENSA_MEM_REG_URAM, - XTENSA_MEM_REG_XLMI, + XTENSA_MEM_REG_SRAM, + XTENSA_MEM_REG_SROM, XTENSA_MEM_REGS_NUM }; +/* Register definition as union for list allocation */ +union xtensa_reg_val_u { + xtensa_reg_val_t val; + uint8_t buf[4]; +}; + +static const struct xtensa_keyval_info_s xt_qerr[XT_QERR_NUM] = { + { .chrval = "E00", .intval = ERROR_FAIL }, + { .chrval = "E01", .intval = ERROR_FAIL }, + { .chrval = "E02", .intval = ERROR_COMMAND_ARGUMENT_INVALID }, + { .chrval = "E03", .intval = ERROR_FAIL }, +}; + +/* Set to true for extra debug logging */ +static const bool xtensa_extra_debug_log; + /** * Gets a config for the specific mem type */ @@ -378,10 +326,10 @@ static inline const struct xtensa_local_mem_config *xtensa_get_mem_config( return &xtensa->core_config->drom; case XTENSA_MEM_REG_DRAM: return &xtensa->core_config->dram; - case XTENSA_MEM_REG_URAM: - return &xtensa->core_config->uram; - case XTENSA_MEM_REG_XLMI: - return &xtensa->core_config->xlmi; + case XTENSA_MEM_REG_SRAM: + return &xtensa->core_config->sram; + case XTENSA_MEM_REG_SROM: + return &xtensa->core_config->srom; default: return NULL; } @@ -424,14 +372,47 @@ static inline const struct xtensa_local_mem_region_config *xtensa_target_memory_ return NULL; } +static inline bool xtensa_is_cacheable(const struct xtensa_cache_config *cache, + const struct xtensa_local_mem_config *mem, + target_addr_t address) +{ + if (!cache->size) + return false; + return xtensa_memory_region_find(mem, address); +} + +static inline bool xtensa_is_icacheable(struct xtensa *xtensa, target_addr_t address) +{ + return xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->iram, address) || + xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->irom, address) || + xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->sram, address) || + xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->srom, address); +} + +static inline bool xtensa_is_dcacheable(struct xtensa *xtensa, target_addr_t address) +{ + return xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->dram, address) || + xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->drom, address) || + xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->sram, address) || + xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->srom, address); +} + static int xtensa_core_reg_get(struct reg *reg) { - /*We don't need this because we read all registers on halt anyway. */ + /* We don't need this because we read all registers on halt anyway. */ struct xtensa *xtensa = (struct xtensa *)reg->arch_info; struct target *target = xtensa->target; if (target->state != TARGET_HALTED) return ERROR_TARGET_NOT_HALTED; + if (!reg->exist) { + if (strncmp(reg->name, "?0x", 3) == 0) { + unsigned int regnum = strtoul(reg->name + 1, 0, 0); + LOG_WARNING("Read unknown register 0x%04x ignored", regnum); + return ERROR_OK; + } + return ERROR_COMMAND_ARGUMENT_INVALID; + } return ERROR_OK; } @@ -444,7 +425,31 @@ static int xtensa_core_reg_set(struct reg *reg, uint8_t *buf) if (target->state != TARGET_HALTED) return ERROR_TARGET_NOT_HALTED; + if (!reg->exist) { + if (strncmp(reg->name, "?0x", 3) == 0) { + unsigned int regnum = strtoul(reg->name + 1, 0, 0); + LOG_WARNING("Write unknown register 0x%04x ignored", regnum); + return ERROR_OK; + } + return ERROR_COMMAND_ARGUMENT_INVALID; + } + buf_cpy(buf, reg->value, reg->size); + + if (xtensa->core_config->windowed) { + /* If the user updates a potential scratch register, track for conflicts */ + for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++) { + if (strcmp(reg->name, xtensa->scratch_ars[s].chrval) == 0) { + LOG_DEBUG("Scratch reg %s [0x%08" PRIx32 "] set from gdb", reg->name, + buf_get_u32(reg->value, 0, 32)); + LOG_DEBUG("scratch_ars mapping: a3/%s, a4/%s", + xtensa->scratch_ars[XT_AR_SCRATCH_AR3].chrval, + xtensa->scratch_ars[XT_AR_SCRATCH_AR4].chrval); + xtensa->scratch_ars[s].intval = true; + break; + } + } + } reg->dirty = true; reg->valid = true; @@ -456,26 +461,13 @@ static const struct reg_arch_type xtensa_reg_type = { .set = xtensa_core_reg_set, }; -const struct reg_arch_type xtensa_user_reg_u32_type = { - .get = xtensa_core_reg_get, - .set = xtensa_core_reg_set, -}; - -const struct reg_arch_type xtensa_user_reg_u128_type = { - .get = xtensa_core_reg_get, - .set = xtensa_core_reg_set, -}; - -static inline size_t xtensa_insn_size_get(uint32_t insn) -{ - return insn & BIT(3) ? 2 : XT_ISNS_SZ_MAX; -} - /* Convert a register index that's indexed relative to windowbase, to the real address. */ -static enum xtensa_reg_id xtensa_windowbase_offset_to_canonical(enum xtensa_reg_id reg_idx, int windowbase) +static enum xtensa_reg_id xtensa_windowbase_offset_to_canonical(struct xtensa *xtensa, + enum xtensa_reg_id reg_idx, + int windowbase) { unsigned int idx; - if (reg_idx >= XT_REG_IDX_AR0 && reg_idx <= XT_REG_IDX_AR63) { + if (reg_idx >= XT_REG_IDX_AR0 && reg_idx <= XT_REG_IDX_ARLAST) { idx = reg_idx - XT_REG_IDX_AR0; } else if (reg_idx >= XT_REG_IDX_A0 && reg_idx <= XT_REG_IDX_A15) { idx = reg_idx - XT_REG_IDX_A0; @@ -483,12 +475,14 @@ static enum xtensa_reg_id xtensa_windowbase_offset_to_canonical(enum xtensa_reg_ LOG_ERROR("Error: can't convert register %d to non-windowbased register!", reg_idx); return -1; } - return ((idx + windowbase * 4) & 63) + XT_REG_IDX_AR0; + return ((idx + windowbase * 4) & (xtensa->core_config->aregs_num - 1)) + XT_REG_IDX_AR0; } -static enum xtensa_reg_id xtensa_canonical_to_windowbase_offset(enum xtensa_reg_id reg_idx, int windowbase) +static enum xtensa_reg_id xtensa_canonical_to_windowbase_offset(struct xtensa *xtensa, + enum xtensa_reg_id reg_idx, + int windowbase) { - return xtensa_windowbase_offset_to_canonical(reg_idx, -windowbase); + return xtensa_windowbase_offset_to_canonical(xtensa, reg_idx, -windowbase); } static void xtensa_mark_register_dirty(struct xtensa *xtensa, enum xtensa_reg_id reg_idx) @@ -497,36 +491,78 @@ static void xtensa_mark_register_dirty(struct xtensa *xtensa, enum xtensa_reg_id reg_list[reg_idx].dirty = true; } -static int xtensa_queue_dbg_reg_read(struct xtensa *xtensa, unsigned int reg, uint8_t *data) +static void xtensa_queue_exec_ins(struct xtensa *xtensa, uint32_t ins) { - struct xtensa_debug_module *dm = &xtensa->dbg_mod; + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DIR0EXEC, ins); +} - if (!xtensa->core_config->trace.enabled && - (reg <= NARADR_MEMADDREND || (reg >= NARADR_PMG && reg <= NARADR_PMSTAT7))) { - LOG_ERROR("Can not access %u reg when Trace Port option disabled!", reg); - return ERROR_FAIL; +static void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint8_t oplen) +{ + const int max_oplen = 64; /* 8 DIRx regs: max width 64B */ + if ((oplen > 0) && (oplen <= max_oplen)) { + uint8_t ops_padded[max_oplen]; + memcpy(ops_padded, ops, oplen); + memset(ops_padded + oplen, 0, max_oplen - oplen); + unsigned int oplenw = DIV_ROUND_UP(oplen, sizeof(uint32_t)); + for (int32_t i = oplenw - 1; i > 0; i--) + xtensa_queue_dbg_reg_write(xtensa, + XDMREG_DIR0 + i, + target_buffer_get_u32(xtensa->target, &ops_padded[sizeof(uint32_t)*i])); + /* Write DIR0EXEC last */ + xtensa_queue_dbg_reg_write(xtensa, + XDMREG_DIR0EXEC, + target_buffer_get_u32(xtensa->target, &ops_padded[0])); } - return dm->dbg_ops->queue_reg_read(dm, reg, data); } -static int xtensa_queue_dbg_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data) +static int xtensa_queue_pwr_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data) { struct xtensa_debug_module *dm = &xtensa->dbg_mod; + return dm->pwr_ops->queue_reg_write(dm, reg, data); +} - if (!xtensa->core_config->trace.enabled && - (reg <= NARADR_MEMADDREND || (reg >= NARADR_PMG && reg <= NARADR_PMSTAT7))) { - LOG_ERROR("Can not access %u reg when Trace Port option disabled!", reg); - return ERROR_FAIL; +/* NOTE: Assumes A3 has already been saved */ +static int xtensa_window_state_save(struct target *target, uint32_t *woe) +{ + struct xtensa *xtensa = target_to_xtensa(target); + int woe_dis; + uint8_t woe_buf[4]; + + if (xtensa->core_config->windowed) { + /* Save PS (LX) and disable window overflow exceptions prior to AR save */ + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_PS, XT_REG_A3)); + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, woe_buf); + int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); + if (res != ERROR_OK) { + LOG_ERROR("Failed to read PS (%d)!", res); + return res; + } + xtensa_core_status_check(target); + *woe = buf_get_u32(woe_buf, 0, 32); + woe_dis = *woe & ~XT_PS_WOE_MSK; + LOG_DEBUG("Clearing PS.WOE (0x%08" PRIx32 " -> 0x%08" PRIx32 ")", *woe, woe_dis); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, woe_dis); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_PS, XT_REG_A3)); } - return dm->dbg_ops->queue_reg_write(dm, reg, data); + return ERROR_OK; } -static void xtensa_queue_exec_ins(struct xtensa *xtensa, uint32_t ins) +/* NOTE: Assumes A3 has already been saved */ +static void xtensa_window_state_restore(struct target *target, uint32_t woe) { - xtensa_queue_dbg_reg_write(xtensa, NARADR_DIR0EXEC, ins); + struct xtensa *xtensa = target_to_xtensa(target); + if (xtensa->core_config->windowed) { + /* Restore window overflow exception state */ + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, woe); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_PS, XT_REG_A3)); + LOG_DEBUG("Restored PS.WOE (0x%08" PRIx32 ")", woe); + } } -static bool xtensa_reg_is_readable(enum xtensa_reg_flags flags, xtensa_reg_val_t cpenable) +static bool xtensa_reg_is_readable(int flags, int cpenable) { if (flags & XT_REGF_NOREAD) return false; @@ -535,69 +571,17 @@ static bool xtensa_reg_is_readable(enum xtensa_reg_flags flags, xtensa_reg_val_t return true; } -static int xtensa_queue_pwr_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data) +static bool xtensa_scratch_regs_fixup(struct xtensa *xtensa, struct reg *reg_list, int i, int j, int a_idx, int ar_idx) { - struct xtensa_debug_module *dm = &xtensa->dbg_mod; - return dm->pwr_ops->queue_reg_write(dm, reg, data); -} - -static bool xtensa_special_reg_exists(struct xtensa *xtensa, enum xtensa_reg_id reg_idx) -{ - /* TODO: array of size XT_NUM_REGS can be used here to map special register ID to - * corresponding config option 'enabled' flag */ - if (reg_idx >= XT_REG_IDX_LBEG && reg_idx <= XT_REG_IDX_LCOUNT) - return xtensa->core_config->loop; - else if (reg_idx == XT_REG_IDX_BR) - return xtensa->core_config->boolean; - else if (reg_idx == XT_REG_IDX_LITBASE) - return xtensa->core_config->ext_l32r; - else if (reg_idx == XT_REG_IDX_SCOMPARE1 || reg_idx == XT_REG_IDX_ATOMCTL) - return xtensa->core_config->cond_store; - else if (reg_idx >= XT_REG_IDX_ACCLO && reg_idx <= XT_REG_IDX_M3) - return xtensa->core_config->mac16; - else if (reg_idx == XT_REG_IDX_WINDOWBASE || reg_idx == XT_REG_IDX_WINDOWSTART) - return xtensa->core_config->windowed; - else if (reg_idx >= XT_REG_IDX_PTEVADDR && reg_idx <= XT_REG_IDX_DTLBCFG) - return xtensa->core_config->mmu.enabled; - else if (reg_idx == XT_REG_IDX_MMID) - return xtensa->core_config->trace.enabled; - else if (reg_idx >= XT_REG_IDX_MEPC && reg_idx <= XT_REG_IDX_MEVADDR) - return xtensa->core_config->mem_err_check; - else if (reg_idx == XT_REG_IDX_CPENABLE) - return xtensa->core_config->coproc; - else if (reg_idx == XT_REG_IDX_VECBASE) - return xtensa->core_config->reloc_vec; - else if (reg_idx == XT_REG_IDX_CCOUNT) - return xtensa->core_config->tim_irq.enabled; - else if (reg_idx >= XT_REG_IDX_CCOMPARE0 && reg_idx <= XT_REG_IDX_CCOMPARE2) - return xtensa->core_config->tim_irq.enabled && - (reg_idx - XT_REG_IDX_CCOMPARE0 < xtensa->core_config->tim_irq.comp_num); - else if (reg_idx == XT_REG_IDX_PRID) - return xtensa->core_config->proc_id; - else if (reg_idx >= XT_REG_IDX_MISC0 && reg_idx <= XT_REG_IDX_MISC3) - return reg_idx - XT_REG_IDX_MISC0 < xtensa->core_config->miscregs_num; - return true; -} - -static bool xtensa_user_reg_exists(struct xtensa *xtensa, enum xtensa_reg_id reg_idx) -{ - if (reg_idx == XT_REG_IDX_THREADPTR) - return xtensa->core_config->threadptr; - if (reg_idx == XT_REG_IDX_FCR || reg_idx == XT_REG_IDX_FSR) - return xtensa->core_config->fp_coproc; - return false; -} - -static inline bool xtensa_fp_reg_exists(struct xtensa *xtensa, enum xtensa_reg_id reg_idx) -{ - return xtensa->core_config->fp_coproc; -} - -static inline bool xtensa_regular_reg_exists(struct xtensa *xtensa, enum xtensa_reg_id reg_idx) -{ - if (reg_idx >= XT_REG_IDX_AR0 && reg_idx <= XT_REG_IDX_AR63) - return reg_idx - XT_REG_IDX_AR0 < xtensa->core_config->aregs_num; - return true; + int a_name = (a_idx == XT_AR_SCRATCH_A3) ? 3 : 4; + if (xtensa->scratch_ars[a_idx].intval && !xtensa->scratch_ars[ar_idx].intval) { + LOG_DEBUG("AR conflict: a%d -> ar%d", a_name, j - XT_REG_IDX_AR0); + memcpy(reg_list[j].value, reg_list[i].value, sizeof(xtensa_reg_val_t)); + } else { + LOG_DEBUG("AR conflict: ar%d -> a%d", j - XT_REG_IDX_AR0, a_name); + memcpy(reg_list[i].value, reg_list[j].value, sizeof(xtensa_reg_val_t)); + } + return xtensa->scratch_ars[a_idx].intval && xtensa->scratch_ars[ar_idx].intval; } static int xtensa_write_dirty_registers(struct target *target) @@ -605,45 +589,50 @@ static int xtensa_write_dirty_registers(struct target *target) struct xtensa *xtensa = target_to_xtensa(target); int res; xtensa_reg_val_t regval, windowbase = 0; - bool scratch_reg_dirty = false; + bool scratch_reg_dirty = false, delay_cpenable = false; struct reg *reg_list = xtensa->core_cache->reg_list; + unsigned int reg_list_size = xtensa->core_cache->num_regs; + bool preserve_a3 = false; + uint8_t a3_buf[4]; + xtensa_reg_val_t a3 = 0, woe; LOG_TARGET_DEBUG(target, "start"); - /*We need to write the dirty registers in the cache list back to the processor. - *Start by writing the SFR/user registers. */ - for (unsigned int i = 0; i < XT_NUM_REGS; i++) { + /* We need to write the dirty registers in the cache list back to the processor. + * Start by writing the SFR/user registers. */ + for (unsigned int i = 0; i < reg_list_size; i++) { + struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs; + unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS; if (reg_list[i].dirty) { - if (xtensa_regs[i].type == XT_REG_SPECIAL || - xtensa_regs[i].type == XT_REG_USER || - xtensa_regs[i].type == XT_REG_FR) { + if (rlist[ridx].type == XT_REG_SPECIAL || + rlist[ridx].type == XT_REG_USER || + rlist[ridx].type == XT_REG_FR) { scratch_reg_dirty = true; + if (i == XT_REG_IDX_CPENABLE) { + delay_cpenable = true; + continue; + } regval = xtensa_reg_get(target, i); - LOG_TARGET_DEBUG(target, "Writing back reg %s val %08" PRIX32, - xtensa_regs[i].name, + LOG_TARGET_DEBUG(target, "Writing back reg %s (%d) val %08" PRIX32, + reg_list[i].name, + rlist[ridx].reg_num, regval); - xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, regval); - xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, XT_REG_A3)); - if (xtensa_regs[i].type == XT_REG_USER) { - if (reg_list[i].exist) - xtensa_queue_exec_ins(xtensa, - XT_INS_WUR(xtensa_regs[i].reg_num, - XT_REG_A3)); - } else if (xtensa_regs[i].type == XT_REG_FR) { - if (reg_list[i].exist) - xtensa_queue_exec_ins(xtensa, - XT_INS_WFR(xtensa_regs[i].reg_num, - XT_REG_A3)); - } else {/*SFR */ - if (reg_list[i].exist) { - unsigned int reg_num = xtensa_regs[i].reg_num; - if (reg_num == XT_PC_REG_NUM_BASE) - /* reg number of PC for debug interrupt - * depends on NDEBUGLEVEL */ - reg_num += xtensa->core_config->debug.irq_level; - - xtensa_queue_exec_ins(xtensa, - XT_INS_WSR(reg_num, XT_REG_A3)); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + if (reg_list[i].exist) { + unsigned int reg_num = rlist[ridx].reg_num; + if (rlist[ridx].type == XT_REG_USER) { + xtensa_queue_exec_ins(xtensa, XT_INS_WUR(xtensa, reg_num, XT_REG_A3)); + } else if (rlist[ridx].type == XT_REG_FR) { + xtensa_queue_exec_ins(xtensa, XT_INS_WFR(xtensa, reg_num, XT_REG_A3)); + } else {/*SFR */ + if (reg_num == XT_PC_REG_NUM_VIRTUAL) + /* reg number of PC for debug interrupt depends on NDEBUGLEVEL + **/ + reg_num = + (XT_PC_REG_NUM_BASE + + xtensa->core_config->debug.irq_level); + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, reg_num, XT_REG_A3)); } } reg_list[i].dirty = false; @@ -652,31 +641,66 @@ static int xtensa_write_dirty_registers(struct target *target) } if (scratch_reg_dirty) xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3); + if (delay_cpenable) { + regval = xtensa_reg_get(target, XT_REG_IDX_CPENABLE); + LOG_TARGET_DEBUG(target, "Writing back reg cpenable (224) val %08" PRIX32, regval); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, + xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, + XT_REG_A3)); + reg_list[XT_REG_IDX_CPENABLE].dirty = false; + } - if (xtensa->core_config->user_regs_num > 0 && - xtensa->core_config->queue_write_dirty_user_regs) - xtensa->core_config->queue_write_dirty_user_regs(target); + preserve_a3 = (xtensa->core_config->windowed); + if (preserve_a3) { + /* Save (windowed) A3 for scratch use */ + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, a3_buf); + res = xtensa_dm_queue_execute(&xtensa->dbg_mod); + if (res != ERROR_OK) + return res; + xtensa_core_status_check(target); + a3 = buf_get_u32(a3_buf, 0, 32); + } if (xtensa->core_config->windowed) { - /*Grab the windowbase, we need it. */ + res = xtensa_window_state_save(target, &woe); + if (res != ERROR_OK) + return res; + /* Grab the windowbase, we need it. */ windowbase = xtensa_reg_get(target, XT_REG_IDX_WINDOWBASE); - /*Check if there are problems with both the ARx as well as the corresponding Rx - * registers set and dirty. */ - /*Warn the user if this happens, not much else we can do... */ + /* Check if there are mismatches between the ARx and corresponding Ax registers. + * When the user sets a register on a windowed config, xt-gdb may set the ARx + * register directly. Thus we take ARx as priority over Ax if both are dirty + * and it's unclear if the user set one over the other explicitly. + */ for (unsigned int i = XT_REG_IDX_A0; i <= XT_REG_IDX_A15; i++) { - unsigned int j = xtensa_windowbase_offset_to_canonical(i, windowbase); + unsigned int j = xtensa_windowbase_offset_to_canonical(xtensa, i, windowbase); if (reg_list[i].dirty && reg_list[j].dirty) { - if (memcmp(reg_list[i].value, reg_list[j].value, - sizeof(xtensa_reg_val_t)) != 0) - LOG_WARNING( - "Warning: Both A%d as well as the physical register it points to (AR%d) are dirty and differs in value. Results are undefined!", - i - XT_REG_IDX_A0, - j - XT_REG_IDX_AR0); + if (memcmp(reg_list[i].value, reg_list[j].value, sizeof(xtensa_reg_val_t)) != 0) { + bool show_warning = true; + if (i == XT_REG_IDX_A3) + show_warning = xtensa_scratch_regs_fixup(xtensa, + reg_list, i, j, XT_AR_SCRATCH_A3, XT_AR_SCRATCH_AR3); + else if (i == XT_REG_IDX_A4) + show_warning = xtensa_scratch_regs_fixup(xtensa, + reg_list, i, j, XT_AR_SCRATCH_A4, XT_AR_SCRATCH_AR4); + if (show_warning) + LOG_WARNING( + "Warning: Both A%d [0x%08" PRIx32 + "] as well as its underlying physical register " + "(AR%d) [0x%08" PRIx32 "] are dirty and differ in value", + i - XT_REG_IDX_A0, + buf_get_u32(reg_list[i].value, 0, 32), + j - XT_REG_IDX_AR0, + buf_get_u32(reg_list[j].value, 0, 32)); + } } } } - /*Write A0-A16 */ + /* Write A0-A16. */ for (unsigned int i = 0; i < 16; i++) { if (reg_list[XT_REG_IDX_A0 + i].dirty) { regval = xtensa_reg_get(target, XT_REG_IDX_A0 + i); @@ -684,22 +708,26 @@ static int xtensa_write_dirty_registers(struct target *target) xtensa_regs[XT_REG_IDX_A0 + i].name, regval, xtensa_regs[XT_REG_IDX_A0 + i].reg_num); - xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, regval); - xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, i)); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, i)); reg_list[XT_REG_IDX_A0 + i].dirty = false; + if (i == 3) { + /* Avoid stomping A3 during restore at end of function */ + a3 = regval; + } } } if (xtensa->core_config->windowed) { - /*Now write AR0-AR63. */ - for (unsigned int j = 0; j < 64; j += 16) { - /*Write the 16 registers we can see */ + /* Now write AR registers */ + for (unsigned int j = 0; j < XT_REG_IDX_ARLAST; j += 16) { + /* Write the 16 registers we can see */ for (unsigned int i = 0; i < 16; i++) { if (i + j < xtensa->core_config->aregs_num) { enum xtensa_reg_id realadr = - xtensa_windowbase_offset_to_canonical(XT_REG_IDX_AR0 + i + j, + xtensa_windowbase_offset_to_canonical(xtensa, XT_REG_IDX_AR0 + i + j, windowbase); - /*Write back any dirty un-windowed registers */ + /* Write back any dirty un-windowed registers */ if (reg_list[realadr].dirty) { regval = xtensa_reg_get(target, realadr); LOG_TARGET_DEBUG( @@ -708,55 +736,38 @@ static int xtensa_write_dirty_registers(struct target *target) xtensa_regs[realadr].name, regval, xtensa_regs[realadr].reg_num); - xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, regval); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval); xtensa_queue_exec_ins(xtensa, - XT_INS_RSR(XT_SR_DDR, xtensa_regs[XT_REG_IDX_AR0 + i].reg_num)); + XT_INS_RSR(xtensa, XT_SR_DDR, + xtensa_regs[XT_REG_IDX_AR0 + i].reg_num)); reg_list[realadr].dirty = false; + if ((i + j) == 3) + /* Avoid stomping AR during A3 restore at end of function */ + a3 = regval; } } } /*Now rotate the window so we'll see the next 16 registers. The final rotate * will wraparound, */ /*leaving us in the state we were. */ - xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(4)); + xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(xtensa, 4)); } - } - res = jtag_execute_queue(); - xtensa_core_status_check(target); - return res; -} + xtensa_window_state_restore(target, woe); -int xtensa_queue_write_dirty_user_regs_u32(struct target *target) -{ - struct xtensa *xtensa = target_to_xtensa(target); - struct reg *reg_list = xtensa->core_cache->reg_list; - xtensa_reg_val_t reg_val; - bool scratch_reg_dirty = false; - - LOG_TARGET_DEBUG(target, "start"); + for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++) + xtensa->scratch_ars[s].intval = false; + } - /* We need to write the dirty registers in the cache list back to the processor. - * Start by writing the SFR/user registers. */ - for (unsigned int i = 0; i < xtensa->core_config->user_regs_num; i++) { - if (!reg_list[XT_USR_REG_START + i].dirty) - continue; - scratch_reg_dirty = true; - reg_val = xtensa_reg_get(target, XT_USR_REG_START + i); - LOG_TARGET_DEBUG(target, "Writing back reg %s val %08" PRIX32, - xtensa->core_config->user_regs[i].name, - reg_val); - xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, reg_val); - xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, XT_REG_A3)); - xtensa_queue_exec_ins(xtensa, - XT_INS_WUR(xtensa->core_config->user_regs[i].reg_num, - XT_REG_A3)); - reg_list[XT_USR_REG_START + i].dirty = false; + if (preserve_a3) { + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, a3); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); } - if (scratch_reg_dirty) - xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3); - return ERROR_OK; + res = xtensa_dm_queue_execute(&xtensa->dbg_mod); + xtensa_core_status_check(target); + + return res; } static inline bool xtensa_is_stopped(struct target *target) @@ -768,14 +779,20 @@ static inline bool xtensa_is_stopped(struct target *target) int xtensa_examine(struct target *target) { struct xtensa *xtensa = target_to_xtensa(target); - unsigned int cmd = PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP | PWRCTL_COREWAKEUP; + unsigned int cmd = PWRCTL_DEBUGWAKEUP(xtensa) | PWRCTL_MEMWAKEUP(xtensa) | PWRCTL_COREWAKEUP(xtensa); LOG_DEBUG("coreid = %d", target->coreid); - xtensa_queue_pwr_reg_write(xtensa, DMREG_PWRCTL, cmd); - xtensa_queue_pwr_reg_write(xtensa, DMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE); + + if (xtensa->core_config->core_type == XT_UNDEF) { + LOG_ERROR("XTensa core not configured; is xtensa-core-openocd.cfg missing?"); + return ERROR_FAIL; + } + + xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd); + xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE(xtensa)); xtensa_dm_queue_enable(&xtensa->dbg_mod); xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); - int res = jtag_execute_queue(); + int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); if (res != ERROR_OK) return res; if (!xtensa_dm_is_online(&xtensa->dbg_mod)) { @@ -792,15 +809,15 @@ int xtensa_examine(struct target *target) int xtensa_wakeup(struct target *target) { struct xtensa *xtensa = target_to_xtensa(target); - unsigned int cmd = PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP | PWRCTL_COREWAKEUP; + unsigned int cmd = PWRCTL_DEBUGWAKEUP(xtensa) | PWRCTL_MEMWAKEUP(xtensa) | PWRCTL_COREWAKEUP(xtensa); if (xtensa->reset_asserted) - cmd |= PWRCTL_CORERESET; - xtensa_queue_pwr_reg_write(xtensa, DMREG_PWRCTL, cmd); + cmd |= PWRCTL_CORERESET(xtensa); + xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd); /* TODO: can we join this with the write above? */ - xtensa_queue_pwr_reg_write(xtensa, DMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE); + xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE(xtensa)); xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); - return jtag_execute_queue(); + return xtensa_dm_queue_execute(&xtensa->dbg_mod); } int xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set) @@ -811,11 +828,11 @@ int xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set) OCDDCR_DEBUGMODEOUTEN | OCDDCR_ENABLEOCD); LOG_TARGET_DEBUG(xtensa->target, "write smpbreak set=0x%" PRIx32 " clear=0x%" PRIx32, set, clear); - xtensa_queue_dbg_reg_write(xtensa, NARADR_DCRSET, set | OCDDCR_ENABLEOCD); - xtensa_queue_dbg_reg_write(xtensa, NARADR_DCRCLR, clear); - xtensa_queue_dbg_reg_write(xtensa, NARADR_DSR, dsr_data); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRSET, set | OCDDCR_ENABLEOCD); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRCLR, clear); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DSR, dsr_data); xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); - return jtag_execute_queue(); + return xtensa_dm_queue_execute(&xtensa->dbg_mod); } int xtensa_smpbreak_set(struct target *target, uint32_t set) @@ -834,9 +851,9 @@ int xtensa_smpbreak_read(struct xtensa *xtensa, uint32_t *val) { uint8_t dcr_buf[sizeof(uint32_t)]; - xtensa_queue_dbg_reg_read(xtensa, NARADR_DCRSET, dcr_buf); + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DCRSET, dcr_buf); xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); - int res = jtag_execute_queue(); + int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); *val = buf_get_u32(dcr_buf, 0, 32); return res; @@ -892,7 +909,7 @@ int xtensa_core_status_check(struct target *target) OCDDSR_EXECEXCEPTION | OCDDSR_EXECOVERRUN); if (res != ERROR_OK && !xtensa->suppress_dsr_errors) LOG_TARGET_ERROR(target, "clearing DSR failed!"); - return xtensa->suppress_dsr_errors ? ERROR_OK : ERROR_FAIL; + return ERROR_FAIL; } return ERROR_OK; } @@ -901,7 +918,6 @@ xtensa_reg_val_t xtensa_reg_get(struct target *target, enum xtensa_reg_id reg_id { struct xtensa *xtensa = target_to_xtensa(target); struct reg *reg = &xtensa->core_cache->reg_list[reg_id]; - assert(reg_id < xtensa->core_cache->num_regs && "Attempt to access non-existing reg!"); return xtensa_reg_get_value(reg); } @@ -909,28 +925,54 @@ void xtensa_reg_set(struct target *target, enum xtensa_reg_id reg_id, xtensa_reg { struct xtensa *xtensa = target_to_xtensa(target); struct reg *reg = &xtensa->core_cache->reg_list[reg_id]; - assert(reg_id < xtensa->core_cache->num_regs && "Attempt to access non-existing reg!"); if (xtensa_reg_get_value(reg) == value) return; xtensa_reg_set_value(reg, value); } +/* Set Ax (XT_REG_RELGEN) register along with its underlying ARx (XT_REG_GENERAL) */ +void xtensa_reg_set_deep_relgen(struct target *target, enum xtensa_reg_id a_idx, xtensa_reg_val_t value) +{ + struct xtensa *xtensa = target_to_xtensa(target); + uint32_t windowbase = (xtensa->core_config->windowed ? + xtensa_reg_get(target, XT_REG_IDX_WINDOWBASE) : 0); + int ar_idx = xtensa_windowbase_offset_to_canonical(xtensa, a_idx, windowbase); + xtensa_reg_set(target, a_idx, value); + xtensa_reg_set(target, ar_idx, value); +} + +/* Read cause for entering halted state; return bitmask in DEBUGCAUSE_* format */ +uint32_t xtensa_cause_get(struct target *target) +{ + return xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE); +} + +void xtensa_cause_clear(struct target *target) +{ + struct xtensa *xtensa = target_to_xtensa(target); + xtensa_reg_set(target, XT_REG_IDX_DEBUGCAUSE, 0); + xtensa->core_cache->reg_list[XT_REG_IDX_DEBUGCAUSE].dirty = false; +} + int xtensa_assert_reset(struct target *target) { struct xtensa *xtensa = target_to_xtensa(target); LOG_TARGET_DEBUG(target, "target_number=%i, begin", target->target_number); - target->state = TARGET_RESET; xtensa_queue_pwr_reg_write(xtensa, - DMREG_PWRCTL, - PWRCTL_JTAGDEBUGUSE | PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP | PWRCTL_COREWAKEUP | - PWRCTL_CORERESET); + XDMREG_PWRCTL, + PWRCTL_JTAGDEBUGUSE(xtensa) | PWRCTL_DEBUGWAKEUP(xtensa) | PWRCTL_MEMWAKEUP(xtensa) | + PWRCTL_COREWAKEUP(xtensa) | PWRCTL_CORERESET(xtensa)); xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); - int res = jtag_execute_queue(); + int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); if (res != ERROR_OK) return res; + + /* registers are now invalid */ xtensa->reset_asserted = true; - return res; + register_cache_invalidate(xtensa->core_cache); + target->state = TARGET_RESET; + return ERROR_OK; } int xtensa_deassert_reset(struct target *target) @@ -940,13 +982,14 @@ int xtensa_deassert_reset(struct target *target) LOG_TARGET_DEBUG(target, "halt=%d", target->reset_halt); if (target->reset_halt) xtensa_queue_dbg_reg_write(xtensa, - NARADR_DCRSET, + XDMREG_DCRSET, OCDDCR_ENABLEOCD | OCDDCR_DEBUGINTERRUPT); xtensa_queue_pwr_reg_write(xtensa, - DMREG_PWRCTL, - PWRCTL_JTAGDEBUGUSE | PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP | PWRCTL_COREWAKEUP); + XDMREG_PWRCTL, + PWRCTL_JTAGDEBUGUSE(xtensa) | PWRCTL_DEBUGWAKEUP(xtensa) | PWRCTL_MEMWAKEUP(xtensa) | + PWRCTL_COREWAKEUP(xtensa)); xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); - int res = jtag_execute_queue(); + int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); if (res != ERROR_OK) return res; target->state = TARGET_RUNNING; @@ -954,17 +997,43 @@ int xtensa_deassert_reset(struct target *target) return res; } +int xtensa_soft_reset_halt(struct target *target) +{ + LOG_TARGET_DEBUG(target, "begin"); + return xtensa_assert_reset(target); +} + int xtensa_fetch_all_regs(struct target *target) { struct xtensa *xtensa = target_to_xtensa(target); struct reg *reg_list = xtensa->core_cache->reg_list; - xtensa_reg_val_t cpenable = 0, windowbase = 0; - uint8_t regvals[XT_NUM_REGS][sizeof(xtensa_reg_val_t)]; - uint8_t dsrs[XT_NUM_REGS][sizeof(xtensa_dsr_t)]; + unsigned int reg_list_size = xtensa->core_cache->num_regs; + xtensa_reg_val_t cpenable = 0, windowbase = 0, a3; + uint32_t woe; + uint8_t a3_buf[4]; bool debug_dsrs = !xtensa->regs_fetched || LOG_LEVEL_IS(LOG_LVL_DEBUG); + union xtensa_reg_val_u *regvals = calloc(reg_list_size, sizeof(*regvals)); + if (!regvals) { + LOG_TARGET_ERROR(target, "unable to allocate memory for regvals!"); + return ERROR_FAIL; + } + union xtensa_reg_val_u *dsrs = calloc(reg_list_size, sizeof(*dsrs)); + if (!dsrs) { + LOG_TARGET_ERROR(target, "unable to allocate memory for dsrs!"); + free(regvals); + return ERROR_FAIL; + } + LOG_TARGET_DEBUG(target, "start"); + /* Save (windowed) A3 so cache matches physical AR3; A3 usable as scratch */ + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, a3_buf); + int res = xtensa_window_state_save(target, &woe); + if (res != ERROR_OK) + goto xtensa_fetch_all_regs_done; + /* Assume the CPU has just halted. We now want to fill the register cache with all the * register contents GDB needs. For speed, we pipeline all the read operations, execute them * in one go, then sort everything out from the regvals variable. */ @@ -975,176 +1044,181 @@ int xtensa_fetch_all_regs(struct target *target) for (unsigned int i = 0; i < 16; i++) { if (i + j < xtensa->core_config->aregs_num) { xtensa_queue_exec_ins(xtensa, - XT_INS_WSR(XT_SR_DDR, xtensa_regs[XT_REG_IDX_AR0 + i].reg_num)); - xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, regvals[XT_REG_IDX_AR0 + i + j]); + XT_INS_WSR(xtensa, XT_SR_DDR, xtensa_regs[XT_REG_IDX_AR0 + i].reg_num)); + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, + regvals[XT_REG_IDX_AR0 + i + j].buf); if (debug_dsrs) - xtensa_queue_dbg_reg_read(xtensa, NARADR_DSR, dsrs[XT_REG_IDX_AR0 + i + j]); + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DSR, + dsrs[XT_REG_IDX_AR0 + i + j].buf); } } - if (xtensa->core_config->windowed) { + if (xtensa->core_config->windowed) /* Now rotate the window so we'll see the next 16 registers. The final rotate * will wraparound, */ /* leaving us in the state we were. */ - xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(4)); - } + xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(xtensa, 4)); } + xtensa_window_state_restore(target, woe); + if (xtensa->core_config->coproc) { - /* As the very first thing after AREGS, go grab the CPENABLE registers. It indicates - * if we can also grab the FP */ - /* (and theoretically other coprocessor) registers, or if this is a bad thing to do.*/ - xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3)); - xtensa_queue_exec_ins(xtensa, XT_INS_WSR(XT_SR_DDR, XT_REG_A3)); - xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, regvals[XT_REG_IDX_CPENABLE]); - } - int res = jtag_execute_queue(); + /* As the very first thing after AREGS, go grab CPENABLE */ + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3)); + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[XT_REG_IDX_CPENABLE].buf); + } + res = xtensa_dm_queue_execute(&xtensa->dbg_mod); if (res != ERROR_OK) { LOG_ERROR("Failed to read ARs (%d)!", res); - return res; + goto xtensa_fetch_all_regs_done; } xtensa_core_status_check(target); - if (xtensa->core_config->coproc) - cpenable = buf_get_u32(regvals[XT_REG_IDX_CPENABLE], 0, 32); + a3 = buf_get_u32(a3_buf, 0, 32); + + if (xtensa->core_config->coproc) { + cpenable = buf_get_u32(regvals[XT_REG_IDX_CPENABLE].buf, 0, 32); + + /* Enable all coprocessors (by setting all bits in CPENABLE) so we can read FP and user registers. */ + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, 0xffffffff); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3)); + + /* Save CPENABLE; flag dirty later (when regcache updated) so original value is always restored */ + LOG_TARGET_DEBUG(target, "CPENABLE: was 0x%" PRIx32 ", all enabled", cpenable); + xtensa_reg_set(target, XT_REG_IDX_CPENABLE, cpenable); + } /* We're now free to use any of A0-A15 as scratch registers * Grab the SFRs and user registers first. We use A3 as a scratch register. */ - for (unsigned int i = 0; i < XT_NUM_REGS; i++) { - if (xtensa_reg_is_readable(xtensa_regs[i].flags, cpenable) && reg_list[i].exist && - (xtensa_regs[i].type == XT_REG_SPECIAL || - xtensa_regs[i].type == XT_REG_USER || xtensa_regs[i].type == XT_REG_FR)) { - if (xtensa_regs[i].type == XT_REG_USER) { - xtensa_queue_exec_ins(xtensa, XT_INS_RUR(xtensa_regs[i].reg_num, XT_REG_A3)); - } else if (xtensa_regs[i].type == XT_REG_FR) { - xtensa_queue_exec_ins(xtensa, XT_INS_RFR(xtensa_regs[i].reg_num, XT_REG_A3)); - } else { /*SFR */ - unsigned int reg_num = xtensa_regs[i].reg_num; - if (reg_num == XT_PC_REG_NUM_BASE) { + for (unsigned int i = 0; i < reg_list_size; i++) { + struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs; + unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS; + if (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist) { + bool reg_fetched = true; + unsigned int reg_num = rlist[ridx].reg_num; + switch (rlist[ridx].type) { + case XT_REG_USER: + xtensa_queue_exec_ins(xtensa, XT_INS_RUR(xtensa, reg_num, XT_REG_A3)); + break; + case XT_REG_FR: + xtensa_queue_exec_ins(xtensa, XT_INS_RFR(xtensa, reg_num, XT_REG_A3)); + break; + case XT_REG_SPECIAL: + if (reg_num == XT_PC_REG_NUM_VIRTUAL) { /* reg number of PC for debug interrupt depends on NDEBUGLEVEL */ - reg_num += xtensa->core_config->debug.irq_level; + reg_num = (XT_PC_REG_NUM_BASE + xtensa->core_config->debug.irq_level); + } else if (reg_num == xtensa_regs[XT_REG_IDX_PS].reg_num) { + /* reg number of PS for debug interrupt depends on NDEBUGLEVEL */ + reg_num = (XT_PS_REG_NUM_BASE + xtensa->core_config->debug.irq_level); + } else if (reg_num == xtensa_regs[XT_REG_IDX_CPENABLE].reg_num) { + /* CPENABLE already read/updated; don't re-read */ + reg_fetched = false; + break; } - xtensa_queue_exec_ins(xtensa, XT_INS_RSR(reg_num, XT_REG_A3)); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, reg_num, XT_REG_A3)); + break; + default: + reg_fetched = false; + } + if (reg_fetched) { + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[i].buf); + if (debug_dsrs) + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DSR, dsrs[i].buf); } - xtensa_queue_exec_ins(xtensa, XT_INS_WSR(XT_SR_DDR, XT_REG_A3)); - xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, regvals[i]); - if (debug_dsrs) - xtensa_queue_dbg_reg_read(xtensa, NARADR_DSR, dsrs[i]); } } /* Ok, send the whole mess to the CPU. */ - res = jtag_execute_queue(); + res = xtensa_dm_queue_execute(&xtensa->dbg_mod); if (res != ERROR_OK) { LOG_ERROR("Failed to fetch AR regs!"); - return res; + goto xtensa_fetch_all_regs_done; } xtensa_core_status_check(target); if (debug_dsrs) { /* DSR checking: follows order in which registers are requested. */ - for (unsigned int i = 0; i < XT_NUM_REGS; i++) { - if (xtensa_reg_is_readable(xtensa_regs[i].flags, cpenable) && reg_list[i].exist && - (xtensa_regs[i].type == XT_REG_SPECIAL || xtensa_regs[i].type == XT_REG_USER || - xtensa_regs[i].type == XT_REG_FR)) { - if (buf_get_u32(dsrs[i], 0, 32) & OCDDSR_EXECEXCEPTION) { - LOG_ERROR("Exception reading %s!", xtensa_regs[i].name); - return ERROR_FAIL; + for (unsigned int i = 0; i < reg_list_size; i++) { + struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs; + unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS; + if (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist && + (rlist[ridx].type != XT_REG_DEBUG) && + (rlist[ridx].type != XT_REG_RELGEN) && + (rlist[ridx].type != XT_REG_TIE) && + (rlist[ridx].type != XT_REG_OTHER)) { + if (buf_get_u32(dsrs[i].buf, 0, 32) & OCDDSR_EXECEXCEPTION) { + LOG_ERROR("Exception reading %s!", reg_list[i].name); + res = ERROR_FAIL; + goto xtensa_fetch_all_regs_done; } } } } - if (xtensa->core_config->user_regs_num > 0 && xtensa->core_config->fetch_user_regs) { - res = xtensa->core_config->fetch_user_regs(target); - if (res != ERROR_OK) - return res; - } - - if (xtensa->core_config->windowed) { + if (xtensa->core_config->windowed) /* We need the windowbase to decode the general addresses. */ - windowbase = buf_get_u32(regvals[XT_REG_IDX_WINDOWBASE], 0, 32); - } + windowbase = buf_get_u32(regvals[XT_REG_IDX_WINDOWBASE].buf, 0, 32); /* Decode the result and update the cache. */ - for (unsigned int i = 0; i < XT_NUM_REGS; i++) { - if (xtensa_reg_is_readable(xtensa_regs[i].flags, cpenable) && reg_list[i].exist) { - if (xtensa_regs[i].type == XT_REG_GENERAL) { - /* TODO: add support for non-windowed configs */ - assert( - xtensa->core_config->windowed && - "Regs fetch is not supported for non-windowed configs!"); + for (unsigned int i = 0; i < reg_list_size; i++) { + struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs; + unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS; + if (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist) { + if ((xtensa->core_config->windowed) && (rlist[ridx].type == XT_REG_GENERAL)) { /* The 64-value general register set is read from (windowbase) on down. * We need to get the real register address by subtracting windowbase and * wrapping around. */ - int realadr = xtensa_canonical_to_windowbase_offset(i, windowbase); - buf_cpy(regvals[realadr], reg_list[i].value, reg_list[i].size); - } else if (xtensa_regs[i].type == XT_REG_RELGEN) { - buf_cpy(regvals[xtensa_regs[i].reg_num], reg_list[i].value, reg_list[i].size); + enum xtensa_reg_id realadr = xtensa_canonical_to_windowbase_offset(xtensa, i, + windowbase); + buf_cpy(regvals[realadr].buf, reg_list[i].value, reg_list[i].size); + } else if (rlist[ridx].type == XT_REG_RELGEN) { + buf_cpy(regvals[rlist[ridx].reg_num].buf, reg_list[i].value, reg_list[i].size); + if (xtensa_extra_debug_log) { + xtensa_reg_val_t regval = buf_get_u32(regvals[rlist[ridx].reg_num].buf, 0, 32); + LOG_DEBUG("%s = 0x%x", rlist[ridx].name, regval); + } } else { - buf_cpy(regvals[i], reg_list[i].value, reg_list[i].size); + xtensa_reg_val_t regval = buf_get_u32(regvals[i].buf, 0, 32); + bool is_dirty = (i == XT_REG_IDX_CPENABLE); + if (xtensa_extra_debug_log) + LOG_INFO("Register %s: 0x%X", reg_list[i].name, regval); + xtensa_reg_set(target, i, regval); + reg_list[i].dirty = is_dirty; /*always do this _after_ xtensa_reg_set! */ } reg_list[i].valid = true; } else { - reg_list[i].valid = false; - } - } - /* We have used A3 as a scratch register and we will need to write that back. */ - xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3); - xtensa->regs_fetched = true; - - return ERROR_OK; -} - -int xtensa_fetch_user_regs_u32(struct target *target) -{ - struct xtensa *xtensa = target_to_xtensa(target); - struct reg *reg_list = xtensa->core_cache->reg_list; - xtensa_reg_val_t cpenable = 0; - uint8_t regvals[XT_USER_REGS_NUM_MAX][sizeof(xtensa_reg_val_t)]; - uint8_t dsrs[XT_USER_REGS_NUM_MAX][sizeof(xtensa_dsr_t)]; - bool debug_dsrs = !xtensa->regs_fetched || LOG_LEVEL_IS(LOG_LVL_DEBUG); - - assert(xtensa->core_config->user_regs_num < XT_USER_REGS_NUM_MAX && "Too many user regs configured!"); - if (xtensa->core_config->coproc) - cpenable = xtensa_reg_get(target, XT_REG_IDX_CPENABLE); - - for (unsigned int i = 0; i < xtensa->core_config->user_regs_num; i++) { - if (!xtensa_reg_is_readable(xtensa->core_config->user_regs[i].flags, cpenable)) - continue; - xtensa_queue_exec_ins(xtensa, XT_INS_RUR(xtensa->core_config->user_regs[i].reg_num, XT_REG_A3)); - xtensa_queue_exec_ins(xtensa, XT_INS_WSR(XT_SR_DDR, XT_REG_A3)); - xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, regvals[i]); - if (debug_dsrs) - xtensa_queue_dbg_reg_read(xtensa, NARADR_DSR, dsrs[i]); - } - /* Ok, send the whole mess to the CPU. */ - int res = jtag_execute_queue(); - if (res != ERROR_OK) { - LOG_ERROR("Failed to fetch AR regs!"); - return res; - } - xtensa_core_status_check(target); - - if (debug_dsrs) { - /* DSR checking: follows order in which registers are requested. */ - for (unsigned int i = 0; i < xtensa->core_config->user_regs_num; i++) { - if (!xtensa_reg_is_readable(xtensa->core_config->user_regs[i].flags, cpenable)) - continue; - if (buf_get_u32(dsrs[i], 0, 32) & OCDDSR_EXECEXCEPTION) { - LOG_ERROR("Exception reading %s!", xtensa->core_config->user_regs[i].name); - return ERROR_FAIL; + if ((rlist[ridx].flags & XT_REGF_MASK) == XT_REGF_NOREAD) { + /* Report read-only registers all-zero but valid */ + reg_list[i].valid = true; + xtensa_reg_set(target, i, 0); + } else { + reg_list[i].valid = false; } } } - for (unsigned int i = 0; i < xtensa->core_config->user_regs_num; i++) { - if (xtensa_reg_is_readable(xtensa->core_config->user_regs[i].flags, cpenable)) { - buf_cpy(regvals[i], reg_list[XT_USR_REG_START + i].value, reg_list[XT_USR_REG_START + i].size); - reg_list[XT_USR_REG_START + i].valid = true; - } else { - reg_list[XT_USR_REG_START + i].valid = false; - } - } - - /* We have used A3 as a scratch register and we will need to write that back. */ + if (xtensa->core_config->windowed) { + /* We have used A3 as a scratch register. + * Windowed configs: restore A3's AR (XT_REG_GENERAL) and and flag for write-back. + */ + enum xtensa_reg_id ar3_idx = xtensa_windowbase_offset_to_canonical(xtensa, XT_REG_IDX_A3, windowbase); + xtensa_reg_set(target, ar3_idx, a3); + xtensa_mark_register_dirty(xtensa, ar3_idx); + + /* Reset scratch_ars[] on fetch. .chrval tracks AR mapping and changes w/ window */ + sprintf(xtensa->scratch_ars[XT_AR_SCRATCH_AR3].chrval, "ar%d", ar3_idx - XT_REG_IDX_AR0); + enum xtensa_reg_id ar4_idx = xtensa_windowbase_offset_to_canonical(xtensa, XT_REG_IDX_A4, windowbase); + sprintf(xtensa->scratch_ars[XT_AR_SCRATCH_AR4].chrval, "ar%d", ar4_idx - XT_REG_IDX_AR0); + for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++) + xtensa->scratch_ars[s].intval = false; + } + + /* We have used A3 (XT_REG_RELGEN) as a scratch register. Restore and flag for write-back. */ + xtensa_reg_set(target, XT_REG_IDX_A3, a3); xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3); - return ERROR_OK; + xtensa->regs_fetched = true; +xtensa_fetch_all_regs_done: + free(regvals); + free(dsrs); + return res; } int xtensa_get_gdb_reg_list(struct target *target, @@ -1153,23 +1227,65 @@ int xtensa_get_gdb_reg_list(struct target *target, enum target_register_class reg_class) { struct xtensa *xtensa = target_to_xtensa(target); - unsigned int num_regs = xtensa->core_config->gdb_general_regs_num; + unsigned int num_regs; - if (reg_class == REG_CLASS_ALL) - num_regs = xtensa->regs_num; + if (reg_class == REG_CLASS_GENERAL) { + if ((xtensa->genpkt_regs_num == 0) || !xtensa->contiguous_regs_list) { + LOG_ERROR("reg_class %d unhandled; 'xtgregs' not found", reg_class); + return ERROR_FAIL; + } + num_regs = xtensa->genpkt_regs_num; + } else { + /* Determine whether to return a contiguous or sparse register map */ + num_regs = xtensa->regmap_contiguous ? xtensa->total_regs_num : xtensa->dbregs_num; + } - LOG_DEBUG("reg_class=%i, num_regs=%d", reg_class, num_regs); + LOG_DEBUG("reg_class=%i, num_regs=%d", (int)reg_class, num_regs); - *reg_list = malloc(num_regs * sizeof(struct reg *)); + *reg_list = calloc(num_regs, sizeof(struct reg *)); if (!*reg_list) return ERROR_FAIL; - for (unsigned int k = 0; k < num_regs; k++) { - unsigned int reg_id = xtensa->core_config->gdb_regs_mapping[k]; - (*reg_list)[k] = &xtensa->core_cache->reg_list[reg_id]; + *reg_list_size = num_regs; + if (xtensa->regmap_contiguous) { + assert((num_regs <= xtensa->total_regs_num) && "contiguous regmap size internal error!"); + for (unsigned int i = 0; i < num_regs; i++) + (*reg_list)[i] = xtensa->contiguous_regs_list[i]; + return ERROR_OK; } - *reg_list_size = num_regs; + for (unsigned int i = 0; i < num_regs; i++) + (*reg_list)[i] = (struct reg *)&xtensa->empty_regs[i]; + unsigned int k = 0; + for (unsigned int i = 0; i < xtensa->core_cache->num_regs && k < num_regs; i++) { + if (xtensa->core_cache->reg_list[i].exist) { + struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs; + unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS; + int sparse_idx = rlist[ridx].dbreg_num; + if (i == XT_REG_IDX_PS) { + if (xtensa->eps_dbglevel_idx == 0) { + LOG_ERROR("eps_dbglevel_idx not set\n"); + return ERROR_FAIL; + } + (*reg_list)[sparse_idx] = &xtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx]; + if (xtensa_extra_debug_log) + LOG_DEBUG("SPARSE GDB reg 0x%x getting EPS%d 0x%x", + sparse_idx, xtensa->core_config->debug.irq_level, + xtensa_reg_get_value((*reg_list)[sparse_idx])); + } else if (rlist[ridx].type == XT_REG_RELGEN) { + (*reg_list)[sparse_idx - XT_REG_IDX_ARFIRST] = &xtensa->core_cache->reg_list[i]; + } else { + (*reg_list)[sparse_idx] = &xtensa->core_cache->reg_list[i]; + } + if (i == XT_REG_IDX_PC) + /* Make a duplicate copy of PC for external access */ + (*reg_list)[XT_PC_DBREG_NUM_BASE] = &xtensa->core_cache->reg_list[i]; + k++; + } + } + + if (k == num_regs) + LOG_ERROR("SPARSE GDB reg list full (size %d)", k); return ERROR_OK; } @@ -1199,9 +1315,9 @@ int xtensa_halt(struct target *target) } LOG_TARGET_DEBUG(target, "Core status 0x%" PRIx32, xtensa_dm_core_status_get(&xtensa->dbg_mod)); if (!xtensa_is_stopped(target)) { - xtensa_queue_dbg_reg_write(xtensa, NARADR_DCRSET, OCDDCR_ENABLEOCD | OCDDCR_DEBUGINTERRUPT); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRSET, OCDDCR_ENABLEOCD | OCDDCR_DEBUGINTERRUPT); xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); - res = jtag_execute_queue(); + res = xtensa_dm_queue_execute(&xtensa->dbg_mod); if (res != ERROR_OK) LOG_TARGET_ERROR(target, "Failed to set OCDDCR_DEBUGINTERRUPT. Can't halt."); } @@ -1233,21 +1349,21 @@ int xtensa_prepare_resume(struct target *target, if (address && !current) { xtensa_reg_set(target, XT_REG_IDX_PC, address); } else { - xtensa_reg_val_t cause = xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE); - if (cause & DEBUGCAUSE_DB) { + uint32_t cause = xtensa_cause_get(target); + LOG_TARGET_DEBUG(target, "DEBUGCAUSE 0x%x (watchpoint %lu) (break %lu)", + cause, (cause & DEBUGCAUSE_DB), (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))); + if (cause & DEBUGCAUSE_DB) /* We stopped due to a watchpoint. We can't just resume executing the * instruction again because */ /* that would trigger the watchpoint again. To fix this, we single-step, * which ignores watchpoints. */ xtensa_do_step(target, current, address, handle_breakpoints); - } - if (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)) { + if (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)) /* We stopped due to a break instruction. We can't just resume executing the * instruction again because */ /* that would trigger the break again. To fix this, we single-step, which * ignores break. */ xtensa_do_step(target, current, address, handle_breakpoints); - } } /* Write back hw breakpoints. Current FreeRTOS SMP code can set a hw breakpoint on an @@ -1274,8 +1390,8 @@ int xtensa_do_resume(struct target *target) LOG_TARGET_DEBUG(target, "start"); - xtensa_queue_exec_ins(xtensa, XT_INS_RFDO); - int res = jtag_execute_queue(); + xtensa_queue_exec_ins(xtensa, XT_INS_RFDO(xtensa)); + int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); if (res != ERROR_OK) { LOG_TARGET_ERROR(target, "Failed to exec RFDO %d!", res); return res; @@ -1315,18 +1431,19 @@ int xtensa_resume(struct target *target, static bool xtensa_pc_in_winexc(struct target *target, target_addr_t pc) { + struct xtensa *xtensa = target_to_xtensa(target); uint8_t insn_buf[XT_ISNS_SZ_MAX]; int err = xtensa_read_buffer(target, pc, sizeof(insn_buf), insn_buf); if (err != ERROR_OK) return false; xtensa_insn_t insn = buf_get_u32(insn_buf, 0, 24); - xtensa_insn_t masked = insn & XT_INS_L32E_S32E_MASK; - if (masked == XT_INS_L32E(0, 0, 0) || masked == XT_INS_S32E(0, 0, 0)) + xtensa_insn_t masked = insn & XT_INS_L32E_S32E_MASK(xtensa); + if (masked == XT_INS_L32E(xtensa, 0, 0, 0) || masked == XT_INS_S32E(xtensa, 0, 0, 0)) return true; - masked = insn & XT_INS_RFWO_RFWU_MASK; - if (masked == XT_INS_RFWO || masked == XT_INS_RFWU) + masked = insn & XT_INS_RFWO_RFWU_MASK(xtensa); + if (masked == XT_INS_RFWO(xtensa) || masked == XT_INS_RFWU(xtensa)) return true; return false; @@ -1339,7 +1456,8 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in const uint32_t icount_val = -2; /* ICOUNT value to load for 1 step */ xtensa_reg_val_t dbreakc[XT_WATCHPOINTS_NUM_MAX]; xtensa_reg_val_t icountlvl, cause; - xtensa_reg_val_t oldps, newps, oldpc, cur_pc; + xtensa_reg_val_t oldps, oldpc, cur_pc; + bool ps_lowered = false; LOG_TARGET_DEBUG(target, "current=%d, address=" TARGET_ADDR_FMT ", handle_breakpoints=%i", current, address, handle_breakpoints); @@ -1349,16 +1467,16 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in return ERROR_TARGET_NOT_HALTED; } - if (xtensa->core_config->debug.icount_sz != 32) { - LOG_TARGET_WARNING(target, "stepping for ICOUNT less then 32 bits is not implemented!"); + if (xtensa->eps_dbglevel_idx == 0) { + LOG_ERROR("eps_dbglevel_idx not set\n"); return ERROR_FAIL; } - /* Save old ps/pc */ - oldps = xtensa_reg_get(target, XT_REG_IDX_PS); + /* Save old ps (EPS[dbglvl] on LX), pc */ + oldps = xtensa_reg_get(target, xtensa->eps_dbglevel_idx); oldpc = xtensa_reg_get(target, XT_REG_IDX_PC); - cause = xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE); + cause = xtensa_cause_get(target); LOG_TARGET_DEBUG(target, "oldps=%" PRIx32 ", oldpc=%" PRIx32 " dbg_cause=%" PRIx32 " exc_cause=%" PRIx32, oldps, oldpc, @@ -1367,8 +1485,7 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in if (handle_breakpoints && (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))) { /* handle hard-coded SW breakpoints (e.g. syscalls) */ LOG_TARGET_DEBUG(target, "Increment PC to pass break instruction..."); - xtensa_reg_set(target, XT_REG_IDX_DEBUGCAUSE, 0); /* so we don't recurse into the same routine */ - xtensa->core_cache->reg_list[XT_REG_IDX_DEBUGCAUSE].dirty = false; + xtensa_cause_clear(target); /* so we don't recurse into the same routine */ /* pretend that we have stepped */ if (cause & DEBUGCAUSE_BI) xtensa_reg_set(target, XT_REG_IDX_PC, oldpc + 3); /* PC = PC+3 */ @@ -1377,13 +1494,22 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in return ERROR_OK; } - /* Xtensa has an ICOUNTLEVEL register which sets the maximum interrupt level at which the - * instructions are to be counted while stepping. - * For example, if we need to step by 2 instructions, and an interrupt occurs inbetween, - * the processor will execute the interrupt, return, and halt after the 2nd instruction. - * However, sometimes we don't want the interrupt handlers to be executed at all, while - * stepping through the code. In this case (XT_STEPPING_ISR_OFF), PS.INTLEVEL can be raised - * to only allow Debug and NMI interrupts. + /* Xtensa LX has an ICOUNTLEVEL register which sets the maximum interrupt level + * at which the instructions are to be counted while stepping. + * + * For example, if we need to step by 2 instructions, and an interrupt occurs + * in between, the processor will trigger the interrupt and halt after the 2nd + * instruction within the interrupt vector and/or handler. + * + * However, sometimes we don't want the interrupt handlers to be executed at all + * while stepping through the code. In this case (XT_STEPPING_ISR_OFF), + * ICOUNTLEVEL can be lowered to the executing code's (level + 1) to prevent ISR + * code from being counted during stepping. Note that C exception handlers must + * run at level 0 and hence will be counted and stepped into, should one occur. + * + * TODO: Certain instructions should never be single-stepped and should instead + * be emulated (per DUG): RSIL >= DBGLEVEL, RSR/WSR [ICOUNT|ICOUNTLEVEL], and + * RFI >= DBGLEVEL. */ if (xtensa->stepping_isr_mode == XT_STEPPING_ISR_OFF) { if (!xtensa->core_config->high_irq.enabled) { @@ -1392,18 +1518,11 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in "disabling IRQs while stepping is not implemented w/o high prio IRQs option!"); return ERROR_FAIL; } - /* Mask all interrupts below Debug, i.e. PS.INTLEVEL = DEBUGLEVEL - 1 */ - xtensa_reg_val_t temp_ps = (oldps & ~0xF) | (xtensa->core_config->debug.irq_level - 1); - xtensa_reg_set(target, XT_REG_IDX_PS, temp_ps); + /* Update ICOUNTLEVEL accordingly */ + icountlvl = MIN((oldps & 0xF) + 1, xtensa->core_config->debug.irq_level); + } else { + icountlvl = xtensa->core_config->debug.irq_level; } - /* Regardless of ISRs masking mode we need to count instructions at any CINTLEVEL during step. - So set `icountlvl` to DEBUGLEVEL. - If ISRs are masked they are disabled in PS (see above), so having `icountlvl` set to DEBUGLEVEL - will allow to step through any type of the code, e.g. 'high int level' ISR. - If ISRs are not masked With `icountlvl` set to DEBUGLEVEL, we can step into any ISR - which can happen (enabled in PS). - */ - icountlvl = xtensa->core_config->debug.irq_level; if (cause & DEBUGCAUSE_DB) { /* We stopped due to a watchpoint. We can't just resume executing the instruction again because @@ -1412,21 +1531,27 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in LOG_TARGET_DEBUG( target, "Single-stepping to get past instruction that triggered the watchpoint..."); - xtensa_reg_set(target, XT_REG_IDX_DEBUGCAUSE, 0); /*so we don't recurse into - * the same routine */ - xtensa->core_cache->reg_list[XT_REG_IDX_DEBUGCAUSE].dirty = false; - /*Save all DBREAKCx registers and set to 0 to disable watchpoints */ + xtensa_cause_clear(target); /* so we don't recurse into the same routine */ + /* Save all DBREAKCx registers and set to 0 to disable watchpoints */ for (unsigned int slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++) { dbreakc[slot] = xtensa_reg_get(target, XT_REG_IDX_DBREAKC0 + slot); xtensa_reg_set(target, XT_REG_IDX_DBREAKC0 + slot, 0); } } - if (!handle_breakpoints && (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))) { + if (!handle_breakpoints && (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))) /* handle normal SW breakpoint */ - xtensa_reg_set(target, XT_REG_IDX_DEBUGCAUSE, 0); /*so we don't recurse into - * the same routine */ - xtensa->core_cache->reg_list[XT_REG_IDX_DEBUGCAUSE].dirty = false; + xtensa_cause_clear(target); /* so we don't recurse into the same routine */ + if ((oldps & 0xf) >= icountlvl) { + /* Lower interrupt level to allow stepping, but flag eps[dbglvl] to be restored */ + ps_lowered = true; + uint32_t newps = (oldps & ~0xf) | (icountlvl - 1); + xtensa_reg_set(target, xtensa->eps_dbglevel_idx, newps); + LOG_TARGET_DEBUG(target, + "Lowering PS.INTLEVEL to allow stepping: %s <- 0x%08" PRIx32 " (was 0x%08" PRIx32 ")", + xtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx].name, + newps, + oldps); } do { xtensa_reg_set(target, XT_REG_IDX_ICOUNTLEVEL, icountlvl); @@ -1470,18 +1595,15 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in target->state = TARGET_RUNNING; return ERROR_FAIL; } - target->debug_reason = DBG_REASON_SINGLESTEP; - target->state = TARGET_HALTED; xtensa_fetch_all_regs(target); - cur_pc = xtensa_reg_get(target, XT_REG_IDX_PC); LOG_TARGET_DEBUG(target, "cur_ps=%" PRIx32 ", cur_pc=%" PRIx32 " dbg_cause=%" PRIx32 " exc_cause=%" PRIx32, xtensa_reg_get(target, XT_REG_IDX_PS), cur_pc, - xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE), + xtensa_cause_get(target), xtensa_reg_get(target, XT_REG_IDX_EXCCAUSE)); /* Do not step into WindowOverflow if ISRs are masked. @@ -1504,6 +1626,10 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in LOG_DEBUG("Stepped from %" PRIX32 " to %" PRIX32, oldpc, cur_pc); break; } while (true); + + target->debug_reason = DBG_REASON_SINGLESTEP; + target->state = TARGET_HALTED; + target_call_event_callbacks(target, TARGET_EVENT_HALTED); LOG_DEBUG("Done stepping, PC=%" PRIX32, cur_pc); if (cause & DEBUGCAUSE_DB) { @@ -1514,12 +1640,11 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in } /* Restore int level */ - /* TODO: Theoretically, this can mess up stepping over an instruction that modifies - * ps.intlevel by itself. TODO: Look into this. */ - if (xtensa->stepping_isr_mode == XT_STEPPING_ISR_OFF) { - newps = xtensa_reg_get(target, XT_REG_IDX_PS); - newps = (newps & ~0xF) | (oldps & 0xf); - xtensa_reg_set(target, XT_REG_IDX_PS, newps); + if (ps_lowered) { + LOG_DEBUG("Restoring %s after stepping: 0x%08" PRIx32, + xtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx].name, + oldps); + xtensa_reg_set(target, xtensa->eps_dbglevel_idx, oldps); } /* write ICOUNTLEVEL back to zero */ @@ -1567,7 +1692,7 @@ static inline target_addr_t xtensa_get_overlap_size(target_addr_t r1_start, } /** - * Check if the address gets to memory regions, and it's access mode + * Check if the address gets to memory regions, and its access mode */ static bool xtensa_memory_op_validate_range(struct xtensa *xtensa, target_addr_t address, size_t size, int access) { @@ -1598,6 +1723,7 @@ int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t si target_addr_t addrend_al = ALIGN_UP(address + size * count, 4); target_addr_t adr = addrstart_al; uint8_t *albuff; + bool bswap = xtensa->target->endianness == TARGET_BIG_ENDIAN; if (target->state != TARGET_HALTED) { LOG_TARGET_WARNING(target, "target not halted"); @@ -1612,39 +1738,62 @@ int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t si } } - if (addrstart_al == address && addrend_al == address + (size * count)) { - albuff = buffer; - } else { - albuff = malloc(addrend_al - addrstart_al); - if (!albuff) { - LOG_TARGET_ERROR(target, "Out of memory allocating %" TARGET_PRIdADDR " bytes!", - addrend_al - addrstart_al); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } + unsigned int alloc_bytes = ALIGN_UP(addrend_al - addrstart_al, sizeof(uint32_t)); + albuff = calloc(alloc_bytes, 1); + if (!albuff) { + LOG_TARGET_ERROR(target, "Out of memory allocating %" PRId64 " bytes!", + addrend_al - addrstart_al); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } /* We're going to use A3 here */ xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3); /* Write start address to A3 */ - xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, addrstart_al); - xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, XT_REG_A3)); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); /* Now we can safely read data from addrstart_al up to addrend_al into albuff */ - for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) { - xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(XT_REG_A3)); - xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, &albuff[i]); + if (xtensa->probe_lsddr32p != 0) { + xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3)); + for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) + xtensa_queue_dbg_reg_read(xtensa, + (adr + sizeof(uint32_t) == addrend_al) ? XDMREG_DDR : XDMREG_DDREXEC, + &albuff[i]); + } else { + xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A4); + for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) { + xtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A4, 0)); + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A4)); + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, &albuff[i]); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr + sizeof(uint32_t)); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + } } - int res = jtag_execute_queue(); - if (res == ERROR_OK) + int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); + if (res == ERROR_OK) { + bool prev_suppress = xtensa->suppress_dsr_errors; + xtensa->suppress_dsr_errors = true; res = xtensa_core_status_check(target); - if (res != ERROR_OK) - LOG_TARGET_WARNING(target, "Failed reading %d bytes at address " TARGET_ADDR_FMT, - count * size, address); - - if (albuff != buffer) { - memcpy(buffer, albuff + (address & 3), (size * count)); - free(albuff); + if (xtensa->probe_lsddr32p == -1) + xtensa->probe_lsddr32p = 1; + xtensa->suppress_dsr_errors = prev_suppress; + } + if (res != ERROR_OK) { + if (xtensa->probe_lsddr32p != 0) { + /* Disable fast memory access instructions and retry before reporting an error */ + LOG_TARGET_INFO(target, "Disabling LDDR32.P/SDDR32.P"); + xtensa->probe_lsddr32p = 0; + res = xtensa_read_memory(target, address, size, count, buffer); + bswap = false; + } else { + LOG_TARGET_WARNING(target, "Failed reading %d bytes at address "TARGET_ADDR_FMT, + count * size, address); + } } + if (bswap) + buf_bswap32(albuff, albuff, addrend_al - addrstart_al); + memcpy(buffer, albuff + (address & 3), (size * count)); + free(albuff); return res; } @@ -1670,6 +1819,7 @@ int xtensa_write_memory(struct target *target, target_addr_t adr = addrstart_al; int res; uint8_t *albuff; + bool fill_head_tail = false; if (target->state != TARGET_HALTED) { LOG_TARGET_WARNING(target, "target not halted"); @@ -1688,38 +1838,53 @@ int xtensa_write_memory(struct target *target, /* Allocate a temporary buffer to put the aligned bytes in, if needed. */ if (addrstart_al == address && addrend_al == address + (size * count)) { - /* We discard the const here because albuff can also be non-const */ - albuff = (uint8_t *)buffer; + if (xtensa->target->endianness == TARGET_BIG_ENDIAN) + /* Need a buffer for byte-swapping */ + albuff = malloc(addrend_al - addrstart_al); + else + /* We discard the const here because albuff can also be non-const */ + albuff = (uint8_t *)buffer; } else { + fill_head_tail = true; albuff = malloc(addrend_al - addrstart_al); - if (!albuff) { - LOG_TARGET_ERROR(target, "Out of memory allocating %" TARGET_PRIdADDR " bytes!", - addrend_al - addrstart_al); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } + } + if (!albuff) { + LOG_TARGET_ERROR(target, "Out of memory allocating %" PRId64 " bytes!", + addrend_al - addrstart_al); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } /* We're going to use A3 here */ xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3); /* If we're using a temp aligned buffer, we need to fill the head and/or tail bit of it. */ - if (albuff != buffer) { + if (fill_head_tail) { /* See if we need to read the first and/or last word. */ if (address & 3) { - xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, addrstart_al); - xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, XT_REG_A3)); - xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(XT_REG_A3)); - xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, &albuff[0]); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + if (xtensa->probe_lsddr32p == 1) { + xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3)); + } else { + xtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A3, 0)); + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3)); + } + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, &albuff[0]); } if ((address + (size * count)) & 3) { - xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, addrend_al - 4); - xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, XT_REG_A3)); - xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(XT_REG_A3)); - xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrend_al - 4); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + if (xtensa->probe_lsddr32p == 1) { + xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3)); + } else { + xtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A3, 0)); + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3)); + } + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, &albuff[addrend_al - addrstart_al - 4]); } /* Grab bytes */ - res = jtag_execute_queue(); + res = xtensa_dm_queue_execute(&xtensa->dbg_mod); if (res != ERROR_OK) { LOG_ERROR("Error issuing unaligned memory write context instruction(s): %d", res); if (albuff != buffer) @@ -1727,24 +1892,110 @@ int xtensa_write_memory(struct target *target, return res; } xtensa_core_status_check(target); - /* Copy data to be written into the aligned buffer */ + if (xtensa->target->endianness == TARGET_BIG_ENDIAN) { + bool swapped_w0 = false; + if (address & 3) { + buf_bswap32(&albuff[0], &albuff[0], 4); + swapped_w0 = true; + } + if ((address + (size * count)) & 3) { + if ((addrend_al - addrstart_al - 4 == 0) && swapped_w0) { + /* Don't double-swap if buffer start/end are within the same word */ + } else { + buf_bswap32(&albuff[addrend_al - addrstart_al - 4], + &albuff[addrend_al - addrstart_al - 4], 4); + } + } + } + /* Copy data to be written into the aligned buffer (in host-endianness) */ memcpy(&albuff[address & 3], buffer, size * count); /* Now we can write albuff in aligned uint32s. */ } + if (xtensa->target->endianness == TARGET_BIG_ENDIAN) + buf_bswap32(albuff, fill_head_tail ? albuff : buffer, addrend_al - addrstart_al); + /* Write start address to A3 */ - xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, addrstart_al); - xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, XT_REG_A3)); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); /* Write the aligned buffer */ - for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) { - xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, buf_get_u32(&albuff[i], 0, 32)); - xtensa_queue_exec_ins(xtensa, XT_INS_SDDR32P(XT_REG_A3)); + if (xtensa->probe_lsddr32p != 0) { + for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) { + if (i == 0) { + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, buf_get_u32(&albuff[i], 0, 32)); + xtensa_queue_exec_ins(xtensa, XT_INS_SDDR32P(xtensa, XT_REG_A3)); + } else { + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDREXEC, buf_get_u32(&albuff[i], 0, 32)); + } + } + } else { + xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A4); + for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) { + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, buf_get_u32(&albuff[i], 0, 32)); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4)); + xtensa_queue_exec_ins(xtensa, XT_INS_S32I(xtensa, XT_REG_A3, XT_REG_A4, 0)); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr + sizeof(uint32_t)); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + } } - res = jtag_execute_queue(); - if (res == ERROR_OK) + + res = xtensa_dm_queue_execute(&xtensa->dbg_mod); + if (res == ERROR_OK) { + bool prev_suppress = xtensa->suppress_dsr_errors; + xtensa->suppress_dsr_errors = true; res = xtensa_core_status_check(target); - if (res != ERROR_OK) - LOG_TARGET_WARNING(target, "Failed writing %d bytes at address " TARGET_ADDR_FMT, count * size, address); + if (xtensa->probe_lsddr32p == -1) + xtensa->probe_lsddr32p = 1; + xtensa->suppress_dsr_errors = prev_suppress; + } + if (res != ERROR_OK) { + if (xtensa->probe_lsddr32p != 0) { + /* Disable fast memory access instructions and retry before reporting an error */ + LOG_TARGET_INFO(target, "Disabling LDDR32.P/SDDR32.P"); + xtensa->probe_lsddr32p = 0; + res = xtensa_write_memory(target, address, size, count, buffer); + } else { + LOG_TARGET_WARNING(target, "Failed writing %d bytes at address "TARGET_ADDR_FMT, + count * size, address); + } + } else { + /* Invalidate ICACHE, writeback DCACHE if present */ + uint32_t issue_ihi = xtensa_is_icacheable(xtensa, address); + uint32_t issue_dhwb = xtensa_is_dcacheable(xtensa, address); + if (issue_ihi || issue_dhwb) { + uint32_t ilinesize = issue_ihi ? xtensa->core_config->icache.line_size : UINT32_MAX; + uint32_t dlinesize = issue_dhwb ? xtensa->core_config->dcache.line_size : UINT32_MAX; + uint32_t linesize = MIN(ilinesize, dlinesize); + uint32_t off = 0; + adr = addrstart_al; + + while ((adr + off) < addrend_al) { + if (off == 0) { + /* Write start address to A3 */ + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + } + if (issue_ihi) + xtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, off)); + if (issue_dhwb) + xtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, off)); + off += linesize; + if (off > 1020) { + /* IHI, DHWB have 8-bit immediate operands (0..1020) */ + adr += off; + off = 0; + } + } + + /* Execute cache WB/INV instructions */ + res = xtensa_dm_queue_execute(&xtensa->dbg_mod); + xtensa_core_status_check(target); + if (res != ERROR_OK) + LOG_TARGET_ERROR(target, + "Error issuing cache writeback/invaldate instruction(s): %d", + res); + } + } if (albuff != buffer) free(albuff); @@ -1766,8 +2017,18 @@ int xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_ int xtensa_poll(struct target *target) { struct xtensa *xtensa = target_to_xtensa(target); + if (xtensa_dm_poll(&xtensa->dbg_mod) != ERROR_OK) { + target->state = TARGET_UNKNOWN; + return ERROR_TARGET_NOT_EXAMINED; + } - int res = xtensa_dm_power_status_read(&xtensa->dbg_mod, PWRSTAT_DEBUGWASRESET | PWRSTAT_COREWASRESET); + int res = xtensa_dm_power_status_read(&xtensa->dbg_mod, PWRSTAT_DEBUGWASRESET(xtensa) | + PWRSTAT_COREWASRESET(xtensa)); + if (xtensa->dbg_mod.power_status.stat != xtensa->dbg_mod.power_status.stath) + LOG_TARGET_DEBUG(target, "PWRSTAT: read 0x%08" PRIx32 ", clear 0x%08lx, reread 0x%08" PRIx32, + xtensa->dbg_mod.power_status.stat, + PWRSTAT_DEBUGWASRESET(xtensa) | PWRSTAT_COREWASRESET(xtensa), + xtensa->dbg_mod.power_status.stath); if (res != ERROR_OK) return res; @@ -1785,10 +2046,16 @@ int xtensa_poll(struct target *target) if (res != ERROR_OK) return res; + uint32_t prev_dsr = xtensa->dbg_mod.core_status.dsr; res = xtensa_dm_core_status_read(&xtensa->dbg_mod); if (res != ERROR_OK) return res; - if (xtensa->dbg_mod.power_status.stath & PWRSTAT_COREWASRESET) { + if (prev_dsr != xtensa->dbg_mod.core_status.dsr) + LOG_TARGET_DEBUG(target, + "DSR has changed: was 0x%08" PRIx32 " now 0x%08" PRIx32, + prev_dsr, + xtensa->dbg_mod.core_status.dsr); + if (xtensa->dbg_mod.power_status.stath & PWRSTAT_COREWASRESET(xtensa)) { /* if RESET state is persitent */ target->state = TARGET_RESET; } else if (!xtensa_dm_is_powered(&xtensa->dbg_mod)) { @@ -1811,7 +2078,7 @@ int xtensa_poll(struct target *target) * priorities: watchpoint == breakpoint > single step > debug interrupt. */ /* Watchpoint and breakpoint events at the same time results in special * debug reason: DBG_REASON_WPTANDBKPT. */ - xtensa_reg_val_t halt_cause = xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE); + uint32_t halt_cause = xtensa_cause_get(target); /* TODO: Add handling of DBG_REASON_EXC_CATCH */ if (halt_cause & DEBUGCAUSE_IC) target->debug_reason = DBG_REASON_SINGLESTEP; @@ -1823,7 +2090,8 @@ int xtensa_poll(struct target *target) } else if (halt_cause & DEBUGCAUSE_DB) { target->debug_reason = DBG_REASON_WATCHPOINT; } - LOG_TARGET_DEBUG(target, "Target halted, pc=0x%08" PRIX32 ", debug_reason=%08x, oldstate=%08x", + LOG_TARGET_DEBUG(target, "Target halted, pc=0x%08" PRIx32 + ", debug_reason=%08" PRIx32 ", oldstate=%08" PRIx32, xtensa_reg_get(target, XT_REG_IDX_PC), target->debug_reason, oldstate); @@ -1831,8 +2099,6 @@ int xtensa_poll(struct target *target) halt_cause, xtensa_reg_get(target, XT_REG_IDX_EXCCAUSE), xtensa->dbg_mod.core_status.dsr); - LOG_TARGET_INFO(target, "Target halted, PC=0x%08" PRIX32 ", debug_reason=%08x", - xtensa_reg_get(target, XT_REG_IDX_PC), target->debug_reason); xtensa_dm_core_status_clear( &xtensa->dbg_mod, OCDDSR_DEBUGPENDBREAK | OCDDSR_DEBUGINTBREAK | OCDDSR_DEBUGPENDTRAX | @@ -1866,25 +2132,101 @@ int xtensa_poll(struct target *target) return ERROR_OK; } +static int xtensa_update_instruction(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer) +{ + struct xtensa *xtensa = target_to_xtensa(target); + unsigned int issue_ihi = xtensa_is_icacheable(xtensa, address); + unsigned int issue_dhwbi = xtensa_is_dcacheable(xtensa, address); + uint32_t icache_line_size = issue_ihi ? xtensa->core_config->icache.line_size : UINT32_MAX; + uint32_t dcache_line_size = issue_dhwbi ? xtensa->core_config->dcache.line_size : UINT32_MAX; + unsigned int same_ic_line = ((address & (icache_line_size - 1)) + size) <= icache_line_size; + unsigned int same_dc_line = ((address & (dcache_line_size - 1)) + size) <= dcache_line_size; + int ret; + + if (size > icache_line_size) + return ERROR_FAIL; + + if (issue_ihi || issue_dhwbi) { + /* We're going to use A3 here */ + xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3); + + /* Write start address to A3 and invalidate */ + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, address); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + LOG_TARGET_DEBUG(target, "DHWBI, IHI for address "TARGET_ADDR_FMT, address); + if (issue_dhwbi) { + xtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, 0)); + if (!same_dc_line) { + LOG_TARGET_DEBUG(target, + "DHWBI second dcache line for address "TARGET_ADDR_FMT, + address + 4); + xtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, 4)); + } + } + if (issue_ihi) { + xtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, 0)); + if (!same_ic_line) { + LOG_TARGET_DEBUG(target, + "IHI second icache line for address "TARGET_ADDR_FMT, + address + 4); + xtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, 4)); + } + } + + /* Execute invalidate instructions */ + ret = xtensa_dm_queue_execute(&xtensa->dbg_mod); + xtensa_core_status_check(target); + if (ret != ERROR_OK) { + LOG_ERROR("Error issuing cache invaldate instruction(s): %d", ret); + return ret; + } + } + + /* Write new instructions to memory */ + ret = target_write_buffer(target, address, size, buffer); + if (ret != ERROR_OK) { + LOG_TARGET_ERROR(target, "Error writing instruction to memory: %d", ret); + return ret; + } + + if (issue_dhwbi) { + /* Flush dcache so instruction propagates. A3 may be corrupted during memory write */ + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, address); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_exec_ins(xtensa, XT_INS_DHWB(xtensa, XT_REG_A3, 0)); + LOG_DEBUG("DHWB dcache line for address "TARGET_ADDR_FMT, address); + if (!same_dc_line) { + LOG_TARGET_DEBUG(target, "DHWB second dcache line for address "TARGET_ADDR_FMT, address + 4); + xtensa_queue_exec_ins(xtensa, XT_INS_DHWB(xtensa, XT_REG_A3, 4)); + } + + /* Execute invalidate instructions */ + ret = xtensa_dm_queue_execute(&xtensa->dbg_mod); + xtensa_core_status_check(target); + } + + /* TODO: Handle L2 cache if present */ + return ret; +} + static int xtensa_sw_breakpoint_add(struct target *target, struct breakpoint *breakpoint, struct xtensa_sw_breakpoint *sw_bp) { + struct xtensa *xtensa = target_to_xtensa(target); int ret = target_read_buffer(target, breakpoint->address, XT_ISNS_SZ_MAX, sw_bp->insn); if (ret != ERROR_OK) { LOG_TARGET_ERROR(target, "Failed to read original instruction (%d)!", ret); return ret; } - sw_bp->insn_sz = xtensa_insn_size_get(buf_get_u32(sw_bp->insn, 0, 24)); + sw_bp->insn_sz = MIN(XT_ISNS_SZ_MAX, breakpoint->length); sw_bp->oocd_bp = breakpoint; - uint32_t break_insn = sw_bp->insn_sz == XT_ISNS_SZ_MAX ? XT_INS_BREAK(0, 0) : XT_INS_BREAKN(0); - /* convert to target endianness */ - uint8_t break_insn_buff[4]; - target_buffer_set_u32(target, break_insn_buff, break_insn); + uint32_t break_insn = sw_bp->insn_sz == XT_ISNS_SZ_MAX ? XT_INS_BREAK(xtensa, 0, 0) : XT_INS_BREAKN(xtensa, 0); - ret = target_write_buffer(target, breakpoint->address, sw_bp->insn_sz, break_insn_buff); + /* Underlying memory write will convert instruction endianness, don't do that here */ + ret = xtensa_update_instruction(target, breakpoint->address, sw_bp->insn_sz, (uint8_t *)&break_insn); if (ret != ERROR_OK) { LOG_TARGET_ERROR(target, "Failed to write breakpoint instruction (%d)!", ret); return ret; @@ -1895,9 +2237,9 @@ static int xtensa_sw_breakpoint_add(struct target *target, static int xtensa_sw_breakpoint_remove(struct target *target, struct xtensa_sw_breakpoint *sw_bp) { - int ret = target_write_buffer(target, sw_bp->oocd_bp->address, sw_bp->insn_sz, sw_bp->insn); + int ret = xtensa_update_instruction(target, sw_bp->oocd_bp->address, sw_bp->insn_sz, sw_bp->insn); if (ret != ERROR_OK) { - LOG_TARGET_ERROR(target, "Failed to read insn (%d)!", ret); + LOG_TARGET_ERROR(target, "Failed to write insn (%d)!", ret); return ret; } sw_bp->oocd_bp = NULL; @@ -1941,7 +2283,8 @@ int xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint) xtensa->hw_brps[slot] = breakpoint; /* We will actually write the breakpoints when we resume the target. */ - LOG_TARGET_DEBUG(target, "placed HW breakpoint @ " TARGET_ADDR_FMT, + LOG_TARGET_DEBUG(target, "placed HW breakpoint %u @ " TARGET_ADDR_FMT, + slot, breakpoint->address); return ERROR_OK; @@ -2063,6 +2406,12 @@ static int xtensa_build_reg_cache(struct target *target) { struct xtensa *xtensa = target_to_xtensa(target); struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); + unsigned int last_dbreg_num = 0; + + if (xtensa->core_regs_num + xtensa->num_optregs != xtensa->total_regs_num) + LOG_TARGET_WARNING(target, "Register count MISMATCH: %d core regs, %d extended regs; %d expected", + xtensa->core_regs_num, xtensa->num_optregs, xtensa->total_regs_num); + struct reg_cache *reg_cache = calloc(1, sizeof(struct reg_cache)); if (!reg_cache) { @@ -2071,86 +2420,101 @@ static int xtensa_build_reg_cache(struct target *target) } reg_cache->name = "Xtensa registers"; reg_cache->next = NULL; - reg_cache->num_regs = XT_NUM_REGS + xtensa->core_config->user_regs_num; /* Init reglist */ - struct reg *reg_list = calloc(reg_cache->num_regs, sizeof(struct reg)); + unsigned int reg_list_size = XT_NUM_REGS + xtensa->num_optregs; + struct reg *reg_list = calloc(reg_list_size, sizeof(struct reg)); if (!reg_list) { LOG_ERROR("Failed to alloc reg list!"); goto fail; } - xtensa->regs_num = 0; - - for (unsigned int i = 0; i < XT_NUM_REGS; i++) { - reg_list[i].exist = false; - if (xtensa_regs[i].type == XT_REG_USER) { - if (xtensa_user_reg_exists(xtensa, i)) - reg_list[i].exist = true; - else - LOG_DEBUG("User reg '%s' (%d) does not exist", xtensa_regs[i].name, i); - } else if (xtensa_regs[i].type == XT_REG_FR) { - if (xtensa_fp_reg_exists(xtensa, i)) - reg_list[i].exist = true; - else - LOG_DEBUG("FP reg '%s' (%d) does not exist", xtensa_regs[i].name, i); - } else if (xtensa_regs[i].type == XT_REG_SPECIAL) { - if (xtensa_special_reg_exists(xtensa, i)) - reg_list[i].exist = true; - else - LOG_DEBUG("Special reg '%s' (%d) does not exist", xtensa_regs[i].name, i); - } else { - if (xtensa_regular_reg_exists(xtensa, i)) - reg_list[i].exist = true; - else - LOG_DEBUG("Regular reg '%s' (%d) does not exist", xtensa_regs[i].name, i); - } - reg_list[i].name = xtensa_regs[i].name; - reg_list[i].size = 32; - reg_list[i].value = calloc(1, 4 /*XT_REG_LEN*/);/* make Clang Static Analyzer happy */ - if (!reg_list[i].value) { - LOG_ERROR("Failed to alloc reg list value!"); + xtensa->dbregs_num = 0; + unsigned int didx = 0; + for (unsigned int whichlist = 0; whichlist < 2; whichlist++) { + struct xtensa_reg_desc *rlist = (whichlist == 0) ? xtensa_regs : xtensa->optregs; + unsigned int listsize = (whichlist == 0) ? XT_NUM_REGS : xtensa->num_optregs; + for (unsigned int i = 0; i < listsize; i++, didx++) { + reg_list[didx].exist = rlist[i].exist; + reg_list[didx].name = rlist[i].name; + reg_list[didx].size = 32; + reg_list[didx].value = calloc(1, 4 /*XT_REG_LEN*/); /* make Clang Static Analyzer happy */ + if (!reg_list[didx].value) { + LOG_ERROR("Failed to alloc reg list value!"); + goto fail; + } + reg_list[didx].dirty = false; + reg_list[didx].valid = false; + reg_list[didx].type = &xtensa_reg_type; + reg_list[didx].arch_info = xtensa; + if (rlist[i].exist && (rlist[i].dbreg_num > last_dbreg_num)) + last_dbreg_num = rlist[i].dbreg_num; + + if (xtensa_extra_debug_log) { + LOG_TARGET_DEBUG(target, + "POPULATE %-16s list %d exist %d, idx %d, type %d, dbreg_num 0x%04x", + reg_list[didx].name, + whichlist, + reg_list[didx].exist, + didx, + rlist[i].type, + rlist[i].dbreg_num); + } + } + } + + xtensa->dbregs_num = last_dbreg_num + 1; + reg_cache->reg_list = reg_list; + reg_cache->num_regs = reg_list_size; + + LOG_TARGET_DEBUG(target, "xtensa->total_regs_num %d reg_list_size %d xtensa->dbregs_num %d", + xtensa->total_regs_num, reg_list_size, xtensa->dbregs_num); + + /* Construct empty-register list for handling unknown register requests */ + xtensa->empty_regs = calloc(xtensa->dbregs_num, sizeof(struct reg)); + if (!xtensa->empty_regs) { + LOG_TARGET_ERROR(target, "ERROR: Out of memory"); + goto fail; + } + for (unsigned int i = 0; i < xtensa->dbregs_num; i++) { + xtensa->empty_regs[i].name = calloc(8, sizeof(char)); + if (!xtensa->empty_regs[i].name) { + LOG_TARGET_ERROR(target, "ERROR: Out of memory"); goto fail; } - reg_list[i].dirty = false; - reg_list[i].valid = false; - reg_list[i].type = &xtensa_reg_type; - reg_list[i].arch_info = xtensa; - if (reg_list[i].exist) - xtensa->regs_num++; - } - for (unsigned int i = 0; i < xtensa->core_config->user_regs_num; i++) { - reg_list[XT_USR_REG_START + i].exist = true; - reg_list[XT_USR_REG_START + i].name = xtensa->core_config->user_regs[i].name; - reg_list[XT_USR_REG_START + i].size = xtensa->core_config->user_regs[i].size; - reg_list[XT_USR_REG_START + i].value = calloc(1, reg_list[XT_USR_REG_START + i].size / 8); - if (!reg_list[XT_USR_REG_START + i].value) { - LOG_ERROR("Failed to alloc user reg list value!"); + sprintf((char *)xtensa->empty_regs[i].name, "?0x%04x", i & 0x0000FFFF); + xtensa->empty_regs[i].size = 32; + xtensa->empty_regs[i].type = &xtensa_reg_type; + xtensa->empty_regs[i].value = calloc(1, 4 /*XT_REG_LEN*/); /* make Clang Static Analyzer happy */ + if (!xtensa->empty_regs[i].value) { + LOG_ERROR("Failed to alloc empty reg list value!"); goto fail; } - reg_list[XT_USR_REG_START + i].dirty = false; - reg_list[XT_USR_REG_START + i].valid = false; - reg_list[XT_USR_REG_START + i].type = xtensa->core_config->user_regs[i].type; - reg_list[XT_USR_REG_START + i].arch_info = xtensa; - xtensa->regs_num++; - } - if (xtensa->core_config->gdb_general_regs_num >= xtensa->regs_num) { - LOG_ERROR("Regs number less then GDB general regs number!"); - goto fail; + xtensa->empty_regs[i].arch_info = xtensa; } - /* assign GDB reg numbers to registers */ - for (unsigned int gdb_reg_id = 0; gdb_reg_id < xtensa->regs_num; gdb_reg_id++) { - unsigned int reg_id = xtensa->core_config->gdb_regs_mapping[gdb_reg_id]; - if (reg_id >= reg_cache->num_regs) { - LOG_ERROR("Invalid GDB map!"); + /* Construct contiguous register list from contiguous descriptor list */ + if (xtensa->regmap_contiguous && xtensa->contiguous_regs_desc) { + xtensa->contiguous_regs_list = calloc(xtensa->total_regs_num, sizeof(struct reg *)); + if (!xtensa->contiguous_regs_list) { + LOG_TARGET_ERROR(target, "ERROR: Out of memory"); goto fail; } - if (!reg_list[reg_id].exist) { - LOG_ERROR("Non-existing reg in GDB map!"); - goto fail; + for (unsigned int i = 0; i < xtensa->total_regs_num; i++) { + unsigned int j; + for (j = 0; j < reg_cache->num_regs; j++) { + if (!strcmp(reg_cache->reg_list[j].name, xtensa->contiguous_regs_desc[i]->name)) { + xtensa->contiguous_regs_list[i] = &(reg_cache->reg_list[j]); + LOG_TARGET_DEBUG(target, + "POPULATE contiguous regs list: %-16s, dbreg_num 0x%04x", + xtensa->contiguous_regs_list[i]->name, + xtensa->contiguous_regs_desc[i]->dbreg_num); + break; + } + } + if (j == reg_cache->num_regs) + LOG_TARGET_WARNING(target, "contiguous register %s not found", + xtensa->contiguous_regs_desc[i]->name); } - reg_list[reg_id].number = gdb_reg_id; } - reg_cache->reg_list = reg_list; xtensa->algo_context_backup = calloc(reg_cache->num_regs, sizeof(void *)); if (!xtensa->algo_context_backup) { @@ -2165,7 +2529,6 @@ static int xtensa_build_reg_cache(struct target *target) goto fail; } } - xtensa->core_cache = reg_cache; if (cache_p) *cache_p = reg_cache; @@ -2173,10 +2536,17 @@ static int xtensa_build_reg_cache(struct target *target) fail: if (reg_list) { - for (unsigned int i = 0; i < reg_cache->num_regs; i++) + for (unsigned int i = 0; i < reg_list_size; i++) free(reg_list[i].value); free(reg_list); } + if (xtensa->empty_regs) { + for (unsigned int i = 0; i < xtensa->dbregs_num; i++) { + free((void *)xtensa->empty_regs[i].name); + free(xtensa->empty_regs[i].value); + } + free(xtensa->empty_regs); + } if (xtensa->algo_context_backup) { for (unsigned int i = 0; i < reg_cache->num_regs; i++) free(xtensa->algo_context_backup[i]); @@ -2187,21 +2557,322 @@ fail: return ERROR_FAIL; } +static int32_t xtensa_gdbqc_parse_exec_tie_ops(struct target *target, char *opstr) +{ + struct xtensa *xtensa = target_to_xtensa(target); + int32_t status = ERROR_COMMAND_ARGUMENT_INVALID; + /* Process op[] list */ + while (opstr && (*opstr == ':')) { + uint8_t ops[32]; + unsigned int oplen = strtoul(opstr + 1, &opstr, 16); + if (oplen > 32) { + LOG_TARGET_ERROR(target, "TIE access instruction too long (%d)\n", oplen); + break; + } + unsigned int i = 0; + while ((i < oplen) && opstr && (*opstr == ':')) + ops[i++] = strtoul(opstr + 1, &opstr, 16); + if (i != oplen) { + LOG_TARGET_ERROR(target, "TIE access instruction malformed (%d)\n", i); + break; + } + + char insn_buf[128]; + sprintf(insn_buf, "Exec %d-byte TIE sequence: ", oplen); + for (i = 0; i < oplen; i++) + sprintf(insn_buf + strlen(insn_buf), "%02x:", ops[i]); + LOG_TARGET_DEBUG(target, "%s", insn_buf); + xtensa_queue_exec_ins_wide(xtensa, ops, oplen); /* Handles endian-swap */ + status = ERROR_OK; + } + return status; +} + +static int xtensa_gdbqc_qxtreg(struct target *target, const char *packet, char **response_p) +{ + struct xtensa *xtensa = target_to_xtensa(target); + bool iswrite = (packet[0] == 'Q'); + enum xtensa_qerr_e error; + + /* Read/write TIE register. Requires spill location. + * qxtreg<num>:<len>:<oplen>:<op[0]>:<...>[:<oplen>:<op[0]>:<...>] + * Qxtreg<num>:<len>:<oplen>:<op[0]>:<...>[:<oplen>:<op[0]>:<...>]=<value> + */ + if (!(xtensa->spill_buf)) { + LOG_ERROR("Spill location not specified. Try 'target remote <host>:3333 &spill_location0'"); + error = XT_QERR_FAIL; + goto xtensa_gdbqc_qxtreg_fail; + } + + char *delim; + uint32_t regnum = strtoul(packet + 6, &delim, 16); + if (*delim != ':') { + LOG_ERROR("Malformed qxtreg packet"); + error = XT_QERR_INVAL; + goto xtensa_gdbqc_qxtreg_fail; + } + uint32_t reglen = strtoul(delim + 1, &delim, 16); + if (*delim != ':') { + LOG_ERROR("Malformed qxtreg packet"); + error = XT_QERR_INVAL; + goto xtensa_gdbqc_qxtreg_fail; + } + uint8_t regbuf[XT_QUERYPKT_RESP_MAX]; + memset(regbuf, 0, XT_QUERYPKT_RESP_MAX); + LOG_DEBUG("TIE reg 0x%08" PRIx32 " %s (%d bytes)", regnum, iswrite ? "write" : "read", reglen); + if (reglen * 2 + 1 > XT_QUERYPKT_RESP_MAX) { + LOG_ERROR("TIE register too large"); + error = XT_QERR_MEM; + goto xtensa_gdbqc_qxtreg_fail; + } + + /* (1) Save spill memory, (1.5) [if write then store value to spill location], + * (2) read old a4, (3) write spill address to a4. + * NOTE: ensure a4 is restored properly by all error handling logic + */ + unsigned int memop_size = (xtensa->spill_loc & 3) ? 1 : 4; + int status = xtensa_read_memory(target, xtensa->spill_loc, memop_size, + xtensa->spill_bytes / memop_size, xtensa->spill_buf); + if (status != ERROR_OK) { + LOG_ERROR("Spill memory save"); + error = XT_QERR_MEM; + goto xtensa_gdbqc_qxtreg_fail; + } + if (iswrite) { + /* Extract value and store in spill memory */ + unsigned int b = 0; + char *valbuf = strchr(delim, '='); + if (!(valbuf && (*valbuf == '='))) { + LOG_ERROR("Malformed Qxtreg packet"); + error = XT_QERR_INVAL; + goto xtensa_gdbqc_qxtreg_fail; + } + valbuf++; + while (*valbuf && *(valbuf + 1)) { + char bytestr[3] = { 0, 0, 0 }; + strncpy(bytestr, valbuf, 2); + regbuf[b++] = strtoul(bytestr, NULL, 16); + valbuf += 2; + } + if (b != reglen) { + LOG_ERROR("Malformed Qxtreg packet"); + error = XT_QERR_INVAL; + goto xtensa_gdbqc_qxtreg_fail; + } + status = xtensa_write_memory(target, xtensa->spill_loc, memop_size, + reglen / memop_size, regbuf); + if (status != ERROR_OK) { + LOG_ERROR("TIE value store"); + error = XT_QERR_MEM; + goto xtensa_gdbqc_qxtreg_fail; + } + } + xtensa_reg_val_t orig_a4 = xtensa_reg_get(target, XT_REG_IDX_A4); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, xtensa->spill_loc); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4)); + + int32_t tieop_status = xtensa_gdbqc_parse_exec_tie_ops(target, delim); + + /* Restore a4 but not yet spill memory. Execute it all... */ + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, orig_a4); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4)); + status = xtensa_dm_queue_execute(&xtensa->dbg_mod); + if (status != ERROR_OK) { + LOG_TARGET_ERROR(target, "TIE queue execute: %d\n", status); + tieop_status = status; + } + status = xtensa_core_status_check(target); + if (status != ERROR_OK) { + LOG_TARGET_ERROR(target, "TIE instr execute: %d\n", status); + tieop_status = status; + } + + if (tieop_status == ERROR_OK) { + if (iswrite) { + /* TIE write succeeded; send OK */ + strcpy(*response_p, "OK"); + } else { + /* TIE read succeeded; copy result from spill memory */ + status = xtensa_read_memory(target, xtensa->spill_loc, memop_size, reglen, regbuf); + if (status != ERROR_OK) { + LOG_TARGET_ERROR(target, "TIE result read"); + tieop_status = status; + } + unsigned int i; + for (i = 0; i < reglen; i++) + sprintf(*response_p + 2 * i, "%02x", regbuf[i]); + *(*response_p + 2 * i) = '\0'; + LOG_TARGET_DEBUG(target, "TIE response: %s", *response_p); + } + } + + /* Restore spill memory first, then report any previous errors */ + status = xtensa_write_memory(target, xtensa->spill_loc, memop_size, + xtensa->spill_bytes / memop_size, xtensa->spill_buf); + if (status != ERROR_OK) { + LOG_ERROR("Spill memory restore"); + error = XT_QERR_MEM; + goto xtensa_gdbqc_qxtreg_fail; + } + if (tieop_status != ERROR_OK) { + LOG_ERROR("TIE execution"); + error = XT_QERR_FAIL; + goto xtensa_gdbqc_qxtreg_fail; + } + return ERROR_OK; + +xtensa_gdbqc_qxtreg_fail: + strcpy(*response_p, xt_qerr[error].chrval); + return xt_qerr[error].intval; +} + +int xtensa_gdb_query_custom(struct target *target, const char *packet, char **response_p) +{ + struct xtensa *xtensa = target_to_xtensa(target); + enum xtensa_qerr_e error; + if (!packet || !response_p) { + LOG_TARGET_ERROR(target, "invalid parameter: packet %p response_p %p", packet, response_p); + return ERROR_FAIL; + } + + *response_p = xtensa->qpkt_resp; + if (strncmp(packet, "qxtn", 4) == 0) { + strcpy(*response_p, "OpenOCD"); + return ERROR_OK; + } else if (strncasecmp(packet, "qxtgdbversion=", 14) == 0) { + return ERROR_OK; + } else if ((strncmp(packet, "Qxtsis=", 7) == 0) || (strncmp(packet, "Qxtsds=", 7) == 0)) { + /* Confirm host cache params match core .cfg file */ + struct xtensa_cache_config *cachep = (packet[4] == 'i') ? + &xtensa->core_config->icache : &xtensa->core_config->dcache; + unsigned int line_size = 0, size = 0, way_count = 0; + sscanf(&packet[7], "%x,%x,%x", &line_size, &size, &way_count); + if ((cachep->line_size != line_size) || + (cachep->size != size) || + (cachep->way_count != way_count)) { + LOG_TARGET_WARNING(target, "%cCache mismatch; check xtensa-core-XXX.cfg file", + cachep == &xtensa->core_config->icache ? 'I' : 'D'); + } + strcpy(*response_p, "OK"); + return ERROR_OK; + } else if ((strncmp(packet, "Qxtiram=", 8) == 0) || (strncmp(packet, "Qxtirom=", 8) == 0)) { + /* Confirm host IRAM/IROM params match core .cfg file */ + struct xtensa_local_mem_config *memp = (packet[5] == 'a') ? + &xtensa->core_config->iram : &xtensa->core_config->irom; + unsigned int base = 0, size = 0, i; + char *pkt = (char *)&packet[7]; + do { + pkt++; + size = strtoul(pkt, &pkt, 16); + pkt++; + base = strtoul(pkt, &pkt, 16); + LOG_TARGET_DEBUG(target, "memcheck: %dB @ 0x%08x", size, base); + for (i = 0; i < memp->count; i++) { + if ((memp->regions[i].base == base) && (memp->regions[i].size == size)) + break; + } + if (i == memp->count) { + LOG_TARGET_WARNING(target, "%s mismatch; check xtensa-core-XXX.cfg file", + memp == &xtensa->core_config->iram ? "IRAM" : "IROM"); + break; + } + for (i = 0; i < 11; i++) { + pkt++; + strtoul(pkt, &pkt, 16); + } + } while (pkt && (pkt[0] == ',')); + strcpy(*response_p, "OK"); + return ERROR_OK; + } else if (strncmp(packet, "Qxtexcmlvl=", 11) == 0) { + /* Confirm host EXCM_LEVEL matches core .cfg file */ + unsigned int excm_level = strtoul(&packet[11], NULL, 0); + if (!xtensa->core_config->high_irq.enabled || + (excm_level != xtensa->core_config->high_irq.excm_level)) + LOG_TARGET_WARNING(target, "EXCM_LEVEL mismatch; check xtensa-core-XXX.cfg file"); + strcpy(*response_p, "OK"); + return ERROR_OK; + } else if ((strncmp(packet, "Qxtl2cs=", 8) == 0) || + (strncmp(packet, "Qxtl2ca=", 8) == 0) || + (strncmp(packet, "Qxtdensity=", 11) == 0)) { + strcpy(*response_p, "OK"); + return ERROR_OK; + } else if (strncmp(packet, "Qxtspill=", 9) == 0) { + char *delim; + uint32_t spill_loc = strtoul(packet + 9, &delim, 16); + if (*delim != ':') { + LOG_ERROR("Malformed Qxtspill packet"); + error = XT_QERR_INVAL; + goto xtensa_gdb_query_custom_fail; + } + xtensa->spill_loc = spill_loc; + xtensa->spill_bytes = strtoul(delim + 1, NULL, 16); + if (xtensa->spill_buf) + free(xtensa->spill_buf); + xtensa->spill_buf = calloc(1, xtensa->spill_bytes); + if (!xtensa->spill_buf) { + LOG_ERROR("Spill buf alloc"); + error = XT_QERR_MEM; + goto xtensa_gdb_query_custom_fail; + } + LOG_TARGET_DEBUG(target, "Set spill 0x%08" PRIx32 " (%d)", xtensa->spill_loc, xtensa->spill_bytes); + strcpy(*response_p, "OK"); + return ERROR_OK; + } else if (strncasecmp(packet, "qxtreg", 6) == 0) { + return xtensa_gdbqc_qxtreg(target, packet, response_p); + } else if ((strncmp(packet, "qTStatus", 8) == 0) || + (strncmp(packet, "qxtftie", 7) == 0) || + (strncmp(packet, "qxtstie", 7) == 0)) { + /* Return empty string to indicate trace, TIE wire debug are unsupported */ + strcpy(*response_p, ""); + return ERROR_OK; + } + + /* Warn for all other queries, but do not return errors */ + LOG_TARGET_WARNING(target, "Unknown target-specific query packet: %s", packet); + strcpy(*response_p, ""); + return ERROR_OK; + +xtensa_gdb_query_custom_fail: + strcpy(*response_p, xt_qerr[error].chrval); + return xt_qerr[error].intval; +} + int xtensa_init_arch_info(struct target *target, struct xtensa *xtensa, - const struct xtensa_config *xtensa_config, const struct xtensa_debug_module_config *dm_cfg) { target->arch_info = xtensa; xtensa->common_magic = XTENSA_COMMON_MAGIC; xtensa->target = target; - xtensa->core_config = xtensa_config; xtensa->stepping_isr_mode = XT_STEPPING_ISR_ON; - if (!xtensa->core_config->exc.enabled || !xtensa->core_config->irq.enabled || - !xtensa->core_config->high_irq.enabled || !xtensa->core_config->debug.enabled) { - LOG_ERROR("Xtensa configuration does not support debugging!"); + xtensa->core_config = calloc(1, sizeof(struct xtensa_config)); + if (!xtensa->core_config) { + LOG_ERROR("Xtensa configuration alloc failed\n"); return ERROR_FAIL; } + + /* Default cache settings are disabled with 1 way */ + xtensa->core_config->icache.way_count = 1; + xtensa->core_config->dcache.way_count = 1; + + /* chrval: AR3/AR4 register names will change with window mapping. + * intval: tracks whether scratch register was set through gdb P packet. + */ + for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++) { + xtensa->scratch_ars[s].chrval = calloc(8, sizeof(char)); + if (!xtensa->scratch_ars[s].chrval) { + for (enum xtensa_ar_scratch_set_e f = 0; f < s; f++) + free(xtensa->scratch_ars[f].chrval); + free(xtensa->core_config); + LOG_ERROR("Xtensa scratch AR alloc failed\n"); + return ERROR_FAIL; + } + xtensa->scratch_ars[s].intval = false; + sprintf(xtensa->scratch_ars[s].chrval, "%s%d", + ((s == XT_AR_SCRATCH_A3) || (s == XT_AR_SCRATCH_A4)) ? "a" : "ar", + ((s == XT_AR_SCRATCH_A3) || (s == XT_AR_SCRATCH_AR3)) ? 3 : 4); + } + return xtensa_dm_init(&xtensa->dbg_mod, dm_cfg); } @@ -2215,12 +2886,12 @@ int xtensa_target_init(struct command_context *cmd_ctx, struct target *target) struct xtensa *xtensa = target_to_xtensa(target); xtensa->come_online_probes_num = 3; - xtensa->hw_brps = calloc(xtensa->core_config->debug.ibreaks_num, sizeof(struct breakpoint *)); + xtensa->hw_brps = calloc(XT_HW_IBREAK_MAX_NUM, sizeof(struct breakpoint *)); if (!xtensa->hw_brps) { LOG_ERROR("Failed to alloc memory for HW breakpoints!"); return ERROR_FAIL; } - xtensa->hw_wps = calloc(xtensa->core_config->debug.dbreaks_num, sizeof(struct watchpoint *)); + xtensa->hw_wps = calloc(XT_HW_DBREAK_MAX_NUM, sizeof(struct watchpoint *)); if (!xtensa->hw_wps) { free(xtensa->hw_brps); LOG_ERROR("Failed to alloc memory for HW watchpoints!"); @@ -2234,6 +2905,11 @@ int xtensa_target_init(struct command_context *cmd_ctx, struct target *target) return ERROR_FAIL; } + xtensa->spill_loc = 0xffffffff; + xtensa->spill_bytes = 0; + xtensa->spill_buf = NULL; + xtensa->probe_lsddr32p = -1; /* Probe for fast load/store operations */ + return xtensa_build_reg_cache(target); } @@ -2254,6 +2930,21 @@ static void xtensa_free_reg_cache(struct target *target) } xtensa->core_cache = NULL; xtensa->algo_context_backup = NULL; + + if (xtensa->empty_regs) { + for (unsigned int i = 0; i < xtensa->dbregs_num; i++) { + free((void *)xtensa->empty_regs[i].name); + free(xtensa->empty_regs[i].value); + } + free(xtensa->empty_regs); + } + xtensa->empty_regs = NULL; + if (xtensa->optregs) { + for (unsigned int i = 0; i < xtensa->num_optregs; i++) + free((void *)xtensa->optregs[i].name); + free(xtensa->optregs); + } + xtensa->optregs = NULL; } void xtensa_target_deinit(struct target *target) @@ -2263,22 +2954,30 @@ void xtensa_target_deinit(struct target *target) LOG_DEBUG("start"); if (target_was_examined(target)) { - int ret = xtensa_queue_dbg_reg_write(xtensa, NARADR_DCRCLR, OCDDCR_ENABLEOCD); + int ret = xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRCLR, OCDDCR_ENABLEOCD); if (ret != ERROR_OK) { LOG_ERROR("Failed to queue OCDDCR_ENABLEOCD clear operation!"); return; } xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); - ret = jtag_execute_queue(); + ret = xtensa_dm_queue_execute(&xtensa->dbg_mod); if (ret != ERROR_OK) { LOG_ERROR("Failed to clear OCDDCR_ENABLEOCD!"); return; } + xtensa_dm_deinit(&xtensa->dbg_mod); } xtensa_free_reg_cache(target); free(xtensa->hw_brps); free(xtensa->hw_wps); free(xtensa->sw_brps); + if (xtensa->spill_buf) { + free(xtensa->spill_buf); + xtensa->spill_buf = NULL; + } + for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++) + free(xtensa->scratch_ars[s].chrval); + free(xtensa->core_config); } const char *xtensa_get_gdb_arch(struct target *target) @@ -2286,6 +2985,523 @@ const char *xtensa_get_gdb_arch(struct target *target) return "xtensa"; } +/* exe <ascii-encoded hexadecimal instruction bytes> */ +static COMMAND_HELPER(xtensa_cmd_exe_do, struct target *target) +{ + struct xtensa *xtensa = target_to_xtensa(target); + + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + /* Process ascii-encoded hex byte string */ + const char *parm = CMD_ARGV[0]; + unsigned int parm_len = strlen(parm); + if ((parm_len >= 64) || (parm_len & 1)) { + LOG_ERROR("Invalid parameter length (%d): must be even, < 64 characters", parm_len); + return ERROR_FAIL; + } + + uint8_t ops[32]; + memset(ops, 0, 32); + unsigned int oplen = parm_len / 2; + char encoded_byte[3] = { 0, 0, 0 }; + for (unsigned int i = 0; i < oplen; i++) { + encoded_byte[0] = *parm++; + encoded_byte[1] = *parm++; + ops[i] = strtoul(encoded_byte, NULL, 16); + } + + /* GDB must handle state save/restore. + * Flush reg cache in case spill location is in an AR + * Update CPENABLE only for this execution; later restore cached copy + * Keep a copy of exccause in case executed code triggers an exception + */ + int status = xtensa_write_dirty_registers(target); + if (status != ERROR_OK) { + LOG_ERROR("%s: Failed to write back register cache.", target_name(target)); + return ERROR_FAIL; + } + xtensa_reg_val_t exccause = xtensa_reg_get(target, XT_REG_IDX_EXCCAUSE); + xtensa_reg_val_t cpenable = xtensa_reg_get(target, XT_REG_IDX_CPENABLE); + xtensa_reg_val_t a3 = xtensa_reg_get(target, XT_REG_IDX_A3); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, 0xffffffff); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, + xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3)); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, a3); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + + /* Queue instruction list and execute everything */ + LOG_TARGET_DEBUG(target, "execute stub: %s", CMD_ARGV[0]); + xtensa_queue_exec_ins_wide(xtensa, ops, oplen); /* Handles endian-swap */ + status = xtensa_dm_queue_execute(&xtensa->dbg_mod); + if (status != ERROR_OK) + LOG_TARGET_ERROR(target, "TIE queue execute: %d\n", status); + status = xtensa_core_status_check(target); + if (status != ERROR_OK) + LOG_TARGET_ERROR(target, "TIE instr execute: %d\n", status); + + /* Reread register cache and restore saved regs after instruction execution */ + if (xtensa_fetch_all_regs(target) != ERROR_OK) + LOG_TARGET_ERROR(target, "%s: Failed to fetch register cache (post-exec).", target_name(target)); + xtensa_reg_set(target, XT_REG_IDX_EXCCAUSE, exccause); + xtensa_reg_set(target, XT_REG_IDX_CPENABLE, cpenable); + return status; +} + +COMMAND_HANDLER(xtensa_cmd_exe) +{ + return CALL_COMMAND_HANDLER(xtensa_cmd_exe_do, get_current_target(CMD_CTX)); +} + +/* xtdef <name> */ +COMMAND_HELPER(xtensa_cmd_xtdef_do, struct xtensa *xtensa) +{ + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + const char *core_name = CMD_ARGV[0]; + if (strcasecmp(core_name, "LX") == 0) { + xtensa->core_config->core_type = XT_LX; + } else { + LOG_ERROR("xtdef [LX]\n"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + return ERROR_OK; +} + +COMMAND_HANDLER(xtensa_cmd_xtdef) +{ + return CALL_COMMAND_HANDLER(xtensa_cmd_xtdef_do, + target_to_xtensa(get_current_target(CMD_CTX))); +} + +static inline bool xtensa_cmd_xtopt_legal_val(char *opt, int val, int min, int max) +{ + if ((val < min) || (val > max)) { + LOG_ERROR("xtopt %s (%d) out of range [%d..%d]\n", opt, val, min, max); + return false; + } + return true; +} + +/* xtopt <name> <value> */ +COMMAND_HELPER(xtensa_cmd_xtopt_do, struct xtensa *xtensa) +{ + if (CMD_ARGC != 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + const char *opt_name = CMD_ARGV[0]; + int opt_val = strtol(CMD_ARGV[1], NULL, 0); + if (strcasecmp(opt_name, "arnum") == 0) { + if (!xtensa_cmd_xtopt_legal_val("arnum", opt_val, 0, 64)) + return ERROR_COMMAND_ARGUMENT_INVALID; + xtensa->core_config->aregs_num = opt_val; + } else if (strcasecmp(opt_name, "windowed") == 0) { + if (!xtensa_cmd_xtopt_legal_val("windowed", opt_val, 0, 1)) + return ERROR_COMMAND_ARGUMENT_INVALID; + xtensa->core_config->windowed = opt_val; + } else if (strcasecmp(opt_name, "cpenable") == 0) { + if (!xtensa_cmd_xtopt_legal_val("cpenable", opt_val, 0, 1)) + return ERROR_COMMAND_ARGUMENT_INVALID; + xtensa->core_config->coproc = opt_val; + } else if (strcasecmp(opt_name, "exceptions") == 0) { + if (!xtensa_cmd_xtopt_legal_val("exceptions", opt_val, 0, 1)) + return ERROR_COMMAND_ARGUMENT_INVALID; + xtensa->core_config->exceptions = opt_val; + } else if (strcasecmp(opt_name, "intnum") == 0) { + if (!xtensa_cmd_xtopt_legal_val("intnum", opt_val, 0, 32)) + return ERROR_COMMAND_ARGUMENT_INVALID; + xtensa->core_config->irq.enabled = (opt_val > 0); + xtensa->core_config->irq.irq_num = opt_val; + } else if (strcasecmp(opt_name, "hipriints") == 0) { + if (!xtensa_cmd_xtopt_legal_val("hipriints", opt_val, 0, 1)) + return ERROR_COMMAND_ARGUMENT_INVALID; + xtensa->core_config->high_irq.enabled = opt_val; + } else if (strcasecmp(opt_name, "excmlevel") == 0) { + if (!xtensa_cmd_xtopt_legal_val("excmlevel", opt_val, 1, 6)) + return ERROR_COMMAND_ARGUMENT_INVALID; + if (!xtensa->core_config->high_irq.enabled) { + LOG_ERROR("xtopt excmlevel requires hipriints\n"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + xtensa->core_config->high_irq.excm_level = opt_val; + } else if (strcasecmp(opt_name, "intlevels") == 0) { + if (xtensa->core_config->core_type == XT_LX) { + if (!xtensa_cmd_xtopt_legal_val("intlevels", opt_val, 2, 6)) + return ERROR_COMMAND_ARGUMENT_INVALID; + } else { + if (!xtensa_cmd_xtopt_legal_val("intlevels", opt_val, 1, 255)) + return ERROR_COMMAND_ARGUMENT_INVALID; + } + if (!xtensa->core_config->high_irq.enabled) { + LOG_ERROR("xtopt intlevels requires hipriints\n"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + xtensa->core_config->high_irq.level_num = opt_val; + } else if (strcasecmp(opt_name, "debuglevel") == 0) { + if (xtensa->core_config->core_type == XT_LX) { + if (!xtensa_cmd_xtopt_legal_val("debuglevel", opt_val, 2, 6)) + return ERROR_COMMAND_ARGUMENT_INVALID; + } else { + if (!xtensa_cmd_xtopt_legal_val("debuglevel", opt_val, 0, 0)) + return ERROR_COMMAND_ARGUMENT_INVALID; + } + xtensa->core_config->debug.enabled = 1; + xtensa->core_config->debug.irq_level = opt_val; + } else if (strcasecmp(opt_name, "ibreaknum") == 0) { + if (!xtensa_cmd_xtopt_legal_val("ibreaknum", opt_val, 0, 2)) + return ERROR_COMMAND_ARGUMENT_INVALID; + xtensa->core_config->debug.ibreaks_num = opt_val; + } else if (strcasecmp(opt_name, "dbreaknum") == 0) { + if (!xtensa_cmd_xtopt_legal_val("dbreaknum", opt_val, 0, 2)) + return ERROR_COMMAND_ARGUMENT_INVALID; + xtensa->core_config->debug.dbreaks_num = opt_val; + } else if (strcasecmp(opt_name, "tracemem") == 0) { + if (!xtensa_cmd_xtopt_legal_val("tracemem", opt_val, 0, 256 * 1024)) + return ERROR_COMMAND_ARGUMENT_INVALID; + xtensa->core_config->trace.mem_sz = opt_val; + xtensa->core_config->trace.enabled = (opt_val > 0); + } else if (strcasecmp(opt_name, "tracememrev") == 0) { + if (!xtensa_cmd_xtopt_legal_val("tracememrev", opt_val, 0, 1)) + return ERROR_COMMAND_ARGUMENT_INVALID; + xtensa->core_config->trace.reversed_mem_access = opt_val; + } else if (strcasecmp(opt_name, "perfcount") == 0) { + if (!xtensa_cmd_xtopt_legal_val("perfcount", opt_val, 0, 8)) + return ERROR_COMMAND_ARGUMENT_INVALID; + xtensa->core_config->debug.perfcount_num = opt_val; + } else { + LOG_WARNING("Unknown xtensa command ignored: \"xtopt %s %s\"", CMD_ARGV[0], CMD_ARGV[1]); + return ERROR_OK; + } + + return ERROR_OK; +} + +COMMAND_HANDLER(xtensa_cmd_xtopt) +{ + return CALL_COMMAND_HANDLER(xtensa_cmd_xtopt_do, + target_to_xtensa(get_current_target(CMD_CTX))); +} + +/* xtmem <type> [parameters] */ +COMMAND_HELPER(xtensa_cmd_xtmem_do, struct xtensa *xtensa) +{ + struct xtensa_cache_config *cachep = NULL; + struct xtensa_local_mem_config *memp = NULL; + int mem_access = 0; + bool is_dcache = false; + + if (CMD_ARGC == 0) { + LOG_ERROR("xtmem <type> [parameters]\n"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + const char *mem_name = CMD_ARGV[0]; + if (strcasecmp(mem_name, "icache") == 0) { + cachep = &xtensa->core_config->icache; + } else if (strcasecmp(mem_name, "dcache") == 0) { + cachep = &xtensa->core_config->dcache; + is_dcache = true; + } else if (strcasecmp(mem_name, "l2cache") == 0) { + /* TODO: support L2 cache */ + } else if (strcasecmp(mem_name, "l2addr") == 0) { + /* TODO: support L2 cache */ + } else if (strcasecmp(mem_name, "iram") == 0) { + memp = &xtensa->core_config->iram; + mem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE; + } else if (strcasecmp(mem_name, "dram") == 0) { + memp = &xtensa->core_config->dram; + mem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE; + } else if (strcasecmp(mem_name, "sram") == 0) { + memp = &xtensa->core_config->sram; + mem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE; + } else if (strcasecmp(mem_name, "irom") == 0) { + memp = &xtensa->core_config->irom; + mem_access = XT_MEM_ACCESS_READ; + } else if (strcasecmp(mem_name, "drom") == 0) { + memp = &xtensa->core_config->drom; + mem_access = XT_MEM_ACCESS_READ; + } else if (strcasecmp(mem_name, "srom") == 0) { + memp = &xtensa->core_config->srom; + mem_access = XT_MEM_ACCESS_READ; + } else { + LOG_ERROR("xtmem types: <icache|dcache|l2cache|l2addr|iram|irom|dram|drom|sram|srom>\n"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + + if (cachep) { + if ((CMD_ARGC != 4) && (CMD_ARGC != 5)) { + LOG_ERROR("xtmem <cachetype> <linebytes> <cachebytes> <ways> [writeback]\n"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + cachep->line_size = strtoul(CMD_ARGV[1], NULL, 0); + cachep->size = strtoul(CMD_ARGV[2], NULL, 0); + cachep->way_count = strtoul(CMD_ARGV[3], NULL, 0); + cachep->writeback = ((CMD_ARGC == 5) && is_dcache) ? + strtoul(CMD_ARGV[4], NULL, 0) : 0; + } else if (memp) { + if (CMD_ARGC != 3) { + LOG_ERROR("xtmem <memtype> <baseaddr> <bytes>\n"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + struct xtensa_local_mem_region_config *memcfgp = &memp->regions[memp->count]; + memcfgp->base = strtoul(CMD_ARGV[1], NULL, 0); + memcfgp->size = strtoul(CMD_ARGV[2], NULL, 0); + memcfgp->access = mem_access; + memp->count++; + } + + return ERROR_OK; +} + +COMMAND_HANDLER(xtensa_cmd_xtmem) +{ + return CALL_COMMAND_HANDLER(xtensa_cmd_xtmem_do, + target_to_xtensa(get_current_target(CMD_CTX))); +} + +/* xtmpu <num FG seg> <min seg size> <lockable> <executeonly> */ +COMMAND_HELPER(xtensa_cmd_xtmpu_do, struct xtensa *xtensa) +{ + if (CMD_ARGC != 4) { + LOG_ERROR("xtmpu <num FG seg> <min seg size> <lockable> <executeonly>\n"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + unsigned int nfgseg = strtoul(CMD_ARGV[0], NULL, 0); + unsigned int minsegsize = strtoul(CMD_ARGV[1], NULL, 0); + unsigned int lockable = strtoul(CMD_ARGV[2], NULL, 0); + unsigned int execonly = strtoul(CMD_ARGV[3], NULL, 0); + + if ((nfgseg > 32)) { + LOG_ERROR("<nfgseg> must be within [0..32]\n"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } else if (minsegsize & (minsegsize - 1)) { + LOG_ERROR("<minsegsize> must be a power of 2 >= 32\n"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } else if (lockable > 1) { + LOG_ERROR("<lockable> must be 0 or 1\n"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } else if (execonly > 1) { + LOG_ERROR("<execonly> must be 0 or 1\n"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + + xtensa->core_config->mpu.enabled = true; + xtensa->core_config->mpu.nfgseg = nfgseg; + xtensa->core_config->mpu.minsegsize = minsegsize; + xtensa->core_config->mpu.lockable = lockable; + xtensa->core_config->mpu.execonly = execonly; + return ERROR_OK; +} + +COMMAND_HANDLER(xtensa_cmd_xtmpu) +{ + return CALL_COMMAND_HANDLER(xtensa_cmd_xtmpu_do, + target_to_xtensa(get_current_target(CMD_CTX))); +} + +/* xtmmu <NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56> */ +COMMAND_HELPER(xtensa_cmd_xtmmu_do, struct xtensa *xtensa) +{ + if (CMD_ARGC != 2) { + LOG_ERROR("xtmmu <NIREFILLENTRIES> <NDREFILLENTRIES>\n"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + unsigned int nirefillentries = strtoul(CMD_ARGV[0], NULL, 0); + unsigned int ndrefillentries = strtoul(CMD_ARGV[1], NULL, 0); + if ((nirefillentries != 16) && (nirefillentries != 32)) { + LOG_ERROR("<nirefillentries> must be 16 or 32\n"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } else if ((ndrefillentries != 16) && (ndrefillentries != 32)) { + LOG_ERROR("<ndrefillentries> must be 16 or 32\n"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + + xtensa->core_config->mmu.enabled = true; + xtensa->core_config->mmu.itlb_entries_count = nirefillentries; + xtensa->core_config->mmu.dtlb_entries_count = ndrefillentries; + return ERROR_OK; +} + +COMMAND_HANDLER(xtensa_cmd_xtmmu) +{ + return CALL_COMMAND_HANDLER(xtensa_cmd_xtmmu_do, + target_to_xtensa(get_current_target(CMD_CTX))); +} + +/* xtregs <numregs> + * xtreg <regname> <regnum> */ +COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa) +{ + if (CMD_ARGC == 1) { + int32_t numregs = strtoul(CMD_ARGV[0], NULL, 0); + if ((numregs <= 0) || (numregs > UINT16_MAX)) { + LOG_ERROR("xtreg <numregs>: Invalid 'numregs' (%d)", numregs); + return ERROR_COMMAND_SYNTAX_ERROR; + } + if ((xtensa->genpkt_regs_num > 0) && (numregs < (int32_t)xtensa->genpkt_regs_num)) { + LOG_ERROR("xtregs (%d) must be larger than numgenregs (%d) (if xtregfmt specified)", + numregs, xtensa->genpkt_regs_num); + return ERROR_COMMAND_SYNTAX_ERROR; + } + xtensa->total_regs_num = numregs; + xtensa->core_regs_num = 0; + xtensa->num_optregs = 0; + /* A little more memory than required, but saves a second initialization pass */ + xtensa->optregs = calloc(xtensa->total_regs_num, sizeof(struct xtensa_reg_desc)); + if (!xtensa->optregs) { + LOG_ERROR("Failed to allocate xtensa->optregs!"); + return ERROR_FAIL; + } + return ERROR_OK; + } else if (CMD_ARGC != 2) { + return ERROR_COMMAND_SYNTAX_ERROR; + } + + /* "xtregfmt contiguous" must be specified prior to the first "xtreg" definition + * if general register (g-packet) requests or contiguous register maps are supported */ + if (xtensa->regmap_contiguous && !xtensa->contiguous_regs_desc) { + xtensa->contiguous_regs_desc = calloc(xtensa->total_regs_num, sizeof(struct xtensa_reg_desc *)); + if (!xtensa->contiguous_regs_desc) { + LOG_ERROR("Failed to allocate xtensa->contiguous_regs_desc!"); + return ERROR_FAIL; + } + } + + const char *regname = CMD_ARGV[0]; + unsigned int regnum = strtoul(CMD_ARGV[1], NULL, 0); + if (regnum > UINT16_MAX) { + LOG_ERROR("<regnum> must be a 16-bit number"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + + if ((xtensa->num_optregs + xtensa->core_regs_num) >= xtensa->total_regs_num) { + if (xtensa->total_regs_num) + LOG_ERROR("'xtreg %s 0x%04x': Too many registers (%d expected, %d core %d extended)", + regname, regnum, + xtensa->total_regs_num, xtensa->core_regs_num, xtensa->num_optregs); + else + LOG_ERROR("'xtreg %s 0x%04x': Number of registers unspecified", + regname, regnum); + return ERROR_FAIL; + } + + /* Determine whether register belongs in xtensa_regs[] or xtensa->xtensa_spec_regs[] */ + struct xtensa_reg_desc *rptr = &xtensa->optregs[xtensa->num_optregs]; + bool is_extended_reg = true; + unsigned int ridx; + for (ridx = 0; ridx < XT_NUM_REGS; ridx++) { + if (strcmp(CMD_ARGV[0], xtensa_regs[ridx].name) == 0) { + /* Flag core register as defined */ + rptr = &xtensa_regs[ridx]; + xtensa->core_regs_num++; + is_extended_reg = false; + break; + } + } + + rptr->exist = true; + if (is_extended_reg) { + /* Register ID, debugger-visible register ID */ + rptr->name = strdup(CMD_ARGV[0]); + rptr->dbreg_num = regnum; + rptr->reg_num = (regnum & XT_REG_INDEX_MASK); + xtensa->num_optregs++; + + /* Register type */ + if ((regnum & XT_REG_GENERAL_MASK) == XT_REG_GENERAL_VAL) { + rptr->type = XT_REG_GENERAL; + } else if ((regnum & XT_REG_USER_MASK) == XT_REG_USER_VAL) { + rptr->type = XT_REG_USER; + } else if ((regnum & XT_REG_FR_MASK) == XT_REG_FR_VAL) { + rptr->type = XT_REG_FR; + } else if ((regnum & XT_REG_SPECIAL_MASK) == XT_REG_SPECIAL_VAL) { + rptr->type = XT_REG_SPECIAL; + } else if ((regnum & XT_REG_RELGEN_MASK) == XT_REG_RELGEN_VAL) { + /* WARNING: For these registers, regnum points to the + * index of the corresponding ARx registers, NOT to + * the processor register number! */ + rptr->type = XT_REG_RELGEN; + rptr->reg_num += XT_REG_IDX_ARFIRST; + rptr->dbreg_num += XT_REG_IDX_ARFIRST; + } else if ((regnum & XT_REG_TIE_MASK) != 0) { + rptr->type = XT_REG_TIE; + } else { + rptr->type = XT_REG_OTHER; + } + + /* Register flags */ + if ((strcmp(rptr->name, "mmid") == 0) || (strcmp(rptr->name, "eraccess") == 0) || + (strcmp(rptr->name, "ddr") == 0) || (strcmp(rptr->name, "intset") == 0) || + (strcmp(rptr->name, "intclear") == 0)) + rptr->flags = XT_REGF_NOREAD; + else + rptr->flags = 0; + + if ((rptr->reg_num == (XT_PS_REG_NUM_BASE + xtensa->core_config->debug.irq_level)) && + (xtensa->core_config->core_type == XT_LX) && (rptr->type == XT_REG_SPECIAL)) { + xtensa->eps_dbglevel_idx = XT_NUM_REGS + xtensa->num_optregs - 1; + LOG_DEBUG("Setting PS (%s) index to %d", rptr->name, xtensa->eps_dbglevel_idx); + } + } else if (strcmp(rptr->name, "cpenable") == 0) { + xtensa->core_config->coproc = true; + } + + /* Build out list of contiguous registers in specified order */ + unsigned int running_reg_count = xtensa->num_optregs + xtensa->core_regs_num; + if (xtensa->contiguous_regs_desc) { + assert((running_reg_count <= xtensa->total_regs_num) && "contiguous register address internal error!"); + xtensa->contiguous_regs_desc[running_reg_count - 1] = rptr; + } + if (xtensa_extra_debug_log) + LOG_DEBUG("Added %s register %-16s: 0x%04x/0x%02x t%d (%d of %d)", + is_extended_reg ? "config-specific" : "core", + rptr->name, rptr->dbreg_num, rptr->reg_num, rptr->type, + is_extended_reg ? xtensa->num_optregs : ridx, + is_extended_reg ? xtensa->total_regs_num : XT_NUM_REGS); + return ERROR_OK; +} + +COMMAND_HANDLER(xtensa_cmd_xtreg) +{ + return CALL_COMMAND_HANDLER(xtensa_cmd_xtreg_do, + target_to_xtensa(get_current_target(CMD_CTX))); +} + +/* xtregfmt <contiguous|sparse> [numgregs] */ +COMMAND_HELPER(xtensa_cmd_xtregfmt_do, struct xtensa *xtensa) +{ + if ((CMD_ARGC == 1) || (CMD_ARGC == 2)) { + if (!strcasecmp(CMD_ARGV[0], "sparse")) { + return ERROR_OK; + } else if (!strcasecmp(CMD_ARGV[0], "contiguous")) { + xtensa->regmap_contiguous = true; + if (CMD_ARGC == 2) { + unsigned int numgregs = strtoul(CMD_ARGV[1], NULL, 0); + if ((numgregs <= 0) || + ((numgregs > xtensa->total_regs_num) && + (xtensa->total_regs_num > 0))) { + LOG_ERROR("xtregfmt: if specified, numgregs (%d) must be <= numregs (%d)", + numgregs, xtensa->total_regs_num); + return ERROR_COMMAND_SYNTAX_ERROR; + } + xtensa->genpkt_regs_num = numgregs; + } + return ERROR_OK; + } + } + return ERROR_COMMAND_SYNTAX_ERROR; +} + +COMMAND_HANDLER(xtensa_cmd_xtregfmt) +{ + return CALL_COMMAND_HANDLER(xtensa_cmd_xtregfmt_do, + target_to_xtensa(get_current_target(CMD_CTX))); +} + COMMAND_HELPER(xtensa_cmd_permissive_mode_do, struct xtensa *xtensa) { return CALL_COMMAND_HANDLER(handle_command_parse_bool, @@ -2436,7 +3652,7 @@ COMMAND_HANDLER(xtensa_cmd_mask_interrupts) COMMAND_HELPER(xtensa_cmd_smpbreak_do, struct target *target) { - int res = ERROR_OK; + int res; uint32_t val = 0; if (CMD_ARGC >= 1) { @@ -2469,16 +3685,15 @@ COMMAND_HELPER(xtensa_cmd_smpbreak_do, struct target *target) } else { struct xtensa *xtensa = target_to_xtensa(target); res = xtensa_smpbreak_read(xtensa, &val); - if (res == ERROR_OK) { + if (res == ERROR_OK) command_print(CMD, "Current bits set:%s%s%s%s", (val & OCDDCR_BREAKINEN) ? " BreakIn" : "", (val & OCDDCR_BREAKOUTEN) ? " BreakOut" : "", (val & OCDDCR_RUNSTALLINEN) ? " RunStallIn" : "", (val & OCDDCR_DEBUGMODEOUTEN) ? " DebugModeOut" : "" ); - } else { + else command_print(CMD, "Failed to get smpbreak config %d", res); - } } return res; } @@ -2667,12 +3882,68 @@ COMMAND_HANDLER(xtensa_cmd_tracedump) target_to_xtensa(get_current_target(CMD_CTX)), CMD_ARGV[0]); } -const struct command_registration xtensa_command_handlers[] = { +static const struct command_registration xtensa_any_command_handlers[] = { + { + .name = "xtdef", + .handler = xtensa_cmd_xtdef, + .mode = COMMAND_CONFIG, + .help = "Configure Xtensa core type", + .usage = "<type>", + }, + { + .name = "xtopt", + .handler = xtensa_cmd_xtopt, + .mode = COMMAND_CONFIG, + .help = "Configure Xtensa core option", + .usage = "<name> <value>", + }, + { + .name = "xtmem", + .handler = xtensa_cmd_xtmem, + .mode = COMMAND_CONFIG, + .help = "Configure Xtensa memory/cache option", + .usage = "<type> [parameters]", + }, + { + .name = "xtmmu", + .handler = xtensa_cmd_xtmmu, + .mode = COMMAND_CONFIG, + .help = "Configure Xtensa MMU option", + .usage = "<NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56>", + }, + { + .name = "xtmpu", + .handler = xtensa_cmd_xtmpu, + .mode = COMMAND_CONFIG, + .help = "Configure Xtensa MPU option", + .usage = "<num FG seg> <min seg size> <lockable> <executeonly>", + }, + { + .name = "xtreg", + .handler = xtensa_cmd_xtreg, + .mode = COMMAND_CONFIG, + .help = "Configure Xtensa register", + .usage = "<regname> <regnum>", + }, + { + .name = "xtregs", + .handler = xtensa_cmd_xtreg, + .mode = COMMAND_CONFIG, + .help = "Configure number of Xtensa registers", + .usage = "<numregs>", + }, + { + .name = "xtregfmt", + .handler = xtensa_cmd_xtregfmt, + .mode = COMMAND_CONFIG, + .help = "Configure format of Xtensa register map", + .usage = "<contiguous|sparse> [numgregs]", + }, { .name = "set_permissive", .handler = xtensa_cmd_permissive_mode, .mode = COMMAND_ANY, - .help = "When set to 1, enable Xtensa permissive mode (less client-side checks)", + .help = "When set to 1, enable Xtensa permissive mode (fewer client-side checks)", .usage = "[0|1]", }, { @@ -2687,8 +3958,7 @@ const struct command_registration xtensa_command_handlers[] = { .handler = xtensa_cmd_smpbreak, .mode = COMMAND_ANY, .help = "Set the way the CPU chains OCD breaks", - .usage = - "[none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]", + .usage = "[none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]", }, { .name = "perfmon_enable", @@ -2701,8 +3971,7 @@ const struct command_registration xtensa_command_handlers[] = { .name = "perfmon_dump", .handler = xtensa_cmd_perfmon_dump, .mode = COMMAND_EXEC, - .help = - "Dump performance counter value. If no argument specified, dumps all counters.", + .help = "Dump performance counter value. If no argument specified, dumps all counters.", .usage = "[counter_id]", }, { @@ -2727,5 +3996,23 @@ const struct command_registration xtensa_command_handlers[] = { .help = "Tracing: Dump trace memory to a files. One file per core.", .usage = "<outfile>", }, + { + .name = "exe", + .handler = xtensa_cmd_exe, + .mode = COMMAND_ANY, + .help = "Xtensa stub execution", + .usage = "<ascii-encoded hexadecimal instruction bytes>", + }, + COMMAND_REGISTRATION_DONE +}; + +const struct command_registration xtensa_command_handlers[] = { + { + .name = "xtensa", + .mode = COMMAND_ANY, + .help = "Xtensa command group", + .usage = "", + .chain = xtensa_any_command_handlers, + }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/xtensa/xtensa.h b/src/target/xtensa/xtensa.h index d8b15e1..4d98f3a 100644 --- a/src/target/xtensa/xtensa.h +++ b/src/target/xtensa/xtensa.h @@ -1,20 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Generic Xtensa target * + * Copyright (C) 2020-2022 Cadence Design Systems, Inc. * * Copyright (C) 2019 Espressif Systems Ltd. * - * Author: Alexey Gerenkov <alexey@espressif.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_TARGET_XTENSA_H @@ -31,41 +20,77 @@ * Holds the interface to Xtensa cores. */ -#define XT_ISNS_SZ_MAX 3 +/* Big-endian vs. little-endian detection */ +#define XT_ISBE(X) ((X)->target->endianness == TARGET_BIG_ENDIAN) + +/* 24-bit break; BE version field-swapped then byte-swapped for use in memory R/W fns */ +#define XT_INS_BREAK_LE(S, T) (0x004000 | (((S) & 0xF) << 8) | (((T) & 0xF) << 4)) +#define XT_INS_BREAK_BE(S, T) (0x000400 | (((S) & 0xF) << 12) | ((T) & 0xF)) +#define XT_INS_BREAK(X, S, T) (XT_ISBE(X) ? XT_INS_BREAK_BE(S, T) : XT_INS_BREAK_LE(S, T)) + +/* 16-bit break; BE version field-swapped then byte-swapped for use in memory R/W fns */ +#define XT_INS_BREAKN_LE(IMM4) (0xF02D | (((IMM4) & 0xF) << 8)) +#define XT_INS_BREAKN_BE(IMM4) (0x0FD2 | (((IMM4) & 0xF) << 12)) +#define XT_INS_BREAKN(X, IMM4) (XT_ISBE(X) ? XT_INS_BREAKN_BE(IMM4) : XT_INS_BREAKN_LE(IMM4)) + +#define XT_ISNS_SZ_MAX 3 + +#define XT_PS_RING(_v_) ((uint32_t)((_v_) & 0x3) << 6) +#define XT_PS_RING_MSK (0x3 << 6) +#define XT_PS_RING_GET(_v_) (((_v_) >> 6) & 0x3) +#define XT_PS_CALLINC_MSK (0x3 << 16) +#define XT_PS_OWB_MSK (0xF << 8) +#define XT_PS_WOE_MSK BIT(18) -#define XT_PS_RING(_v_) ((uint32_t)((_v_) & 0x3) << 6) -#define XT_PS_RING_MSK (0x3 << 6) -#define XT_PS_RING_GET(_v_) (((_v_) >> 6) & 0x3) -#define XT_PS_CALLINC_MSK (0x3 << 16) -#define XT_PS_OWB_MSK (0xF << 8) +#define XT_LOCAL_MEM_REGIONS_NUM_MAX 8 -#define XT_LOCAL_MEM_REGIONS_NUM_MAX 8 +#define XT_AREGS_NUM_MAX 64 +#define XT_USER_REGS_NUM_MAX 256 -#define XT_AREGS_NUM_MAX 64 -#define XT_USER_REGS_NUM_MAX 256 +#define XT_MEM_ACCESS_NONE 0x0 +#define XT_MEM_ACCESS_READ 0x1 +#define XT_MEM_ACCESS_WRITE 0x2 + +#define XT_MAX_TIE_REG_WIDTH (512) /* TIE register file max 4096 bits */ +#define XT_QUERYPKT_RESP_MAX (XT_MAX_TIE_REG_WIDTH * 2 + 1) + +enum xtensa_qerr_e { + XT_QERR_INTERNAL = 0, + XT_QERR_FAIL, + XT_QERR_INVAL, + XT_QERR_MEM, + XT_QERR_NUM, +}; + +/* An and ARn registers potentially used as scratch regs */ +enum xtensa_ar_scratch_set_e { + XT_AR_SCRATCH_A3 = 0, + XT_AR_SCRATCH_AR3, + XT_AR_SCRATCH_A4, + XT_AR_SCRATCH_AR4, + XT_AR_SCRATCH_NUM +}; -#define XT_MEM_ACCESS_NONE 0x0 -#define XT_MEM_ACCESS_READ 0x1 -#define XT_MEM_ACCESS_WRITE 0x2 +struct xtensa_keyval_info_s { + char *chrval; + int intval; +}; -enum xtensa_mem_err_detect { - XT_MEM_ERR_DETECT_NONE, - XT_MEM_ERR_DETECT_PARITY, - XT_MEM_ERR_DETECT_ECC, +enum xtensa_type { + XT_UNDEF = 0, + XT_LX, }; struct xtensa_cache_config { uint8_t way_count; - uint8_t line_size; - uint16_t size; - bool writeback; - enum xtensa_mem_err_detect mem_err_check; + uint32_t line_size; + uint32_t size; + int writeback; }; struct xtensa_local_mem_region_config { target_addr_t base; uint32_t size; - enum xtensa_mem_err_detect mem_err_check; int access; }; @@ -78,13 +103,14 @@ struct xtensa_mmu_config { bool enabled; uint8_t itlb_entries_count; uint8_t dtlb_entries_count; - bool ivarway56; - bool dvarway56; }; -struct xtensa_exception_config { +struct xtensa_mpu_config { bool enabled; - uint8_t depc_num; + uint8_t nfgseg; + uint32_t minsegsize; + bool lockable; + bool execonly; }; struct xtensa_irq_config { @@ -94,8 +120,8 @@ struct xtensa_irq_config { struct xtensa_high_prio_irq_config { bool enabled; + uint8_t level_num; uint8_t excm_level; - uint8_t nmi_num; }; struct xtensa_debug_config { @@ -103,7 +129,7 @@ struct xtensa_debug_config { uint8_t irq_level; uint8_t ibreaks_num; uint8_t dbreaks_num; - uint8_t icount_sz; + uint8_t perfcount_num; }; struct xtensa_tracing_config { @@ -112,48 +138,26 @@ struct xtensa_tracing_config { bool reversed_mem_access; }; -struct xtensa_timer_irq_config { - bool enabled; - uint8_t comp_num; -}; - struct xtensa_config { - bool density; + enum xtensa_type core_type; uint8_t aregs_num; bool windowed; bool coproc; - bool fp_coproc; - bool loop; - uint8_t miscregs_num; - bool threadptr; - bool boolean; - bool cond_store; - bool ext_l32r; - bool mac16; - bool reloc_vec; - bool proc_id; - bool mem_err_check; - uint16_t user_regs_num; - const struct xtensa_user_reg_desc *user_regs; - int (*fetch_user_regs)(struct target *target); - int (*queue_write_dirty_user_regs)(struct target *target); + bool exceptions; + struct xtensa_irq_config irq; + struct xtensa_high_prio_irq_config high_irq; + struct xtensa_mmu_config mmu; + struct xtensa_mpu_config mpu; + struct xtensa_debug_config debug; + struct xtensa_tracing_config trace; struct xtensa_cache_config icache; struct xtensa_cache_config dcache; struct xtensa_local_mem_config irom; struct xtensa_local_mem_config iram; struct xtensa_local_mem_config drom; struct xtensa_local_mem_config dram; - struct xtensa_local_mem_config uram; - struct xtensa_local_mem_config xlmi; - struct xtensa_mmu_config mmu; - struct xtensa_exception_config exc; - struct xtensa_irq_config irq; - struct xtensa_high_prio_irq_config high_irq; - struct xtensa_timer_irq_config tim_irq; - struct xtensa_debug_config debug; - struct xtensa_tracing_config trace; - unsigned int gdb_general_regs_num; - const unsigned int *gdb_regs_mapping; + struct xtensa_local_mem_config sram; + struct xtensa_local_mem_config srom; }; typedef uint32_t xtensa_insn_t; @@ -187,13 +191,26 @@ struct xtensa_sw_breakpoint { */ struct xtensa { unsigned int common_magic; - const struct xtensa_config *core_config; + struct xtensa_chip_common *xtensa_chip; + struct xtensa_config *core_config; struct xtensa_debug_module dbg_mod; struct reg_cache *core_cache; - unsigned int regs_num; + unsigned int total_regs_num; + unsigned int core_regs_num; + bool regmap_contiguous; + unsigned int genpkt_regs_num; + struct xtensa_reg_desc **contiguous_regs_desc; + struct reg **contiguous_regs_list; + /* Per-config Xtensa registers as specified via "xtreg" in xtensa-core*.cfg */ + struct xtensa_reg_desc *optregs; + unsigned int num_optregs; + struct reg *empty_regs; + char qpkt_resp[XT_QUERYPKT_RESP_MAX]; /* An array of pointers to buffers to backup registers' values while algo is run on target. * Size is 'regs_num'. */ void **algo_context_backup; + unsigned int eps_dbglevel_idx; + unsigned int dbregs_num; struct target *target; bool reset_asserted; enum xtensa_stepping_isr_mode stepping_isr_mode; @@ -204,11 +221,18 @@ struct xtensa { bool permissive_mode; /* bypass memory checks */ bool suppress_dsr_errors; uint32_t smp_break; + uint32_t spill_loc; + unsigned int spill_bytes; + uint8_t *spill_buf; + int8_t probe_lsddr32p; /* Sometimes debug module's 'powered' bit is cleared after reset, but get set after some * time.This is the number of polling periods after which core is considered to be powered * off (marked as unexamined) if the bit retains to be cleared (e.g. if core is disabled by * SW running on target).*/ uint8_t come_online_probes_num; + bool proc_syscall; + bool halt_request; + struct xtensa_keyval_info_s scratch_ars[XT_AR_SCRATCH_NUM]; bool regs_fetched; /* true after first register fetch completed successfully */ }; @@ -222,7 +246,6 @@ static inline struct xtensa *target_to_xtensa(struct target *target) int xtensa_init_arch_info(struct target *target, struct xtensa *xtensa, - const struct xtensa_config *cfg, const struct xtensa_debug_module_config *dm_cfg); int xtensa_target_init(struct command_context *cmd_ctx, struct target *target); void xtensa_target_deinit(struct target *target); @@ -245,11 +268,41 @@ static inline bool xtensa_data_addr_valid(struct target *target, uint32_t addr) return true; if (xtensa_addr_in_mem(&xtensa->core_config->dram, addr)) return true; - if (xtensa_addr_in_mem(&xtensa->core_config->uram, addr)) + if (xtensa_addr_in_mem(&xtensa->core_config->sram, addr)) return true; return false; } +static inline int xtensa_queue_dbg_reg_read(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint8_t *data) +{ + struct xtensa_debug_module *dm = &xtensa->dbg_mod; + + if (!xtensa->core_config->trace.enabled && + (reg <= XDMREG_MEMADDREND || (reg >= XDMREG_PMG && reg <= XDMREG_PMSTAT7))) { + LOG_ERROR("Can not access %u reg when Trace Port option disabled!", reg); + return ERROR_FAIL; + } + return dm->dbg_ops->queue_reg_read(dm, reg, data); +} + +static inline int xtensa_queue_dbg_reg_write(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint32_t data) +{ + struct xtensa_debug_module *dm = &xtensa->dbg_mod; + + if (!xtensa->core_config->trace.enabled && + (reg <= XDMREG_MEMADDREND || (reg >= XDMREG_PMG && reg <= XDMREG_PMSTAT7))) { + LOG_ERROR("Can not access %u reg when Trace Port option disabled!", reg); + return ERROR_FAIL; + } + return dm->dbg_ops->queue_reg_write(dm, reg, data); +} + +static inline int xtensa_core_status_clear(struct target *target, uint32_t bits) +{ + struct xtensa *xtensa = target_to_xtensa(target); + return xtensa_dm_core_status_clear(&xtensa->dbg_mod, bits); +} + int xtensa_core_status_check(struct target *target); int xtensa_examine(struct target *target); @@ -260,11 +313,15 @@ int xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set); int xtensa_smpbreak_read(struct xtensa *xtensa, uint32_t *val); xtensa_reg_val_t xtensa_reg_get(struct target *target, enum xtensa_reg_id reg_id); void xtensa_reg_set(struct target *target, enum xtensa_reg_id reg_id, xtensa_reg_val_t value); +void xtensa_reg_set_deep_relgen(struct target *target, enum xtensa_reg_id a_idx, xtensa_reg_val_t value); int xtensa_fetch_all_regs(struct target *target); int xtensa_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class); +uint32_t xtensa_cause_get(struct target *target); +void xtensa_cause_clear(struct target *target); +void xtensa_cause_reset(struct target *target); int xtensa_poll(struct target *target); void xtensa_on_poll(struct target *target); int xtensa_halt(struct target *target); @@ -293,17 +350,31 @@ int xtensa_write_buffer(struct target *target, target_addr_t address, uint32_t c int xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum); int xtensa_assert_reset(struct target *target); int xtensa_deassert_reset(struct target *target); +int xtensa_soft_reset_halt(struct target *target); int xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint); int xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint); int xtensa_watchpoint_add(struct target *target, struct watchpoint *watchpoint); int xtensa_watchpoint_remove(struct target *target, struct watchpoint *watchpoint); void xtensa_set_permissive_mode(struct target *target, bool state); -int xtensa_fetch_user_regs_u32(struct target *target); -int xtensa_queue_write_dirty_user_regs_u32(struct target *target); const char *xtensa_get_gdb_arch(struct target *target); +int xtensa_gdb_query_custom(struct target *target, const char *packet, char **response_p); + +COMMAND_HELPER(xtensa_cmd_xtdef_do, struct xtensa *xtensa); +COMMAND_HELPER(xtensa_cmd_xtopt_do, struct xtensa *xtensa); +COMMAND_HELPER(xtensa_cmd_xtmem_do, struct xtensa *xtensa); +COMMAND_HELPER(xtensa_cmd_xtmpu_do, struct xtensa *xtensa); +COMMAND_HELPER(xtensa_cmd_xtmmu_do, struct xtensa *xtensa); +COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa); +COMMAND_HELPER(xtensa_cmd_xtregfmt_do, struct xtensa *xtensa); +COMMAND_HELPER(xtensa_cmd_permissive_mode_do, struct xtensa *xtensa); +COMMAND_HELPER(xtensa_cmd_mask_interrupts_do, struct xtensa *xtensa); +COMMAND_HELPER(xtensa_cmd_smpbreak_do, struct target *target); +COMMAND_HELPER(xtensa_cmd_perfmon_dump_do, struct xtensa *xtensa); +COMMAND_HELPER(xtensa_cmd_perfmon_enable_do, struct xtensa *xtensa); +COMMAND_HELPER(xtensa_cmd_tracestart_do, struct xtensa *xtensa); +COMMAND_HELPER(xtensa_cmd_tracestop_do, struct xtensa *xtensa); +COMMAND_HELPER(xtensa_cmd_tracedump_do, struct xtensa *xtensa, const char *fname); -extern const struct reg_arch_type xtensa_user_reg_u32_type; -extern const struct reg_arch_type xtensa_user_reg_u128_type; extern const struct command_registration xtensa_command_handlers[]; #endif /* OPENOCD_TARGET_XTENSA_H */ diff --git a/src/target/xtensa/xtensa_chip.c b/src/target/xtensa/xtensa_chip.c new file mode 100644 index 0000000..c62992f --- /dev/null +++ b/src/target/xtensa/xtensa_chip.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * Xtensa Chip-level Target Support for OpenOCD * + * Copyright (C) 2020-2022 Cadence Design Systems, Inc. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "assert.h" +#include <target/target.h> +#include <target/target_type.h> +#include <target/arm_adi_v5.h> +#include <rtos/rtos.h> +#include "xtensa_chip.h" + +int xtensa_chip_init_arch_info(struct target *target, void *arch_info, + struct xtensa_debug_module_config *dm_cfg) +{ + struct xtensa_chip_common *xtensa_chip = (struct xtensa_chip_common *)arch_info; + int ret = xtensa_init_arch_info(target, &xtensa_chip->xtensa, dm_cfg); + if (ret != ERROR_OK) + return ret; + /* All xtensa target structures point back to original xtensa_chip */ + xtensa_chip->xtensa.xtensa_chip = arch_info; + return ERROR_OK; +} + +int xtensa_chip_target_init(struct command_context *cmd_ctx, struct target *target) +{ + return xtensa_target_init(cmd_ctx, target); +} + +int xtensa_chip_arch_state(struct target *target) +{ + return ERROR_OK; +} + +static int xtensa_chip_poll(struct target *target) +{ + enum target_state old_state = target->state; + int ret = xtensa_poll(target); + + if (old_state != TARGET_HALTED && target->state == TARGET_HALTED) { + /*Call any event callbacks that are applicable */ + if (old_state == TARGET_DEBUG_RUNNING) + target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); + else + target_call_event_callbacks(target, TARGET_EVENT_HALTED); + } + + return ret; +} + +static int xtensa_chip_virt2phys(struct target *target, + target_addr_t virtual, target_addr_t *physical) +{ + if (physical) { + *physical = virtual; + return ERROR_OK; + } + return ERROR_FAIL; +} + +static const struct xtensa_debug_ops xtensa_chip_dm_dbg_ops = { + .queue_enable = xtensa_dm_queue_enable, + .queue_reg_read = xtensa_dm_queue_reg_read, + .queue_reg_write = xtensa_dm_queue_reg_write +}; + +static const struct xtensa_power_ops xtensa_chip_dm_pwr_ops = { + .queue_reg_read = xtensa_dm_queue_pwr_reg_read, + .queue_reg_write = xtensa_dm_queue_pwr_reg_write +}; + +static int xtensa_chip_target_create(struct target *target, Jim_Interp *interp) +{ + struct xtensa_debug_module_config xtensa_chip_dm_cfg = { + .dbg_ops = &xtensa_chip_dm_dbg_ops, + .pwr_ops = &xtensa_chip_dm_pwr_ops, + .tap = NULL, + .queue_tdi_idle = NULL, + .queue_tdi_idle_arg = NULL, + .dap = NULL, + .debug_ap = NULL, + .debug_apsel = DP_APSEL_INVALID, + .ap_offset = 0, + }; + + struct adiv5_private_config *pc = target->private_config; + if (adiv5_verify_config(pc) == ERROR_OK) { + xtensa_chip_dm_cfg.dap = pc->dap; + xtensa_chip_dm_cfg.debug_apsel = pc->ap_num; + xtensa_chip_dm_cfg.ap_offset = target->dbgbase; + LOG_DEBUG("DAP: ap_num %" PRId64 " DAP %p\n", pc->ap_num, pc->dap); + } else { + xtensa_chip_dm_cfg.tap = target->tap; + LOG_DEBUG("JTAG: %s:%s pos %d", target->tap->chip, target->tap->tapname, + target->tap->abs_chain_position); + } + + struct xtensa_chip_common *xtensa_chip = calloc(1, sizeof(struct xtensa_chip_common)); + if (!xtensa_chip) { + LOG_ERROR("Failed to alloc chip-level memory!"); + return ERROR_FAIL; + } + + int ret = xtensa_chip_init_arch_info(target, xtensa_chip, &xtensa_chip_dm_cfg); + if (ret != ERROR_OK) { + LOG_ERROR("Failed to init arch info!"); + free(xtensa_chip); + return ret; + } + + /*Assume running target. If different, the first poll will fix this. */ + target->state = TARGET_RUNNING; + target->debug_reason = DBG_REASON_NOTHALTED; + return ERROR_OK; +} + +static void xtensa_chip_target_deinit(struct target *target) +{ + struct xtensa *xtensa = target_to_xtensa(target); + xtensa_target_deinit(target); + free(xtensa->xtensa_chip); +} + +static int xtensa_chip_examine(struct target *target) +{ + struct xtensa *xtensa = target_to_xtensa(target); + int retval = xtensa_dm_examine(&xtensa->dbg_mod); + if (retval == ERROR_OK) + retval = xtensa_examine(target); + return retval; +} + +static int xtensa_chip_jim_configure(struct target *target, struct jim_getopt_info *goi) +{ + static bool dap_configured; + int ret = adiv5_jim_configure(target, goi); + if (ret == JIM_OK) { + LOG_DEBUG("xtensa '-dap' target option found"); + dap_configured = true; + } + if (!dap_configured) { + LOG_DEBUG("xtensa '-dap' target option not yet found, assuming JTAG..."); + target->has_dap = false; + } + return ret; +} + +/** Methods for generic example of Xtensa-based chip-level targets. */ +struct target_type xtensa_chip_target = { + .name = "xtensa", + + .poll = xtensa_chip_poll, + .arch_state = xtensa_chip_arch_state, + + .halt = xtensa_halt, + .resume = xtensa_resume, + .step = xtensa_step, + + .assert_reset = xtensa_assert_reset, + .deassert_reset = xtensa_deassert_reset, + .soft_reset_halt = xtensa_soft_reset_halt, + + .virt2phys = xtensa_chip_virt2phys, + .mmu = xtensa_mmu_is_enabled, + .read_memory = xtensa_read_memory, + .write_memory = xtensa_write_memory, + + .read_buffer = xtensa_read_buffer, + .write_buffer = xtensa_write_buffer, + + .checksum_memory = xtensa_checksum_memory, + + .get_gdb_reg_list = xtensa_get_gdb_reg_list, + + .add_breakpoint = xtensa_breakpoint_add, + .remove_breakpoint = xtensa_breakpoint_remove, + + .add_watchpoint = xtensa_watchpoint_add, + .remove_watchpoint = xtensa_watchpoint_remove, + + .target_create = xtensa_chip_target_create, + .target_jim_configure = xtensa_chip_jim_configure, + .init_target = xtensa_chip_target_init, + .examine = xtensa_chip_examine, + .deinit_target = xtensa_chip_target_deinit, + + .gdb_query_custom = xtensa_gdb_query_custom, + + .commands = xtensa_command_handlers, +}; diff --git a/src/target/xtensa/xtensa_chip.h b/src/target/xtensa/xtensa_chip.h new file mode 100644 index 0000000..5200deb --- /dev/null +++ b/src/target/xtensa/xtensa_chip.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/*************************************************************************** + * Xtensa Chip-level Target Support for OpenOCD * + * Copyright (C) 2020-2022 Cadence Design Systems, Inc. * + ***************************************************************************/ + +#ifndef OPENOCD_TARGET_XTENSA_CHIP_H +#define OPENOCD_TARGET_XTENSA_CHIP_H + +#include <target/target.h> +#include "xtensa.h" +#include "xtensa_debug_module.h" + +struct xtensa_chip_common { + struct xtensa xtensa; + /* Chip-specific extensions can be added here */ +}; + +static inline struct xtensa_chip_common *target_to_xtensa_chip(struct target *target) +{ + return container_of(target->arch_info, struct xtensa_chip_common, xtensa); +} + +int xtensa_chip_init_arch_info(struct target *target, void *arch_info, + struct xtensa_debug_module_config *dm_cfg); +int xtensa_chip_target_init(struct command_context *cmd_ctx, struct target *target); +int xtensa_chip_arch_state(struct target *target); +void xtensa_chip_queue_tdi_idle(struct target *target); +void xtensa_chip_on_reset(struct target *target); +bool xtensa_chip_on_halt(struct target *target); +void xtensa_chip_on_poll(struct target *target); + +#endif /* OPENOCD_TARGET_XTENSA_CHIP_H */ diff --git a/src/target/xtensa/xtensa_debug_module.c b/src/target/xtensa/xtensa_debug_module.c index c6959ae..31d7a94 100644 --- a/src/target/xtensa/xtensa_debug_module.c +++ b/src/target/xtensa/xtensa_debug_module.c @@ -1,25 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** - * Generic Xtensa debug module API for OpenOCD * + * Xtensa Debug Module (XDM) Support for OpenOCD * + * Copyright (C) 2020-2022 Cadence Design Systems, Inc. * * Copyright (C) 2019 Espressif Systems Ltd. * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include <config.h> #endif +#include <helper/align.h> #include "xtensa_debug_module.h" #define TAPINS_PWRCTL 0x08 @@ -35,11 +26,18 @@ #define TAPINS_IDCODE_LEN 32 #define TAPINS_BYPASS_LEN 1 +/* Table of power register offsets for APB space */ +static const struct xtensa_dm_pwr_reg_offsets xdm_pwr_regs[XDMREG_PWRNUM] = + XTENSA_DM_PWR_REG_OFFSETS; + +/* Table of debug register offsets for Nexus and APB space */ +static const struct xtensa_dm_reg_offsets xdm_regs[XDMREG_NUM] = + XTENSA_DM_REG_OFFSETS; static void xtensa_dm_add_set_ir(struct xtensa_debug_module *dm, uint8_t value) { struct scan_field field; - uint8_t t[4] = { 0 }; + uint8_t t[4] = { 0, 0, 0, 0 }; memset(&field, 0, sizeof(field)); field.num_bits = dm->tap->ir_length; @@ -67,87 +65,167 @@ int xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_mod { if (!dm || !cfg) return ERROR_FAIL; + if (!IS_ALIGNED(cfg->ap_offset, XTENSA_DM_APB_ALIGN)) { + LOG_ERROR("Xtensa DM APB offset must be aligned to a %dKB multiple", + XTENSA_DM_APB_ALIGN / 1024); + return ERROR_FAIL; + } dm->pwr_ops = cfg->pwr_ops; dm->dbg_ops = cfg->dbg_ops; dm->tap = cfg->tap; dm->queue_tdi_idle = cfg->queue_tdi_idle; dm->queue_tdi_idle_arg = cfg->queue_tdi_idle_arg; + dm->dap = cfg->dap; + dm->debug_ap = cfg->debug_ap; + dm->debug_apsel = cfg->debug_apsel; + dm->ap_offset = cfg->ap_offset; return ERROR_OK; } -int xtensa_dm_queue_enable(struct xtensa_debug_module *dm) +void xtensa_dm_deinit(struct xtensa_debug_module *dm) { - return dm->dbg_ops->queue_reg_write(dm, NARADR_DCRSET, OCDDCR_ENABLEOCD); + if (dm->debug_ap) { + dap_put_ap(dm->debug_ap); + dm->debug_ap = NULL; + } } -int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *value) +int xtensa_dm_poll(struct xtensa_debug_module *dm) { - uint8_t regdata = (reg << 1) | 0; - uint8_t dummy[4] = { 0, 0, 0, 0 }; + /* Check if debug_ap is available to prevent segmentation fault. + * If the re-examination after an error does not find a MEM-AP + * (e.g. the target stopped communicating), debug_ap pointer + * can suddenly become NULL. + */ + return (!dm || (dm->dap && !dm->debug_ap)) ? ERROR_FAIL : ERROR_OK; +} + +int xtensa_dm_examine(struct xtensa_debug_module *dm) +{ + struct adiv5_dap *swjdp = dm->dap; + int retval = ERROR_OK; + + if (swjdp) { + LOG_DEBUG("DM examine: DAP AP select %d", dm->debug_apsel); + if (dm->debug_ap) { + dap_put_ap(dm->debug_ap); + dm->debug_ap = NULL; + } + if (dm->debug_apsel == DP_APSEL_INVALID) { + LOG_DEBUG("DM examine: search for APB-type MEM-AP..."); + /* TODO: Determine whether AP_TYPE_AXI_AP APs can be supported... */ + retval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &dm->debug_ap); + if (retval != ERROR_OK) { + LOG_ERROR("Could not find MEM-AP to control the core"); + return retval; + } + } else { + dm->debug_ap = dap_get_ap(swjdp, dm->debug_apsel); + } + + /* TODO: Allow a user-specified AP instead of relying on AP_TYPE_APB_AP */ + dm->debug_apsel = dm->debug_ap->ap_num; + LOG_DEBUG("DM examine: Setting apsel to %d", dm->debug_apsel); + + /* Leave (only) generic DAP stuff for debugport_init(); */ + dm->debug_ap->memaccess_tck = 8; + + retval = mem_ap_init(dm->debug_ap); + if (retval != ERROR_OK) { + LOG_ERROR("MEM-AP init failed: %d", retval); + return retval; + } + + /* TODO: how to set autoincrement range? Hard-code it to 1024 bytes for now */ + dm->debug_ap->tar_autoincr_block = (1 << 10); + } + + return retval; +} - if (reg > NARADR_MAX) { +int xtensa_dm_queue_enable(struct xtensa_debug_module *dm) +{ + return dm->dbg_ops->queue_reg_write(dm, XDMREG_DCRSET, OCDDCR_ENABLEOCD); +} + +int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *value) +{ + if (reg >= XDMREG_NUM) { LOG_ERROR("Invalid DBG reg ID %d!", reg); return ERROR_FAIL; } + if (dm->dap) + /* NOTE: Future optimization: mem_ap_read_u32() offers higher performance with + * queued reads, but requires an API change to pass value as a 32-bit pointer. + */ + return mem_ap_read_buf(dm->debug_ap, value, 4, 1, xdm_regs[reg].apb + dm->ap_offset); + uint8_t regdata = (xdm_regs[reg].nar << 1) | 0; + uint8_t dummy[4] = { 0, 0, 0, 0 }; xtensa_dm_add_set_ir(dm, TAPINS_NARSEL); xtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_ADRLEN, ®data, NULL, TAP_IDLE); xtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_DATALEN, dummy, value, TAP_IDLE); return ERROR_OK; } -int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint32_t value) +int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t value) { - uint8_t regdata = (reg << 1) | 1; - uint8_t valdata[] = { value, value >> 8, value >> 16, value >> 24 }; - - if (reg > NARADR_MAX) { + if (reg >= XDMREG_NUM) { LOG_ERROR("Invalid DBG reg ID %d!", reg); return ERROR_FAIL; } + if (dm->dap) + return mem_ap_write_u32(dm->debug_ap, xdm_regs[reg].apb + dm->ap_offset, value); + uint8_t regdata = (xdm_regs[reg].nar << 1) | 1; + uint8_t valdata[] = { value, value >> 8, value >> 16, value >> 24 }; xtensa_dm_add_set_ir(dm, TAPINS_NARSEL); xtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_ADRLEN, ®data, NULL, TAP_IDLE); xtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_DATALEN, valdata, NULL, TAP_IDLE); return ERROR_OK; } -int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data, uint8_t clear) +int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm, + enum xtensa_dm_pwr_reg reg, + uint8_t *data, + uint32_t clear) { - uint8_t value_clr = clear; - uint8_t tap_insn; - int tap_insn_sz; - - if (reg == DMREG_PWRCTL) { - tap_insn = TAPINS_PWRCTL; - tap_insn_sz = TAPINS_PWRCTL_LEN; - } else if (reg == DMREG_PWRSTAT) { - tap_insn = TAPINS_PWRSTAT; - tap_insn_sz = TAPINS_PWRSTAT_LEN; - } else { + if (reg >= XDMREG_PWRNUM) { LOG_ERROR("Invalid PWR reg ID %d!", reg); return ERROR_FAIL; } + if (dm->dap) { + /* NOTE: Future optimization: mem_ap_read_u32() offers higher performance with + * queued reads, but requires an API change to pass value as a 32-bit pointer. + */ + uint32_t apbreg = xdm_pwr_regs[reg].apb + dm->ap_offset; + int retval = mem_ap_read_buf(dm->debug_ap, data, 4, 1, apbreg); + if (retval == ERROR_OK) + retval = mem_ap_write_u32(dm->debug_ap, apbreg, clear); + return retval; + } + uint8_t value_clr = (uint8_t)clear; + uint8_t tap_insn = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL : TAPINS_PWRSTAT; + int tap_insn_sz = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL_LEN : TAPINS_PWRSTAT_LEN; xtensa_dm_add_set_ir(dm, tap_insn); xtensa_dm_add_dr_scan(dm, tap_insn_sz, &value_clr, data, TAP_IDLE); return ERROR_OK; } -int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data) +int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm, + enum xtensa_dm_pwr_reg reg, + uint32_t data) { - uint8_t value = data; - uint8_t tap_insn; - int tap_insn_sz; - - if (reg == DMREG_PWRCTL) { - tap_insn = TAPINS_PWRCTL; - tap_insn_sz = TAPINS_PWRCTL_LEN; - } else if (reg == DMREG_PWRSTAT) { - tap_insn = TAPINS_PWRSTAT; - tap_insn_sz = TAPINS_PWRSTAT_LEN; - } else { + if (reg >= XDMREG_PWRNUM) { LOG_ERROR("Invalid PWR reg ID %d!", reg); return ERROR_FAIL; } + if (dm->dap) { + uint32_t apbreg = xdm_pwr_regs[reg].apb + dm->ap_offset; + return mem_ap_write_u32(dm->debug_ap, apbreg, data); + } + uint8_t tap_insn = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL : TAPINS_PWRSTAT; + int tap_insn_sz = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL_LEN : TAPINS_PWRSTAT_LEN; + uint8_t value = (uint8_t)data; xtensa_dm_add_set_ir(dm, tap_insn); xtensa_dm_add_dr_scan(dm, tap_insn_sz, &value, NULL, TAP_IDLE); return ERROR_OK; @@ -157,9 +235,9 @@ int xtensa_dm_device_id_read(struct xtensa_debug_module *dm) { uint8_t id_buf[sizeof(uint32_t)]; - dm->dbg_ops->queue_reg_read(dm, NARADR_OCDID, id_buf); + dm->dbg_ops->queue_reg_read(dm, XDMREG_OCDID, id_buf); xtensa_dm_queue_tdi_idle(dm); - int res = jtag_execute_queue(); + int res = xtensa_dm_queue_execute(dm); if (res != ERROR_OK) return res; dm->device_id = buf_get_u32(id_buf, 0, 32); @@ -168,16 +246,22 @@ int xtensa_dm_device_id_read(struct xtensa_debug_module *dm) int xtensa_dm_power_status_read(struct xtensa_debug_module *dm, uint32_t clear) { - /* uint8_t id_buf[sizeof(uint32_t)]; */ + uint8_t stat_buf[sizeof(uint32_t)] = { 0, 0, 0, 0 }; + uint8_t stath_buf[sizeof(uint32_t)] = { 0, 0, 0, 0 }; /* TODO: JTAG does not work when PWRCTL_JTAGDEBUGUSE is not set. - * It is set in xtensa_examine(), need to move reading of NARADR_OCDID out of this function */ - /* dm->dbg_ops->queue_reg_read(dm, NARADR_OCDID, id_buf); + * It is set in xtensa_examine(), need to move reading of XDMREG_OCDID out of this function */ + /* dm->dbg_ops->queue_reg_read(dm, XDMREG_OCDID, id_buf); *Read reset state */ - dm->pwr_ops->queue_reg_read(dm, DMREG_PWRSTAT, &dm->power_status.stat, clear); - dm->pwr_ops->queue_reg_read(dm, DMREG_PWRSTAT, &dm->power_status.stath, clear); + dm->pwr_ops->queue_reg_read(dm, XDMREG_PWRSTAT, stat_buf, clear); + dm->pwr_ops->queue_reg_read(dm, XDMREG_PWRSTAT, stath_buf, clear); xtensa_dm_queue_tdi_idle(dm); - return jtag_execute_queue(); + int res = xtensa_dm_queue_execute(dm); + if (res != ERROR_OK) + return res; + dm->power_status.stat = buf_get_u32(stat_buf, 0, 32); + dm->power_status.stath = buf_get_u32(stath_buf, 0, 32); + return res; } int xtensa_dm_core_status_read(struct xtensa_debug_module *dm) @@ -185,9 +269,9 @@ int xtensa_dm_core_status_read(struct xtensa_debug_module *dm) uint8_t dsr_buf[sizeof(uint32_t)]; xtensa_dm_queue_enable(dm); - dm->dbg_ops->queue_reg_read(dm, NARADR_DSR, dsr_buf); + dm->dbg_ops->queue_reg_read(dm, XDMREG_DSR, dsr_buf); xtensa_dm_queue_tdi_idle(dm); - int res = jtag_execute_queue(); + int res = xtensa_dm_queue_execute(dm); if (res != ERROR_OK) return res; dm->core_status.dsr = buf_get_u32(dsr_buf, 0, 32); @@ -196,37 +280,37 @@ int xtensa_dm_core_status_read(struct xtensa_debug_module *dm) int xtensa_dm_core_status_clear(struct xtensa_debug_module *dm, xtensa_dsr_t bits) { - dm->dbg_ops->queue_reg_write(dm, NARADR_DSR, bits); + dm->dbg_ops->queue_reg_write(dm, XDMREG_DSR, bits); xtensa_dm_queue_tdi_idle(dm); - return jtag_execute_queue(); + return xtensa_dm_queue_execute(dm); } int xtensa_dm_trace_start(struct xtensa_debug_module *dm, struct xtensa_trace_start_config *cfg) { /*Turn off trace unit so we can start a new trace. */ - dm->dbg_ops->queue_reg_write(dm, NARADR_TRAXCTRL, 0); + dm->dbg_ops->queue_reg_write(dm, XDMREG_TRAXCTRL, 0); xtensa_dm_queue_tdi_idle(dm); - int res = jtag_execute_queue(); + int res = xtensa_dm_queue_execute(dm); if (res != ERROR_OK) return res; /*Set up parameters */ - dm->dbg_ops->queue_reg_write(dm, NARADR_TRAXADDR, 0); + dm->dbg_ops->queue_reg_write(dm, XDMREG_TRAXADDR, 0); if (cfg->stopmask != XTENSA_STOPMASK_DISABLED) { - dm->dbg_ops->queue_reg_write(dm, NARADR_PCMATCHCTRL, + dm->dbg_ops->queue_reg_write(dm, XDMREG_PCMATCHCTRL, (cfg->stopmask << PCMATCHCTRL_PCML_SHIFT)); - dm->dbg_ops->queue_reg_write(dm, NARADR_TRIGGERPC, cfg->stoppc); + dm->dbg_ops->queue_reg_write(dm, XDMREG_TRIGGERPC, cfg->stoppc); } - dm->dbg_ops->queue_reg_write(dm, NARADR_DELAYCNT, cfg->after); + dm->dbg_ops->queue_reg_write(dm, XDMREG_DELAYCNT, cfg->after); /*Options are mostly hardcoded for now. ToDo: make this more configurable. */ dm->dbg_ops->queue_reg_write( dm, - NARADR_TRAXCTRL, + XDMREG_TRAXCTRL, TRAXCTRL_TREN | ((cfg->stopmask != XTENSA_STOPMASK_DISABLED) ? TRAXCTRL_PCMEN : 0) | TRAXCTRL_TMEN | (cfg->after_is_words ? 0 : TRAXCTRL_CNTU) | (0 << TRAXCTRL_SMPER_SHIFT) | TRAXCTRL_PTOWS); xtensa_dm_queue_tdi_idle(dm); - return jtag_execute_queue(); + return xtensa_dm_queue_execute(dm); } int xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable) @@ -235,9 +319,9 @@ int xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable) uint32_t traxctl; struct xtensa_trace_status trace_status; - dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXCTRL, traxctl_buf); + dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXCTRL, traxctl_buf); xtensa_dm_queue_tdi_idle(dm); - int res = jtag_execute_queue(); + int res = xtensa_dm_queue_execute(dm); if (res != ERROR_OK) return res; traxctl = buf_get_u32(traxctl_buf, 0, 32); @@ -245,9 +329,9 @@ int xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable) if (!pto_enable) traxctl &= ~(TRAXCTRL_PTOWS | TRAXCTRL_PTOWT); - dm->dbg_ops->queue_reg_write(dm, NARADR_TRAXCTRL, traxctl | TRAXCTRL_TRSTP); + dm->dbg_ops->queue_reg_write(dm, XDMREG_TRAXCTRL, traxctl | TRAXCTRL_TRSTP); xtensa_dm_queue_tdi_idle(dm); - res = jtag_execute_queue(); + res = xtensa_dm_queue_execute(dm); if (res != ERROR_OK) return res; @@ -267,9 +351,9 @@ int xtensa_dm_trace_status_read(struct xtensa_debug_module *dm, struct xtensa_tr { uint8_t traxstat_buf[sizeof(uint32_t)]; - dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXSTAT, traxstat_buf); + dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXSTAT, traxstat_buf); xtensa_dm_queue_tdi_idle(dm); - int res = jtag_execute_queue(); + int res = xtensa_dm_queue_execute(dm); if (res == ERROR_OK && status) status->stat = buf_get_u32(traxstat_buf, 0, 32); return res; @@ -285,12 +369,12 @@ int xtensa_dm_trace_config_read(struct xtensa_debug_module *dm, struct xtensa_tr if (!config) return ERROR_FAIL; - dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXCTRL, traxctl_buf); - dm->dbg_ops->queue_reg_read(dm, NARADR_MEMADDRSTART, memadrstart_buf); - dm->dbg_ops->queue_reg_read(dm, NARADR_MEMADDREND, memadrend_buf); - dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXADDR, adr_buf); + dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXCTRL, traxctl_buf); + dm->dbg_ops->queue_reg_read(dm, XDMREG_MEMADDRSTART, memadrstart_buf); + dm->dbg_ops->queue_reg_read(dm, XDMREG_MEMADDREND, memadrend_buf); + dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXADDR, adr_buf); xtensa_dm_queue_tdi_idle(dm); - int res = jtag_execute_queue(); + int res = xtensa_dm_queue_execute(dm); if (res == ERROR_OK) { config->ctrl = buf_get_u32(traxctl_buf, 0, 32); config->memaddr_start = buf_get_u32(memadrstart_buf, 0, 32); @@ -306,9 +390,9 @@ int xtensa_dm_trace_data_read(struct xtensa_debug_module *dm, uint8_t *dest, uin return ERROR_FAIL; for (unsigned int i = 0; i < size / 4; i++) - dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXDATA, &dest[i * 4]); + dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXDATA, &dest[i * 4]); xtensa_dm_queue_tdi_idle(dm); - return jtag_execute_queue(); + return xtensa_dm_queue_execute(dm); } int xtensa_dm_perfmon_enable(struct xtensa_debug_module *dm, int counter_id, @@ -324,13 +408,13 @@ int xtensa_dm_perfmon_enable(struct xtensa_debug_module *dm, int counter_id, (config->kernelcnt << 3); /* enable performance monitor */ - dm->dbg_ops->queue_reg_write(dm, NARADR_PMG, 0x1); + dm->dbg_ops->queue_reg_write(dm, XDMREG_PMG, 0x1); /* reset counter */ - dm->dbg_ops->queue_reg_write(dm, NARADR_PM0 + counter_id, 0); - dm->dbg_ops->queue_reg_write(dm, NARADR_PMCTRL0 + counter_id, pmctrl); - dm->dbg_ops->queue_reg_read(dm, NARADR_PMSTAT0 + counter_id, pmstat_buf); + dm->dbg_ops->queue_reg_write(dm, XDMREG_PM0 + counter_id, 0); + dm->dbg_ops->queue_reg_write(dm, XDMREG_PMCTRL0 + counter_id, pmctrl); + dm->dbg_ops->queue_reg_read(dm, XDMREG_PMSTAT0 + counter_id, pmstat_buf); xtensa_dm_queue_tdi_idle(dm); - return jtag_execute_queue(); + return xtensa_dm_queue_execute(dm); } int xtensa_dm_perfmon_dump(struct xtensa_debug_module *dm, int counter_id, @@ -339,10 +423,10 @@ int xtensa_dm_perfmon_dump(struct xtensa_debug_module *dm, int counter_id, uint8_t pmstat_buf[4]; uint8_t pmcount_buf[4]; - dm->dbg_ops->queue_reg_read(dm, NARADR_PMSTAT0 + counter_id, pmstat_buf); - dm->dbg_ops->queue_reg_read(dm, NARADR_PM0 + counter_id, pmcount_buf); + dm->dbg_ops->queue_reg_read(dm, XDMREG_PMSTAT0 + counter_id, pmstat_buf); + dm->dbg_ops->queue_reg_read(dm, XDMREG_PM0 + counter_id, pmcount_buf); xtensa_dm_queue_tdi_idle(dm); - int res = jtag_execute_queue(); + int res = xtensa_dm_queue_execute(dm); if (res == ERROR_OK) { uint32_t stat = buf_get_u32(pmstat_buf, 0, 32); uint64_t result = buf_get_u32(pmcount_buf, 0, 32); diff --git a/src/target/xtensa/xtensa_debug_module.h b/src/target/xtensa/xtensa_debug_module.h index 692f0f6..b382e03 100644 --- a/src/target/xtensa/xtensa_debug_module.h +++ b/src/target/xtensa/xtensa_debug_module.h @@ -1,36 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** - * Xtensa debug module API * + * Xtensa Debug Module (XDM) Support for OpenOCD * + * Copyright (C) 2020-2022 Cadence Design Systems, Inc. * * Copyright (C) 2019 Espressif Systems Ltd. * - * <alexey@espressif.com> * - * * * Derived from original ESP8266 target. * - * Copyright (C) 2015 by Angus Gratton * - * gus@projectgus.com * - * * - * 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, see <http://www.gnu.org/licenses/>. * + * Author: Angus Gratton gus@projectgus.com * ***************************************************************************/ #ifndef OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H #define OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H #include <jtag/jtag.h> +#include <target/arm_adi_v5.h> #include <helper/bits.h> #include <target/target.h> /* Virtual IDs for using with xtensa_power_ops API */ -#define DMREG_PWRCTL 0x00 -#define DMREG_PWRSTAT 0x01 +enum xtensa_dm_pwr_reg { + XDMREG_PWRCTL = 0x00, + XDMREG_PWRSTAT, + XDMREG_PWRNUM +}; + +/* Debug Module Power Register offsets within APB */ +struct xtensa_dm_pwr_reg_offsets { + uint16_t apb; +}; + +/* Debug Module Power Register offset structure; must include XDMREG_PWRNUM entries */ +#define XTENSA_DM_PWR_REG_OFFSETS { \ + /* Power/Reset Registers */ \ + { .apb = 0x3020 }, /* XDMREG_PWRCTL */ \ + { .apb = 0x3024 }, /* XDMREG_PWRSTAT */ \ +} /* From the manual: @@ -43,81 +46,203 @@ Module to happen correctly. When it is set, any write to this bit clears it. Either don't access it, or re-write it to 1 so JTAG accesses continue. */ -#define PWRCTL_JTAGDEBUGUSE BIT(7) -#define PWRCTL_DEBUGRESET BIT(6) -#define PWRCTL_CORERESET BIT(4) -#define PWRCTL_DEBUGWAKEUP BIT(2) -#define PWRCTL_MEMWAKEUP BIT(1) -#define PWRCTL_COREWAKEUP BIT(0) - -#define PWRSTAT_DEBUGWASRESET BIT(6) -#define PWRSTAT_COREWASRESET BIT(4) -#define PWRSTAT_CORESTILLNEEDED BIT(3) -#define PWRSTAT_DEBUGDOMAINON BIT(2) -#define PWRSTAT_MEMDOMAINON BIT(1) -#define PWRSTAT_COREDOMAINON BIT(0) - -/* *** NAR addresses (also used as IDs for debug registers in xtensa_debug_ops API) *** - *TRAX registers */ -#define NARADR_TRAXID 0x00 -#define NARADR_TRAXCTRL 0x01 -#define NARADR_TRAXSTAT 0x02 -#define NARADR_TRAXDATA 0x03 -#define NARADR_TRAXADDR 0x04 -#define NARADR_TRIGGERPC 0x05 -#define NARADR_PCMATCHCTRL 0x06 -#define NARADR_DELAYCNT 0x07 -#define NARADR_MEMADDRSTART 0x08 -#define NARADR_MEMADDREND 0x09 -/*Performance monitor registers */ -#define NARADR_PMG 0x20 -#define NARADR_INTPC 0x24 -#define NARADR_PM0 0x28 -/*... */ -#define NARADR_PM7 0x2F -#define NARADR_PMCTRL0 0x30 -/*... */ -#define NARADR_PMCTRL7 0x37 -#define NARADR_PMSTAT0 0x38 -/*... */ -#define NARADR_PMSTAT7 0x3F -/*OCD registers */ -#define NARADR_OCDID 0x40 -#define NARADR_DCRCLR 0x42 -#define NARADR_DCRSET 0x43 -#define NARADR_DSR 0x44 -#define NARADR_DDR 0x45 -#define NARADR_DDREXEC 0x46 -#define NARADR_DIR0EXEC 0x47 -#define NARADR_DIR0 0x48 -#define NARADR_DIR1 0x49 -/*... */ -#define NARADR_DIR7 0x4F -/*Misc registers */ -#define NARADR_PWRCTL 0x58 -#define NARADR_PWRSTAT 0x59 -#define NARADR_ERISTAT 0x5A -/*CoreSight registers */ -#define NARADR_ITCTRL 0x60 -#define NARADR_CLAIMSET 0x68 -#define NARADR_CLAIMCLR 0x69 -#define NARADR_LOCKACCESS 0x6c -#define NARADR_LOCKSTATUS 0x6d -#define NARADR_AUTHSTATUS 0x6e -#define NARADR_DEVID 0x72 -#define NARADR_DEVTYPE 0x73 -#define NARADR_PERID4 0x74 -/*... */ -#define NARADR_PERID7 0x77 -#define NARADR_PERID0 0x78 -/*... */ -#define NARADR_PERID3 0x7b -#define NARADR_COMPID0 0x7c -/*... */ -#define NARADR_COMPID3 0x7f -#define NARADR_MAX NARADR_COMPID3 - -/*OCD registers, bit definitions */ +#define PWRCTL_JTAGDEBUGUSE(x) (((x)->dbg_mod.dap) ? (0) : BIT(7)) +#define PWRCTL_DEBUGRESET(x) (((x)->dbg_mod.dap) ? BIT(28) : BIT(6)) +#define PWRCTL_CORERESET(x) (((x)->dbg_mod.dap) ? BIT(16) : BIT(4)) +#define PWRCTL_DEBUGWAKEUP(x) (((x)->dbg_mod.dap) ? BIT(12) : BIT(2)) +#define PWRCTL_MEMWAKEUP(x) (((x)->dbg_mod.dap) ? BIT(8) : BIT(1)) +#define PWRCTL_COREWAKEUP(x) (((x)->dbg_mod.dap) ? BIT(0) : BIT(0)) + +#define PWRSTAT_DEBUGWASRESET_DM(d) (((d)->dap) ? BIT(28) : BIT(6)) +#define PWRSTAT_COREWASRESET_DM(d) (((d)->dap) ? BIT(16) : BIT(4)) +#define PWRSTAT_DEBUGWASRESET(x) (PWRSTAT_DEBUGWASRESET_DM(&((x)->dbg_mod))) +#define PWRSTAT_COREWASRESET(x) (PWRSTAT_COREWASRESET_DM(&((x)->dbg_mod))) +#define PWRSTAT_CORESTILLNEEDED(x) (((x)->dbg_mod.dap) ? BIT(4) : BIT(3)) +#define PWRSTAT_DEBUGDOMAINON(x) (((x)->dbg_mod.dap) ? BIT(12) : BIT(2)) +#define PWRSTAT_MEMDOMAINON(x) (((x)->dbg_mod.dap) ? BIT(8) : BIT(1)) +#define PWRSTAT_COREDOMAINON(x) (((x)->dbg_mod.dap) ? BIT(0) : BIT(0)) + +/* Virtual IDs for using with xtensa_debug_ops API */ +enum xtensa_dm_reg { + /* TRAX Registers */ + XDMREG_TRAXID = 0x00, + XDMREG_TRAXCTRL, + XDMREG_TRAXSTAT, + XDMREG_TRAXDATA, + XDMREG_TRAXADDR, + XDMREG_TRIGGERPC, + XDMREG_PCMATCHCTRL, + XDMREG_DELAYCNT, + XDMREG_MEMADDRSTART, + XDMREG_MEMADDREND, + + /* Performance Monitor Registers */ + XDMREG_PMG, + XDMREG_INTPC, + XDMREG_PM0, + XDMREG_PM1, + XDMREG_PM2, + XDMREG_PM3, + XDMREG_PM4, + XDMREG_PM5, + XDMREG_PM6, + XDMREG_PM7, + XDMREG_PMCTRL0, + XDMREG_PMCTRL1, + XDMREG_PMCTRL2, + XDMREG_PMCTRL3, + XDMREG_PMCTRL4, + XDMREG_PMCTRL5, + XDMREG_PMCTRL6, + XDMREG_PMCTRL7, + XDMREG_PMSTAT0, + XDMREG_PMSTAT1, + XDMREG_PMSTAT2, + XDMREG_PMSTAT3, + XDMREG_PMSTAT4, + XDMREG_PMSTAT5, + XDMREG_PMSTAT6, + XDMREG_PMSTAT7, + + /* OCD Registers */ + XDMREG_OCDID, + XDMREG_DCRCLR, + XDMREG_DCRSET, + XDMREG_DSR, + XDMREG_DDR, + XDMREG_DDREXEC, + XDMREG_DIR0EXEC, + XDMREG_DIR0, + XDMREG_DIR1, + XDMREG_DIR2, + XDMREG_DIR3, + XDMREG_DIR4, + XDMREG_DIR5, + XDMREG_DIR6, + XDMREG_DIR7, + + /* Misc Registers */ + XDMREG_ERISTAT, + + /* CoreSight Registers */ + XDMREG_ITCTRL, + XDMREG_CLAIMSET, + XDMREG_CLAIMCLR, + XDMREG_LOCKACCESS, + XDMREG_LOCKSTATUS, + XDMREG_AUTHSTATUS, + XDMREG_DEVID, + XDMREG_DEVTYPE, + XDMREG_PERID4, + XDMREG_PERID5, + XDMREG_PERID6, + XDMREG_PERID7, + XDMREG_PERID0, + XDMREG_PERID1, + XDMREG_PERID2, + XDMREG_PERID3, + XDMREG_COMPID0, + XDMREG_COMPID1, + XDMREG_COMPID2, + XDMREG_COMPID3, + + XDMREG_NUM +}; + +/* Debug Module Register offsets within Nexus (NAR) or APB */ +struct xtensa_dm_reg_offsets { + uint8_t nar; + uint16_t apb; +}; + +/* Debug Module Register offset structure; must include XDMREG_NUM entries */ +#define XTENSA_DM_REG_OFFSETS { \ + /* TRAX Registers */ \ + { .nar = 0x00, .apb = 0x0000 }, /* XDMREG_TRAXID */ \ + { .nar = 0x01, .apb = 0x0004 }, /* XDMREG_TRAXCTRL */ \ + { .nar = 0x02, .apb = 0x0008 }, /* XDMREG_TRAXSTAT */ \ + { .nar = 0x03, .apb = 0x000c }, /* XDMREG_TRAXDATA */ \ + { .nar = 0x04, .apb = 0x0010 }, /* XDMREG_TRAXADDR */ \ + { .nar = 0x05, .apb = 0x0014 }, /* XDMREG_TRIGGERPC */ \ + { .nar = 0x06, .apb = 0x0018 }, /* XDMREG_PCMATCHCTRL */ \ + { .nar = 0x07, .apb = 0x001c }, /* XDMREG_DELAYCNT */ \ + { .nar = 0x08, .apb = 0x0020 }, /* XDMREG_MEMADDRSTART */ \ + { .nar = 0x09, .apb = 0x0024 }, /* XDMREG_MEMADDREND */ \ + \ + /* Performance Monitor Registers */ \ + { .nar = 0x20, .apb = 0x1000 }, /* XDMREG_PMG */ \ + { .nar = 0x24, .apb = 0x1010 }, /* XDMREG_INTPC */ \ + { .nar = 0x28, .apb = 0x1080 }, /* XDMREG_PM0 */ \ + { .nar = 0x29, .apb = 0x1084 }, /* XDMREG_PM1 */ \ + { .nar = 0x2a, .apb = 0x1088 }, /* XDMREG_PM2 */ \ + { .nar = 0x2b, .apb = 0x108c }, /* XDMREG_PM3 */ \ + { .nar = 0x2c, .apb = 0x1090 }, /* XDMREG_PM4 */ \ + { .nar = 0x2d, .apb = 0x1094 }, /* XDMREG_PM5 */ \ + { .nar = 0x2e, .apb = 0x1098 }, /* XDMREG_PM6 */ \ + { .nar = 0x2f, .apb = 0x109c }, /* XDMREG_PM7 */ \ + { .nar = 0x30, .apb = 0x1100 }, /* XDMREG_PMCTRL0 */ \ + { .nar = 0x31, .apb = 0x1104 }, /* XDMREG_PMCTRL1 */ \ + { .nar = 0x32, .apb = 0x1108 }, /* XDMREG_PMCTRL2 */ \ + { .nar = 0x33, .apb = 0x110c }, /* XDMREG_PMCTRL3 */ \ + { .nar = 0x34, .apb = 0x1110 }, /* XDMREG_PMCTRL4 */ \ + { .nar = 0x35, .apb = 0x1114 }, /* XDMREG_PMCTRL5 */ \ + { .nar = 0x36, .apb = 0x1118 }, /* XDMREG_PMCTRL6 */ \ + { .nar = 0x37, .apb = 0x111c }, /* XDMREG_PMCTRL7 */ \ + { .nar = 0x38, .apb = 0x1180 }, /* XDMREG_PMSTAT0 */ \ + { .nar = 0x39, .apb = 0x1184 }, /* XDMREG_PMSTAT1 */ \ + { .nar = 0x3a, .apb = 0x1188 }, /* XDMREG_PMSTAT2 */ \ + { .nar = 0x3b, .apb = 0x118c }, /* XDMREG_PMSTAT3 */ \ + { .nar = 0x3c, .apb = 0x1190 }, /* XDMREG_PMSTAT4 */ \ + { .nar = 0x3d, .apb = 0x1194 }, /* XDMREG_PMSTAT5 */ \ + { .nar = 0x3e, .apb = 0x1198 }, /* XDMREG_PMSTAT6 */ \ + { .nar = 0x3f, .apb = 0x119c }, /* XDMREG_PMSTAT7 */ \ + \ + /* OCD Registers */ \ + { .nar = 0x40, .apb = 0x2000 }, /* XDMREG_OCDID */ \ + { .nar = 0x42, .apb = 0x2008 }, /* XDMREG_DCRCLR */ \ + { .nar = 0x43, .apb = 0x200c }, /* XDMREG_DCRSET */ \ + { .nar = 0x44, .apb = 0x2010 }, /* XDMREG_DSR */ \ + { .nar = 0x45, .apb = 0x2014 }, /* XDMREG_DDR */ \ + { .nar = 0x46, .apb = 0x2018 }, /* XDMREG_DDREXEC */ \ + { .nar = 0x47, .apb = 0x201c }, /* XDMREG_DIR0EXEC */ \ + { .nar = 0x48, .apb = 0x2020 }, /* XDMREG_DIR0 */ \ + { .nar = 0x49, .apb = 0x2024 }, /* XDMREG_DIR1 */ \ + { .nar = 0x4a, .apb = 0x2028 }, /* XDMREG_DIR2 */ \ + { .nar = 0x4b, .apb = 0x202c }, /* XDMREG_DIR3 */ \ + { .nar = 0x4c, .apb = 0x2030 }, /* XDMREG_DIR4 */ \ + { .nar = 0x4d, .apb = 0x2034 }, /* XDMREG_DIR5 */ \ + { .nar = 0x4e, .apb = 0x2038 }, /* XDMREG_DIR6 */ \ + { .nar = 0x4f, .apb = 0x203c }, /* XDMREG_DIR7 */ \ + \ + /* Misc Registers */ \ + { .nar = 0x5a, .apb = 0x3028 }, /* XDMREG_ERISTAT */ \ + \ + /* CoreSight Registers */ \ + { .nar = 0x60, .apb = 0x3f00 }, /* XDMREG_ITCTRL */ \ + { .nar = 0x68, .apb = 0x3fa0 }, /* XDMREG_CLAIMSET */ \ + { .nar = 0x69, .apb = 0x3fa4 }, /* XDMREG_CLAIMCLR */ \ + { .nar = 0x6c, .apb = 0x3fb0 }, /* XDMREG_LOCKACCESS */ \ + { .nar = 0x6d, .apb = 0x3fb4 }, /* XDMREG_LOCKSTATUS */ \ + { .nar = 0x6e, .apb = 0x3fb8 }, /* XDMREG_AUTHSTATUS */ \ + { .nar = 0x72, .apb = 0x3fc8 }, /* XDMREG_DEVID */ \ + { .nar = 0x73, .apb = 0x3fcc }, /* XDMREG_DEVTYPE */ \ + { .nar = 0x74, .apb = 0x3fd0 }, /* XDMREG_PERID4 */ \ + { .nar = 0x75, .apb = 0x3fd4 }, /* XDMREG_PERID5 */ \ + { .nar = 0x76, .apb = 0x3fd8 }, /* XDMREG_PERID6 */ \ + { .nar = 0x77, .apb = 0x3fdc }, /* XDMREG_PERID7 */ \ + { .nar = 0x78, .apb = 0x3fe0 }, /* XDMREG_PERID0 */ \ + { .nar = 0x79, .apb = 0x3fe4 }, /* XDMREG_PERID1 */ \ + { .nar = 0x7a, .apb = 0x3fe8 }, /* XDMREG_PERID2 */ \ + { .nar = 0x7b, .apb = 0x3fec }, /* XDMREG_PERID3 */ \ + { .nar = 0x7c, .apb = 0x3ff0 }, /* XDMREG_COMPID0 */ \ + { .nar = 0x7d, .apb = 0x3ff4 }, /* XDMREG_COMPID1 */ \ + { .nar = 0x7e, .apb = 0x3ff8 }, /* XDMREG_COMPID2 */ \ + { .nar = 0x7f, .apb = 0x3ffc }, /* XDMREG_COMPID3 */ \ +} + +#define XTENSA_DM_APB_ALIGN 0x4000 + +/* OCD registers, bit definitions */ #define OCDDCR_ENABLEOCD BIT(0) #define OCDDCR_DEBUGINTERRUPT BIT(1) #define OCDDCR_INTERRUPTALLCONDS BIT(2) @@ -164,7 +289,7 @@ #define TRAXCTRL_CTIEN BIT(5) /* Cross-trigger enable */ #define TRAXCTRL_TMEN BIT(7) /* Tracemem Enable. Always set. */ #define TRAXCTRL_CNTU BIT(9) /* Post-stop-trigger countdown units; selects when DelayCount-- happens. - *0 - every 32-bit word written to tracemem, 1 - every cpu instruction */ + * 0 - every 32-bit word written to tracemem, 1 - every cpu instruction */ #define TRAXCTRL_TSEN BIT(11) /* Undocumented/deprecated? */ #define TRAXCTRL_SMPER_SHIFT 12 /* Send sync every 2^(9-smper) messages. 7=reserved, 0=no sync msg */ #define TRAXCTRL_SMPER_MASK 0x07 /* Synchronization message period */ @@ -202,7 +327,7 @@ #define PCMATCHCTRL_PCML_SHIFT 0 /* Amount of lower bits to ignore in pc trigger register */ #define PCMATCHCTRL_PCML_MASK 0x1F #define PCMATCHCTRL_PCMS BIT(31) /* PC Match Sense, 0-match when procs PC is in-range, 1-match when - *out-of-range */ + * out-of-range */ #define XTENSA_MAX_PERF_COUNTERS 2 #define XTENSA_MAX_PERF_SELECT 32 @@ -216,20 +341,24 @@ struct xtensa_debug_ops { /** enable operation */ int (*queue_enable)(struct xtensa_debug_module *dm); /** register read. */ - int (*queue_reg_read)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data); + int (*queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *data); /** register write. */ - int (*queue_reg_write)(struct xtensa_debug_module *dm, unsigned int reg, uint32_t data); + int (*queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t data); }; +/* Xtensa power registers are 8 bits wide on JTAG interfaces but 32 bits wide + * when accessed via APB/DAP. In order to use DAP queuing APIs (for optimal + * performance), the XDM power register APIs take 32-bit register params. + */ struct xtensa_power_ops { /** register read. */ - int (*queue_reg_read)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data, - uint8_t clear); + int (*queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint8_t *data, + uint32_t clear); /** register write. */ - int (*queue_reg_write)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data); + int (*queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint32_t data); }; -typedef uint8_t xtensa_pwrstat_t; +typedef uint32_t xtensa_pwrstat_t; typedef uint32_t xtensa_ocdid_t; typedef uint32_t xtensa_dsr_t; typedef uint32_t xtensa_traxstat_t; @@ -283,29 +412,62 @@ struct xtensa_perfmon_result { struct xtensa_debug_module_config { const struct xtensa_power_ops *pwr_ops; const struct xtensa_debug_ops *dbg_ops; + + /* Either JTAG or DAP structures will be populated */ struct jtag_tap *tap; void (*queue_tdi_idle)(struct target *target); void *queue_tdi_idle_arg; + + /* For targets conforming to ARM Debug Interface v5, + * "dap" references the Debug Access Port (DAP) + * used to make requests to the target; + * "debug_ap" is AP instance connected to processor + */ + struct adiv5_dap *dap; + struct adiv5_ap *debug_ap; + int debug_apsel; + uint32_t ap_offset; }; struct xtensa_debug_module { const struct xtensa_power_ops *pwr_ops; const struct xtensa_debug_ops *dbg_ops; + + /* Either JTAG or DAP structures will be populated */ struct jtag_tap *tap; void (*queue_tdi_idle)(struct target *target); void *queue_tdi_idle_arg; + /* DAP struct; AP instance connected to processor */ + struct adiv5_dap *dap; + struct adiv5_ap *debug_ap; + int debug_apsel; + struct xtensa_power_status power_status; struct xtensa_core_status core_status; xtensa_ocdid_t device_id; + uint32_t ap_offset; }; int xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_module_config *cfg); +void xtensa_dm_deinit(struct xtensa_debug_module *dm); +int xtensa_dm_poll(struct xtensa_debug_module *dm); +int xtensa_dm_examine(struct xtensa_debug_module *dm); int xtensa_dm_queue_enable(struct xtensa_debug_module *dm); -int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *value); -int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint32_t value); -int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data, uint8_t clear); -int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data); +int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *value); +int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t value); +int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm, + enum xtensa_dm_pwr_reg reg, + uint8_t *data, + uint32_t clear); +int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm, + enum xtensa_dm_pwr_reg reg, + uint32_t data); + +static inline int xtensa_dm_queue_execute(struct xtensa_debug_module *dm) +{ + return dm->dap ? dap_run(dm->dap) : jtag_execute_queue(); +} static inline void xtensa_dm_queue_tdi_idle(struct xtensa_debug_module *dm) { @@ -352,19 +514,19 @@ static inline bool xtensa_dm_is_online(struct xtensa_debug_module *dm) int res = xtensa_dm_device_id_read(dm); if (res != ERROR_OK) return false; - return (dm->device_id != 0xffffffff && dm->device_id != 0); + return dm->device_id != 0xffffffff && dm->device_id != 0; } static inline bool xtensa_dm_tap_was_reset(struct xtensa_debug_module *dm) { - return !(dm->power_status.prev_stat & PWRSTAT_DEBUGWASRESET) && - dm->power_status.stat & PWRSTAT_DEBUGWASRESET; + return !(dm->power_status.prev_stat & PWRSTAT_DEBUGWASRESET_DM(dm)) && + dm->power_status.stat & PWRSTAT_DEBUGWASRESET_DM(dm); } static inline bool xtensa_dm_core_was_reset(struct xtensa_debug_module *dm) { - return !(dm->power_status.prev_stat & PWRSTAT_COREWASRESET) && - dm->power_status.stat & PWRSTAT_COREWASRESET; + return !(dm->power_status.prev_stat & PWRSTAT_COREWASRESET_DM(dm)) && + dm->power_status.stat & PWRSTAT_COREWASRESET_DM(dm); } static inline bool xtensa_dm_core_is_stalled(struct xtensa_debug_module *dm) diff --git a/src/target/xtensa/xtensa_regs.h b/src/target/xtensa/xtensa_regs.h index 7602131..1d9d365 100644 --- a/src/target/xtensa/xtensa_regs.h +++ b/src/target/xtensa/xtensa_regs.h @@ -1,22 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Generic Xtensa target API for OpenOCD * + * Copyright (C) 2020-2022 Cadence Design Systems, Inc. * * Copyright (C) 2016-2019 Espressif Systems Ltd. * * Author: Angus Gratton gus@projectgus.com * - * Author: Jeroen Domburg <jeroen@espressif.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ + #ifndef OPENOCD_TARGET_XTENSA_REGS_H #define OPENOCD_TARGET_XTENSA_REGS_H @@ -25,6 +15,7 @@ struct reg_arch_type; enum xtensa_reg_id { XT_REG_IDX_PC = 0, XT_REG_IDX_AR0, + XT_REG_IDX_ARFIRST = XT_REG_IDX_AR0, XT_REG_IDX_AR1, XT_REG_IDX_AR2, XT_REG_IDX_AR3, @@ -40,152 +31,23 @@ enum xtensa_reg_id { XT_REG_IDX_AR13, XT_REG_IDX_AR14, XT_REG_IDX_AR15, - XT_REG_IDX_AR16, - XT_REG_IDX_AR17, - XT_REG_IDX_AR18, - XT_REG_IDX_AR19, - XT_REG_IDX_AR20, - XT_REG_IDX_AR21, - XT_REG_IDX_AR22, - XT_REG_IDX_AR23, - XT_REG_IDX_AR24, - XT_REG_IDX_AR25, - XT_REG_IDX_AR26, - XT_REG_IDX_AR27, - XT_REG_IDX_AR28, - XT_REG_IDX_AR29, - XT_REG_IDX_AR30, - XT_REG_IDX_AR31, - XT_REG_IDX_AR32, - XT_REG_IDX_AR33, - XT_REG_IDX_AR34, - XT_REG_IDX_AR35, - XT_REG_IDX_AR36, - XT_REG_IDX_AR37, - XT_REG_IDX_AR38, - XT_REG_IDX_AR39, - XT_REG_IDX_AR40, - XT_REG_IDX_AR41, - XT_REG_IDX_AR42, - XT_REG_IDX_AR43, - XT_REG_IDX_AR44, - XT_REG_IDX_AR45, - XT_REG_IDX_AR46, - XT_REG_IDX_AR47, - XT_REG_IDX_AR48, - XT_REG_IDX_AR49, - XT_REG_IDX_AR50, - XT_REG_IDX_AR51, - XT_REG_IDX_AR52, - XT_REG_IDX_AR53, - XT_REG_IDX_AR54, - XT_REG_IDX_AR55, - XT_REG_IDX_AR56, - XT_REG_IDX_AR57, - XT_REG_IDX_AR58, - XT_REG_IDX_AR59, - XT_REG_IDX_AR60, - XT_REG_IDX_AR61, - XT_REG_IDX_AR62, - XT_REG_IDX_AR63, - XT_REG_IDX_LBEG, - XT_REG_IDX_LEND, - XT_REG_IDX_LCOUNT, - XT_REG_IDX_SAR, + XT_REG_IDX_ARLAST = 64, /* Max 64 ARs */ XT_REG_IDX_WINDOWBASE, XT_REG_IDX_WINDOWSTART, - XT_REG_IDX_CONFIGID0, - XT_REG_IDX_CONFIGID1, XT_REG_IDX_PS, - XT_REG_IDX_THREADPTR, - XT_REG_IDX_BR, - XT_REG_IDX_SCOMPARE1, - XT_REG_IDX_ACCLO, - XT_REG_IDX_ACCHI, - XT_REG_IDX_M0, - XT_REG_IDX_M1, - XT_REG_IDX_M2, - XT_REG_IDX_M3, - XT_REG_IDX_F0, - XT_REG_IDX_F1, - XT_REG_IDX_F2, - XT_REG_IDX_F3, - XT_REG_IDX_F4, - XT_REG_IDX_F5, - XT_REG_IDX_F6, - XT_REG_IDX_F7, - XT_REG_IDX_F8, - XT_REG_IDX_F9, - XT_REG_IDX_F10, - XT_REG_IDX_F11, - XT_REG_IDX_F12, - XT_REG_IDX_F13, - XT_REG_IDX_F14, - XT_REG_IDX_F15, - XT_REG_IDX_FCR, - XT_REG_IDX_FSR, - XT_REG_IDX_MMID, XT_REG_IDX_IBREAKENABLE, - XT_REG_IDX_MEMCTL, - XT_REG_IDX_ATOMCTL, + XT_REG_IDX_DDR, XT_REG_IDX_IBREAKA0, XT_REG_IDX_IBREAKA1, XT_REG_IDX_DBREAKA0, XT_REG_IDX_DBREAKA1, XT_REG_IDX_DBREAKC0, XT_REG_IDX_DBREAKC1, - XT_REG_IDX_EPC1, - XT_REG_IDX_EPC2, - XT_REG_IDX_EPC3, - XT_REG_IDX_EPC4, - XT_REG_IDX_EPC5, - XT_REG_IDX_EPC6, - XT_REG_IDX_EPC7, - XT_REG_IDX_DEPC, - XT_REG_IDX_EPS2, - XT_REG_IDX_EPS3, - XT_REG_IDX_EPS4, - XT_REG_IDX_EPS5, - XT_REG_IDX_EPS6, - XT_REG_IDX_EPS7, - XT_REG_IDX_EXCSAVE1, - XT_REG_IDX_EXCSAVE2, - XT_REG_IDX_EXCSAVE3, - XT_REG_IDX_EXCSAVE4, - XT_REG_IDX_EXCSAVE5, - XT_REG_IDX_EXCSAVE6, - XT_REG_IDX_EXCSAVE7, XT_REG_IDX_CPENABLE, - XT_REG_IDX_INTERRUPT, - XT_REG_IDX_INTSET, - XT_REG_IDX_INTCLEAR, - XT_REG_IDX_INTENABLE, - XT_REG_IDX_VECBASE, XT_REG_IDX_EXCCAUSE, XT_REG_IDX_DEBUGCAUSE, - XT_REG_IDX_CCOUNT, - XT_REG_IDX_PRID, XT_REG_IDX_ICOUNT, XT_REG_IDX_ICOUNTLEVEL, - XT_REG_IDX_EXCVADDR, - XT_REG_IDX_CCOMPARE0, - XT_REG_IDX_CCOMPARE1, - XT_REG_IDX_CCOMPARE2, - XT_REG_IDX_MISC0, - XT_REG_IDX_MISC1, - XT_REG_IDX_MISC2, - XT_REG_IDX_MISC3, - XT_REG_IDX_LITBASE, - XT_REG_IDX_PTEVADDR, - XT_REG_IDX_RASID, - XT_REG_IDX_ITLBCFG, - XT_REG_IDX_DTLBCFG, - XT_REG_IDX_MEPC, - XT_REG_IDX_MEPS, - XT_REG_IDX_MESAVE, - XT_REG_IDX_MESR, - XT_REG_IDX_MECR, - XT_REG_IDX_MEVADDR, XT_REG_IDX_A0, XT_REG_IDX_A1, XT_REG_IDX_A2, @@ -202,77 +64,72 @@ enum xtensa_reg_id { XT_REG_IDX_A13, XT_REG_IDX_A14, XT_REG_IDX_A15, - XT_REG_IDX_PWRCTL, - XT_REG_IDX_PWRSTAT, - XT_REG_IDX_ERISTAT, - XT_REG_IDX_CS_ITCTRL, - XT_REG_IDX_CS_CLAIMSET, - XT_REG_IDX_CS_CLAIMCLR, - XT_REG_IDX_CS_LOCKACCESS, - XT_REG_IDX_CS_LOCKSTATUS, - XT_REG_IDX_CS_AUTHSTATUS, - XT_REG_IDX_FAULT_INFO, - XT_REG_IDX_TRAX_ID, - XT_REG_IDX_TRAX_CTRL, - XT_REG_IDX_TRAX_STAT, - XT_REG_IDX_TRAX_DATA, - XT_REG_IDX_TRAX_ADDR, - XT_REG_IDX_TRAX_PCTRIGGER, - XT_REG_IDX_TRAX_PCMATCH, - XT_REG_IDX_TRAX_DELAY, - XT_REG_IDX_TRAX_MEMSTART, - XT_REG_IDX_TRAX_MEMEND, - XT_REG_IDX_PMG, - XT_REG_IDX_PMPC, - XT_REG_IDX_PM0, - XT_REG_IDX_PM1, - XT_REG_IDX_PMCTRL0, - XT_REG_IDX_PMCTRL1, - XT_REG_IDX_PMSTAT0, - XT_REG_IDX_PMSTAT1, - XT_REG_IDX_OCD_ID, - XT_REG_IDX_OCD_DCRCLR, - XT_REG_IDX_OCD_DCRSET, - XT_REG_IDX_OCD_DSR, - XT_REG_IDX_OCD_DDR, - XT_NUM_REGS, - /* chip-specific user registers go after ISA-defined ones */ - XT_USR_REG_START = XT_NUM_REGS + XT_NUM_REGS }; typedef uint32_t xtensa_reg_val_t; +#define XT_NUM_A_REGS 16 + enum xtensa_reg_type { XT_REG_GENERAL = 0, /* General-purpose register; part of the windowed register set */ XT_REG_USER = 1, /* User register, needs RUR to read */ XT_REG_SPECIAL = 2, /* Special register, needs RSR to read */ XT_REG_DEBUG = 3, /* Register used for the debug interface. Don't mess with this. */ XT_REG_RELGEN = 4, /* Relative general address. Points to the absolute addresses plus the window - *index */ + * index */ XT_REG_FR = 5, /* Floating-point register */ + XT_REG_TIE = 6, /* TIE (custom) register */ + XT_REG_OTHER = 7, /* Other (typically legacy) register */ + XT_REG_TYPE_NUM, + + /* enum names must be one of the above types + _VAL or _MASK */ + XT_REG_GENERAL_MASK = 0xFFC0, + XT_REG_GENERAL_VAL = 0x0100, + XT_REG_USER_MASK = 0xFF00, + XT_REG_USER_VAL = 0x0300, + XT_REG_SPECIAL_MASK = 0xFF00, + XT_REG_SPECIAL_VAL = 0x0200, + XT_REG_DEBUG_MASK = 0xFF00, + XT_REG_DEBUG_VAL = 0x0200, + XT_REG_RELGEN_MASK = 0xFFE0, + XT_REG_RELGEN_VAL = 0x0000, + XT_REG_FR_MASK = 0xFFF0, + XT_REG_FR_VAL = 0x0030, + XT_REG_TIE_MASK = 0xF000, + XT_REG_TIE_VAL = 0xF000, /* unused */ + XT_REG_OTHER_MASK = 0xFFFF, + XT_REG_OTHER_VAL = 0xF000, /* unused */ + + XT_REG_INDEX_MASK = 0x00FF }; enum xtensa_reg_flags { XT_REGF_NOREAD = 0x01, /* Register is write-only */ - XT_REGF_COPROC0 = 0x02 /* Can't be read if coproc0 isn't enabled */ + XT_REGF_COPROC0 = 0x02, /* Can't be read if coproc0 isn't enabled */ + XT_REGF_MASK = 0x03 }; struct xtensa_reg_desc { const char *name; + bool exist; unsigned int reg_num; /* ISA register num (meaning depends on register type) */ + unsigned int dbreg_num; /* Debugger-visible register num (reg type encoded) */ enum xtensa_reg_type type; enum xtensa_reg_flags flags; }; -struct xtensa_user_reg_desc { - const char *name; - /* ISA register num (meaning depends on register type) */ - unsigned int reg_num; - enum xtensa_reg_flags flags; - uint32_t size; - const struct reg_arch_type *type; -}; +#define _XT_MK_DBREGN(reg_num, reg_type) \ + ((reg_type ## _VAL) | (reg_num)) + +#define _XT_MK_DBREGN_MASK(reg_num, reg_mask) \ + ((reg_mask) | (reg_num)) + +#define XT_MK_REG_DESC(n, r, t, f) \ + { .name = (n), .exist = false, .reg_num = (r), \ + .dbreg_num = _XT_MK_DBREGN(r, t), .type = (t), \ + .flags = (f) } -extern const struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS]; +extern struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS]; #endif /* OPENOCD_TARGET_XTENSA_REGS_H */ diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index 9076d9b..cb4f48f 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libtransport.la %C%_libtransport_la_SOURCES = \ %D%/transport.c \ diff --git a/src/transport/transport.c b/src/transport/transport.c index ba1af33..d72a48b 100644 --- a/src/transport/transport.c +++ b/src/transport/transport.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /* * Copyright (c) 2010 by David Brownell - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H diff --git a/src/transport/transport.h b/src/transport/transport.h index e04f780..00d8b07 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* * Copyright (c) 2010 by David Brownell * Copyright (C) 2011 Tomasz Boleslaw CEDRO (http://www.tomek.cedro.info) - * - * 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, see <http://www.gnu.org/licenses/>. */ #ifndef OPENOCD_TRANSPORT_TRANSPORT_H diff --git a/src/xsvf/Makefile.am b/src/xsvf/Makefile.am index 61e6fb9..08f1cc1 100644 --- a/src/xsvf/Makefile.am +++ b/src/xsvf/Makefile.am @@ -1,2 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + noinst_LTLIBRARIES += %D%/libxsvf.la %C%_libxsvf_la_SOURCES = %D%/xsvf.c %D%/xsvf.h diff --git a/src/xsvf/xsvf.c b/src/xsvf/xsvf.c index c4ce55a..0266c21 100644 --- a/src/xsvf/xsvf.c +++ b/src/xsvf/xsvf.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -10,19 +12,6 @@ * * * Copyright (C) 2009 SoftPLC Corporation. http://softplc.com * * Dick Hollenbeck <dick@softplc.com> * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ /* The specification for SVF is available here: diff --git a/src/xsvf/xsvf.h b/src/xsvf/xsvf.h index aa0f4f0..04ba056 100644 --- a/src/xsvf/xsvf.h +++ b/src/xsvf/xsvf.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * - * * - * 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, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #ifndef OPENOCD_XSVF_XSVF_H |