]> git.sur5r.net Git - openocd/blob - contrib/libdcc/dcc_stdio.c
contrib: enable cortex-m0 and cortex-m4 libdcc support
[openocd] / contrib / libdcc / dcc_stdio.c
1 /***************************************************************************
2  *   Copyright (C) 2008 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *   Copyright (C) 2008 by Spencer Oliver                                  *
5  *   spen@spen-soft.co.uk                                                  *
6  *   Copyright (C) 2008 by Frederik Kriewtz                                *
7  *   frederik@kriewitz.eu                                                  *
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  *   This program is distributed in the hope that it will be useful,       *
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
17  *   GNU General Public License for more details.                          *
18  *                                                                         *
19  *   You should have received a copy of the GNU General Public License     *
20  *   along with this program; if not, write to the                         *
21  *   Free Software Foundation, Inc.,                                       *
22  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
23  ***************************************************************************/
24
25 #include "dcc_stdio.h"
26
27 #define TARGET_REQ_TRACEMSG                                     0x00
28 #define TARGET_REQ_DEBUGMSG_ASCII                       0x01
29 #define TARGET_REQ_DEBUGMSG_HEXMSG(size)        (0x01 | ((size & 0xff) << 8))
30 #define TARGET_REQ_DEBUGCHAR                            0x02
31
32 #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_6SM__)
33
34 /* we use the System Control Block DCRDR reg to simulate a arm7_9 dcc channel
35  * DCRDR[7:0] is used by target for status
36  * DCRDR[15:8] is used by target for write buffer
37  * DCRDR[23:16] is used for by host for status
38  * DCRDR[31:24] is used for by host for write buffer */
39
40 #define NVIC_DBG_DATA_R         (*((volatile unsigned short *)0xE000EDF8))
41
42 #define BUSY    1
43
44 void dbg_write(unsigned long dcc_data)
45 {
46         int len = 4;
47
48         while (len--)
49         {
50                 /* wait for data ready */
51                 while (NVIC_DBG_DATA_R & BUSY);
52
53                 /* write our data and set write flag - tell host there is data*/
54                 NVIC_DBG_DATA_R = (unsigned short)(((dcc_data & 0xff) << 8) | BUSY);
55                 dcc_data >>= 8;
56         }
57 }
58
59 #elif defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5T__)
60
61 void dbg_write(unsigned long dcc_data)
62 {
63         unsigned long dcc_status;
64
65         do {
66                 asm volatile("mrc p14, 0, %0, c0, c0" : "=r" (dcc_status));
67         } while (dcc_status & 0x2);
68
69         asm volatile("mcr p14, 0, %0, c1, c0" : : "r" (dcc_data));
70 }
71
72 #else
73  #error unsupported target
74 #endif
75
76 void dbg_trace_point(unsigned long number)
77 {
78         dbg_write(TARGET_REQ_TRACEMSG | (number << 8));
79 }
80
81 void dbg_write_u32(const unsigned long *val, long len)
82 {
83         dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(4) | ((len & 0xffff) << 16));
84
85         while (len > 0)
86         {
87                 dbg_write(*val);
88
89                 val++;
90                 len--;
91         }
92 }
93
94 void dbg_write_u16(const unsigned short *val, long len)
95 {
96         unsigned long dcc_data;
97
98         dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(2) | ((len & 0xffff) << 16));
99
100         while (len > 0)
101         {
102                 dcc_data = val[0]
103                         | ((len > 1) ? val[1] << 16: 0x0000);
104
105                 dbg_write(dcc_data);
106
107                 val += 2;
108                 len -= 2;
109         }
110 }
111
112 void dbg_write_u8(const unsigned char *val, long len)
113 {
114         unsigned long dcc_data;
115
116         dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(1) | ((len & 0xffff) << 16));
117
118         while (len > 0)
119         {
120                 dcc_data = val[0]
121                         | ((len > 1) ? val[1] << 8 : 0x00)
122                         | ((len > 2) ? val[2] << 16 : 0x00)
123                         | ((len > 3) ? val[3] << 24 : 0x00);
124
125                 dbg_write(dcc_data);
126
127                 val += 4;
128                 len -= 4;
129         }
130 }
131
132 void dbg_write_str(const char *msg)
133 {
134         long len;
135         unsigned long dcc_data;
136
137         for (len = 0; msg[len] && (len < 65536); len++);
138
139         dbg_write(TARGET_REQ_DEBUGMSG_ASCII | ((len & 0xffff) << 16));
140
141         while (len > 0)
142         {
143                 dcc_data = msg[0]
144                         | ((len > 1) ? msg[1] << 8 : 0x00)
145                         | ((len > 2) ? msg[2] << 16 : 0x00)
146                         | ((len > 3) ? msg[3] << 24 : 0x00);
147                 dbg_write(dcc_data);
148
149                 msg += 4;
150                 len -= 4;
151         }
152 }
153
154 void dbg_write_char(char msg)
155 {
156         dbg_write(TARGET_REQ_DEBUGCHAR | ((msg & 0xff) << 16));
157 }