ixp425_npe.c (172357) | ixp425_npe.c (172358) |
---|---|
1/*- 2 * Copyright (c) 2006 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 43 unchanged lines hidden (view full) --- 52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * SUCH DAMAGE. 58*/ 59#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2006 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 43 unchanged lines hidden (view full) --- 52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * SUCH DAMAGE. 58*/ 59#include <sys/cdefs.h> |
60__FBSDID("$FreeBSD: head/sys/arm/xscale/ixp425/ixp425_npe.c 172357 2007-09-27 21:18:34Z cognet $"); | 60__FBSDID("$FreeBSD: head/sys/arm/xscale/ixp425/ixp425_npe.c 172358 2007-09-27 22:39:49Z cognet $"); |
61 62/* 63 * Intel XScale Network Processing Engine (NPE) support. 64 * 65 * Each NPE has an ixpnpeX device associated with it that is 66 * attached at boot. Depending on the microcode loaded into 67 * an NPE there may be an Ethernet interface (npeX) or some 68 * other network interface (e.g. for ATM). This file has support 69 * for loading microcode images and the associated NPE CPU 70 * manipulations (start, stop, reset). 71 * 72 * The code here basically replaces the npeDl and npeMh classes 73 * in the Intel Access Library (IAL). 74 * | 61 62/* 63 * Intel XScale Network Processing Engine (NPE) support. 64 * 65 * Each NPE has an ixpnpeX device associated with it that is 66 * attached at boot. Depending on the microcode loaded into 67 * an NPE there may be an Ethernet interface (npeX) or some 68 * other network interface (e.g. for ATM). This file has support 69 * for loading microcode images and the associated NPE CPU 70 * manipulations (start, stop, reset). 71 * 72 * The code here basically replaces the npeDl and npeMh classes 73 * in the Intel Access Library (IAL). 74 * |
75 * NB: Microcode images comes from ixNpeMicrocode.c | 75 * NB: Microcode images are loaded with firmware(9). To 76 * include microcode in a static kernel include the 77 * ixpnpe_fw device. Otherwise the firmware will be 78 * automatically loaded from the filesystem. |
76 */ 77#include <sys/param.h> 78#include <sys/systm.h> 79#include <sys/kernel.h> 80#include <sys/malloc.h> 81#include <sys/module.h> 82#include <sys/time.h> 83#include <sys/bus.h> 84#include <sys/resource.h> 85#include <sys/rman.h> 86#include <sys/sysctl.h> | 79 */ 80#include <sys/param.h> 81#include <sys/systm.h> 82#include <sys/kernel.h> 83#include <sys/malloc.h> 84#include <sys/module.h> 85#include <sys/time.h> 86#include <sys/bus.h> 87#include <sys/resource.h> 88#include <sys/rman.h> 89#include <sys/sysctl.h> |
87#include <sys/endian.h> | |
88 | 90 |
91#include <sys/linker.h> 92#include <sys/firmware.h> 93 |
|
89#include <machine/bus.h> 90#include <machine/cpu.h> 91#include <machine/cpufunc.h> 92#include <machine/resource.h> 93#include <machine/intr.h> 94#include <arm/xscale/ixp425/ixp425reg.h> 95#include <arm/xscale/ixp425/ixp425var.h> 96 97#include <arm/xscale/ixp425/ixp425_npereg.h> 98#include <arm/xscale/ixp425/ixp425_npevar.h> 99 | 94#include <machine/bus.h> 95#include <machine/cpu.h> 96#include <machine/cpufunc.h> 97#include <machine/resource.h> 98#include <machine/intr.h> 99#include <arm/xscale/ixp425/ixp425reg.h> 100#include <arm/xscale/ixp425/ixp425var.h> 101 102#include <arm/xscale/ixp425/ixp425_npereg.h> 103#include <arm/xscale/ixp425/ixp425_npevar.h> 104 |
100#include <arm/xscale/ixp425/IxNpeMicrocode.c> 101 | |
102struct ixpnpe_softc { 103 device_t sc_dev; 104 bus_space_tag_t sc_iot; 105 bus_space_handle_t sc_ioh; 106 bus_size_t sc_size; /* size of mapped register window */ 107 struct resource *sc_irq; /* IRQ resource */ 108 void *sc_ih; /* interrupt handler */ 109 struct mtx sc_mtx; /* mailbox lock */ --- 304 unchanged lines hidden (view full) --- 414 return ESRCH; 415} 416 417int 418ixpnpe_init(struct ixpnpe_softc *sc, const char *imageName, uint32_t imageId) 419{ 420 uint32_t imageSize; 421 const uint32_t *imageCodePtr; | 105struct ixpnpe_softc { 106 device_t sc_dev; 107 bus_space_tag_t sc_iot; 108 bus_space_handle_t sc_ioh; 109 bus_size_t sc_size; /* size of mapped register window */ 110 struct resource *sc_irq; /* IRQ resource */ 111 void *sc_ih; /* interrupt handler */ 112 struct mtx sc_mtx; /* mailbox lock */ --- 304 unchanged lines hidden (view full) --- 417 return ESRCH; 418} 419 420int 421ixpnpe_init(struct ixpnpe_softc *sc, const char *imageName, uint32_t imageId) 422{ 423 uint32_t imageSize; 424 const uint32_t *imageCodePtr; |
425 const struct firmware *fw; |
|
422 int error; 423 424 DPRINTF(sc->sc_dev, "load %s, imageId 0x%08x\n", imageName, imageId); 425 426#if 0 427 IxFeatureCtrlDeviceId devid = IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId); 428 /* 429 * Checking if image being loaded is meant for device that is running. 430 * Image is forward compatible. i.e Image built for IXP42X should run 431 * on IXP46X but not vice versa. 432 */ 433 if (devid > (ixFeatureCtrlDeviceRead() & IX_FEATURE_CTRL_DEVICE_TYPE_MASK)) 434 return EINVAL; 435#endif 436 error = ixpnpe_stopandreset(sc); /* stop and reset the NPE */ 437 if (error != 0) 438 return error; 439 | 426 int error; 427 428 DPRINTF(sc->sc_dev, "load %s, imageId 0x%08x\n", imageName, imageId); 429 430#if 0 431 IxFeatureCtrlDeviceId devid = IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId); 432 /* 433 * Checking if image being loaded is meant for device that is running. 434 * Image is forward compatible. i.e Image built for IXP42X should run 435 * on IXP46X but not vice versa. 436 */ 437 if (devid > (ixFeatureCtrlDeviceRead() & IX_FEATURE_CTRL_DEVICE_TYPE_MASK)) 438 return EINVAL; 439#endif 440 error = ixpnpe_stopandreset(sc); /* stop and reset the NPE */ 441 if (error != 0) 442 return error; 443 |
440 error = npe_findimage(sc, IxNpeMicrocode_array, imageId, 441 &imageCodePtr, &imageSize); | 444 fw = firmware_get(imageName); 445 if (fw == NULL) 446 return ENOENT; 447 448 /* Locate desired image in files w/ combined images */ 449 error = npe_findimage(sc, fw->data, imageId, &imageCodePtr, &imageSize); |
442 if (error != 0) 443 goto done; 444 445 /* 446 * If download was successful, store image Id in list of 447 * currently loaded images. If a critical error occured 448 * during download, record that the NPE has an invalid image 449 */ 450 mtx_lock(&sc->sc_mtx); 451 error = npe_load_image(sc, imageCodePtr, 1 /*VERIFY*/); 452 if (error == 0) { 453 sc->validImage = 1; 454 error = ixpnpe_start_locked(sc); 455 } else { 456 sc->validImage = 0; 457 } 458 sc->functionalityId = IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId); 459 mtx_unlock(&sc->sc_mtx); 460done: | 450 if (error != 0) 451 goto done; 452 453 /* 454 * If download was successful, store image Id in list of 455 * currently loaded images. If a critical error occured 456 * during download, record that the NPE has an invalid image 457 */ 458 mtx_lock(&sc->sc_mtx); 459 error = npe_load_image(sc, imageCodePtr, 1 /*VERIFY*/); 460 if (error == 0) { 461 sc->validImage = 1; 462 error = ixpnpe_start_locked(sc); 463 } else { 464 sc->validImage = 0; 465 } 466 sc->functionalityId = IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId); 467 mtx_unlock(&sc->sc_mtx); 468done: |
469 firmware_put(fw, FIRMWARE_UNLOAD); |
|
461 DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error); 462 return error; 463} 464 465int 466ixpnpe_getfunctionality(struct ixpnpe_softc *sc) 467{ 468 return (sc->validImage ? sc->functionalityId : 0); --- 27 unchanged lines hidden (view full) --- 496 497 npeMemAddress = bp->npeMemAddress; 498 blockSize = bp->size; /* NB: instruction/data count */ 499 if (npeMemAddress + blockSize > sc->insMemSize) { 500 device_printf(sc->sc_dev, "Block size too big for NPE memory\n"); 501 return EINVAL; /* XXX */ 502 } 503 for (i = 0; i < blockSize; i++, npeMemAddress++) { | 470 DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error); 471 return error; 472} 473 474int 475ixpnpe_getfunctionality(struct ixpnpe_softc *sc) 476{ 477 return (sc->validImage ? sc->functionalityId : 0); --- 27 unchanged lines hidden (view full) --- 505 506 npeMemAddress = bp->npeMemAddress; 507 blockSize = bp->size; /* NB: instruction/data count */ 508 if (npeMemAddress + blockSize > sc->insMemSize) { 509 device_printf(sc->sc_dev, "Block size too big for NPE memory\n"); 510 return EINVAL; /* XXX */ 511 } 512 for (i = 0; i < blockSize; i++, npeMemAddress++) { |
504 if (npe_ins_write(sc, npeMemAddress, htobe32(bp->data[i]), 505 verify) != 0) { | 513 if (npe_ins_write(sc, npeMemAddress, bp->data[i], verify) != 0) { |
506 device_printf(sc->sc_dev, "NPE instruction write failed"); 507 return EIO; 508 } 509 } 510 return 0; 511} 512 513static int --- 5 unchanged lines hidden (view full) --- 519 520 npeMemAddress = bp->npeMemAddress; 521 blockSize = bp->size; /* NB: instruction/data count */ 522 if (npeMemAddress + blockSize > sc->dataMemSize) { 523 device_printf(sc->sc_dev, "Block size too big for NPE memory\n"); 524 return EINVAL; 525 } 526 for (i = 0; i < blockSize; i++, npeMemAddress++) { | 514 device_printf(sc->sc_dev, "NPE instruction write failed"); 515 return EIO; 516 } 517 } 518 return 0; 519} 520 521static int --- 5 unchanged lines hidden (view full) --- 527 528 npeMemAddress = bp->npeMemAddress; 529 blockSize = bp->size; /* NB: instruction/data count */ 530 if (npeMemAddress + blockSize > sc->dataMemSize) { 531 device_printf(sc->sc_dev, "Block size too big for NPE memory\n"); 532 return EINVAL; 533 } 534 for (i = 0; i < blockSize; i++, npeMemAddress++) { |
527 if (npe_data_write(sc, npeMemAddress, htobe32(bp->data[i]), verify) 528 != 0) { | 535 if (npe_data_write(sc, npeMemAddress, bp->data[i], verify) != 0) { |
529 device_printf(sc->sc_dev, "NPE data write failed\n"); 530 return EIO; 531 } 532 } 533 return 0; 534} 535 536static int --- 29 unchanged lines hidden (view full) --- 566 } 567 /* NOTE that there is no STEVT register for Context 0 */ 568 if (cNum == 0 && reg == IX_NPEDL_CTXT_REG_STEVT) { 569 device_printf(sc->sc_dev, "no STEVT for Context 0\n"); 570 error = EINVAL; 571 break; 572 } 573 | 536 device_printf(sc->sc_dev, "NPE data write failed\n"); 537 return EIO; 538 } 539 } 540 return 0; 541} 542 543static int --- 29 unchanged lines hidden (view full) --- 573 } 574 /* NOTE that there is no STEVT register for Context 0 */ 575 if (cNum == 0 && reg == IX_NPEDL_CTXT_REG_STEVT) { 576 device_printf(sc->sc_dev, "no STEVT for Context 0\n"); 577 error = EINVAL; 578 break; 579 } 580 |
574 if (npe_ctx_reg_write(sc, cNum, reg, htobe32(regVal), verify) != 0) { | 581 if (npe_ctx_reg_write(sc, cNum, reg, regVal, verify) != 0) { |
575 device_printf(sc->sc_dev, "write of state-info to NPE failed\n"); 576 error = EIO; 577 break; 578 } 579 } 580 581 npe_cpu_step_restore(sc); 582 return error; --- 807 unchanged lines hidden --- | 582 device_printf(sc->sc_dev, "write of state-info to NPE failed\n"); 583 error = EIO; 584 break; 585 } 586 } 587 588 npe_cpu_step_restore(sc); 589 return error; --- 807 unchanged lines hidden --- |