/* ap.c COPYRIGHT FUJITSU LIMITED 2015 */ /** * \file ap.c * Licence details are found in the file LICENSE. * * \brief * Initiallization code for CPU cores other than the boot core. * * \author Taku Shimosawa \par * Copyright (C) 2011 - 2012 Taku Shimosawa * * \author Balazs Gerofi \par * Copyright (C) 2012 RIKEN AICS * * * HISTORY: * 2012/10/10: bgerofi - enable syscall channels for all MIC cores * */ #include #include #include #include #include #include #include #include #include #include #include #include #include //#define DEBUG_PRINT_AP #ifdef DEBUG_PRINT_AP #undef DDEBUG_DEFAULT #define DDEBUG_DEFAULT DDEBUG_PRINT #endif int num_processors = 1; static volatile int ap_stop = 1; mcs_lock_node_t ap_syscall_semaphore; static void ap_wait(void) { init_tick(); while (ap_stop) { barrier(); cpu_pause(); } sync_tick(); kmalloc_init(); sched_init(); arch_start_pvclock(); if (find_command_line("hidos")) { mcs_lock_node_t mcs_node; int ikc_cpu = ihk_mc_get_ikc_cpu(ihk_mc_get_processor_id()); if(ikc_cpu < 0) { ekprintf("%s,ihk_mc_get_ikc_cpu failed\n", __FUNCTION__); } mcs_lock_lock_noirq(&ap_syscall_semaphore, &mcs_node); init_host_ikc2mckernel(); init_host_ikc2linux(ikc_cpu); mcs_lock_unlock_noirq(&ap_syscall_semaphore, &mcs_node); } /* one of them listens */ mc_ikc_test_init(); schedule(); } void ap_start(void) { init_tick(); mcs_lock_init(&ap_syscall_semaphore); ap_stop = 0; sync_tick(); } void ap_init(void) { struct ihk_mc_cpu_info *cpu_info; int i; int bsp_hw_id, bsp_cpu_id; ihk_mc_init_ap(); init_delay(); cpu_info = ihk_mc_get_cpu_info(); bsp_hw_id = ihk_mc_get_hardware_processor_id(); /* If no information exists, UP mode */ if (!cpu_info) { return; } bsp_cpu_id = 0; for (i = 0; i < cpu_info->ncpus; ++i) { if (cpu_info->hw_ids[i] == bsp_hw_id) { bsp_cpu_id = i; break; } } kprintf("BSP: %d (HW ID: %d @ NUMA %d)\n", bsp_cpu_id, bsp_hw_id, cpu_info->nodes[0]); for (i = 0; i < cpu_info->ncpus; i++) { if (cpu_info->hw_ids[i] == bsp_hw_id) { continue; } dkprintf("AP Booting: %d (HW ID: %d @ NUMA %d)\n", i, cpu_info->hw_ids[i], cpu_info->nodes[i]); ihk_mc_boot_cpu(cpu_info->hw_ids[i], (unsigned long)ap_wait); num_processors++; } kprintf("BSP: booted %d AP CPUs\n", cpu_info->ncpus - 1); } #include #include #include #include static ssize_t show_int(struct sysfs_ops *ops, void *instance, void *buf, size_t size) { int *p = instance; return snprintf(buf, size, "%d\n", *p); }/* show_int() */ struct sysfs_ops show_int_ops = { .show = &show_int, }; struct fake_cpu_info { int online; }; static struct fake_cpu_info *fake_cpu_infos = NULL; enum fake_cpu_info_member { ONLINE, }; struct fake_cpu_info_ops { enum fake_cpu_info_member member; struct sysfs_ops ops; }; static ssize_t show_fake_cpu_info(struct sysfs_ops *ops0, void *instance, void *buf, size_t size) { struct fake_cpu_info_ops *ops = container_of(ops0, struct fake_cpu_info_ops, ops); struct fake_cpu_info *info = instance; ssize_t n; switch (ops->member) { case ONLINE: n = snprintf(buf, size, "%d\n", info->online); break; default: n = -EINVAL; break; } if (n >= size) { n = -ENOSPC; } return n; } /* show_fake_cpu_info() */ static ssize_t store_fake_cpu_info(struct sysfs_ops *ops0, void *instance, void *buf, size_t size) { struct fake_cpu_info_ops *ops = container_of(ops0, struct fake_cpu_info_ops, ops); struct fake_cpu_info *info = instance; ssize_t n; switch (ops->member) { case ONLINE: kprintf("NYI:store_fake_cpu_info(%p,%p,%p,%ld): " "online %d --> \"%.*s\"\n", ops0, instance, buf, size, info->online, (int)size, buf); n = size; break; default: n = -EIO; break; } return n; } /* store_fake_cpu_info() */ static struct fake_cpu_info_ops show_fci_online = { .member = ONLINE, .ops = { .show = &show_fake_cpu_info, .store = &store_fake_cpu_info, }, }; void cpu_sysfs_setup(void) { int error; int cpu; sysfs_handle_t targeth; struct fake_cpu_info *info; /* sample of simple variable **********************************/ error = sysfs_createf(&show_int_ops, &num_processors, 0444, "/sys/devices/system/cpu/num_processors"); if (error) { panic("cpu_sysfs_setup:sysfs_createf(num_processors) failed\n"); } /* sample of more complex variable ****************************/ /* setup table */ info = kmalloc(sizeof(*info) * num_processors, IHK_MC_AP_CRITICAL); for (cpu = 0; cpu < num_processors; ++cpu) { info[cpu].online = 1; } fake_cpu_infos = info; /* setup sysfs tree */ for (cpu = 0; cpu < num_processors; ++cpu) { /* online */ error = sysfs_createf(&show_fci_online.ops, &fake_cpu_infos[cpu], 0644, "/sys/devices/system/cpu/cpu%d/online", cpu); if (error) { panic("cpu_sysfs_setup:sysfs_createf failed\n"); } /* link to cpu%d */ error = sysfs_lookupf(&targeth, "/sys/devices/system/cpu/cpu%d", cpu); if (error) { panic("cpu_sysfs_setup:sysfs_lookupf failed\n"); } error = sysfs_symlinkf(targeth, "/sys/bus/cpu/devices/cpu%d", cpu); if (error) { panic("cpu_sysfs_setup:sysfs_symlinkf failed\n"); } } return; } /* cpu_sysfs_setup() */