コード例 #1
0
/**
 * Main entrypoint of the application. Here we setup shared
 * memory and fork processes for each cpu. This simulates the
 * normal simple executive environment of one process per
 * cpu core.
 *
 * @param argc   Number of command line arguments
 * @param argv   The command line arguments
 * @return Return value for the process
 */
int main(int argc, const char *argv[])
{
    CVMX_SHARED static cvmx_spinlock_t mask_lock = CVMX_SPINLOCK_UNLOCKED_INITIALIZER;
    CVMX_SHARED static int32_t pending_fork;
    unsigned long cpumask;
    unsigned long cpu;

    setup_system_info();

    if (sizeof(void*) == 4)
    {
        if (linux_mem32_min)
            setup_reserve32();
        else
        {
            printf("\nFailed to access 32bit shared memory region. Most likely the Kernel\n"
                   "has not been configured for 32bit shared memory access. Check the\n"
                   "kernel configuration.\n"
                   "Aborting...\n\n");
            exit(-1);
        }
    }

    setup_cvmx_shared();

    /* Check to make sure the Chip version matches the configured version */
    octeon_model_version_check(cvmx_app_init_processor_id);

    /* Get the list of logical cpus we should run on */
    if (sched_getaffinity(0, sizeof(cpumask), (cpu_set_t*)&cpumask))
    {
        perror("sched_getaffinity failed");
        exit(errno);
    }

    cvmx_sysinfo_t *system_info = cvmx_sysinfo_get();

    cvmx_atomic_set32(&pending_fork, 1);
    for (cpu=0; cpu<16; cpu++)
    {
        if (cpumask & (1<<cpu))
        {
            /* Turn off the bit for this CPU number. We've counted him */
            cpumask ^= (1<<cpu);
            /* If this is the last CPU to run on, use this process instead of forking another one */
            if (cpumask == 0)
                break;
            /* Increment the number of CPUs running this app */
            cvmx_atomic_add32(&pending_fork, 1);
            /* Fork a process for the new CPU */
            int pid = fork();
            if (pid == 0)
            {
                break;
            }
            else if (pid == -1)
            {
                perror("Fork failed");
                exit(errno);
            }
        }
    }

    /* Set affinity to lock me to the correct CPU */
    cpumask = (1<<cpu);
    if (sched_setaffinity(0, sizeof(cpumask), (cpu_set_t*)&cpumask))
    {
        perror("sched_setaffinity failed");
        exit(errno);
    }

    cvmx_spinlock_lock(&mask_lock);
    system_info->core_mask |= 1<<cvmx_get_core_num();
    cvmx_atomic_add32(&pending_fork, -1);
    if (cvmx_atomic_get32(&pending_fork) == 0)
        cvmx_dprintf("Active coremask = 0x%x\n", system_info->core_mask);
    cvmx_spinlock_unlock(&mask_lock);

    /* Spinning waiting for forks to complete */
    while (cvmx_atomic_get32(&pending_fork)) {}

    cvmx_coremask_barrier_sync(system_info->core_mask);

    int result = appmain(argc, argv);

    shutdown_cvmx_shared();

    return result;
}
コード例 #2
0
ファイル: octeon_machdep.c プロジェクト: 2trill2spill/freebsd
void
platform_start(__register_t a0, __register_t a1, __register_t a2 __unused,
    __register_t a3)
{
	const struct octeon_feature_description *ofd;
	uint64_t platform_counter_freq;
	int rv;

	mips_postboot_fixup();

	/*
	 * Initialize boot parameters so that we can determine things like
	 * which console we shoud use, etc.
	 */
	octeon_boot_params_init(a3);

	/* Initialize pcpu stuff */
	mips_pcpu0_init();
	mips_timer_early_init(cvmx_sysinfo_get()->cpu_clock_hz);

	/* Initialize console.  */
	cninit();

	/*
	 * Display information about the CPU.
	 */
#if !defined(OCTEON_MODEL)
	printf("Using runtime CPU model checks.\n");
#else
	printf("Compiled for CPU model: " __XSTRING(OCTEON_MODEL) "\n");
#endif
	strcpy(cpu_model, octeon_model_get_string(cvmx_get_proc_id()));
	printf("CPU Model: %s\n", cpu_model);
	printf("CPU clock: %uMHz  Core Mask: %#x\n",
	       cvmx_sysinfo_get()->cpu_clock_hz / 1000000,
	       cvmx_sysinfo_get()->core_mask);
	rv = octeon_model_version_check(cvmx_get_proc_id());
	if (rv == -1)
		panic("%s: kernel not compatible with this processor.", __func__);

	/*
	 * Display information about the board.
	 */
#if defined(OCTEON_BOARD_CAPK_0100ND)
	strcpy(cpu_board, "CAPK-0100ND");
	if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_CN3010_EVB_HS5) {
		panic("Compiled for %s, but board type is %s.", cpu_board,
		       cvmx_board_type_to_string(cvmx_sysinfo_get()->board_type));
	}
#else
	strcpy(cpu_board,
	       cvmx_board_type_to_string(cvmx_sysinfo_get()->board_type));
#endif
	printf("Board: %s\n", cpu_board);
	printf("Board Type: %u  Revision: %u/%u\n",
	       cvmx_sysinfo_get()->board_type,
	       cvmx_sysinfo_get()->board_rev_major,
	       cvmx_sysinfo_get()->board_rev_minor);
	printf("Serial number: %s\n", cvmx_sysinfo_get()->board_serial_number);

	/*
	 * Additional on-chip hardware/settings.
	 *
	 * XXX Display PCI host/target?  What else?
	 */
	printf("MAC address base: %6D (%u configured)\n",
	       cvmx_sysinfo_get()->mac_addr_base, ":",
	       cvmx_sysinfo_get()->mac_addr_count);


	octeon_ciu_reset();
	/*
	 * Convert U-Boot 'bootoctlinux' loader command line arguments into
	 * boot flags and kernel environment variables.
	 */
	bootverbose = 1;
	octeon_init_kenv(a3);

	/*
	 * For some reason on the cn38xx simulator ebase register is set to
	 * 0x80001000 at bootup time.  Move it back to the default, but
	 * when we move to having support for multiple executives, we need
	 * to rethink this.
	 */
	mips_wr_ebase(0x80000000);

	octeon_memory_init();
	init_param1();
	init_param2(physmem);
	mips_cpu_init();
	pmap_bootstrap();
	mips_proc0_init();
	mutex_init();
	kdb_init();
#ifdef KDB
	if (boothowto & RB_KDB)
		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
	cpu_clock = cvmx_sysinfo_get()->cpu_clock_hz;
	platform_counter_freq = cpu_clock;
	octeon_timecounter.tc_frequency = cpu_clock;
	platform_timecounter = &octeon_timecounter;
	mips_timer_init_params(platform_counter_freq, 0);
	set_cputicker(octeon_get_ticks, cpu_clock, 0);

#ifdef SMP
	/*
	 * Clear any pending IPIs.
	 */
	cvmx_write_csr(CVMX_CIU_MBOX_CLRX(0), 0xffffffff);
#endif

	printf("Octeon SDK: %s\n", OCTEON_SDK_VERSION_STRING);
	printf("Available Octeon features:");
	for (ofd = octeon_feature_descriptions; ofd->ofd_string != NULL; ofd++)
		if (octeon_has_feature(ofd->ofd_feature))
			printf(" %s", ofd->ofd_string);
	printf("\n");
}