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