Example #1
0
int main(int argc, const char *argv[]) {
    icmCLPP parser = icmCLParser("ArmIntegratorCP", ICM_AC_ALL);
    icmCLParserUsageMessage(parser, "Usage (Linux Kernel)\n"
    		                        "  ArmIntegratorCP --kernel <kernel image> --ramdisk <initial ramdisk>\n"
    		                        "Usage (BareMetal)\n"
    		                        "  ArmIntegratorCP --program <elf file> --semihost <semihost file> --nographics\n");
    cmdParserAddUserArgs(parser);

    icmCLParseArgs(parser, argc, argv);

    // Check to see what UART options are used
    //
    Bool setUartport = icmCLParseArgUsed (parser,"uartport");
    if (options.uartconsole && setUartport) {
    	icmMessage("E", PLATFORM"_CFG", "Can only specify one of --uartport and --uartconsole");
    } else if (setUartport) {
        char buf[32];
        snprintf(buf, sizeof(buf), "0x"FMT_6408x, options.uartport);
        icmOverride(PLATFORM"/"UART"/portnum", buf);			// Override the parameter to cause the UART to open port "portnum"

    } else if (options.uartconsole) {
    	icmOverride(PLATFORM"/"UART"/console", "1");			// Override the parameter to cause the UART to open a console
    }

    if(options.nographics) {
    	icmOverride(PLATFORM"/"LCD"/noGraphics", "1");
    }

    // Check to see if the program argument is loading a non Linux Kernel
    if(icmCLParseArgUsed (parser,"program")) {
		if(icmCLParseArgUsed (parser,"kernel")) {
			icmMessage("E", PLATFORM, "Arguments '--program' and '--kernel' cannot be used together");
		} else {
			icmMessage("I", PLATFORM, "Loading baremetal application, disabling '%s'", SMARTLOADER);
	        icmOverride(PLATFORM"/"SMARTLOADER"/disable", "1");
		}

	} else {
    	if(options.kernel) {
    		icmOverride(PLATFORM"/"SMARTLOADER"/kernel", options.kernel);
    	}
    	if(options.ramdisk) {
    		icmOverride(PLATFORM"/"SMARTLOADER"/initrd", options.ramdisk);
    	}

    }

    platformConstructor();

    if(icmCLParseArgUsed (parser,"program") && (options.semihost)) {
		icmAddInterceptObject (handles.arm1_c, PLATFORM"/"CPU"/semihost",options.semihost, NULL, NULL);
	}

    icmSimulationStarting();
    icmSimulatePlatform();

    icmTerminate();
    return 0;
}
Example #2
0
// Platform entry point
int main(int argc, char **argv) {

    // Get the name of the application to run from the command line
    if (argc != 2) {
        icmPrintf("usage: %s <pa application>\n", argv[0]);
        return -1;
    }

    // Initialize OVPsim, enabling verbose mode to get statistics at end of execution
    icmInit(ICM_VERBOSE | ICM_STOP_ON_CTRLC | ICM_ENABLE_IMPERAS_INTERCEPTS, NULL, 0);

    /***************************************************************************************************
       MURAC Primary Architecture
         - ARM processor
     ***************************************************************************************************/
#ifdef INTECEPT_OBJECT_SUPPORTED
    const char *armModel    = icmGetVlnvString(NULL, "arm.ovpworld.org", "processor", "arm", "1.0", "model");
#endif
    const char *armSemihost = icmGetVlnvString(NULL, "arm.ovpworld.org", "semihosting", "armNewlib", "1.0", "model");

    icmAttrListP armUserAttr = icmNewAttrList();
    icmAddStringAttr(armUserAttr, "compatibility", "gdb");
    icmAddStringAttr(armUserAttr, "variant", "Cortex-A8");
    icmAddStringAttr(armUserAttr, "UAL", "1");

    // Create the Primary Architecture (PA) processor
    icmProcessorP pa = icmNewProcessor(
        "pa",                // CPU name
        "arm",               // CPU type
        0,                   // CPU cpuId
        0,                   // CPU model flags
        32,                  // address bits
#ifdef INTECEPT_OBJECT_SUPPORTED
        armModel,            // model file
#else

        MURAC_PA_MODEL_FILE, // model file
#endif
        "modelAttrs",        // model attributes
        SIMULATION_FLAGS,    // simulation flags
        armUserAttr,         // user-defined attributes
        armSemihost,         // semi-hosting file
        "modelAttrs"         // semi-hosting attributes
    );

#ifdef INTECEPT_OBJECT_SUPPORTED
    // Add intercept libarary for MURAC Primary Architecture instructions
    icmAddInterceptObject(pa, "murac_pa", MURAC_PA_INSTRUCTIONS_FILE, "modelAttrs", 0);
#endif

    /***************************************************************************************************
       System Memory
     ***************************************************************************************************/
    // Local memory for the PA
    // the ARM processor toolchain sites code in lower memory and stack in higher memory
    // so we will use two memories
    // NOTE: this is just a consequence of the default linker script used
    icmMemoryP codeMemory = icmNewMemory("code_memory", ICM_PRIV_RWX, 0x9fffffff);
    icmMemoryP localPA    = icmNewMemory("local_pa_memory", ICM_PRIV_RWX, 0x0fffffff);

    // Local memory for the AA
    icmMemoryP localAA    = icmNewMemory("local_aa_memory", ICM_PRIV_RWX, 0x0fffffff);

    // Processor state memory (shared)
    icmMemoryP prStateMemory = icmNewMemory("pr_state_memory", ICM_PRIV_RWX, 0x100);

    /***************************************************************************************************
       System Bus connections
     ***************************************************************************************************/
    icmBusP busPA = icmNewBus("pa_bus", 32);
    icmBusP busAA = icmNewBus("aa_bus", 32);

    // Connect Primary Architecture to the pa bus
    icmConnectProcessorBusses(pa, busPA, busPA);

    // Connect memories to the busses
    icmConnectMemoryToBus(busPA, "pa_code_memory_port", codeMemory, 0x00000000);
    icmConnectMemoryToBus(busPA, "pa_local_memory_port", localPA, 0xf0000000);
    icmConnectMemoryToBus(busPA, "pa_pr_state_memory_port", prStateMemory, 0xcf000000);

    icmConnectMemoryToBus(busAA, "aa_code_memory_port", codeMemory, 0x00000000);
    icmConnectMemoryToBus(busAA, "aa_local_memory_port", localAA, 0xf0000000);
    icmConnectMemoryToBus(busAA, "aa_pr_state_memory_port", prStateMemory, 0xcf000000);

    /***************************************************************************************************
       MURAC Peripherals (Auxiliary Architecture)
     ***************************************************************************************************/
    icmAttrListP fpgaAttrs = icmNewAttrList();
    if(finishOnSoftReset) {
        icmAddUns64Attr(fpgaAttrs, "stoponsoftreset",  1);
    }
    icmPseP muracFpga = icmNewPSE("muracFpga", MURAC_AA_FPGA_PSE_FILE, fpgaAttrs, 0, 0);

    // Connect memory access ports to the bus
    icmConnectPSEBus(muracFpga, busAA, "fpga_memread", True, 0x00000000, 0xffffffff);
    icmConnectPSEBus(muracFpga, busAA, "fpga_memwrite", True, 0x00000000, 0xffffffff);
    
    /***************************************************************************************************
       System Interrupt connections
     ***************************************************************************************************/
    icmNetP intBrArch = icmNewNet("brArch");
    icmNetP intRetArch = icmNewNet("retArch");

    // connect the processor interrupt port to the net
    icmConnectProcessorNet(pa, intBrArch, "brarch", ICM_OUTPUT);
    // connect the FPGA interrupt port to the net
    icmConnectPSENet(muracFpga, intBrArch, "fpga_brarch", ICM_INPUT);

    // connect the processor interrupt port to the net
    icmConnectProcessorNet(pa, intRetArch, "fiq", ICM_INPUT);
    // connect the FPGA interrupt port to the net
    icmConnectPSENet(muracFpga, intRetArch, "fpga_retarch", ICM_OUTPUT);

    /***************************************************************************************************
       Information
     ***************************************************************************************************/

    // Show the bus connections
    icmPrintf("\nPrimary Architecture Bus Connections\n");
    icmPrintBusConnections(busPA);
    icmPrintf("\nAuxiliary Architecture Bus Connections\n");
    icmPrintBusConnections(busAA);
    icmPrintf("\nNet Connections\n");
    icmPrintNetConnections();
    icmPrintf("\n");

    /***************************************************************************************************
       MURAC Simulation
     ***************************************************************************************************/

    // Load the application code into the primary architecture memory
    icmLoadProcessorMemory(pa, argv[1], False, False, True);

    // Run the simulation until done (no instruction limit)
    icmProcessorP final = icmSimulatePlatform();
    if ( final && (icmGetStopReason(final) == ICM_SR_INTERRUPT ) ) {
        icmPrintf("*** MURAC simulation interrupted\n");
    }

    // report the total number of instructions executed
    icmPrintf("MURAC Primary Architecture has executed " FMT_64u " instructions\n", icmGetProcessorICount(pa));

    icmTerminate();
    
    return 0;

}