int main() { /* * L'adresse de démarrage décodée depuis le fichier S-record n'est pas * prise en compte, puisque le processeur PowerPC ne peut démarrer qu'à * l'adresse 0xFFFFFFFC. Une fois le fichier S-record chargé en mémoire, * on demande au processeur de se reseter pour booter le nouveau programme. */ Xuint32 start_address; XStatus status; XCache_DisableDCache(); XCache_DisableICache(); print("Starting bootloader.\r\n"); status = load_srec("a:\\boot.me", &start_address); if (status == XST_SUCCESS) { // branchement print("All right ! Let's go, girls !\r\n\r\n"); usleep(100000); asm("lis 0,0x3000"); asm("mtdbcr0 0"); // soft reset powaaa !! } print("Boot failed.\r\n"); return 0; }
int main( int argc, char *argv[] ) { Huint sta; void* retval; hthread_t tid; hthread_attr_t attr; int num_ops = 0; printf( "\n****Main Thread****... \n" ); XCache_DisableDCache(); // ************************************************************************************* unsigned int *fcn_pointer = (unsigned int*)(HWTI_BASEADDR + 6*sizeof(int)); int code_offset = 0; FuncPointer fp = 0; unsigned char * prog_ptr = 0; unsigned int * first_instr = 0; // Initialize code offset and program pointer code_offset = 0x1f0; //0x1d4;//0x1a8; prog_ptr = (unsigned char *)&junk_o; // Initialize function pointer (actual place to jump to) fp = (FuncPointer)(prog_ptr + code_offset); // Initialize a pointer that allows one to "look" at the 1st instruction first_instr = (unsigned int*)(prog_ptr + code_offset); *fcn_pointer = (int)fp; // ************************************************************************************* for( num_ops = 0; num_ops < 5; num_ops++) { // Initialize the attributes for the hardware thread hthread_attr_init( &attr ); hthread_attr_sethardware( &attr, HWTI_BASEADDR ); // Create the hardware thread printf( "Starting Hardware Thread... \r" ); sta = hthread_create( &tid, &attr, (void*)fp, (void*)(num_ops) ); printf( "Started Hardware Thread (TID = %d) (ARG = %d)... 0x%8.8x\n", tid, num_ops, sta ); // Clean up the attribute structure hthread_attr_destroy( &attr ); // Wait for the hardware thread to exit printf( "Waiting for Hardware Thread... \r" ); hthread_join( tid, &retval ); printf( "Joined on Hardware Thread... 0x%8.8x\n", (Huint)retval ); } // Return from main return 0; }
//! at start enable cache void cyg_user_start(void){ #ifdef USE_CACHE printf( "enabling data cache for external ram\n" ); XCache_EnableDCache( 0xF0000000 ); #else printf( "data cache disabled\n" ); XCache_DisableDCache( ); #endif }
void disable_caches() { #ifdef __PPC__ XCache_DisableDCache(); XCache_DisableICache(); #elif __MICROBLAZE__ #ifdef XPAR_MICROBLAZE_USE_DCACHE #if !XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK microblaze_invalidate_dcache(); #endif microblaze_disable_dcache(); #endif #ifdef XPAR_MICROBLAZE_USE_ICACHE microblaze_invalidate_icache(); microblaze_disable_icache(); #endif #endif }
int main (void) { XCache_EnableICache(0x80000001); XCache_EnableDCache(0x80000000); /* Initialize RS232 - Set baudrate and number of stop bits */ XUartNs550_SetBaud(XPAR_RS232_BASEADDR, XPAR_XUARTNS550_CLOCK_HZ, 9600); XUartNs550_mSetLineControlReg(XPAR_RS232_BASEADDR, XUN_LCR_8_DATA_BITS); print("-- Entering main() --\r\n"); /* * MemoryTest routine will not be run for the memory at * 0x81000000 (FLASH_8Mx16) * because it is a read-only memory */ /* * MemoryTest routine will not be run for the memory at * 0x00000000 (DDR_SDRAM_1) * because it is being used to hold a part of this application program */ /* * MemoryTest routine will not be run for the memory at * 0xfffff000 (plb_bram_if_cntlr_1) * because it is being used to hold a part of this application program */ print("-- Exiting main() --\r\n"); XCache_DisableDCache(); XCache_DisableICache(); return 0; }
int main (void) { XCache_EnableICache(0x00000001); XCache_EnableDCache(0x00000001); XCache_DisableDCache(); XCache_DisableICache(); xil_printf("\r\n-- Entering main() --\r\n"); /************************ SDRAM SelfTest **************************/ xil_printf("Performing SelfTest of SDRAM controller...\r\n"); int iteration = 0; while(1) { xil_printf("*Iteration %d\r\n", iteration++); int Status; int i; volatile a; volatile b; int TotalErrors; Xuint8 dcm_psen, dcm_psincdec, dcm_done; mySDRAMConfig = XMpmc_LookupConfig(XPAR_MPMC_0_DEVICE_ID); if(mySDRAMConfig == NULL) { xil_printf("Could not find SDRAM based on dev id\r\n"); return XST_FAILURE; } else { xil_printf("Got SDRAM config\r\n"); } Status = XMpmc_CfgInitialize(&mySDRAM,mySDRAMConfig, XPAR_MPMC_0_MPMC_BASEADDR); if(Status != XST_SUCCESS) { xil_printf("Initialization Failed!\r\n"); return XST_FAILURE; } else { xil_printf("Initialization Complete!\r\n"); } Status = XMpmc_SelfTest(&mySDRAM); if(Status != XST_SUCCESS) { xil_printf("SelfTest Failed!\r\n"); return XST_FAILURE; } else { xil_printf("SelfTest Complete!\r\n"); } /***************** START CALIBRATION ***************/ Status = MpmcCalibrationExample(XPAR_MPMC_0_DEVICE_ID); if (Status != XST_SUCCESS) { return XST_FAILURE; } /***************** END CALIBRATION *****************/ TotalErrors = MpmcMemTestExample(XPAR_MPMC_0_DEVICE_ID); if (TotalErrors) { xil_printf("\r\n### Program finished with errors ###\r\n"); } else { xil_printf("\r\n### Program finished successfully ###\r\n"); } ENABLE_ICACHE(); ENABLE_DCACHE(); Xuint32 memSize = XPAR_MPMC_0_MPMC_HIGHADDR - XPAR_MPMC_0_MPMC_BASEADDR + 1; //get correct SDRAM size Xuint32* myAddress = (Xuint32*)XPAR_MPMC_0_MPMC_BASEADDR; xil_printf("\r\nStarting Wade's special Test...\r\n"); char wadeSuccess = RunAllMemoryTests(myAddress, memSize); if (wadeSuccess){ xil_printf("Wade's test PASSED!"); } else{ xil_printf("Wade's test FAILED!"); } xil_printf("Total Errors: %d\r\n", TotalErrors); } }
void disable_caches() { XCache_DisableDCache(); XCache_DisableICache(); }
int main( int argc, char *argv[] ) { unsigned int i, start_count = 0, done_count = 0; timing_t t_start = 0, t_stop = 0, t_gen = 0, t_sort = 0, t_merge = 0, t_check = 0; unsigned int *addr; unsigned int dummy; int retval; printf( "-------------------------------------------------------\n" "ReconOS hardware multithreading case study (sort)\n" "(c) Computer Engineering Group, University of Paderborn\n\n" "eCos/POSIX, multi-threaded hardware version (" __FILE__ ")\n" "Compiled on " __DATE__ ", " __TIME__ ".\n" "-------------------------------------------------------\n\n" ); #ifdef USE_CACHE printf( "enabling data cache for external ram\n" ); XCache_EnableDCache( 0x80000000 ); #else printf( "data cache disabled\n" ); XCache_DisableDCache( ); #endif data = buf_a; //---------------------------------- //-- GENERATE DATA //---------------------------------- printf( "Generating data..." ); t_start = gettime( ); generate_data( data, SIZE ); t_stop = gettime( ); t_gen = calc_timediff_ms( t_start, t_stop ); printf( "done\n" ); #ifdef USE_CACHE // flush cache contents - the hardware can only read from main memory // TODO: storing could be more efficient printf( "Flushing cache..." ); XCache_EnableDCache( 0x80000000 ); printf( "done\n" ); #endif //---------------------------------- //-- SORT DATA //---------------------------------- // create mail boxes for 'start' and 'complete' messages mb_start_attr.mq_flags = mb_done_attr.mq_flags = 0; mb_start_attr.mq_maxmsg = mb_done_attr.mq_maxmsg = 10; mb_start_attr.mq_msgsize = mb_done_attr.mq_msgsize = 4; mb_start_attr.mq_curmsgs = mb_done_attr.mq_curmsgs = 0; // unlink mailboxes, if they exist retval = mq_unlink("/mb_start"); if (retval != 0 && errno != ENOENT) { // we don't care if it doesn't exist diag_printf("unable to unlink mb_start"); } retval = mq_unlink("/mb_done"); if (retval != 0 && errno != ENOENT) { // we don't care if it doesn't exist diag_printf("unable to unlink mb_done"); } // open/create mailboxes mb_start = mq_open("/mb_start", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG, &mb_start_attr); if (mb_start == (mqd_t)-1) { diag_printf("unable to create mb_start"); } mb_done = mq_open("/mb_done", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG, &mb_done_attr); if (mb_done == (mqd_t)-1) { diag_printf("unable to create mb_done"); } // create sorting sowftware threads for ( i = 0; i < MT_HW_NUM_SW_THREADS; i++ ) { pthread_attr_init(&thread_sorter_attr[i]); pthread_create(&thread_sorter[i], &thread_sorter_attr[i], sort8k_entry_posix, (void*)i); } // create sorting hardware thread pthread_attr_init(&hwthread_sorter_attr); pthread_attr_setstacksize(&hwthread_sorter_attr, STACK_SIZE); rthread_attr_init(&hwthread_sorter_hwattr); rthread_attr_setslotnum(&hwthread_sorter_hwattr, 0); rthread_attr_setresources(&hwthread_sorter_hwattr, hwthread_sorter_resources, 2); rthread_create(&hwthread_sorter, &hwthread_sorter_attr, &hwthread_sorter_hwattr, (void*)0); printf( "Sorting data..." ); i = 0; t_start = gettime( ); // put 9 messages into mb_start while ( start_count < 9 ) { addr = &data[i]; if ( mq_send( mb_start, ( void * ) &addr, sizeof(addr), 0 ) == 0 ) { start_count++; i += N; } else { perror("while sending to mq_send"); break; } } t_stop = gettime( ); t_sort += calc_timediff_ms( t_start, t_stop ); while ( done_count < SIZE / N ) { t_start = gettime( ); // if we have something to distribute, // put one into the start mailbox if ( start_count < SIZE / N ) { addr = &data[i]; if ( mq_send( mb_start, ( void * ) &addr, sizeof(addr), 0 ) == 0 ) { start_count++; i += N; } else { perror("while sending to mq_send"); break; } } // see whether anybody's done if ( mq_receive( mb_done, (void*)&dummy, sizeof(dummy), 0 ) == sizeof(dummy) ) { done_count++; } else { perror( "while receiving from mq_done" ); break; } t_stop = gettime( ); t_sort += calc_timediff_ms( t_start, t_stop ); } printf( "done\n" ); #ifdef USE_CACHE // flush cache contents // TODO: invalidating would suffice printf( "Flushing cache..." ); XCache_EnableDCache( 0x80000000 ); printf( "done\n" ); #endif //---------------------------------- //-- MERGE DATA //---------------------------------- printf( "Merging data..." ); t_start = gettime( ); data = recursive_merge( data, buf_b, SIZE, N, simple_merge ); t_stop = gettime( ); t_merge = calc_timediff_ms( t_start, t_stop ); printf( "done\n" ); //---------------------------------- //-- CHECK DATA //---------------------------------- printf( "Checking sorted data..." ); t_start = gettime( ); if ( check_data( data, SIZE ) != 0 ) printf( "CHECK FAILED!\n" ); else printf( "check successful.\n" ); t_stop = gettime( ); t_check = calc_timediff_ms( t_start, t_stop ); printf( "\nRunning times (size: %d words):\n" "\tGenerate data: %d ms\n" "\tSort data : %d ms\n" "\tMerge data : %d ms\n" "\tCheck data : %d ms\n" "\nTotal computation time (sort & merge): %d ms\n", SIZE, t_gen, t_sort, t_merge, t_check, t_sort + t_merge ); return 0; }
/** * * This function gets the calibration value. * * @param InstancePtr is a pointer to an XMpmc instance to be worked on. * * @return XST_SUCCESS if the DCM Phase shift decrement is completed * else XST_FAILURE. * * @note None. * *****************************************************************************/ int MpmcGetCalibrate(XMpmc *InstancePtr, u32 MemoryStartAddr, MpmcCalibReturnValue *CalibStatus) { int Count; MpmcCalibValue LocalCalibValue; int ValidCount; u32 RegValue; u8 Toggle = 0; u32 Status; LocalCalibValue.FoundValid = FALSE; RegValue = MPMC_RDEN_DELAY_MIN_VAL; /* * Get the initial value from the register. */ LocalCalibValue.OrigTapValue = XMpmc_GetStaticPhyReg(InstancePtr) & XMPMC_SPIR_DCM_TAP_VALUE_MASK; if (LocalCalibValue.OrigTapValue > MPMC_MAX_TAPS) { LocalCalibValue.OrigTapValue = LocalCalibValue.OrigTapValue - 0x100; } /* * Try to find valid calibration settings. */ while (LocalCalibValue.FoundValid == FALSE) { LocalCalibValue.MinValue = MPMC_MAX_TAPS - 1; LocalCalibValue.MaxValue = MPMC_MIN_TAPS + 1; /* * Reset DCM to minimum value */ Status = MpmcResetDcmPhaseShift(InstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Read the memory and check that data versus the expected * value. * * If the value matches, read the current calibration value. * Repeat this to ensure that this is not on a transition. * If the value is incorrect in any of these increments, the * value must be re-established. * * If the value at 0 does match then we are probably in a case * where the window is a wrap case. This means that we are * looking for the upper bound not the lower bound. */ ValidCount = 0; for (Count = MPMC_MIN_TAPS; Count < MPMC_MAX_TAPS; Count++) { MpmcWriteTestPattern(MemoryStartAddr, Toggle); if (MpmcCheckPattern(MemoryStartAddr, Toggle) != XST_SUCCESS) { /* * Found invalid calibration setting. */ if (ValidCount > MPMC_EDGE_TAPS) { LocalCalibValue.MaxValue = Count; } ValidCount = 0; } else { /* * Found valid calibration setting * Check to make sure that cache reads work. */ #ifdef __MICROBLAZE__ #if XPAR_MICROBLAZE_0_USE_DCACHE /* * Initialize and Enable the data cache. */ microblaze_init_dcache_range(0, XPAR_MICROBLAZE_0_DCACHE_BYTE_SIZE); microblaze_enable_dcache(); #endif #endif #ifdef __PPC__ /* * Enable the Dcache for all memory regions * except the boot region of the PPC. */ XCache_InvalidateDCacheLine(MemoryStartAddr); XCache_EnableDCache(0xFFFFFFFE); #endif Status = MpmcCheckPattern(MemoryStartAddr, Toggle); /* * Disable and reinitialize the data cache. */ #ifdef __MICROBLAZE__ #if XPAR_MICROBLAZE_0_USE_DCACHE microblaze_disable_dcache(); microblaze_init_dcache_range(0, XPAR_MICROBLAZE_0_DCACHE_BYTE_SIZE); #endif #endif #ifdef __PPC__ XCache_DisableDCache(); XCache_InvalidateDCacheLine(MemoryStartAddr); #endif if (Status != XST_SUCCESS) { /* * Found invalid calibration setting */ if (ValidCount > MPMC_EDGE_TAPS) { LocalCalibValue.MaxValue = Count; } ValidCount = 0; } else { /* * Found valid calibration setting */ if (ValidCount == MPMC_EDGE_TAPS) { LocalCalibValue.MinValue = Count - MPMC_EDGE_TAPS; LocalCalibValue.MaxValue = Count; } else if (ValidCount > MPMC_EDGE_TAPS) { LocalCalibValue.MaxValue = Count; } ValidCount++; if (ValidCount>MPMC_EDGE_TAPS) { LocalCalibValue.FoundValid = TRUE; } } } Status = MpmcIncDcmPhaseShift(InstancePtr, RegValue); if (Status != XST_SUCCESS) { return XST_FAILURE; } if (Toggle == 0) { Toggle = 1; } else { Toggle = 0; } } if ((LocalCalibValue.FoundValid == FALSE) && (((RegValue & XMPMC_SPIR_RDEN_DELAY_MASK) != MPMC_RDEN_DELAY_MAX_VAL) || ((RegValue & XMPMC_SPIR_RDDATA_CLK_SEL_MASK) != XMPMC_SPIR_RDDATA_CLK_SEL_MASK) || ((RegValue & XMPMC_SPIR_RDDATA_SWAP_RISE_MASK) != XMPMC_SPIR_RDDATA_SWAP_RISE_MASK))){ if ((RegValue & XMPMC_SPIR_RDEN_DELAY_MASK) != MPMC_RDEN_DELAY_MAX_VAL) { RegValue = RegValue + MPMC_RDEN_DELAY_INC; } else if ((RegValue & XMPMC_SPIR_RDDATA_CLK_SEL_MASK) != XMPMC_SPIR_RDDATA_CLK_SEL_MASK) { RegValue = (RegValue | XMPMC_SPIR_RDEN_DELAY_MASK) - XMPMC_SPIR_RDEN_DELAY_MASK + MPMC_RDEN_DELAY_MIN_VAL + XMPMC_SPIR_RDDATA_CLK_SEL_MASK; } else if ((RegValue & XMPMC_SPIR_RDDATA_SWAP_RISE_MASK) != XMPMC_SPIR_RDDATA_SWAP_RISE_MASK) { RegValue = (RegValue | XMPMC_SPIR_RDEN_DELAY_MASK) - XMPMC_SPIR_RDEN_DELAY_MASK + MPMC_RDEN_DELAY_MIN_VAL - XMPMC_SPIR_RDDATA_CLK_SEL_MASK + XMPMC_SPIR_RDDATA_SWAP_RISE_MASK; } } else if (LocalCalibValue.FoundValid == FALSE) { xil_printf("\r\n ERROR: Could not calibrate.\r\n"); return XST_FAILURE; } } CalibStatus->FoundValid = LocalCalibValue.FoundValid; CalibStatus->MinValue = LocalCalibValue.MinValue; CalibStatus->MaxValue = LocalCalibValue.MaxValue; CalibStatus->RegValue = RegValue; if (LocalCalibValue.MaxValue >= LocalCalibValue.MinValue) { CalibStatus->CalibTapValue = (LocalCalibValue.MinValue + LocalCalibValue.MaxValue)/2; } else { CalibStatus->CalibTapValue = (LocalCalibValue.MinValue + LocalCalibValue.MaxValue + MPMC_NUMBER_TAPS)/2; if (CalibStatus->CalibTapValue > MPMC_MAX_TAPS) { CalibStatus->CalibTapValue = (CalibStatus->CalibTapValue - MPMC_NUMBER_TAPS); } } return XST_SUCCESS; }
/** * * The purpose of this function is to illustrate how to use the MPMC * driver for the Calibration of the Static Phy. * * @param DeviceId is device ID of the XMpmc Device, typically * XPAR_<MPMC_instance>_DEVICE_ID value from xparameters.h. * * @return XST_SUCCESS to indicate success, otherwise XST_FAILURE. * * @note None. * ******************************************************************************/ int MpmcCalibrationExample(u16 DeviceId) { XMpmc_Config *CfgPtr; int Status; MpmcCalibReturnValue CalibStatus; /* * Disable the data cache and reinitialize it. */ #ifdef __MICROBLAZE__ #if XPAR_MICROBLAZE_0_USE_DCACHE microblaze_disable_dcache(); microblaze_init_dcache_range(0, XPAR_MICROBLAZE_0_DCACHE_BYTE_SIZE); #endif #endif #ifdef __PPC__ XCache_DisableDCache(); XCache_InvalidateDCacheLine(MPMC_CALIBRATON_STARTADDR); #endif //xil_printf("\r\n Starting the Calibration Example \n\n"); /* * Initialize the MPMC device. */ CfgPtr = XMpmc_LookupConfig(DeviceId); if (CfgPtr == XNULL) { return XST_FAILURE; } Status = XMpmc_CfgInitialize(&Mpmc, CfgPtr, CfgPtr->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait for the initial initialization sequence to be complete. */ while ((XMpmc_GetStaticPhyReg(&Mpmc) & XMPMC_SPIR_INIT_DONE_MASK) != XMPMC_SPIR_INIT_DONE_MASK); /* * Begin Calibration. */ Status = MpmcGetCalibrate(&Mpmc, MPMC_CALIBRATON_STARTADDR, &CalibStatus); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the calibrated value in the Static Phy Register. */ if (CalibStatus.FoundValid == TRUE) { /* xil_printf("\r Setting the phase shift to %0d. ", CalibStatus.CalibTapValue); xil_printf("Min Value = %d. Max Value = %d.\r\n", CalibStatus.MinValue, CalibStatus.MaxValue); */ MpmcSetCalibrate(&Mpmc, CalibStatus.CalibTapValue, CalibStatus.RegValue); if (Status != XST_SUCCESS) { return XST_FAILURE; } } //xil_printf("\r\n Calibration is Successful \r\n"); return XST_SUCCESS; }
int run_tests() { // Timer variables xps_timer_t timer; int time_create, time_start, time_unlock, time_stop; // Mutex hthread_mutex_t * mutex = (hthread_mutex_t*)malloc( sizeof(hthread_mutex_t) ); hthread_mutex_init( mutex, NULL ); float min; // Thread attribute structures Huint sta[NUM_THREADS]; void* retval[NUM_THREADS]; hthread_t tid[NUM_THREADS]; hthread_attr_t attr[NUM_THREADS]; targ_t thread_arg[NUM_THREADS]; // Setup Cache XCache_DisableDCache(); XCache_EnableICache(0xc0000801); // Create timer xps_timer_create(&timer, (int*)0x20400000); // Start timer xps_timer_start(&timer); // ************************************************************************************* extern unsigned char intermediate[]; extern unsigned int min_handle_offset; unsigned int min_handle = (min_handle_offset) + (unsigned int)(&intermediate); // ************************************************************************************* printf("Code start address = 0x%08x\n", (unsigned int)&intermediate); int i = 0; float main_array[ARRAY_LENGTH]; printf("Addr of array = 0x%08x\n",(unsigned int)&main_array[0]); for (i = 0; i < ARRAY_LENGTH; i++) { main_array[i] = (i+2)*3.14f; } int num_items = ARRAY_LENGTH/NUM_THREADS; int extra_items = ARRAY_LENGTH - (num_items*NUM_THREADS); float * start_addr = &main_array[0]; for (i = 0; i < NUM_THREADS; i++) { // Initialize the attributes for the hardware threads hthread_attr_init( &attr[i] ); hthread_attr_sethardware( &attr[i], (void*)base_array[i] ); // Initialize thread arguments thread_arg[i].num_items = num_items; thread_arg[i].data_ptr = start_addr; thread_arg[i].min_mutex = mutex; thread_arg[i].min = &min; start_addr+=num_items; } // Add in extra items for the last thread if needed thread_arg[i-1].num_items += extra_items; int num_ops = 0; for( num_ops = 0; num_ops < 2; num_ops = num_ops + 1) { printf("******* Round %d ********\n",num_ops); #ifdef USE_MB_THREAD printf("**** MB-based Threads ****\n"); #else printf("**** PPC-based Threads ****\n"); #endif min = 9999999; // Lock mutex before hand so that timing will not include thread creation time hthread_mutex_lock(mutex); // Start timing thread create time_create = xps_timer_read_counter(&timer); for (i = 0; i < NUM_THREADS; i++) { // Create the worker threads #ifdef USE_MB_THREAD // Create MB Thread sta[i] = hthread_create( &tid[i], &attr[i], (void*)(min_handle), (void*)(&thread_arg[i]) ); #else // Create SW Thread sta[i] = hthread_create( &tid[i], NULL, min_thread, (void*)(&thread_arg[i]) ); #endif } // Allow created threads to begin running and start timer time_start = xps_timer_read_counter(&timer); hthread_mutex_unlock(mutex); time_unlock = xps_timer_read_counter(&timer); // Wait for the threads to exit //printf( "Waiting for thread(s) to complete... \n" ); for (i = 0; i < NUM_THREADS; i++) { hthread_join( tid[i], &retval[i] ); } time_stop = xps_timer_read_counter(&timer); // Display results printf("Min = %f\n",min); for (i = 0; i < NUM_THREADS; i++) { printf("TID = 0x%08x, status = 0x%08x, retval = 0x%08x\n",tid[i],sta[i],(Huint)retval[i]); } printf("*********************************\n"); printf("Create time = %u\n",time_create); printf("Start time = %u\n",time_start); printf("Unlock time = %u\n",time_unlock); printf("Stop time = %u\n",time_stop); printf("*********************************\n"); printf("Creation time (|Start - Create|) = %u\n",time_start - time_create); printf("Unlock time (|Unlock - Start|) = %u\n",time_unlock - time_start); printf("Elapsed time (|Stop - Start|) = %u\n",time_stop - time_start); } hthread_mutex_destroy( mutex ); free( mutex ); // Clean up the attribute structures for (i = 0; i < NUM_THREADS; i++) { hthread_attr_destroy( &attr[i] ); } printf ("-- Complete --\n"); // Return from main return 0; }
int main (void) { XCache_EnableICache(0x80000001); XCache_EnableDCache(0x80000001); /* Initialize RS232 - Set baudrate and number of stop bits */ XUartNs550_SetBaud(XPAR_RS232_BASEADDR, XPAR_XUARTNS550_CLOCK_HZ, 9600); XUartNs550_mSetLineControlReg(XPAR_RS232_BASEADDR, XUN_LCR_8_DATA_BITS); print("-- Entering main() --\r\n"); /* * MemoryTest routine will not be run for the memory at * 0xffff0000 (xps_bram_if_cntlr_1) * because it is being used to hold a part of this application program */ /* * MemoryTest routine will not be run for the memory at * 0x86000000 (FLASH_8Mx16) * because it is a read-only memory */ /* Testing Memory (DDR2_SDRAM_16Mx32)*/ { XStatus status; print("Starting MemoryTest for DDR2_SDRAM_16Mx32:\r\n"); print(" Running 32-bit test..."); status = XUtil_MemoryTest32((Xuint32*)XPAR_DDR2_SDRAM_16MX32_MEM_BASEADDR, 1024, 0xAAAA5555, XUT_ALLMEMTESTS); if (status == XST_SUCCESS) { print("PASSED!\r\n"); } else { print("FAILED!\r\n"); } print(" Running 16-bit test..."); status = XUtil_MemoryTest16((Xuint16*)XPAR_DDR2_SDRAM_16MX32_MEM_BASEADDR, 2048, 0xAA55, XUT_ALLMEMTESTS); if (status == XST_SUCCESS) { print("PASSED!\r\n"); } else { print("FAILED!\r\n"); } print(" Running 8-bit test..."); status = XUtil_MemoryTest8((Xuint8*)XPAR_DDR2_SDRAM_16MX32_MEM_BASEADDR, 4096, 0xA5, XUT_ALLMEMTESTS); if (status == XST_SUCCESS) { print("PASSED!\r\n"); } else { print("FAILED!\r\n"); } } print("-- Exiting main() --\r\n"); XCache_DisableDCache(); XCache_DisableICache(); return 0; }
int main( int argc, char *argv[] ) { unsigned int i, start_count = 0, done_count = 0, j; timing_t t_start = 0, t_stop = 0, t_gen = 0, t_sort = 0, t_merge = 0, t_check = 0, t_tmp; printf( "-------------------------------------------------------\n" "ReconOS hardware multithreading case study (sort)\n" "(c) Computer Engineering Group, University of Paderborn\n\n" "eCos, single-threaded hardware version (" __FILE__ ")\n" "Compiled on " __DATE__ ", " __TIME__ ".\n" "-------------------------------------------------------\n\n" ); #ifdef USE_CACHE printf( "enabling data cache for external ram\n" ); XCache_EnableDCache( 0x80000000 ); #else printf( "data cache disabled\n" ); XCache_DisableDCache( ); #endif data = buf_a; //---------------------------------- //-- GENERATE DATA //---------------------------------- printf( "Generating data..." ); t_start = gettime( ); generate_data( data, SIZE ); t_stop = gettime( ); t_gen = calc_timediff_ms( t_start, t_stop ); printf( "done\n" ); #ifdef USE_CACHE // flush cache contents - the hardware can only read from main memory // TODO: storing could be more efficient printf( "Flushing cache..." ); XCache_EnableDCache( 0x80000000 ); printf( "done\n" ); #endif //---------------------------------- //-- SORT DATA //---------------------------------- // create mail boxes for 'start' and 'complete' messages cyg_mbox_create( &mb_start_handle, &mb_start ); cyg_mbox_create( &mb_done_handle, &mb_done ); // create sorting thread reconos_hwthread_create( 16, // priority 0, // entry data (not needed) "MT_HW_SORT", // thread name hwthread_sorter_stack, // stack STACK_SIZE, // stack size &hwthread_sorter_handle, // thread handle &hwthread_sorter, // thread object (void*)UPBHWR_OSIF_0_BASEADDR, XPAR_OPB_INTC_0_OSIF_0_INTERRUPT_INTR+1, // ( void * ) XPAR_PLB_RECONOS_SLOT_0_BASEADDR, // base address // XPAR_OPB_INTC_0_PLB_RECONOS_SLOT_0_INTERRUPT_INTR + 1, // interrupt hwthread_sorter_resources, // resource array 2, // number of resources 0xFFFFFFFF, 0xFFFFFFFF ); cyg_thread_resume( hwthread_sorter_handle ); printf( "Sorting data..." ); i = 0; while ( done_count < SIZE / N ) { t_start = gettime( ); // if we have something to distribute, // put as many as possile into the start mailbox while ( start_count < SIZE / N ) { if ( cyg_mbox_tryput( mb_start_handle, ( void * ) &data[i] ) == true ) { start_count++; i += N; } else { // mailbox full break; } } t_stop = gettime( ); t_sort += calc_timediff_ms( t_start, t_stop ); // see whether anybody's done t_start = gettime( ); if ( ( t_tmp = ( timing_t ) cyg_mbox_get( mb_done_handle ) ) != 0 ) { done_count++; } else { printf( "cyg_mbox_get returned NULL!\n" ); } t_stop = gettime( ); t_sort += calc_timediff_ms( t_start, t_stop ); } printf( "done\n" ); #ifdef USE_CACHE // flush cache contents // TODO: invalidating would suffice printf( "Flushing cache..." ); XCache_EnableDCache( 0x80000000 ); printf( "done\n" ); #endif //---------------------------------- //-- MERGE DATA //---------------------------------- printf( "Merging data..." ); t_start = gettime( ); data = recursive_merge( data, buf_b, SIZE, N, simple_merge ); t_stop = gettime( ); t_merge = calc_timediff_ms( t_start, t_stop ); printf( "done\n" ); //---------------------------------- //-- CHECK DATA //---------------------------------- printf( "Checking sorted data..." ); t_start = gettime( ); if ( check_data( data, SIZE ) != 0 ) printf( "CHECK FAILED!\n" ); else printf( "check successful.\n" ); t_stop = gettime( ); t_check = calc_timediff_ms( t_start, t_stop ); printf( "\nRunning times (size: %d words):\n" "\tGenerate data: %d ms\n" "\tSort data : %d ms\n" "\tMerge data : %d ms\n" "\tCheck data : %d ms\n" "\nTotal computation time (sort & merge): %d ms\n", SIZE, t_gen, t_sort, t_merge, t_check, t_sort + t_merge ); return 0; }
int run_tests() { if (NUM_THREADS > NUM_CPUS){ printf("CANNOT USE MORE THAN (%d) HETEROGENEOUS THREADS!!!!\r\n", NUM_CPUS); return (-1); } // Timer variables xps_timer_t timer; int time_create, time_start, time_stop; // Thread attribute structures Huint sta[NUM_THREADS]; void* retval[NUM_THREADS]; hthread_t tid[NUM_THREADS]; hthread_attr_t attr[NUM_THREADS]; targ_t thread_arg[NUM_THREADS]; // Setup Cache XCache_DisableDCache(); XCache_EnableICache(0xc0000801); // Create timer xps_timer_create(&timer, (int*)0x20400000); // Start timer xps_timer_start(&timer); // ************************************************************************************* extern unsigned char intermediate[]; extern unsigned int distance_handle_offset; unsigned int distance_handle = (distance_handle_offset) + (unsigned int)(&intermediate); printf("Code start address = 0x%08x\n", (unsigned int)&intermediate); // ************************************************************************************* int vals_x0[ARR_LENGTH]; int vals_x1[ARR_LENGTH]; int vals_y0[ARR_LENGTH]; int vals_y1[ARR_LENGTH]; int vals_ds[ARR_LENGTH]; int j = 0; for (j = 0; j < NUM_THREADS; j++) { // Initialize the attributes for the threads hthread_attr_init( &attr[j] ); hthread_attr_sethardware( &attr[j], (void*)base_array[j] ); } for (j = 0; j < ARR_LENGTH; j++) { vals_x0[j] = ARR_LENGTH - j; vals_y0[j] = ARR_LENGTH - j; vals_x1[j] = ARR_LENGTH - j + 1; vals_y1[j] = ARR_LENGTH - j; } #ifdef MY_DEBUG #endif int num_ops = 0; for( num_ops = 0; num_ops < 2; num_ops = num_ops + 1) { printf("******* Round %d ********\n",num_ops); #ifdef USE_MB_THREAD printf("**** MB-based Threads ****\n"); #else printf("**** PPC-based Threads ****\n"); #endif for (j = 0; j < ARR_LENGTH; j++) { vals_x0[j] = ARR_LENGTH - j; } // Initialize thread arguments int num_items = ARR_LENGTH/NUM_THREADS; int extra_items = ARR_LENGTH - (num_items*NUM_THREADS); for ( j= 0; j < NUM_THREADS; j++) { thread_arg[j].x0s = &vals_x0[j*(num_items)]; thread_arg[j].y0s = &vals_y0[j*(num_items)]; thread_arg[j].x1s = &vals_x1[j*(num_items)]; thread_arg[j].y1s = &vals_y1[j*(num_items)]; thread_arg[j].distances = &vals_ds[j*(num_items)]; thread_arg[j].length = num_items; } // Add in extra items for the last thread if needed thread_arg[j-1].length += extra_items; time_create = xps_timer_read_counter(&timer); // Create threads for (j = 0; j < NUM_THREADS; j++) { // Create the distance thread #ifdef USE_MB_THREAD // Create MB Thread sta[j] = hthread_create( &tid[j], &attr[j], (void*)distance_handle, (void*)(&thread_arg[j]) ); //printf( "Started MB Thread (TID = %d) \n", tid[j]); #else // Create SW Thread sta[j] = hthread_create( &tid[j], NULL, distance_thread, (void*)(&thread_arg[j]) ); //printf( "Started SW Thread (TID = %d) \n", tid[j]); #endif } // Allow created threads to begin running and start timer time_start = xps_timer_read_counter(&timer); // Join on all threads for (j = 0; j < NUM_THREADS; j++) { hthread_join( tid[j], &retval[j] ); } // Grab stop time time_stop = xps_timer_read_counter(&timer); // Print out status for (j = 0; j < NUM_THREADS; j++) { printf("TID[%d] = 0x%08x, status = 0x%08x, retval = 0x%08x\n",j,tid[j],sta[j],(unsigned int)retval[j]); } printf("*********************************\n"); printf("Create time = %u\n",time_create); printf("Start time = %u\n",time_start); printf("Stop time = %u\n",time_stop); printf("*********************************\n"); printf("Creation time (|Start - Create|) = %u\n",time_start - time_create); printf("Elapsed time (|Stop - Start|) = %u\n",time_stop - time_start); printf("Total time (|Create - Stop|) = %u\n",time_stop - time_create); } #ifdef MY_DEBUG for (j = 0; j < ARR_LENGTH; j++) { printf("D(%d) = %d\n",j,vals_ds[j]); } #endif // Clean up the attribute structures for (j = 0; j < NUM_THREADS; j++) { hthread_attr_destroy( &attr[j] ); } printf ("-- Complete --\n"); // Return from main return 0; }
/****************************************************************************** * Name: main * Description: Program entry point * * Returns: int - returns 0 if no errors ******************************************************************************/ int main() { /* declare a network interface and network addresses */ struct netif *netif, server_netif; struct ip_addr ipaddr, netmask, gw; /* specify a unique MAC address for the board */ #ifdef XPAR_CPU_PPC440_CORE_CLOCK_FREQ_HZ /* set MAC on ML507 board */ unsigned char mac_ethernet_address[] = {0x00, 0x0a, 0x35, 0x01, 0xC9, 0x76}; #else /* set MAC on ML410 board */ unsigned char mac_ethernet_address[] = {0x00, 0x0a, 0x35, 0x01, 0x9A, 0xFE}; #endif /* set the network interface pointer */ netif = &server_netif; /* enable caches */ XCache_EnableICache( INSTR_CACHE ); XCache_EnableDCache( DATA_CACHE ); /* setup interrupts */ setup_interrupts(); /* initliaze network addresses to be used */ IP4_ADDR( &ipaddr, 192, 168, 1, 15 ); IP4_ADDR( &netmask, 255, 255, 255, 0 ); IP4_ADDR( &gw, 192, 168, 1, 1 ); /* print the application header and IP settings */ print_app_header(); print_ip_settings(&ipaddr, &netmask, &gw); /* initialize lwip */ lwip_init(); /* add network interface to the netif_list, and set it as default */ if( !xemac_add( netif, &ipaddr, &netmask, &gw, mac_ethernet_address, EMAC_BASEADDR ) ) { xil_printf( "Error adding N/W interface\n\r" ); return -1; } netif_set_default( netif ); /* now enable interrupts */ enable_interrupts(); /* specify that the network if is up */ netif_set_up( netif ); /* start the application */ start_application(); /* print debug header if debug mode set */ #ifdef QMFIR_DEBUG debug_menu(); while( 1) { qmfir_debug(); } #endif /* receive and process packets */ while( 1 ) { xemacif_input( netif ); } /* disable caches */ XCache_DisableDCache(); XCache_DisableICache(); return 0; } /* main */
int main( int argc, char *argv[] ) { int i; //int s, msg, retval; volatile int * src = (volatile int*)(((int)mem/16 + 1)*16 + 4); // align to 8 + 4 bytes volatile int * dst = src + MEMSIZE/4; XCache_DisableDCache(); args[0] = (int)src; args[1] = (int)dst; args[2] = (int)MEMSIZE; printf("begin memcopy_test_posix\n"); /* printf("args = 0x%08X\n",(unsigned int)args); for(i = 0; i < 3; i++){ printf("args[%d] = 0x%08X\n",i,args[i]); } */ for(i = 0; i < MEMSIZE/4; i++){ src[i] = i + 1; dst[i] = 0; } /* // set message queue attributes to non-blocking, 10 messages with 4 bytes each mbox_attr.mq_flags = 0; mbox_attr.mq_maxmsg = 10000; mbox_attr.mq_msgsize = 4; mbox_attr.mq_curmsgs = 0; // create mailboxes mbox = mq_open("/mbox", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG, &mbox_attr); if (mbox == (mqd_t)-1) { perror("unable to create mbox"); } */ // create hardware thread printf("creating hw thread... "); POSIX_HWT_CREATE(0,(unsigned int)args,thread_resources); printf("ok\n"); cyg_thread_delay(100); /* retval = mq_receive(mbox, (char*)&msg, 4, NULL); printf("init_data: 0x%08X (retval %d)\n", msg, retval); i = 0; s = (unsigned int)src; while(1){ retval = mq_receive(mbox, (char*)&msg, 4, NULL); if(msg == 0x0112358D) break; switch(i){ case 0: printf("SRC"); break; case 1: printf("DST"); break; case 2: printf("SIZE"); break; } printf(": 0x%08X (retval %d)", msg, retval); if(i == 0){ int d = (unsigned int)msg - s; if(d == 4) printf(" SINGLE"); else if(d == 128) printf(" *** BURST ***"); else printf(" chunk size = %u bytes", d); s = msg; } printf("\n"); i = (i + 1) % 3; } for(i = 0; i < MEMSIZE/4; i++){ printf("dst[0x%08X] = %d\n", i, dst[i]); } */ for(i = 0; i < MEMSIZE/4; i++){ if(src[i] != dst[i]){ printf("memcopy failed.\n"); printf("error: destination[%d] = %d, should be %d\n",i,dst[i],src[i]); return 1; } } printf("memcopy ok. (%d bytes copied correctly)\n",MEMSIZE); printf("memcopy_test_posix done.\n"); return 0; }
//int main( int argc, char *argv[] ) int run_tests() { if (NUM_THREADS > NUM_CPUS){ printf("CANNOT USE MORE THAN (%d) HETEROGENEOUS THREADS!!!!\r\n",NUM_CPUS); return (-1); } // Timer variables xps_timer_t timer; int time_create, time_start, time_stop; // Thread attribute structures Huint sta[NUM_THREADS]; void* retval[NUM_THREADS]; hthread_t tid[NUM_THREADS]; hthread_attr_t attr[NUM_THREADS]; targ_t thread_arg[NUM_THREADS]; // Setup Cache XCache_DisableDCache(); XCache_EnableICache(0xc0000801); // Create timer xps_timer_create(&timer, (int*)0x20400000); // Start timer xps_timer_start(&timer); // ************************************************************************************* extern unsigned char intermediate[]; extern unsigned int sort_handle_offset; unsigned int sort_handle = (sort_handle_offset) + (unsigned int)(&intermediate); // ************************************************************************************* float local_data[ARR_LENGTH]; int j = 0; printf("Code start address = 0x%08x\n", (unsigned int)&intermediate); for (j = 0; j < NUM_THREADS; j++) { // Initialize the attributes for the threads hthread_attr_init( &attr[j] ); hthread_attr_sethardware( &attr[j], (void*)base_array[j] ); } for (j = 0; j < ARR_LENGTH; j++) { local_data[j] = (ARR_LENGTH - j)*1.00; } #ifdef MY_DEBUG show_array(&local_data[0], ARR_LENGTH); #endif int num_ops = 0; for( num_ops = 0; num_ops < 2; num_ops = num_ops + 1) { printf("******* Round %d ********\n",num_ops); #ifdef USE_MB_THREAD printf("**** MB-based Threads ****\n"); #else printf("**** PPC-based Threads ****\n"); #endif for (j = 0; j < ARR_LENGTH; j++) { local_data[j] = ARR_LENGTH - j; } // Initialize thread arguments for ( j= 0; j < NUM_THREADS; j++) { thread_arg[j].data = &local_data[j*(ARR_LENGTH/NUM_THREADS)]; thread_arg[j].length = ARR_LENGTH/NUM_THREADS; } time_create = xps_timer_read_counter(&timer); // Create threads for (j = 0; j < NUM_THREADS; j++) { // Create the sort thread #ifdef USE_MB_THREAD // Create MB Thread sta[j] = hthread_create( &tid[j], &attr[j], (void*)sort_handle, (void*)(&thread_arg[j]) ); //printf( "Started MB Thread (TID = %d) \n", tid[j]); #else // Create SW Thread sta[j] = hthread_create( &tid[j], NULL, bubblesort_thread, (void*)(&thread_arg[j]) ); //printf( "Started SW Thread (TID = %d) \n", tid[j]); #endif } // Allow created threads to begin running and start timer time_start = xps_timer_read_counter(&timer); // Join on all threads for (j = 0; j < NUM_THREADS; j++) { hthread_join( tid[j], &retval[j] ); } // Grab stop time time_stop = xps_timer_read_counter(&timer); // Print out status for (j = 0; j < NUM_THREADS; j++) { printf("TID[%d] = 0x%08x, status = 0x%08x, retval = 0x%08x\n",j,tid[j],sta[j],(unsigned int)retval[j]); } printf("*********************************\n"); printf("Create time = %u\n",time_create); printf("Start time = %u\n",time_start); printf("Stop time = %u\n",time_stop); printf("*********************************\n"); printf("Creation time (|Start - Create|) = %u\n",time_start - time_create); printf("Elapsed time (|Stop - Start|) = %u\n",time_stop - time_start); printf("Total time (|Create - Stop|) = %u\n",time_stop - time_create); } #ifdef MY_DEBUG show_array(&local_data[0], ARR_LENGTH); check_array(&local_data[0], ARR_LENGTH); // Note there will be errors as the data set is not merged #endif // Clean up the attribute structures for (j = 0; j < NUM_THREADS; j++) { hthread_attr_destroy( &attr[j] ); } printf ("-- Complete --\n"); // Return from main return 0; }