I have managed to load the uEngines. In case others are curious what is necessary, I have included a program for the StrongArm which will load a simple uEngine program to write the number "5" to the evaluation board LEDs (similar to Scott Karlin's previous StrongARM LED activation except for use of the uEngines). It is intended to be loaded with the VxWorks boot loader. Getting this to work I have noticed a number of things in the manuals that the Intel might want to look into. I refer to the newest manuals we have, dated "March, 2000". (HRM sect 4.7) does not mention that the ECS bit should also be turned off again. Also the first step says the uEngine can be in the "Reset" state. This is not true: only the "Stopped" or "Paused" states work. (HRM sect 4.6.3) does not mention that the VS bit in the CTX_WAKEUP_EVENTS register for a given context must be set before that context can be run by the arbiter. (HRM sect 3.3, HRM sect 8.9.1, and PRM appendix C) disagree on the bounds of the SRAM SlowPort memory region. And finally some things that initially tripped us up: (PRM sect 4) In the register description tables, the "Access" column sometimes incorrectly says "Read" even if a few bits of the register are "Read/Write". I suggest the Intel folks get rid of this column entirely, since all of the information is provided by the "R/W" column on the same page. (Sort of HRM sect 4.7) The uEngines memory is word-addressed while the StrongARM memory is byte-addressed. It took me a while to notice this means the uEngines do not have byte addressing bits at all. That is, I was using only addresses 0, 4, 8, and so forth. The correct thing to do wass use 0, 1, 2, 3, etc. This difference also has implications for comparing memory maps (for things like the LED addresses, etc). Tammo ------------- uEngine LED activation code below -------------- typedef unsigned int uint32; #define IXP1200_RESET 0x4200007C static uint32 CSR_Base[6] = { 0xB0000000, 0xB0000800, 0xB0001000, 0xB0001800, 0xB0002000, 0xB0002800 }; typedef enum { USTORE_ADDRESS = 0x0, USTORE_DATA = 0x4, ALU_OUTPUT = 0x08, ACTIVE_CTX_STS = 0x10, CTX_ARB_CTL = 0x24, CTX_ENABLES = 0x28, CC_ENABLE = 0x2C, } csrOffsets; static uint32 CTX_STS[4] = { 0x34, 0x38, 0x3C, 0x40 }; static uint32 CTX_WAKEUP_EVENTS[4] = { 0x54, 0x58, 0x5C, 0x60 }; inline extern uint32 memRead(uint32 address, uint32 bitOffset, uint32 bitCount) { uint32 mask = (0xFFFFFFFFul >> (32 - bitCount)) << bitOffset; uint32 value = *((volatile uint32 *)address); return (value & mask) >> bitOffset; } inline extern void memWrite(uint32 address, uint32 value) { *((volatile uint32 *)address) = value; } inline extern uint32 memOverwrite(uint32 address, uint32 bitOffset, uint32 bitCount, uint32 value) { // Write value into a bitCount wide field bitOffset bits from the LSB // at memory location address, leaving the remaining bits as-is. uint32 mask = (0xFFFFFFFFul >> (32 - bitCount)) << bitOffset; uint32 prevValue = memRead(address, 0, 32); uint32 newValue = prevValue & ~mask; newValue |= (value << bitOffset) & mask; memWrite(address, newValue); return prevValue; } inline extern uint32 csrRead(int uEng, uint32 address, uint32 bitOffset, uint32 bitCount) { return memRead(address + CSR_Base[uEng], bitOffset, bitCount); } inline extern void csrWrite(int uEng, uint32 address, uint32 value) { memWrite(address + CSR_Base[uEng], value); } inline extern uint32 csrOverwrite(int uEng, uint32 address, uint32 bitOffset, uint32 bitCount, uint32 value) { return memOverwrite(address + CSR_Base[uEng], bitOffset, bitCount, value); } // The uCode. Notice that 0x742000 is the memory-mapped address // of the LEDs from uEngineLand. uint32 ucode_Arr[] = { 0xD8100008, // immed_w0[ledaddr, (0x742000 & 0xFFFF)] 0xD8143A00, // immed_w1[ledaddr, ((0x742000 >> 16) & 0xFFFF)] 0xA00E0039, // sram[write, $xfer0, ledaddr, 0, 1], ctx_swap 0xDC000280, // immed[$xfer0, 5] ;; in delay slot 0xE00C0004 // ctx_arb [kill] }; int ucode_Len = (sizeof(ucode_Arr) / 4); void __main(void) { uint32 destAddr = 0x0; // Where in the uStore to put code int uEng = 0; // Which uEngine to use int ctx = 0; // Which thread to use uint32 loadAddr; int i; // Take uEng out of reset state memOverwrite(IXP1200_RESET, uEng, 1, 0x0); // Load the uCode loadAddr = destAddr | 0x00000400; // Set ECS bit for (i = 0; i < ucode_Len; i++, loadAddr++) { csrWrite(uEng, USTORE_ADDRESS, loadAddr); // target uStore location csrWrite(uEng, USTORE_DATA, ucode_Arr[i]); // desired uStore contents } csrWrite(uEng, USTORE_ADDRESS, 0x0); // Unset ECS bit // Prep the other uEngine state csrOverwrite(uEng, CTX_STS[ctx], 0, 10, destAddr); csrOverwrite(uEng, CTX_WAKEUP_EVENTS[ctx], 0, 10, 0x1); csrOverwrite(uEng, ACTIVE_CTX_STS, 0, 2, ctx); csrOverwrite(uEng, CTX_ARB_CTL, 2, 2, ctx + 1); // Start the thread csrOverwrite(uEng, CTX_ENABLES, 8 + ctx, 1, 0x1); // Wait for uEngine to finish while (csrRead(uEng, ACTIVE_CTX_STS, 2, 1)) { // Waiting... } } ------------- uEngine LED activation compilation process -------------- arm-unknown-coff-gcc -nostartfiles -nodefaultlibs -fno-builtin \ -mcpu=strongarm110 -mapcs-32 -mno-sched-prolog -fvolatile -O2 \ -Wall -Winline -Wstrict-prototypes -c demo.c arm-unknown-coff-ld -X -N -e ___main -Ttext 00001000 demo.o -o bootimage.coff ---------------------------