1 /* $NetBSD: ixp425_npe.c,v 1.2 2007/02/22 05:14:05 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 Sam Leffler, Errno Consulting 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer, 12 * without modification. 13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 14 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 15 * redistribution must be conditioned upon including a substantially 16 * similar Disclaimer requirement for further binary redistribution. 17 * 18 * NO WARRANTY 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 22 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 23 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 24 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 29 * THE POSSIBILITY OF SUCH DAMAGES. 30 */ 31 32 /*- 33 * Copyright (c) 2001-2005, Intel Corporation. 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. Neither the name of the Intel Corporation nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 50 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 */ 61 #include <sys/cdefs.h> 62 #if 0 63 __FBSDID("$FreeBSD: src/sys/arm/xscale/ixp425/ixp425_npe.c,v 1.1 2006/11/19 23:55:23 sam Exp $"); 64 #endif 65 __KERNEL_RCSID(0, "$NetBSD: ixp425_npe.c,v 1.2 2007/02/22 05:14:05 thorpej Exp $"); 66 67 /* 68 * Intel XScale Network Processing Engine (NPE) support. 69 * 70 * Each NPE has an ixpnpeX device associated with it that is 71 * attached at boot. Depending on the microcode loaded into 72 * an NPE there may be an Ethernet interface (npeX) or some 73 * other network interface (e.g. for ATM). This file has support 74 * for loading microcode images and the associated NPE CPU 75 * manipulations (start, stop, reset). 76 * 77 * The code here basically replaces the npeDl and npeMh classes 78 * in the Intel Access Library (IAL). 79 * 80 * NB: Microcode images are loaded with firmware(9). To 81 * include microcode in a static kernel include the 82 * ixpnpe_fw device. Otherwise the firmware will be 83 * automatically loaded from the filesystem. 84 */ 85 #include <sys/param.h> 86 #include <sys/systm.h> 87 #include <sys/kernel.h> 88 #include <sys/malloc.h> 89 #include <sys/time.h> 90 #include <sys/proc.h> 91 92 #include <dev/firmload.h> 93 94 #include <machine/bus.h> 95 #include <machine/cpu.h> 96 #include <machine/intr.h> 97 98 #include <arm/xscale/ixp425reg.h> 99 #include <arm/xscale/ixp425var.h> 100 #include <arm/xscale/ixp425_ixmevar.h> 101 102 #include <arm/xscale/ixp425_npereg.h> 103 #include <arm/xscale/ixp425_npevar.h> 104 105 #include "locators.h" 106 107 struct ixpnpe_softc { 108 struct device sc_dev; 109 bus_dma_tag_t sc_dt; 110 bus_space_tag_t sc_iot; 111 bus_space_handle_t sc_ioh; 112 bus_size_t sc_size; /* size of mapped register window */ 113 int sc_unit; 114 void *sc_ih; /* interrupt handler */ 115 struct simplelock sc_lock; /* mailbox lock */ 116 uint32_t sc_msg[2]; /* reply msg collected in ixpnpe_intr */ 117 int sc_msgwaiting; /* sc_msg holds valid data */ 118 119 int validImage; /* valid ucode image loaded */ 120 int started; /* NPE is started */ 121 uint8_t functionalityId;/* ucode functionality ID */ 122 int insMemSize; /* size of instruction memory */ 123 int dataMemSize; /* size of data memory */ 124 uint32_t savedExecCount; 125 uint32_t savedEcsDbgCtxtReg2; 126 }; 127 128 /* 129 * IXP425_NPE_MICROCODE will be defined by ixp425-fw.mk IFF the 130 * microcode object file exists in sys/arch/arm/xscale. 131 * 132 * To permit building the NPE drivers without microcode (so they 133 * don't bitrot due to lack of use), we use "empty" microcode so 134 * that the NPE drivers will simply fail to start at runtime. 135 */ 136 #ifdef IXP425_NPE_MICROCODE 137 extern char _binary_IxNpeMicrocode_dat_start[]; 138 #else 139 static char _binary_IxNpeMicrocode_dat_start[] = { 140 0xfe, 0xed, 0xf0, 0x0d, 0xfe, 0xed, 0xf0, 0x0d 141 }; 142 #endif 143 144 #define IX_NPEDL_NPEIMAGE_FIELD_MASK 0xff 145 146 /* used to read download map from version in microcode image */ 147 #define IX_NPEDL_BLOCK_TYPE_INSTRUCTION 0x00000000 148 #define IX_NPEDL_BLOCK_TYPE_DATA 0x00000001 149 #define IX_NPEDL_BLOCK_TYPE_STATE 0x00000002 150 #define IX_NPEDL_END_OF_DOWNLOAD_MAP 0x0000000F 151 152 /* 153 * masks used to extract address info from State information context 154 * register addresses as read from microcode image 155 */ 156 #define IX_NPEDL_MASK_STATE_ADDR_CTXT_REG 0x0000000F 157 #define IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM 0x000000F0 158 159 /* LSB offset of Context Number field in State-Info Context Address */ 160 #define IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM 4 161 162 /* size (in words) of single State Information entry (ctxt reg address|data) */ 163 #define IX_NPEDL_STATE_INFO_ENTRY_SIZE 2 164 165 typedef struct { 166 uint32_t type; 167 uint32_t offset; 168 } IxNpeDlNpeMgrDownloadMapBlockEntry; 169 170 typedef union { 171 IxNpeDlNpeMgrDownloadMapBlockEntry block; 172 uint32_t eodmMarker; 173 } IxNpeDlNpeMgrDownloadMapEntry; 174 175 typedef struct { 176 /* 1st entry in the download map (there may be more than one) */ 177 IxNpeDlNpeMgrDownloadMapEntry entry[1]; 178 } IxNpeDlNpeMgrDownloadMap; 179 180 /* used to access an instruction or data block in a microcode image */ 181 typedef struct { 182 uint32_t npeMemAddress; 183 uint32_t size; 184 uint32_t data[1]; 185 } IxNpeDlNpeMgrCodeBlock; 186 187 /* used to access each Context Reg entry state-information block */ 188 typedef struct { 189 uint32_t addressInfo; 190 uint32_t value; 191 } IxNpeDlNpeMgrStateInfoCtxtRegEntry; 192 193 /* used to access a state-information block in a microcode image */ 194 typedef struct { 195 uint32_t size; 196 IxNpeDlNpeMgrStateInfoCtxtRegEntry ctxtRegEntry[1]; 197 } IxNpeDlNpeMgrStateInfoBlock; 198 199 static int npe_debug = 0; 200 #define DPRINTF(dev, fmt, ...) do { \ 201 if (npe_debug) printf(fmt, __VA_ARGS__); \ 202 } while (0) 203 #define DPRINTFn(n, dev, fmt, ...) do { \ 204 if (npe_debug >= n) printf(fmt, __VA_ARGS__); \ 205 } while (0) 206 207 static int npe_checkbits(struct ixpnpe_softc *, uint32_t reg, uint32_t); 208 static int npe_isstopped(struct ixpnpe_softc *); 209 static int npe_load_ins(struct ixpnpe_softc *, 210 const IxNpeDlNpeMgrCodeBlock *bp, int verify); 211 static int npe_load_data(struct ixpnpe_softc *, 212 const IxNpeDlNpeMgrCodeBlock *bp, int verify); 213 static int npe_load_stateinfo(struct ixpnpe_softc *, 214 const IxNpeDlNpeMgrStateInfoBlock *bp, int verify); 215 static int npe_load_image(struct ixpnpe_softc *, 216 const uint32_t *imageCodePtr, int verify); 217 static int npe_cpu_reset(struct ixpnpe_softc *); 218 static int npe_cpu_start(struct ixpnpe_softc *); 219 static int npe_cpu_stop(struct ixpnpe_softc *); 220 static void npe_cmd_issue_write(struct ixpnpe_softc *, 221 uint32_t cmd, uint32_t addr, uint32_t data); 222 static uint32_t npe_cmd_issue_read(struct ixpnpe_softc *, 223 uint32_t cmd, uint32_t addr); 224 static int npe_ins_write(struct ixpnpe_softc *, 225 uint32_t addr, uint32_t data, int verify); 226 static int npe_data_write(struct ixpnpe_softc *, 227 uint32_t addr, uint32_t data, int verify); 228 static void npe_ecs_reg_write(struct ixpnpe_softc *, 229 uint32_t reg, uint32_t data); 230 static uint32_t npe_ecs_reg_read(struct ixpnpe_softc *, uint32_t reg); 231 static void npe_issue_cmd(struct ixpnpe_softc *, uint32_t command); 232 static void npe_cpu_step_save(struct ixpnpe_softc *); 233 static int npe_cpu_step(struct ixpnpe_softc *, uint32_t npeInstruction, 234 uint32_t ctxtNum, uint32_t ldur); 235 static void npe_cpu_step_restore(struct ixpnpe_softc *); 236 static int npe_logical_reg_read(struct ixpnpe_softc *, 237 uint32_t regAddr, uint32_t regSize, 238 uint32_t ctxtNum, uint32_t *regVal); 239 static int npe_logical_reg_write(struct ixpnpe_softc *, 240 uint32_t regAddr, uint32_t regVal, 241 uint32_t regSize, uint32_t ctxtNum, int verify); 242 static int npe_physical_reg_write(struct ixpnpe_softc *, 243 uint32_t regAddr, uint32_t regValue, int verify); 244 static int npe_ctx_reg_write(struct ixpnpe_softc *, uint32_t ctxtNum, 245 uint32_t ctxtReg, uint32_t ctxtRegVal, int verify); 246 247 static int ixpnpe_intr(void *arg); 248 249 static uint32_t 250 npe_reg_read(struct ixpnpe_softc *sc, bus_size_t off) 251 { 252 uint32_t v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, off); 253 DPRINTFn(9, sc->sc_dev, "%s(0x%lx) => 0x%x\n", __func__, off, v); 254 return v; 255 } 256 257 static void 258 npe_reg_write(struct ixpnpe_softc *sc, bus_size_t off, uint32_t val) 259 { 260 DPRINTFn(9, sc->sc_dev, "%s(0x%lx, 0x%x)\n", __func__, off, val); 261 bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, val); 262 } 263 264 static int ixpnpe_match(struct device *, struct cfdata *, void *); 265 static void ixpnpe_attach(struct device *, struct device *, void *); 266 static int ixpnpe_print(void *, const char *); 267 static int ixpnpe_search(struct device *, struct cfdata *, const int *, 268 void *); 269 270 CFATTACH_DECL(ixpnpe, sizeof(struct ixpnpe_softc), 271 ixpnpe_match, ixpnpe_attach, NULL, NULL); 272 273 static int 274 ixpnpe_match(struct device *parent, struct cfdata *match, void *arg) 275 { 276 struct ixme_attach_args *ixa = arg; 277 278 return (ixa->ixa_npe == 1 || ixa->ixa_npe == 2); 279 } 280 281 static void 282 ixpnpe_attach(struct device *parent, struct device *self, void *arg) 283 { 284 struct ixpnpe_softc *sc = (void *)self; 285 struct ixme_attach_args *ixa = arg; 286 bus_addr_t base; 287 int irq; 288 289 aprint_naive("\n"); 290 aprint_normal("\n"); 291 292 sc->sc_iot = ixa->ixa_iot; 293 sc->sc_dt = ixa->ixa_dt; 294 sc->sc_unit = ixa->ixa_npe; 295 296 simple_lock_init(&sc->sc_lock); 297 298 /* XXX: Check features to ensure this NPE is enabled */ 299 300 switch (ixa->ixa_npe) { 301 default: 302 panic("%s: Invalid NPE!", sc->sc_dev.dv_xname); 303 304 case 1: 305 base = IXP425_NPE_B_HWBASE; 306 sc->sc_size = IXP425_NPE_B_SIZE; 307 irq = IXP425_INT_NPE_B; 308 309 /* size of instruction memory */ 310 sc->insMemSize = IX_NPEDL_INS_MEMSIZE_WORDS_NPEB; 311 /* size of data memory */ 312 sc->dataMemSize = IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB; 313 break; 314 315 case 2: 316 base = IXP425_NPE_C_HWBASE; 317 sc->sc_size = IXP425_NPE_C_SIZE; 318 irq = IXP425_INT_NPE_C; 319 320 /* size of instruction memory */ 321 sc->insMemSize = IX_NPEDL_INS_MEMSIZE_WORDS_NPEC; 322 /* size of data memory */ 323 sc->dataMemSize = IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC; 324 break; 325 } 326 if (bus_space_map(sc->sc_iot, base, sc->sc_size, 0, &sc->sc_ioh)) 327 panic("%s: Cannot map registers", sc->sc_dev.dv_xname); 328 329 /* 330 * Setup IRQ and handler for NPE message support. 331 */ 332 sc->sc_ih = ixp425_intr_establish(irq, IPL_NET, ixpnpe_intr, sc); 333 if (sc->sc_ih == NULL) 334 panic("%s: Unable to establish irq %u", sc->sc_dev.dv_xname, irq); 335 /* enable output fifo interrupts (NB: must also set OFIFO Write Enable) */ 336 npe_reg_write(sc, IX_NPECTL, 337 npe_reg_read(sc, IX_NPECTL) | (IX_NPECTL_OFE | IX_NPECTL_OFWE)); 338 339 config_search_ia(ixpnpe_search, self, "ixpnpe", ixa); 340 } 341 342 static int 343 ixpnpe_print(void *arg, const char *name) 344 { 345 346 return (UNCONF); 347 } 348 349 static int 350 ixpnpe_search(struct device *parent, struct cfdata *cf, const int *ldesc, 351 void *arg) 352 { 353 struct ixpnpe_softc *sc = (void *)parent; 354 struct ixme_attach_args *ixa = arg; 355 struct ixpnpe_attach_args na; 356 357 na.na_unit = ixa->ixa_npe; 358 na.na_phy = cf->cf_loc[IXPNPECF_PHY]; 359 na.na_npe = sc; 360 na.na_iot = ixa->ixa_iot; 361 na.na_dt = ixa->ixa_dt; 362 363 if (config_match(parent, cf, &na) > 0) { 364 config_attach(parent, cf, &na, ixpnpe_print); 365 return (1); 366 } 367 368 return (0); 369 } 370 371 int 372 ixpnpe_stopandreset(struct ixpnpe_softc *sc) 373 { 374 int error; 375 376 simple_lock(&sc->sc_lock); 377 error = npe_cpu_stop(sc); /* stop NPE */ 378 if (error == 0) 379 error = npe_cpu_reset(sc); /* reset it */ 380 if (error == 0) 381 sc->started = 0; /* mark stopped */ 382 simple_unlock(&sc->sc_lock); 383 384 DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error); 385 return error; 386 } 387 388 static int 389 ixpnpe_start_locked(struct ixpnpe_softc *sc) 390 { 391 int error; 392 393 if (!sc->started) { 394 error = npe_cpu_start(sc); 395 if (error == 0) 396 sc->started = 1; 397 } else 398 error = 0; 399 400 DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error); 401 return error; 402 } 403 404 int 405 ixpnpe_start(struct ixpnpe_softc *sc) 406 { 407 int ret; 408 409 simple_lock(&sc->sc_lock); 410 ret = ixpnpe_start_locked(sc); 411 simple_unlock(&sc->sc_lock); 412 return (ret); 413 } 414 415 int 416 ixpnpe_stop(struct ixpnpe_softc *sc) 417 { 418 int error; 419 420 simple_lock(&sc->sc_lock); 421 error = npe_cpu_stop(sc); 422 if (error == 0) 423 sc->started = 0; 424 simple_unlock(&sc->sc_lock); 425 426 DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error); 427 return error; 428 } 429 430 /* 431 * Indicates the start of an NPE Image, in new NPE Image Library format. 432 * 2 consecutive occurances indicates the end of the NPE Image Library 433 */ 434 #define NPE_IMAGE_MARKER 0xfeedf00d 435 436 /* 437 * NPE Image Header definition, used in new NPE Image Library format 438 */ 439 typedef struct { 440 uint32_t marker; 441 uint32_t id; 442 uint32_t size; 443 } IxNpeDlImageMgrImageHeader; 444 445 static int 446 npe_findimage(struct ixpnpe_softc *sc, 447 const uint32_t *imageLibrary, uint32_t imageId, 448 const uint32_t **imagePtr, uint32_t *imageSize) 449 { 450 const IxNpeDlImageMgrImageHeader *image; 451 uint32_t offset = 0; 452 453 while (imageLibrary[offset] == NPE_IMAGE_MARKER) { 454 image = (const IxNpeDlImageMgrImageHeader *)&imageLibrary[offset]; 455 offset += sizeof(IxNpeDlImageMgrImageHeader)/sizeof(uint32_t); 456 457 DPRINTF(sc->sc_dev, "%s: off %u mark 0x%x id 0x%x size %u\n", 458 __func__, offset, image->marker, image->id, image->size); 459 if (image->id == imageId) { 460 *imagePtr = imageLibrary + offset; 461 *imageSize = image->size; 462 return 0; 463 } 464 /* 2 consecutive NPE_IMAGE_MARKER's indicates end of library */ 465 if (image->id == NPE_IMAGE_MARKER) { 466 printf("%s: imageId 0x%08x not found in image library header\n", 467 sc->sc_dev.dv_xname, imageId); 468 /* reached end of library, image not found */ 469 return EIO; 470 } 471 offset += image->size; 472 } 473 return EIO; 474 } 475 476 int 477 ixpnpe_init(struct ixpnpe_softc *sc, const char *imageName, uint32_t imageId) 478 { 479 uint32_t imageSize; 480 const uint32_t *imageCodePtr; 481 void *fw; 482 int error; 483 484 DPRINTF(sc->sc_dev, "load %s, imageId 0x%08x\n", imageName, imageId); 485 486 #if 0 487 IxFeatureCtrlDeviceId devid = IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId); 488 /* 489 * Checking if image being loaded is meant for device that is running. 490 * Image is forward compatible. i.e Image built for IXP42X should run 491 * on IXP46X but not vice versa. 492 */ 493 if (devid > (ixFeatureCtrlDeviceRead() & IX_FEATURE_CTRL_DEVICE_TYPE_MASK)) 494 return EINVAL; 495 #endif 496 error = ixpnpe_stopandreset(sc); /* stop and reset the NPE */ 497 if (error != 0) 498 return error; 499 500 fw = (void *)_binary_IxNpeMicrocode_dat_start; 501 502 /* Locate desired image in files w/ combined images */ 503 error = npe_findimage(sc, (void *)fw /*fw->data*/, imageId, &imageCodePtr, &imageSize); 504 if (error != 0) 505 goto done; 506 507 /* 508 * If download was successful, store image Id in list of 509 * currently loaded images. If a critical error occured 510 * during download, record that the NPE has an invalid image 511 */ 512 simple_lock(&sc->sc_lock); 513 error = npe_load_image(sc, imageCodePtr, 1 /*VERIFY*/); 514 if (error == 0) { 515 sc->validImage = 1; 516 error = ixpnpe_start_locked(sc); 517 } else { 518 sc->validImage = 0; 519 } 520 sc->functionalityId = IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId); 521 simple_unlock(&sc->sc_lock); 522 done: 523 DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error); 524 return error; 525 } 526 527 int 528 ixpnpe_getfunctionality(struct ixpnpe_softc *sc) 529 { 530 return (sc->validImage ? sc->functionalityId : 0); 531 } 532 533 static int 534 npe_checkbits(struct ixpnpe_softc *sc, uint32_t reg, uint32_t expectedBitsSet) 535 { 536 uint32_t val; 537 538 val = npe_reg_read(sc, reg); 539 DPRINTFn(5, sc->sc_dev, "%s(0x%x, 0x%x) => 0x%x (%u)\n", 540 __func__, reg, expectedBitsSet, val, 541 (val & expectedBitsSet) == expectedBitsSet); 542 return ((val & expectedBitsSet) == expectedBitsSet); 543 } 544 545 static int 546 npe_isstopped(struct ixpnpe_softc *sc) 547 { 548 return npe_checkbits(sc, 549 IX_NPEDL_REG_OFFSET_EXCTL, IX_NPEDL_EXCTL_STATUS_STOP); 550 } 551 552 static int 553 npe_load_ins(struct ixpnpe_softc *sc, 554 const IxNpeDlNpeMgrCodeBlock *bp, int verify) 555 { 556 uint32_t npeMemAddress; 557 int i, blockSize; 558 559 npeMemAddress = bp->npeMemAddress; 560 blockSize = bp->size; /* NB: instruction/data count */ 561 if (npeMemAddress + blockSize > sc->insMemSize) { 562 printf("%s: Block size too big for NPE memory\n", sc->sc_dev.dv_xname); 563 return EINVAL; /* XXX */ 564 } 565 for (i = 0; i < blockSize; i++, npeMemAddress++) { 566 if (npe_ins_write(sc, npeMemAddress, bp->data[i], verify) != 0) { 567 printf("%s: NPE instruction write failed", sc->sc_dev.dv_xname); 568 return EIO; 569 } 570 } 571 return 0; 572 } 573 574 static int 575 npe_load_data(struct ixpnpe_softc *sc, 576 const IxNpeDlNpeMgrCodeBlock *bp, int verify) 577 { 578 uint32_t npeMemAddress; 579 int i, blockSize; 580 581 npeMemAddress = bp->npeMemAddress; 582 blockSize = bp->size; /* NB: instruction/data count */ 583 if (npeMemAddress + blockSize > sc->dataMemSize) { 584 printf("%s: Block size too big for NPE memory\n", sc->sc_dev.dv_xname); 585 return EINVAL; 586 } 587 for (i = 0; i < blockSize; i++, npeMemAddress++) { 588 if (npe_data_write(sc, npeMemAddress, bp->data[i], verify) != 0) { 589 printf("%s: NPE data write failed\n", sc->sc_dev.dv_xname); 590 return EIO; 591 } 592 } 593 return 0; 594 } 595 596 static int 597 npe_load_stateinfo(struct ixpnpe_softc *sc, 598 const IxNpeDlNpeMgrStateInfoBlock *bp, int verify) 599 { 600 int i, nentries, error; 601 602 npe_cpu_step_save(sc); 603 604 /* for each state-info context register entry in block */ 605 nentries = bp->size / IX_NPEDL_STATE_INFO_ENTRY_SIZE; 606 error = 0; 607 for (i = 0; i < nentries; i++) { 608 /* each state-info entry is 2 words (address, value) in length */ 609 uint32_t regVal = bp->ctxtRegEntry[i].value; 610 uint32_t addrInfo = bp->ctxtRegEntry[i].addressInfo; 611 612 uint32_t reg = (addrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_REG); 613 uint32_t cNum = (addrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM) >> 614 IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM; 615 616 /* error-check Context Register No. and Context Number values */ 617 if (!(0 <= reg && reg < IX_NPEDL_CTXT_REG_MAX)) { 618 printf("%s: invalid Context Register %u\n", sc->sc_dev.dv_xname, 619 reg); 620 error = EINVAL; 621 break; 622 } 623 if (!(0 <= cNum && cNum < IX_NPEDL_CTXT_NUM_MAX)) { 624 printf("%s: invalid Context Number %u\n", sc->sc_dev.dv_xname, 625 cNum); 626 error = EINVAL; 627 break; 628 } 629 /* NOTE that there is no STEVT register for Context 0 */ 630 if (cNum == 0 && reg == IX_NPEDL_CTXT_REG_STEVT) { 631 printf("%s: no STEVT for Context 0\n", sc->sc_dev.dv_xname); 632 error = EINVAL; 633 break; 634 } 635 636 if (npe_ctx_reg_write(sc, cNum, reg, regVal, verify) != 0) { 637 printf("%s: write of state-info to NPE failed\n", 638 sc->sc_dev.dv_xname); 639 error = EIO; 640 break; 641 } 642 } 643 644 npe_cpu_step_restore(sc); 645 return error; 646 } 647 648 static int 649 npe_load_image(struct ixpnpe_softc *sc, 650 const uint32_t *imageCodePtr, int verify) 651 { 652 #define EOM(marker) ((marker) == IX_NPEDL_END_OF_DOWNLOAD_MAP) 653 const IxNpeDlNpeMgrDownloadMap *downloadMap; 654 int i, error; 655 656 if (!npe_isstopped(sc)) { /* verify NPE is stopped */ 657 printf("%s: cannot load image, NPE not stopped\n", sc->sc_dev.dv_xname); 658 return EIO; 659 } 660 661 /* 662 * Read Download Map, checking each block type and calling 663 * appropriate function to perform download 664 */ 665 error = 0; 666 downloadMap = (const IxNpeDlNpeMgrDownloadMap *) imageCodePtr; 667 for (i = 0; !EOM(downloadMap->entry[i].eodmMarker); i++) { 668 /* calculate pointer to block to be downloaded */ 669 const uint32_t *bp = imageCodePtr + downloadMap->entry[i].block.offset; 670 switch (downloadMap->entry[i].block.type) { 671 case IX_NPEDL_BLOCK_TYPE_INSTRUCTION: 672 error = npe_load_ins(sc, 673 (const IxNpeDlNpeMgrCodeBlock *) bp, verify); 674 DPRINTF(sc->sc_dev, "%s: inst, error %d\n", __func__, error); 675 break; 676 case IX_NPEDL_BLOCK_TYPE_DATA: 677 error = npe_load_data(sc, 678 (const IxNpeDlNpeMgrCodeBlock *) bp, verify); 679 DPRINTF(sc->sc_dev, "%s: data, error %d\n", __func__, error); 680 break; 681 case IX_NPEDL_BLOCK_TYPE_STATE: 682 error = npe_load_stateinfo(sc, 683 (const IxNpeDlNpeMgrStateInfoBlock *) bp, verify); 684 DPRINTF(sc->sc_dev, "%s: state, error %d\n", __func__, error); 685 break; 686 default: 687 printf("%s: unknown block type 0x%x in download map\n", 688 sc->sc_dev.dv_xname, downloadMap->entry[i].block.type); 689 error = EIO; /* XXX */ 690 break; 691 } 692 if (error != 0) 693 break; 694 } 695 return error; 696 #undef EOM 697 } 698 699 /* contains Reset values for Context Store Registers */ 700 static const struct { 701 uint32_t regAddr; 702 uint32_t regResetVal; 703 } ixNpeDlEcsRegResetValues[] = { 704 { IX_NPEDL_ECS_BG_CTXT_REG_0, IX_NPEDL_ECS_BG_CTXT_REG_0_RESET }, 705 { IX_NPEDL_ECS_BG_CTXT_REG_1, IX_NPEDL_ECS_BG_CTXT_REG_1_RESET }, 706 { IX_NPEDL_ECS_BG_CTXT_REG_2, IX_NPEDL_ECS_BG_CTXT_REG_2_RESET }, 707 { IX_NPEDL_ECS_PRI_1_CTXT_REG_0, IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET }, 708 { IX_NPEDL_ECS_PRI_1_CTXT_REG_1, IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET }, 709 { IX_NPEDL_ECS_PRI_1_CTXT_REG_2, IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET }, 710 { IX_NPEDL_ECS_PRI_2_CTXT_REG_0, IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET }, 711 { IX_NPEDL_ECS_PRI_2_CTXT_REG_1, IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET }, 712 { IX_NPEDL_ECS_PRI_2_CTXT_REG_2, IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET }, 713 { IX_NPEDL_ECS_DBG_CTXT_REG_0, IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET }, 714 { IX_NPEDL_ECS_DBG_CTXT_REG_1, IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET }, 715 { IX_NPEDL_ECS_DBG_CTXT_REG_2, IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET }, 716 { IX_NPEDL_ECS_INSTRUCT_REG, IX_NPEDL_ECS_INSTRUCT_REG_RESET } 717 }; 718 719 /* contains Reset values for Context Store Registers */ 720 static const uint32_t ixNpeDlCtxtRegResetValues[] = { 721 IX_NPEDL_CTXT_REG_RESET_STEVT, 722 IX_NPEDL_CTXT_REG_RESET_STARTPC, 723 IX_NPEDL_CTXT_REG_RESET_REGMAP, 724 IX_NPEDL_CTXT_REG_RESET_CINDEX, 725 }; 726 727 #define IX_NPEDL_RESET_NPE_PARITY 0x0800 728 #define IX_NPEDL_PARITY_BIT_MASK 0x3F00FFFF 729 #define IX_NPEDL_CONFIG_CTRL_REG_MASK 0x3F3FFFFF 730 731 static int 732 npe_cpu_reset(struct ixpnpe_softc *sc) 733 { 734 #define N(a) (sizeof(a) / sizeof(a[0])) 735 uint32_t ctxtReg; /* identifies Context Store reg (0-3) */ 736 uint32_t regAddr; 737 uint32_t regVal; 738 uint32_t resetNpeParity; 739 uint32_t ixNpeConfigCtrlRegVal; 740 int i, error = 0; 741 742 /* pre-store the NPE Config Control Register Value */ 743 ixNpeConfigCtrlRegVal = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_CTL); 744 ixNpeConfigCtrlRegVal |= 0x3F000000; 745 746 /* disable the parity interrupt */ 747 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_CTL, 748 (ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK)); 749 DPRINTFn(2, sc->sc_dev, "%s: dis parity int, CTL => 0x%x\n", 750 __func__, ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK); 751 752 npe_cpu_step_save(sc); 753 754 /* 755 * Clear the FIFOs. 756 */ 757 while (npe_checkbits(sc, 758 IX_NPEDL_REG_OFFSET_WFIFO, IX_NPEDL_MASK_WFIFO_VALID)) { 759 /* read from the Watch-point FIFO until empty */ 760 (void) npe_reg_read(sc, IX_NPEDL_REG_OFFSET_WFIFO); 761 } 762 763 while (npe_checkbits(sc, 764 IX_NPEDL_REG_OFFSET_STAT, IX_NPEDL_MASK_STAT_OFNE)) { 765 /* read from the outFIFO until empty */ 766 (void) npe_reg_read(sc, IX_NPEDL_REG_OFFSET_FIFO); 767 } 768 769 while (npe_checkbits(sc, 770 IX_NPEDL_REG_OFFSET_STAT, IX_NPEDL_MASK_STAT_IFNE)) { 771 /* 772 * Step execution of the NPE intruction to read inFIFO using 773 * the Debug Executing Context stack. 774 */ 775 error = npe_cpu_step(sc, IX_NPEDL_INSTR_RD_FIFO, 0, 0); 776 if (error != 0) { 777 DPRINTF(sc->sc_dev, "%s: cannot step (1), error %u\n", 778 __func__, error); 779 npe_cpu_step_restore(sc); 780 return error; 781 } 782 } 783 784 /* 785 * Reset the mailbox reg 786 */ 787 /* ...from XScale side */ 788 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_MBST, IX_NPEDL_REG_RESET_MBST); 789 /* ...from NPE side */ 790 error = npe_cpu_step(sc, IX_NPEDL_INSTR_RESET_MBOX, 0, 0); 791 if (error != 0) { 792 DPRINTF(sc->sc_dev, "%s: cannot step (2), error %u\n", __func__, error); 793 npe_cpu_step_restore(sc); 794 return error; 795 } 796 797 /* 798 * Reset the physical registers in the NPE register file: 799 * Note: no need to save/restore REGMAP for Context 0 here 800 * since all Context Store regs are reset in subsequent code. 801 */ 802 for (regAddr = 0; 803 regAddr < IX_NPEDL_TOTAL_NUM_PHYS_REG && error == 0; 804 regAddr++) { 805 /* for each physical register in the NPE reg file, write 0 : */ 806 error = npe_physical_reg_write(sc, regAddr, 0, true); 807 if (error != 0) { 808 DPRINTF(sc->sc_dev, "%s: cannot write phy reg, error %u\n", 809 __func__, error); 810 npe_cpu_step_restore(sc); 811 return error; /* abort reset */ 812 } 813 } 814 815 /* 816 * Reset the context store: 817 */ 818 for (i = IX_NPEDL_CTXT_NUM_MIN; i <= IX_NPEDL_CTXT_NUM_MAX; i++) { 819 /* set each context's Context Store registers to reset values: */ 820 for (ctxtReg = 0; ctxtReg < IX_NPEDL_CTXT_REG_MAX; ctxtReg++) { 821 /* NOTE that there is no STEVT register for Context 0 */ 822 if (!(i == 0 && ctxtReg == IX_NPEDL_CTXT_REG_STEVT)) { 823 regVal = ixNpeDlCtxtRegResetValues[ctxtReg]; 824 error = npe_ctx_reg_write(sc, i, ctxtReg, regVal, true); 825 if (error != 0) { 826 DPRINTF(sc->sc_dev, "%s: cannot write ctx reg, error %u\n", 827 __func__, error); 828 npe_cpu_step_restore(sc); 829 return error; /* abort reset */ 830 } 831 } 832 } 833 } 834 835 npe_cpu_step_restore(sc); 836 837 /* write Reset values to Execution Context Stack registers */ 838 for (i = 0; i < N(ixNpeDlEcsRegResetValues); i++) 839 npe_ecs_reg_write(sc, 840 ixNpeDlEcsRegResetValues[i].regAddr, 841 ixNpeDlEcsRegResetValues[i].regResetVal); 842 843 /* clear the profile counter */ 844 npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT); 845 846 /* clear registers EXCT, AP0, AP1, AP2 and AP3 */ 847 for (regAddr = IX_NPEDL_REG_OFFSET_EXCT; 848 regAddr <= IX_NPEDL_REG_OFFSET_AP3; 849 regAddr += sizeof(uint32_t)) 850 npe_reg_write(sc, regAddr, 0); 851 852 /* Reset the Watch-count register */ 853 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_WC, 0); 854 855 /* 856 * WR IXA00055043 - Remove IMEM Parity Introduced by NPE Reset Operation 857 */ 858 859 /* 860 * Reset the NPE and its coprocessor - to reset internal 861 * states and remove parity error. Note this makes no 862 * sense based on the documentation. The feature control 863 * register always reads back as 0 on the ixp425 and further 864 * the bit definition of NPEA/NPEB is off by 1 according to 865 * the Intel documention--so we're blindly following the 866 * Intel code w/o any real understanding. 867 */ 868 regVal = EXP_BUS_READ_4(ixp425_softc, EXP_FCTRL_OFFSET); 869 DPRINTFn(2, sc->sc_dev, "%s: FCTRL 0x%x\n", __func__, regVal); 870 resetNpeParity = 871 IX_NPEDL_RESET_NPE_PARITY << (1 + sc->sc_unit); 872 DPRINTFn(2, sc->sc_dev, "%s: FCTRL fuse parity, write 0x%x\n", 873 __func__, regVal | resetNpeParity); 874 EXP_BUS_WRITE_4(ixp425_softc, EXP_FCTRL_OFFSET, regVal | resetNpeParity); 875 876 /* un-fuse and un-reset the NPE & coprocessor */ 877 DPRINTFn(2, sc->sc_dev, "%s: FCTRL unfuse parity, write 0x%x\n", 878 __func__, regVal & resetNpeParity); 879 EXP_BUS_WRITE_4(ixp425_softc, EXP_FCTRL_OFFSET, regVal &~ resetNpeParity); 880 881 /* 882 * Call NpeMgr function to stop the NPE again after the Feature Control 883 * has unfused and Un-Reset the NPE and its associated Coprocessors. 884 */ 885 error = npe_cpu_stop(sc); 886 887 /* restore NPE configuration bus Control Register - Parity Settings */ 888 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_CTL, 889 (ixNpeConfigCtrlRegVal & IX_NPEDL_CONFIG_CTRL_REG_MASK)); 890 DPRINTFn(2, sc->sc_dev, "%s: restore CTL => 0x%x\n", 891 __func__, npe_reg_read(sc, IX_NPEDL_REG_OFFSET_CTL)); 892 893 return error; 894 #undef N 895 } 896 897 static int 898 npe_cpu_start(struct ixpnpe_softc *sc) 899 { 900 uint32_t ecsRegVal; 901 902 /* 903 * Ensure only Background Context Stack Level is Active by turning off 904 * the Active bit in each of the other Executing Context Stack levels. 905 */ 906 ecsRegVal = npe_ecs_reg_read(sc, IX_NPEDL_ECS_PRI_1_CTXT_REG_0); 907 ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE; 908 npe_ecs_reg_write(sc, IX_NPEDL_ECS_PRI_1_CTXT_REG_0, ecsRegVal); 909 910 ecsRegVal = npe_ecs_reg_read(sc, IX_NPEDL_ECS_PRI_2_CTXT_REG_0); 911 ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE; 912 npe_ecs_reg_write(sc, IX_NPEDL_ECS_PRI_2_CTXT_REG_0, ecsRegVal); 913 914 ecsRegVal = npe_ecs_reg_read(sc, IX_NPEDL_ECS_DBG_CTXT_REG_0); 915 ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE; 916 npe_ecs_reg_write(sc, IX_NPEDL_ECS_DBG_CTXT_REG_0, ecsRegVal); 917 918 /* clear the pipeline */ 919 npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE); 920 921 /* start NPE execution by issuing command through EXCTL register on NPE */ 922 npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_NPE_START); 923 924 /* 925 * Check execution status of NPE to verify operation was successful. 926 */ 927 return npe_checkbits(sc, 928 IX_NPEDL_REG_OFFSET_EXCTL, IX_NPEDL_EXCTL_STATUS_RUN) ? 0 : EIO; 929 } 930 931 static int 932 npe_cpu_stop(struct ixpnpe_softc *sc) 933 { 934 /* stop NPE execution by issuing command through EXCTL register on NPE */ 935 npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_NPE_STOP); 936 937 /* verify that NPE Stop was successful */ 938 return npe_checkbits(sc, 939 IX_NPEDL_REG_OFFSET_EXCTL, IX_NPEDL_EXCTL_STATUS_STOP) ? 0 : EIO; 940 } 941 942 #define IX_NPEDL_REG_SIZE_BYTE 8 943 #define IX_NPEDL_REG_SIZE_SHORT 16 944 #define IX_NPEDL_REG_SIZE_WORD 32 945 946 /* 947 * Introduce extra read cycles after issuing read command to NPE 948 * so that we read the register after the NPE has updated it 949 * This is to overcome race condition between XScale and NPE 950 */ 951 #define IX_NPEDL_DELAY_READ_CYCLES 2 952 /* 953 * To mask top three MSBs of 32bit word to download into NPE IMEM 954 */ 955 #define IX_NPEDL_MASK_UNUSED_IMEM_BITS 0x1FFFFFFF; 956 957 static void 958 npe_cmd_issue_write(struct ixpnpe_softc *sc, 959 uint32_t cmd, uint32_t addr, uint32_t data) 960 { 961 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXDATA, data); 962 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXAD, addr); 963 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXCTL, cmd); 964 } 965 966 static uint32_t 967 npe_cmd_issue_read(struct ixpnpe_softc *sc, uint32_t cmd, uint32_t addr) 968 { 969 uint32_t data; 970 int i; 971 972 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXAD, addr); 973 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXCTL, cmd); 974 for (i = 0; i <= IX_NPEDL_DELAY_READ_CYCLES; i++) 975 data = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_EXDATA); 976 return data; 977 } 978 979 static int 980 npe_ins_write(struct ixpnpe_softc *sc, uint32_t addr, uint32_t data, int verify) 981 { 982 DPRINTFn(4, sc->sc_dev, "%s(0x%x, 0x%x)\n", __func__, addr, data); 983 npe_cmd_issue_write(sc, IX_NPEDL_EXCTL_CMD_WR_INS_MEM, addr, data); 984 if (verify) { 985 uint32_t rdata; 986 987 /* 988 * Write invalid data to this reg, so we can see if we're reading 989 * the EXDATA register too early. 990 */ 991 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXDATA, ~data); 992 993 /* Disabled since top 3 MSB are not used for Azusa hardware Refer WR:IXA00053900*/ 994 data &= IX_NPEDL_MASK_UNUSED_IMEM_BITS; 995 996 rdata = npe_cmd_issue_read(sc, IX_NPEDL_EXCTL_CMD_RD_INS_MEM, addr); 997 rdata &= IX_NPEDL_MASK_UNUSED_IMEM_BITS; 998 999 if (data != rdata) 1000 return EIO; 1001 } 1002 return 0; 1003 } 1004 1005 static int 1006 npe_data_write(struct ixpnpe_softc *sc, uint32_t addr, uint32_t data, int verify) 1007 { 1008 DPRINTFn(4, sc->sc_dev, "%s(0x%x, 0x%x)\n", __func__, addr, data); 1009 npe_cmd_issue_write(sc, IX_NPEDL_EXCTL_CMD_WR_DATA_MEM, addr, data); 1010 if (verify) { 1011 /* 1012 * Write invalid data to this reg, so we can see if we're reading 1013 * the EXDATA register too early. 1014 */ 1015 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXDATA, ~data); 1016 if (data != npe_cmd_issue_read(sc, IX_NPEDL_EXCTL_CMD_RD_DATA_MEM, addr)) 1017 return EIO; 1018 } 1019 return 0; 1020 } 1021 1022 static void 1023 npe_ecs_reg_write(struct ixpnpe_softc *sc, uint32_t reg, uint32_t data) 1024 { 1025 npe_cmd_issue_write(sc, IX_NPEDL_EXCTL_CMD_WR_ECS_REG, reg, data); 1026 } 1027 1028 static uint32_t 1029 npe_ecs_reg_read(struct ixpnpe_softc *sc, uint32_t reg) 1030 { 1031 return npe_cmd_issue_read(sc, IX_NPEDL_EXCTL_CMD_RD_ECS_REG, reg); 1032 } 1033 1034 static void 1035 npe_issue_cmd(struct ixpnpe_softc *sc, uint32_t command) 1036 { 1037 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXCTL, command); 1038 } 1039 1040 static void 1041 npe_cpu_step_save(struct ixpnpe_softc *sc) 1042 { 1043 /* turn off the halt bit by clearing Execution Count register. */ 1044 /* save reg contents 1st and restore later */ 1045 sc->savedExecCount = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_EXCT); 1046 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXCT, 0); 1047 1048 /* ensure that IF and IE are on (temporarily), so that we don't end up 1049 * stepping forever */ 1050 sc->savedEcsDbgCtxtReg2 = npe_ecs_reg_read(sc, IX_NPEDL_ECS_DBG_CTXT_REG_2); 1051 1052 npe_ecs_reg_write(sc, IX_NPEDL_ECS_DBG_CTXT_REG_2, 1053 (sc->savedEcsDbgCtxtReg2 | IX_NPEDL_MASK_ECS_DBG_REG_2_IF | 1054 IX_NPEDL_MASK_ECS_DBG_REG_2_IE)); 1055 } 1056 1057 static int 1058 npe_cpu_step(struct ixpnpe_softc *sc, uint32_t npeInstruction, 1059 uint32_t ctxtNum, uint32_t ldur) 1060 { 1061 #define IX_NPE_DL_MAX_NUM_OF_RETRIES 1000000 1062 uint32_t ecsDbgRegVal; 1063 uint32_t oldWatchcount, newWatchcount; 1064 int tries; 1065 1066 /* set the Active bit, and the LDUR, in the debug level */ 1067 ecsDbgRegVal = IX_NPEDL_MASK_ECS_REG_0_ACTIVE | 1068 (ldur << IX_NPEDL_OFFSET_ECS_REG_0_LDUR); 1069 1070 npe_ecs_reg_write(sc, IX_NPEDL_ECS_DBG_CTXT_REG_0, ecsDbgRegVal); 1071 1072 /* 1073 * Set CCTXT at ECS DEBUG L3 to specify in which context to execute the 1074 * instruction, and set SELCTXT at ECS DEBUG Level to specify which context 1075 * store to access. 1076 * Debug ECS Level Reg 1 has form 0x000n000n, where n = context number 1077 */ 1078 ecsDbgRegVal = (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_CCTXT) | 1079 (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT); 1080 1081 npe_ecs_reg_write(sc, IX_NPEDL_ECS_DBG_CTXT_REG_1, ecsDbgRegVal); 1082 1083 /* clear the pipeline */ 1084 npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE); 1085 1086 /* load NPE instruction into the instruction register */ 1087 npe_ecs_reg_write(sc, IX_NPEDL_ECS_INSTRUCT_REG, npeInstruction); 1088 1089 /* we need this value later to wait for completion of NPE execution step */ 1090 oldWatchcount = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_WC); 1091 1092 /* issue a Step One command via the Execution Control register */ 1093 npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_NPE_STEP); 1094 1095 /* 1096 * Force the XScale to wait until the NPE has finished execution step 1097 * NOTE that this delay will be very small, just long enough to allow a 1098 * single NPE instruction to complete execution; if instruction execution 1099 * is not completed before timeout retries, exit the while loop. 1100 */ 1101 newWatchcount = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_WC); 1102 for (tries = 0; tries < IX_NPE_DL_MAX_NUM_OF_RETRIES && 1103 newWatchcount == oldWatchcount; tries++) { 1104 /* Watch Count register increments when NPE completes an instruction */ 1105 newWatchcount = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_WC); 1106 } 1107 return (tries < IX_NPE_DL_MAX_NUM_OF_RETRIES) ? 0 : EIO; 1108 #undef IX_NPE_DL_MAX_NUM_OF_RETRIES 1109 } 1110 1111 static void 1112 npe_cpu_step_restore(struct ixpnpe_softc *sc) 1113 { 1114 /* clear active bit in debug level */ 1115 npe_ecs_reg_write(sc, IX_NPEDL_ECS_DBG_CTXT_REG_0, 0); 1116 1117 /* clear the pipeline */ 1118 npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE); 1119 1120 /* restore Execution Count register contents. */ 1121 npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXCT, sc->savedExecCount); 1122 1123 /* restore IF and IE bits to original values */ 1124 npe_ecs_reg_write(sc, IX_NPEDL_ECS_DBG_CTXT_REG_2, sc->savedEcsDbgCtxtReg2); 1125 } 1126 1127 static int 1128 npe_logical_reg_read(struct ixpnpe_softc *sc, 1129 uint32_t regAddr, uint32_t regSize, 1130 uint32_t ctxtNum, uint32_t *regVal) 1131 { 1132 uint32_t npeInstruction, mask; 1133 int error; 1134 1135 switch (regSize) { 1136 case IX_NPEDL_REG_SIZE_BYTE: 1137 npeInstruction = IX_NPEDL_INSTR_RD_REG_BYTE; 1138 mask = 0xff; 1139 break; 1140 case IX_NPEDL_REG_SIZE_SHORT: 1141 npeInstruction = IX_NPEDL_INSTR_RD_REG_SHORT; 1142 mask = 0xffff; 1143 break; 1144 case IX_NPEDL_REG_SIZE_WORD: 1145 npeInstruction = IX_NPEDL_INSTR_RD_REG_WORD; 1146 mask = 0xffffffff; 1147 break; 1148 default: 1149 return EINVAL; 1150 } 1151 1152 /* make regAddr be the SRC and DEST operands (e.g. movX d0, d0) */ 1153 npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_SRC) | 1154 (regAddr << IX_NPEDL_OFFSET_INSTR_DEST); 1155 1156 /* step execution of NPE intruction using Debug Executing Context stack */ 1157 error = npe_cpu_step(sc, npeInstruction, ctxtNum, IX_NPEDL_RD_INSTR_LDUR); 1158 if (error != 0) { 1159 DPRINTF(sc->sc_dev, "%s(0x%x, %u, %u), cannot step, error %d\n", 1160 __func__, regAddr, regSize, ctxtNum, error); 1161 return error; 1162 } 1163 /* read value of register from Execution Data register */ 1164 *regVal = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_EXDATA); 1165 1166 /* align value from left to right */ 1167 *regVal = (*regVal >> (IX_NPEDL_REG_SIZE_WORD - regSize)) & mask; 1168 1169 return 0; 1170 } 1171 1172 static int 1173 npe_logical_reg_write(struct ixpnpe_softc *sc, uint32_t regAddr, uint32_t regVal, 1174 uint32_t regSize, uint32_t ctxtNum, int verify) 1175 { 1176 int error; 1177 1178 DPRINTFn(4, sc->sc_dev, "%s(0x%x, 0x%x, %u, %u)\n", 1179 __func__, regAddr, regVal, regSize, ctxtNum); 1180 if (regSize == IX_NPEDL_REG_SIZE_WORD) { 1181 /* NPE register addressing is left-to-right: e.g. |d0|d1|d2|d3| */ 1182 /* Write upper half-word (short) to |d0|d1| */ 1183 error = npe_logical_reg_write(sc, regAddr, 1184 regVal >> IX_NPEDL_REG_SIZE_SHORT, 1185 IX_NPEDL_REG_SIZE_SHORT, ctxtNum, verify); 1186 if (error != 0) 1187 return error; 1188 1189 /* Write lower half-word (short) to |d2|d3| */ 1190 error = npe_logical_reg_write(sc, 1191 regAddr + sizeof(uint16_t), 1192 regVal & 0xffff, 1193 IX_NPEDL_REG_SIZE_SHORT, ctxtNum, verify); 1194 } else { 1195 uint32_t npeInstruction; 1196 1197 switch (regSize) { 1198 case IX_NPEDL_REG_SIZE_BYTE: 1199 npeInstruction = IX_NPEDL_INSTR_WR_REG_BYTE; 1200 regVal &= 0xff; 1201 break; 1202 case IX_NPEDL_REG_SIZE_SHORT: 1203 npeInstruction = IX_NPEDL_INSTR_WR_REG_SHORT; 1204 regVal &= 0xffff; 1205 break; 1206 default: 1207 return EINVAL; 1208 } 1209 /* fill dest operand field of instruction with destination reg addr */ 1210 npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_DEST); 1211 1212 /* fill src operand field of instruction with least-sig 5 bits of val*/ 1213 npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA) << 1214 IX_NPEDL_OFFSET_INSTR_SRC); 1215 1216 /* fill coprocessor field of instruction with most-sig 11 bits of val*/ 1217 npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA) << 1218 IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA); 1219 1220 /* step execution of NPE intruction using Debug ECS */ 1221 error = npe_cpu_step(sc, npeInstruction, 1222 ctxtNum, IX_NPEDL_WR_INSTR_LDUR); 1223 } 1224 if (error != 0) { 1225 DPRINTF(sc->sc_dev, "%s(0x%x, 0x%x, %u, %u), error %u writing reg\n", 1226 __func__, regAddr, regVal, regSize, ctxtNum, error); 1227 return error; 1228 } 1229 if (verify) { 1230 uint32_t retRegVal; 1231 1232 error = npe_logical_reg_read(sc, regAddr, regSize, ctxtNum, &retRegVal); 1233 if (error == 0 && regVal != retRegVal) 1234 error = EIO; /* XXX ambiguous */ 1235 } 1236 return error; 1237 } 1238 1239 /* 1240 * There are 32 physical registers used in an NPE. These are 1241 * treated as 16 pairs of 32-bit registers. To write one of the pair, 1242 * write the pair number (0-16) to the REGMAP for Context 0. Then write 1243 * the value to register 0 or 4 in the regfile, depending on which 1244 * register of the pair is to be written 1245 */ 1246 static int 1247 npe_physical_reg_write(struct ixpnpe_softc *sc, 1248 uint32_t regAddr, uint32_t regValue, int verify) 1249 { 1250 int error; 1251 1252 /* 1253 * Set REGMAP for context 0 to (regAddr >> 1) to choose which pair (0-16) 1254 * of physical registers to write . 1255 */ 1256 error = npe_logical_reg_write(sc, IX_NPEDL_CTXT_REG_ADDR_REGMAP, 1257 (regAddr >> IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP), 1258 IX_NPEDL_REG_SIZE_SHORT, 0, verify); 1259 if (error == 0) { 1260 /* regAddr = 0 or 4 */ 1261 regAddr = (regAddr & IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR) * 1262 sizeof(uint32_t); 1263 error = npe_logical_reg_write(sc, regAddr, regValue, 1264 IX_NPEDL_REG_SIZE_WORD, 0, verify); 1265 } 1266 return error; 1267 } 1268 1269 static int 1270 npe_ctx_reg_write(struct ixpnpe_softc *sc, uint32_t ctxtNum, 1271 uint32_t ctxtReg, uint32_t ctxtRegVal, int verify) 1272 { 1273 DPRINTFn(4, sc->sc_dev, "%s(%u, %u, %u)\n", 1274 __func__, ctxtNum, ctxtReg, ctxtRegVal); 1275 /* 1276 * Context 0 has no STARTPC. Instead, this value is used to set 1277 * NextPC for Background ECS, to set where NPE starts executing code 1278 */ 1279 if (ctxtNum == 0 && ctxtReg == IX_NPEDL_CTXT_REG_STARTPC) { 1280 /* read BG_CTXT_REG_0, update NEXTPC bits, and write back to reg */ 1281 uint32_t v = npe_ecs_reg_read(sc, IX_NPEDL_ECS_BG_CTXT_REG_0); 1282 v &= ~IX_NPEDL_MASK_ECS_REG_0_NEXTPC; 1283 v |= (ctxtRegVal << IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC) & 1284 IX_NPEDL_MASK_ECS_REG_0_NEXTPC; 1285 1286 npe_ecs_reg_write(sc, IX_NPEDL_ECS_BG_CTXT_REG_0, v); 1287 return 0; 1288 } else { 1289 static const struct { 1290 uint32_t regAddress; 1291 uint32_t regSize; 1292 } regAccInfo[IX_NPEDL_CTXT_REG_MAX] = { 1293 { IX_NPEDL_CTXT_REG_ADDR_STEVT, IX_NPEDL_REG_SIZE_BYTE }, 1294 { IX_NPEDL_CTXT_REG_ADDR_STARTPC, IX_NPEDL_REG_SIZE_SHORT }, 1295 { IX_NPEDL_CTXT_REG_ADDR_REGMAP, IX_NPEDL_REG_SIZE_SHORT }, 1296 { IX_NPEDL_CTXT_REG_ADDR_CINDEX, IX_NPEDL_REG_SIZE_BYTE } 1297 }; 1298 return npe_logical_reg_write(sc, regAccInfo[ctxtReg].regAddress, 1299 ctxtRegVal, regAccInfo[ctxtReg].regSize, ctxtNum, verify); 1300 } 1301 } 1302 1303 /* 1304 * NPE Mailbox support. 1305 */ 1306 #define IX_NPEMH_MAXTRIES 100000 1307 1308 static int 1309 ixpnpe_ofifo_wait(struct ixpnpe_softc *sc) 1310 { 1311 int i; 1312 1313 for (i = 0; i < IX_NPEMH_MAXTRIES; i++) { 1314 if (npe_reg_read(sc, IX_NPESTAT) & IX_NPESTAT_OFNE) 1315 return 1; 1316 DELAY(10); 1317 } 1318 printf("%s: %s: timeout, last status 0x%x\n", sc->sc_dev.dv_xname, 1319 __func__, npe_reg_read(sc, IX_NPESTAT)); 1320 return 0; 1321 } 1322 1323 static int 1324 ixpnpe_intr(void *arg) 1325 { 1326 struct ixpnpe_softc *sc = arg; 1327 uint32_t status; 1328 1329 status = npe_reg_read(sc, IX_NPESTAT); 1330 if ((status & IX_NPESTAT_OFINT) == 0) { 1331 /* NB: should not happen */ 1332 printf("%s: %s: status 0x%x\n", sc->sc_dev.dv_xname, __func__, status); 1333 /* XXX must silence interrupt? */ 1334 return(1); 1335 } 1336 /* 1337 * A message is waiting in the output FIFO, copy it so 1338 * the interrupt will be silenced; then signal anyone 1339 * waiting to collect the result. 1340 */ 1341 sc->sc_msgwaiting = -1; /* NB: error indicator */ 1342 if (ixpnpe_ofifo_wait(sc)) { 1343 sc->sc_msg[0] = npe_reg_read(sc, IX_NPEFIFO); 1344 if (ixpnpe_ofifo_wait(sc)) { 1345 sc->sc_msg[1] = npe_reg_read(sc, IX_NPEFIFO); 1346 sc->sc_msgwaiting = 1; /* successful fetch */ 1347 } 1348 } 1349 wakeup(sc); 1350 1351 return (1); 1352 } 1353 1354 static int 1355 ixpnpe_ififo_wait(struct ixpnpe_softc *sc) 1356 { 1357 int i; 1358 1359 for (i = 0; i < IX_NPEMH_MAXTRIES; i++) { 1360 if (npe_reg_read(sc, IX_NPESTAT) & IX_NPESTAT_IFNF) 1361 return 1; 1362 DELAY(10); 1363 } 1364 return 0; 1365 } 1366 1367 static int 1368 ixpnpe_sendmsg_locked(struct ixpnpe_softc *sc, const uint32_t msg[2]) 1369 { 1370 int error = 0; 1371 1372 sc->sc_msgwaiting = 0; 1373 if (ixpnpe_ififo_wait(sc)) { 1374 npe_reg_write(sc, IX_NPEFIFO, msg[0]); 1375 if (ixpnpe_ififo_wait(sc)) 1376 npe_reg_write(sc, IX_NPEFIFO, msg[1]); 1377 else 1378 error = EIO; 1379 } else 1380 error = EIO; 1381 1382 if (error) 1383 printf("%s: input FIFO timeout, msg [0x%x,0x%x]\n", 1384 sc->sc_dev.dv_xname, msg[0], msg[1]); 1385 return error; 1386 } 1387 1388 static int 1389 ixpnpe_recvmsg_locked(struct ixpnpe_softc *sc, uint32_t msg[2]) 1390 { 1391 1392 if (!sc->sc_msgwaiting) 1393 ltsleep(sc, 0, "npemh", 0, &sc->sc_lock); 1394 bcopy(sc->sc_msg, msg, sizeof(sc->sc_msg)); 1395 /* NB: sc_msgwaiting != 1 means the ack fetch failed */ 1396 return sc->sc_msgwaiting != 1 ? EIO : 0; 1397 } 1398 1399 /* 1400 * Send a msg to the NPE and wait for a reply. We use the 1401 * private mutex and sleep until an interrupt is received 1402 * signalling the availability of data in the output FIFO 1403 * so the caller cannot be holding a mutex. May be better 1404 * piggyback on the caller's mutex instead but that would 1405 * make other locking confusing. 1406 */ 1407 int 1408 ixpnpe_sendandrecvmsg(struct ixpnpe_softc *sc, 1409 const uint32_t send[2], uint32_t recv[2]) 1410 { 1411 int error; 1412 1413 simple_lock(&sc->sc_lock); 1414 error = ixpnpe_sendmsg_locked(sc, send); 1415 if (error == 0) 1416 error = ixpnpe_recvmsg_locked(sc, recv); 1417 simple_unlock(&sc->sc_lock); 1418 1419 return error; 1420 } 1421 1422 /* XXX temporary, not reliable */ 1423 1424 int 1425 ixpnpe_sendmsg(struct ixpnpe_softc *sc, const uint32_t msg[2]) 1426 { 1427 int error; 1428 1429 simple_lock(&sc->sc_lock); 1430 error = ixpnpe_sendmsg_locked(sc, msg); 1431 simple_unlock(&sc->sc_lock); 1432 1433 return error; 1434 } 1435 1436 int 1437 ixpnpe_recvmsg(struct ixpnpe_softc *sc, uint32_t msg[2]) 1438 { 1439 int error; 1440 1441 simple_lock(&sc->sc_lock); 1442 if (sc->sc_msgwaiting) 1443 bcopy(sc->sc_msg, msg, sizeof(sc->sc_msg)); 1444 /* NB: sc_msgwaiting != 1 means the ack fetch failed */ 1445 error = sc->sc_msgwaiting != 1 ? EIO : 0; 1446 simple_unlock(&sc->sc_lock); 1447 1448 return error; 1449 } 1450