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