1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * JTAG console device File: dev_jtag.c 5 * 6 * This file supports a serial-port-style console over the 7 * BCM12500's JTAG port. 8 * 9 * Author: Mitch Lichtenberg 10 * Kip Walker 11 * 12 ********************************************************************* 13 * 14 * Copyright 2000,2001,2002,2003 15 * Broadcom Corporation. All rights reserved. 16 * 17 * This software is furnished under license and may be used and 18 * copied only in accordance with the following terms and 19 * conditions. Subject to these conditions, you may download, 20 * copy, install, use, modify and distribute modified or unmodified 21 * copies of this software in source and/or binary form. No title 22 * or ownership is transferred hereby. 23 * 24 * 1) Any source code used, modified or distributed must reproduce 25 * and retain this copyright notice and list of conditions 26 * as they appear in the source file. 27 * 28 * 2) No right is granted to use any trade name, trademark, or 29 * logo of Broadcom Corporation. The "Broadcom Corporation" 30 * name may not be used to endorse or promote products derived 31 * from this software without the prior written permission of 32 * Broadcom Corporation. 33 * 34 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 35 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 36 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 37 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 38 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 39 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 40 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 41 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 42 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 43 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 44 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 45 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 46 * THE POSSIBILITY OF SUCH DAMAGE. 47 ********************************************************************* */ 48 49 50#include "cfe.h" 51#include "sbmips.h" 52#include "sb1250_defs.h" 53 54/* XXX How can I share these definitions with console clients? */ 55#define JTAG_CONS_CONTROL 0x00 56#define JTAG_CONS_INPUT 0x20 57#define JTAG_CONS_OUTPUT 0x40 58#define JTAG_CONS_MAGICNUM 0x50FABEEF12349873LL 59 60#define jtag_input_len(data) (((data) >> 56) & 0xFF) 61 62/* ********************************************************************* 63 * Prototypes 64 ********************************************************************* */ 65 66static void jtag_probe(cfe_driver_t *drv, 67 unsigned long probe_a, unsigned long probe_b, 68 void *probe_ptr); 69 70 71static int jtag_open(cfe_devctx_t *ctx); 72static int jtag_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 73static int jtag_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat); 74static int jtag_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 75static int jtag_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 76static int jtag_close(cfe_devctx_t *ctx); 77 78/* ********************************************************************* 79 * Device dispatch table 80 ********************************************************************* */ 81 82const static cfe_devdisp_t jtag_dispatch = { 83 jtag_open, 84 jtag_read, 85 jtag_inpstat, 86 jtag_write, 87 jtag_ioctl, 88 jtag_close, 89 NULL, 90 NULL 91}; 92 93/* ********************************************************************* 94 * Device descriptor 95 ********************************************************************* */ 96 97const cfe_driver_t jtagconsole = { 98 "JTAG serial console", 99 "jtag", 100 CFE_DEV_SERIAL, 101 &jtag_dispatch, 102 jtag_probe 103}; 104 105/* ********************************************************************* 106 * Local constants and structures 107 ********************************************************************* */ 108 109 110typedef struct jtag_s { 111 unsigned long jtag_input; 112 unsigned long jtag_output; 113 unsigned long jtag_control; 114 uint64_t input_buf; 115 int waiting_input; 116} jtag_t; 117 118 119/* ********************************************************************* 120 * jtag_probe(drv,probe_a,probe_b,probe_ptr) 121 * 122 * Device "Probe" routine. This routine creates the soft 123 * context for the device and calls the attach routine. 124 * 125 * Input parameters: 126 * drv - driver structure 127 * probe_a,probe_b,probe_ptr - probe args 128 * 129 * Return value: 130 * nothing 131 ********************************************************************* */ 132 133 134static void jtag_probe(cfe_driver_t *drv, 135 unsigned long probe_a, 136 unsigned long probe_b, 137 void *probe_ptr) 138{ 139 jtag_t *softc; 140 char descr[80]; 141 142 /* 143 * probe_a is the physical base address within JTAG space of the 144 * communications area. 145 */ 146 147 softc = (jtag_t *) KMALLOC(sizeof(jtag_t),0); 148 if (softc) { 149 softc->jtag_input = probe_a + JTAG_CONS_INPUT; 150 softc->jtag_output = probe_a + JTAG_CONS_OUTPUT; 151 softc->jtag_control = probe_a + JTAG_CONS_CONTROL; 152 softc->waiting_input = 0; 153 xsprintf(descr,"%s at 0x%X",drv->drv_description,probe_a); 154 cfe_attach(drv,softc,NULL,descr); 155 } 156} 157 158 159 160/* ********************************************************************* 161 * jtag_open(ctx) 162 * 163 * Open the device 164 * 165 * Input parameters: 166 * ctx - device context 167 * 168 * Return value: 169 * 0 if ok, else error code 170 ********************************************************************* */ 171static int jtag_open(cfe_devctx_t *ctx) 172{ 173 jtag_t *softc = ctx->dev_softc; 174 int64_t timer; 175 uint64_t magic; 176 177 TIMER_SET(timer, 120*CFE_HZ); 178 do { 179 POLL(); 180 magic = SBREADCSR(softc->jtag_control); 181 } while ((magic == 0) && !TIMER_EXPIRED(timer)); 182 183 if (magic != JTAG_CONS_MAGICNUM) { 184 return -1; 185 } 186 187 return 0; 188} 189 190/* ********************************************************************* 191 * jtag_grab_dword(softc) 192 * 193 * Get the next dword (if any) from the JTAG client. (Local helper 194 * function - not part of the device dispatch table). 195 * 196 * Input parameters: 197 * softc - jtag structure 198 ********************************************************************* */ 199static void jtag_grab_dword(jtag_t *softc) 200{ 201 uint64_t inbuf; 202 203 inbuf = SBREADCSR(softc->jtag_input); 204 softc->waiting_input = jtag_input_len(inbuf); 205 softc->input_buf = inbuf << 8; 206} 207 208/* ********************************************************************* 209 * jtag_read(ctx,buffer) 210 * 211 * Read data from the device 212 * 213 * Input parameters: 214 * ctx - device context 215 * buffer - I/O buffer descriptor 216 * 217 * Return value: 218 * 0 if successful, or <0 if error 219 ********************************************************************* */ 220static int jtag_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer) 221{ 222 jtag_t *softc = ctx->dev_softc; 223 hsaddr_t bptr; 224 int blen; 225 uint8_t b; 226 227 bptr = buffer->buf_ptr; 228 blen = buffer->buf_length; 229 230 /* If the caller always inpstats first, we don't need to do this! */ 231 if (softc->waiting_input == 0) { 232 jtag_grab_dword(softc); 233 } 234 235 while ((blen > 0) && (softc->waiting_input)) { 236 int bytes = blen > softc->waiting_input ? softc->waiting_input : blen; 237 int i; 238 239 /* Take min(waiting,blen) from input_buf */ 240 for (i=0; i<bytes; i++) { 241 b = (softc->input_buf >> 56) & 0xFF; 242 hs_write8(bptr,b); 243 bptr++; 244 softc->input_buf <<= 8; 245 } 246 247 softc->waiting_input -= bytes; 248 blen -= bytes; 249 250 if (softc->waiting_input == 0) { 251 /* Look for more */ 252 jtag_grab_dword(softc); 253 } 254 } 255 256 buffer->buf_retlen = buffer->buf_length - blen; 257 258 return 0; 259} 260 261/* ********************************************************************* 262 * jtag_inpstat(ctx,inpstat) 263 * 264 * Determine if read data is available 265 * 266 * Input parameters: 267 * ctx - device context 268 * inpstat - input status structure 269 * 270 * Return value: 271 * 0 272 ********************************************************************* */ 273 274static int jtag_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat) 275{ 276 jtag_t *softc = ctx->dev_softc; 277 278 if (softc->waiting_input == 0) { 279 jtag_grab_dword(softc); 280 } 281 282 inpstat->inp_status = softc->waiting_input ? 1 : 0; 283 284 return 0; 285} 286 287/* ********************************************************************* 288 * jtag_write(ctx,buffer) 289 * 290 * Write data to the device 291 * 292 * Input parameters: 293 * ctx - device context 294 * buffer - I/O buffer descriptor 295 * 296 * Return value: 297 * 0 if successful, or <0 if error 298 ********************************************************************* */ 299static int jtag_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer) 300{ 301 jtag_t *softc = ctx->dev_softc; 302 hsaddr_t bptr; 303 uint8_t b; 304 int blen, bytes, i; 305 uint64_t data; 306 307 bptr = buffer->buf_ptr; 308 blen = buffer->buf_length; 309 310 while (blen > 0) { 311 bytes = (blen > 7) ? 7 : blen; 312 data = bytes; 313 for (i=0; i<bytes; i++) { 314 data <<= 8; 315 b = hs_read8(bptr); 316 bptr++; 317 data |= b; 318 319 } 320 if (bytes < 7) 321 data <<= 8 * (7-bytes); 322 blen -= bytes; 323 SBWRITECSR(softc->jtag_output, data); 324 } 325 326 buffer->buf_retlen = buffer->buf_length - blen; /* always 0 */ 327 return 0; /* XXX blen? */ 328} 329 330/* ********************************************************************* 331 * jtag_ioctl(ctx,buffer) 332 * 333 * Do I/O control operations 334 * 335 * Input parameters: 336 * ctx - device context 337 * buffer - I/O control args 338 * 339 * Return value: 340 * 0 if ok 341 * else error code 342 ********************************************************************* */ 343 344static int jtag_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer) 345{ 346 return -1; 347} 348 349/* ********************************************************************* 350 * jtag_close(ctx) 351 * 352 * Close the device. 353 * 354 * Input parameters: 355 * ctx - device context 356 * 357 * Return value: 358 * 0 359 ********************************************************************* */ 360 361static int jtag_close(cfe_devctx_t *ctx) 362{ 363 return 0; 364} 365 366 367