2008-03-01 14:51:26 -06:00
|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2008 by Dominic Rath *
|
|
|
|
* Dominic.Rath@gmx.de *
|
|
|
|
* Copyright (C) 2008 by Spencer Oliver *
|
|
|
|
* spen@spen-soft.co.uk *
|
2008-10-08 00:05:57 -05:00
|
|
|
* Copyright (C) 2008 by Frederik Kriewtz *
|
|
|
|
* frederik@kriewitz.eu *
|
2008-03-01 14:51:26 -06:00
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* This program is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
2018-06-11 14:47:52 -05:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
2008-03-01 14:51:26 -06:00
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include "dcc_stdio.h"
|
|
|
|
|
2008-12-02 01:22:53 -06:00
|
|
|
#define TARGET_REQ_TRACEMSG 0x00
|
|
|
|
#define TARGET_REQ_DEBUGMSG_ASCII 0x01
|
|
|
|
#define TARGET_REQ_DEBUGMSG_HEXMSG(size) (0x01 | ((size & 0xff) << 8))
|
|
|
|
#define TARGET_REQ_DEBUGCHAR 0x02
|
|
|
|
|
2012-05-15 07:36:11 -05:00
|
|
|
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_6SM__)
|
2008-03-01 14:51:26 -06:00
|
|
|
|
2012-05-15 07:36:11 -05:00
|
|
|
/* we use the System Control Block DCRDR reg to simulate a arm7_9 dcc channel
|
2008-03-01 14:51:26 -06:00
|
|
|
* DCRDR[7:0] is used by target for status
|
|
|
|
* DCRDR[15:8] is used by target for write buffer
|
|
|
|
* DCRDR[23:16] is used for by host for status
|
|
|
|
* DCRDR[31:24] is used for by host for write buffer */
|
|
|
|
|
2008-10-08 15:16:51 -05:00
|
|
|
#define NVIC_DBG_DATA_R (*((volatile unsigned short *)0xE000EDF8))
|
2008-10-08 00:05:57 -05:00
|
|
|
|
2008-03-01 14:51:26 -06:00
|
|
|
#define BUSY 1
|
|
|
|
|
2008-10-08 00:05:57 -05:00
|
|
|
void dbg_write(unsigned long dcc_data)
|
2008-03-01 14:51:26 -06:00
|
|
|
{
|
|
|
|
int len = 4;
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-03-01 14:51:26 -06:00
|
|
|
while (len--)
|
|
|
|
{
|
|
|
|
/* wait for data ready */
|
2008-10-08 00:05:57 -05:00
|
|
|
while (NVIC_DBG_DATA_R & BUSY);
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-10-08 00:05:57 -05:00
|
|
|
/* write our data and set write flag - tell host there is data*/
|
|
|
|
NVIC_DBG_DATA_R = (unsigned short)(((dcc_data & 0xff) << 8) | BUSY);
|
2008-03-01 14:51:26 -06:00
|
|
|
dcc_data >>= 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-02 01:22:53 -06:00
|
|
|
#elif defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5T__)
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-10-08 00:05:57 -05:00
|
|
|
void dbg_write(unsigned long dcc_data)
|
2008-03-01 14:51:26 -06:00
|
|
|
{
|
2008-10-08 00:05:57 -05:00
|
|
|
unsigned long dcc_status;
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-03-01 14:51:26 -06:00
|
|
|
do {
|
|
|
|
asm volatile("mrc p14, 0, %0, c0, c0" : "=r" (dcc_status));
|
|
|
|
} while (dcc_status & 0x2);
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-03-01 14:51:26 -06:00
|
|
|
asm volatile("mcr p14, 0, %0, c1, c0" : : "r" (dcc_data));
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
#error unsupported target
|
|
|
|
#endif
|
|
|
|
|
2008-10-08 00:05:57 -05:00
|
|
|
void dbg_trace_point(unsigned long number)
|
2008-10-08 15:16:51 -05:00
|
|
|
{
|
2008-10-08 00:05:57 -05:00
|
|
|
dbg_write(TARGET_REQ_TRACEMSG | (number << 8));
|
|
|
|
}
|
2008-03-01 14:51:26 -06:00
|
|
|
|
2008-10-08 00:05:57 -05:00
|
|
|
void dbg_write_u32(const unsigned long *val, long len)
|
2008-10-08 15:16:51 -05:00
|
|
|
{
|
2008-10-08 00:05:57 -05:00
|
|
|
dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(4) | ((len & 0xffff) << 16));
|
2008-03-01 14:51:26 -06:00
|
|
|
|
|
|
|
while (len > 0)
|
|
|
|
{
|
|
|
|
dbg_write(*val);
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-03-01 14:51:26 -06:00
|
|
|
val++;
|
|
|
|
len--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-08 00:05:57 -05:00
|
|
|
void dbg_write_u16(const unsigned short *val, long len)
|
2008-03-01 14:51:26 -06:00
|
|
|
{
|
2008-10-08 00:05:57 -05:00
|
|
|
unsigned long dcc_data;
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-10-08 00:05:57 -05:00
|
|
|
dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(2) | ((len & 0xffff) << 16));
|
2008-03-01 14:51:26 -06:00
|
|
|
|
|
|
|
while (len > 0)
|
|
|
|
{
|
2009-10-13 12:00:46 -05:00
|
|
|
dcc_data = val[0]
|
2008-10-08 00:05:57 -05:00
|
|
|
| ((len > 1) ? val[1] << 16: 0x0000);
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-03-01 14:51:26 -06:00
|
|
|
dbg_write(dcc_data);
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-03-01 14:51:26 -06:00
|
|
|
val += 2;
|
|
|
|
len -= 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-08 00:05:57 -05:00
|
|
|
void dbg_write_u8(const unsigned char *val, long len)
|
2008-10-08 15:16:51 -05:00
|
|
|
{
|
2008-10-08 00:05:57 -05:00
|
|
|
unsigned long dcc_data;
|
2008-03-01 14:51:26 -06:00
|
|
|
|
2008-10-08 00:05:57 -05:00
|
|
|
dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(1) | ((len & 0xffff) << 16));
|
2008-03-01 14:51:26 -06:00
|
|
|
|
|
|
|
while (len > 0)
|
|
|
|
{
|
|
|
|
dcc_data = val[0]
|
|
|
|
| ((len > 1) ? val[1] << 8 : 0x00)
|
|
|
|
| ((len > 2) ? val[2] << 16 : 0x00)
|
|
|
|
| ((len > 3) ? val[3] << 24 : 0x00);
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-03-01 14:51:26 -06:00
|
|
|
dbg_write(dcc_data);
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-10-08 00:05:57 -05:00
|
|
|
val += 4;
|
|
|
|
len -= 4;
|
2008-03-01 14:51:26 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-08 00:05:57 -05:00
|
|
|
void dbg_write_str(const char *msg)
|
2008-03-01 14:51:26 -06:00
|
|
|
{
|
2008-10-08 00:05:57 -05:00
|
|
|
long len;
|
|
|
|
unsigned long dcc_data;
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-03-01 14:51:26 -06:00
|
|
|
for (len = 0; msg[len] && (len < 65536); len++);
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-10-08 00:05:57 -05:00
|
|
|
dbg_write(TARGET_REQ_DEBUGMSG_ASCII | ((len & 0xffff) << 16));
|
2008-10-08 15:16:51 -05:00
|
|
|
|
2008-03-01 14:51:26 -06:00
|
|
|
while (len > 0)
|
2008-10-08 00:05:57 -05:00
|
|
|
{
|
2008-03-01 14:51:26 -06:00
|
|
|
dcc_data = msg[0]
|
|
|
|
| ((len > 1) ? msg[1] << 8 : 0x00)
|
|
|
|
| ((len > 2) ? msg[2] << 16 : 0x00)
|
|
|
|
| ((len > 3) ? msg[3] << 24 : 0x00);
|
|
|
|
dbg_write(dcc_data);
|
2009-10-13 12:00:46 -05:00
|
|
|
|
2008-03-01 14:51:26 -06:00
|
|
|
msg += 4;
|
|
|
|
len -= 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-08 00:05:57 -05:00
|
|
|
void dbg_write_char(char msg)
|
2008-10-08 15:16:51 -05:00
|
|
|
{
|
2008-10-08 00:05:57 -05:00
|
|
|
dbg_write(TARGET_REQ_DEBUGCHAR | ((msg & 0xff) << 16));
|
2008-03-01 14:51:26 -06:00
|
|
|
}
|