support builtin-x86 and builtin-mic

This commit is contained in:
shirasawa
2013-01-06 15:45:17 +09:00
parent 884bd5db82
commit 9818e199f6
17 changed files with 380 additions and 142 deletions

View File

@@ -1,29 +1,36 @@
DEST=$(O)/elfboot
CFLAGS=-c -Wall -O CFLAGS=-c -Wall -O
CFLAGS_TEST=-DTEST CFLAGS_TEST=-DTEST
all: elfboot all: $(DEST) $(DEST)/elfboot
elfboot: elfboot.bin $(DEST)/elfboot: $(DEST)/elfboot.bin
cp $^ $@ cp $^ $@
truncate -s $(shell expr '(' `stat -c '%s' $^` + 4095 ')' / 4096 '*' 4096) $@ truncate -s $(shell expr '(' `stat -c '%s' $^` + 4095 ')' / 4096 '*' 4096) $@
elfboot.bin: elfboot.elf $(DEST)/elfboot.bin: $(DEST)/elfboot.elf
$(OBJCOPY) -O binary $^ $@ $(OBJCOPY) -O binary $^ $@
elfboot.elf: head.o elfboot.raw.o raw.lds $(DEST)/elfboot.elf: $(DEST)/head.o $(DEST)/elfboot.raw.o raw.lds
$(LD) $(LDFLAGS_RAW) -T raw.lds -o $@ $^ $(LD) $(LDFLAGS_RAW) -T raw.lds -o $@ $^
elfboot_test: elfboot.test.o test_main.o $(DEST)/elfboot_test: $(DEST)/elfboot.test.o $(DEST)/test_main.o
$(CC) -o $@ $^ $(CC) -o $@ $^
elfboot.raw.o: elfboot.c $(DEST)/head.o: head.S
$(CC) $(CFLAGS) -o $@ $^ $(CC) $(CFLAGS) -o $@ $^
elfboot.test.o: elfboot.c $(DEST)/elfboot.raw.o: elfboot.c
$(CC) $(CFLAGS) -o $@ $^
$(DEST)/elfboot.test.o: elfboot.c
$(CC) $(CFLAGS) $(CFLAGS_TEST) -o $@ $^ $(CC) $(CFLAGS) $(CFLAGS_TEST) -o $@ $^
clean: clean:
$(RM) elfboot *.bin *.elf elfboot_test *.o $(RM) $(DEST)/elfboot *.bin $(DEST)/*.elf $(DEST)/elfboot_test *.o
disas: disas:
$(OBJDUMP) -b binary -m i386:x86-64 -D elfboot.bin $(OBJDUMP) -b binary -m i386:x86-64 -D $(DEST)/elfboot.bin
$(DEST):
@mkdir -p $(DEST)

View File

@@ -16,9 +16,9 @@
#define dprintk(...) #define dprintk(...)
#endif #endif
static DECLARE_WAIT_QUEUE_HEAD(wq_prepare); //static DECLARE_WAIT_QUEUE_HEAD(wq_prepare);
extern struct mcctrl_channel *channels; //extern struct mcctrl_channel *channels;
int mcctrl_ikc_set_recv_cpu(int cpu); int mcctrl_ikc_set_recv_cpu(ihk_os_t os, int cpu);
static long mcexec_prepare_image(ihk_os_t os, static long mcexec_prepare_image(ihk_os_t os,
struct program_load_desc * __user udesc) struct program_load_desc * __user udesc)
@@ -27,6 +27,7 @@ static long mcexec_prepare_image(ihk_os_t os,
struct ikc_scd_packet isp; struct ikc_scd_packet isp;
void *args, *envs; void *args, *envs;
long ret = 0; long ret = 0;
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
if (copy_from_user(&desc, udesc, if (copy_from_user(&desc, udesc,
sizeof(struct program_load_desc))) { sizeof(struct program_load_desc))) {
@@ -77,9 +78,9 @@ static long mcexec_prepare_image(ihk_os_t os,
printk("%p (%lx)\n", pdesc, isp.arg); printk("%p (%lx)\n", pdesc, isp.arg);
pdesc->status = 0; pdesc->status = 0;
mcctrl_ikc_send(pdesc->cpu, &isp); mcctrl_ikc_send(os, pdesc->cpu, &isp);
wait_event_interruptible(wq_prepare, pdesc->status); wait_event_interruptible(usrdata->wq_prepare, pdesc->status);
if (copy_to_user(udesc, pdesc, sizeof(struct program_load_desc) + if (copy_to_user(udesc, pdesc, sizeof(struct program_load_desc) +
sizeof(struct program_image_section) * desc.num_sections)) { sizeof(struct program_image_section) * desc.num_sections)) {
@@ -167,7 +168,7 @@ int mcexec_load_image(ihk_os_t os, struct program_transfer *__user upt)
#endif #endif
} }
extern unsigned long last_thread_exec; //extern unsigned long last_thread_exec;
static long mcexec_start_image(ihk_os_t os, static long mcexec_start_image(ihk_os_t os,
struct program_load_desc * __user udesc) struct program_load_desc * __user udesc)
@@ -175,23 +176,24 @@ static long mcexec_start_image(ihk_os_t os,
struct program_load_desc desc; struct program_load_desc desc;
struct ikc_scd_packet isp; struct ikc_scd_packet isp;
struct mcctrl_channel *c; struct mcctrl_channel *c;
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
if (copy_from_user(&desc, udesc, if (copy_from_user(&desc, udesc,
sizeof(struct program_load_desc))) { sizeof(struct program_load_desc))) {
return -EFAULT; return -EFAULT;
} }
c = channels + desc.cpu; c = usrdata->channels + desc.cpu;
mcctrl_ikc_set_recv_cpu(desc.cpu); mcctrl_ikc_set_recv_cpu(os, desc.cpu);
last_thread_exec = desc.cpu; usrdata->last_thread_exec = desc.cpu;
isp.msg = SCD_MSG_SCHEDULE_PROCESS; isp.msg = SCD_MSG_SCHEDULE_PROCESS;
isp.ref = desc.cpu; isp.ref = desc.cpu;
isp.arg = desc.rprocess; isp.arg = desc.rprocess;
mcctrl_ikc_send(desc.cpu, &isp); mcctrl_ikc_send(os, desc.cpu, &isp);
return 0; return 0;
} }
@@ -207,31 +209,37 @@ int mcexec_syscall(struct mcctrl_channel *c, unsigned long arg)
#ifndef DO_USER_MODE #ifndef DO_USER_MODE
int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c, int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c,
struct syscall_request *sc); struct syscall_request *sc);
static int remaining_job, base_cpu, job_pos; // static int remaining_job, base_cpu, job_pos;
#endif #endif
extern int num_channels; // extern int num_channels;
extern int mcctrl_dma_abort; // extern int mcctrl_dma_abort;
int mcexec_wait_syscall(ihk_os_t os, struct syscall_wait_desc *__user req) int mcexec_wait_syscall(ihk_os_t os, struct syscall_wait_desc *__user req)
{ {
struct syscall_wait_desc swd; struct syscall_wait_desc swd;
struct mcctrl_channel *c; struct mcctrl_channel *c;
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
#ifndef DO_USER_MODE
unsigned long s, w, d;
#endif
if (copy_from_user(&swd, req, sizeof(swd.cpu))) { if (copy_from_user(&swd, req, sizeof(swd.cpu))) {
return -EFAULT; return -EFAULT;
} }
c = channels + swd.cpu; if(swd.cpu >= usrdata->num_channels)return -EINVAL;
c = usrdata->channels + swd.cpu;
#ifdef DO_USER_MODE #ifdef DO_USER_MODE
wait_event_interruptible(c->wq_syscall, c->req); wait_event_interruptible(c->wq_syscall, c->req);
c->req = 0; c->req = 0;
#else #else
while (1) { while (1) {
c = channels + swd.cpu; c = usrdata->channels + swd.cpu;
rdtscll(s); rdtscll(s);
if (!remaining_job) { if (!usrdata->remaining_job) {
while (!(*c->param.doorbell_va)) { while (!(*c->param.doorbell_va)) {
mb(); mb();
cpu_relax(); cpu_relax();
@@ -243,22 +251,22 @@ int mcexec_wait_syscall(ihk_os_t os, struct syscall_wait_desc *__user req)
d = (*c->param.doorbell_va) - 1; d = (*c->param.doorbell_va) - 1;
*c->param.doorbell_va = 0; *c->param.doorbell_va = 0;
if (d < 0 || d >= num_channels) { if (d < 0 || d >= usrdata->num_channels) {
d = 0; d = 0;
} }
base_cpu = d; usrdata->base_cpu = d;
job_pos = 0; usrdata->job_pos = 0;
remaining_job = 1; usrdata->remaining_job = 1;
} else { } else {
job_pos++; usrdata->job_pos++;
} }
for (; job_pos < num_channels; job_pos++) { for (; usrdata->job_pos < usrdata->num_channels; usrdata->job_pos++) {
if (base_cpu + job_pos >= num_channels) { if (base_cpu + job_pos >= num_channels) {
c = channels + c = usrdata->channels +
(base_cpu + job_pos - num_channels); (usrdata->base_cpu + usrdata->job_pos - usrdata->num_channels);
} else { } else {
c = channels + base_cpu + job_pos; c = usrdata->channels + usrdata->base_cpu + usrdata->job_pos;
} }
if (!c) { if (!c) {
continue; continue;
@@ -278,12 +286,12 @@ int mcexec_wait_syscall(ihk_os_t os, struct syscall_wait_desc *__user req)
#ifndef DO_USER_MODE #ifndef DO_USER_MODE
return 0; return 0;
} }
if (mcctrl_dma_abort) { if (usrdata->mcctrl_dma_abort) {
return -2; return -2;
} }
} }
} }
remaining_job = 0; usrdata->remaining_job = 0;
} }
#endif #endif
return 0; return 0;
@@ -404,6 +412,7 @@ long mcexec_ret_syscall(ihk_os_t os, struct syscall_ret_desc *__user arg)
{ {
struct syscall_ret_desc ret; struct syscall_ret_desc ret;
struct mcctrl_channel *mc; struct mcctrl_channel *mc;
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
#if 0 #if 0
ihk_dma_channel_t channel; ihk_dma_channel_t channel;
struct ihk_dma_request request; struct ihk_dma_request request;
@@ -417,7 +426,7 @@ long mcexec_ret_syscall(ihk_os_t os, struct syscall_ret_desc *__user arg)
if (copy_from_user(&ret, arg, sizeof(struct syscall_ret_desc))) { if (copy_from_user(&ret, arg, sizeof(struct syscall_ret_desc))) {
return -EFAULT; return -EFAULT;
} }
mc = channels + ret.cpu; mc = usrdata->channels + ret.cpu;
if (!mc) { if (!mc) {
return -EINVAL; return -EINVAL;
} }
@@ -501,12 +510,13 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg)
return -EINVAL; return -EINVAL;
} }
void mcexec_prepare_ack(unsigned long arg) void mcexec_prepare_ack(ihk_os_t os, unsigned long arg)
{ {
struct program_load_desc *desc = phys_to_virt(arg); struct program_load_desc *desc = phys_to_virt(arg);
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
desc->status = 1; desc->status = 1;
wake_up_all(&wq_prepare); wake_up_all(&usrdata->wq_prepare);
} }

View File

@@ -9,9 +9,14 @@
#include <linux/slab.h> #include <linux/slab.h>
#include "mcctrl.h" #include "mcctrl.h"
#define OS_MAX_MINOR 64
extern long __mcctrl_control(ihk_os_t, unsigned int, unsigned long); extern long __mcctrl_control(ihk_os_t, unsigned int, unsigned long);
extern int prepare_ikc_channels(ihk_os_t os); extern int prepare_ikc_channels(ihk_os_t os);
extern void destroy_ikc_channels(ihk_os_t os); extern void destroy_ikc_channels(ihk_os_t os);
#ifndef DO_USER_MODE
extern void mcctrl_syscall_init(void);
#endif
static long mcctrl_ioctl(ihk_os_t os, unsigned int request, void *priv, static long mcctrl_ioctl(ihk_os_t os, unsigned int request, void *priv,
unsigned long arg) unsigned long arg)
@@ -30,33 +35,70 @@ static struct ihk_os_user_call_handler mcctrl_uchs[] = {
{ .request = MCEXEC_UP_FREE_DMA, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_FREE_DMA, .func = mcctrl_ioctl },
}; };
static struct ihk_os_user_call mcctrl_uc = { static struct ihk_os_user_call mcctrl_uc_proto = {
.num_handlers = sizeof(mcctrl_uchs) / sizeof(mcctrl_uchs[0]), .num_handlers = sizeof(mcctrl_uchs) / sizeof(mcctrl_uchs[0]),
.handlers = mcctrl_uchs, .handlers = mcctrl_uchs,
}; };
static ihk_os_t os; static struct ihk_os_user_call mcctrl_uc[OS_MAX_MINOR];
static ihk_os_t os[OS_MAX_MINOR];
static int __init mcctrl_init(void) static int __init mcctrl_init(void)
{ {
os = ihk_host_find_os(0, NULL); int i;
if (!os) { int rc;
printk("OS #0 not found.\n");
return -ENOENT; rc = -ENOENT;
for(i = 0; i < OS_MAX_MINOR; i++){
os[i] = ihk_host_find_os(i, NULL);
if (os[i]) {
printk("OS #%d found.\n", i);
rc = 0;
}
} }
if (prepare_ikc_channels(os) != 0) { if(rc){
printk("Preparing syscall channels failed.\n"); printk("OS not found.\n");
return -EINVAL; return rc;
} }
return ihk_os_register_user_call_handlers(os, &mcctrl_uc); for(i = 0; i < OS_MAX_MINOR; i++){
if (os[i]) {
if (prepare_ikc_channels(os[i]) != 0) {
printk("Preparing syscall channels failed.\n");
os[i] = NULL;
}
}
}
#ifndef DO_USER_MODE
mcctrl_syscall_init();
#endif
for(i = 0; i < OS_MAX_MINOR; i++){
if (os[i]) {
memcpy(mcctrl_uc + i, &mcctrl_uc_proto, sizeof mcctrl_uc_proto);
rc = ihk_os_register_user_call_handlers(os[i], mcctrl_uc + i);
if(rc < 0){
destroy_ikc_channels(os[i]);
os[i] = NULL;
}
}
}
return 0;
} }
static void __exit mcctrl_exit(void) static void __exit mcctrl_exit(void)
{ {
int i;
printk("mcctrl: unregistered.\n"); printk("mcctrl: unregistered.\n");
ihk_os_unregister_user_call_handlers(os, &mcctrl_uc); for(i = 0; i < OS_MAX_MINOR; i++){
destroy_ikc_channels(os); if(os[i]){
ihk_os_unregister_user_call_handlers(os[i], mcctrl_uc + i);
destroy_ikc_channels(os[i]);
}
}
} }
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");

View File

@@ -3,18 +3,19 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h>
#include "mcctrl.h" #include "mcctrl.h"
#include <ihk/ikc.h> #ifdef ATTACHED_MIC
#include <ikc/master.h>
#include <sysdeps/mic/mic/micconst.h> #include <sysdeps/mic/mic/micconst.h>
#endif
#define REQUEST_SHIFT 16 #define REQUEST_SHIFT 16
int num_channels; //int num_channels;
struct mcctrl_channel *channels; //struct mcctrl_channel *channels;
void mcexec_prepare_ack(unsigned long arg); void mcexec_prepare_ack(ihk_os_t os, unsigned long arg);
static void mcctrl_ikc_init(ihk_os_t os, int cpu, unsigned long rphys); static void mcctrl_ikc_init(ihk_os_t os, int cpu, unsigned long rphys);
int mcexec_syscall(struct mcctrl_channel *c, unsigned long arg); int mcexec_syscall(struct mcctrl_channel *c, unsigned long arg);
@@ -22,6 +23,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
void *__packet, void *__os) void *__packet, void *__os)
{ {
struct ikc_scd_packet *pisp = __packet; struct ikc_scd_packet *pisp = __packet;
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(__os);
switch (pisp->msg) { switch (pisp->msg) {
case SCD_MSG_INIT_CHANNEL: case SCD_MSG_INIT_CHANNEL:
@@ -29,30 +31,33 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
break; break;
case SCD_MSG_PREPARE_PROCESS_ACKED: case SCD_MSG_PREPARE_PROCESS_ACKED:
mcexec_prepare_ack(pisp->arg); mcexec_prepare_ack(__os, pisp->arg);
break; break;
case SCD_MSG_SYSCALL_ONESIDE: case SCD_MSG_SYSCALL_ONESIDE:
mcexec_syscall(channels + pisp->ref, pisp->arg); mcexec_syscall(usrdata->channels + pisp->ref, pisp->arg);
break; break;
} }
return 0; return 0;
} }
int mcctrl_ikc_send(int cpu, struct ikc_scd_packet *pisp) int mcctrl_ikc_send(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp)
{ {
if (cpu < 0 || cpu >= num_channels || !channels[cpu].c) { struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
if (cpu < 0 || cpu >= usrdata->num_channels || !usrdata->channels[cpu].c) {
return -EINVAL; return -EINVAL;
} }
return ihk_ikc_send(channels[cpu].c, pisp, 0); return ihk_ikc_send(usrdata->channels[cpu].c, pisp, 0);
} }
int mcctrl_ikc_send_msg(int cpu, int msg, int ref, unsigned long arg) int mcctrl_ikc_send_msg(ihk_os_t os, int cpu, int msg, int ref, unsigned long arg)
{ {
struct ikc_scd_packet packet; struct ikc_scd_packet packet;
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
if (cpu < 0 || cpu >= num_channels || !channels[cpu].c) { if (cpu < 0 || cpu >= usrdata->num_channels || !usrdata->channels[cpu].c) {
return -EINVAL; return -EINVAL;
} }
@@ -60,34 +65,39 @@ int mcctrl_ikc_send_msg(int cpu, int msg, int ref, unsigned long arg)
packet.ref = ref; packet.ref = ref;
packet.arg = arg; packet.arg = arg;
return ihk_ikc_send(channels[cpu].c, &packet, 0); return ihk_ikc_send(usrdata->channels[cpu].c, &packet, 0);
} }
int mcctrl_ikc_set_recv_cpu(int cpu) int mcctrl_ikc_set_recv_cpu(ihk_os_t os, int cpu)
{ {
ihk_ikc_channel_set_cpu(channels[cpu].c, struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
ihk_ikc_channel_set_cpu(usrdata->channels[cpu].c,
ihk_ikc_get_processor_id()); ihk_ikc_get_processor_id());
kprintf("Setting the target to %d\n", kprintf("Setting the target to %d\n",
ihk_ikc_get_processor_id()); ihk_ikc_get_processor_id());
return 0; return 0;
} }
int mcctrl_ikc_is_valid_thread(int cpu) int mcctrl_ikc_is_valid_thread(ihk_os_t os, int cpu)
{ {
if (cpu < 0 || cpu >= num_channels || !channels[cpu].c) { struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
if (cpu < 0 || cpu >= usrdata->num_channels || !usrdata->channels[cpu].c) {
return 0; return 0;
} else { } else {
return 1; return 1;
} }
} }
unsigned long *mcctrl_doorbell_va; //unsigned long *mcctrl_doorbell_va;
unsigned long mcctrl_doorbell_pa; //unsigned long mcctrl_doorbell_pa;
static void mcctrl_ikc_init(ihk_os_t os, int cpu, unsigned long rphys) static void mcctrl_ikc_init(ihk_os_t os, int cpu, unsigned long rphys)
{ {
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
struct ikc_scd_packet packet; struct ikc_scd_packet packet;
struct mcctrl_channel *pmc = channels + cpu; struct mcctrl_channel *pmc = usrdata->channels + cpu;
unsigned long phys; unsigned long phys;
struct ikc_scd_init_param *rpm; struct ikc_scd_init_param *rpm;
@@ -111,8 +121,8 @@ static void mcctrl_ikc_init(ihk_os_t os, int cpu, unsigned long rphys)
(void *)__get_free_pages(GFP_KERNEL, (void *)__get_free_pages(GFP_KERNEL,
REQUEST_SHIFT - PAGE_SHIFT); REQUEST_SHIFT - PAGE_SHIFT);
pmc->param.request_pa = virt_to_phys(pmc->param.request_va); pmc->param.request_pa = virt_to_phys(pmc->param.request_va);
pmc->param.doorbell_va = mcctrl_doorbell_va; pmc->param.doorbell_va = usrdata->mcctrl_doorbell_va;
pmc->param.doorbell_pa = mcctrl_doorbell_pa; pmc->param.doorbell_pa = usrdata->mcctrl_doorbell_pa;
pmc->param.post_va = (void *)__get_free_page(GFP_KERNEL); pmc->param.post_va = (void *)__get_free_page(GFP_KERNEL);
pmc->param.post_pa = virt_to_phys(pmc->param.post_va); pmc->param.post_pa = virt_to_phys(pmc->param.post_va);
memset(pmc->param.doorbell_va, 0, PAGE_SIZE); memset(pmc->param.doorbell_va, 0, PAGE_SIZE);
@@ -168,18 +178,20 @@ static int connect_handler(struct ihk_ikc_channel_info *param)
{ {
struct ihk_ikc_channel_desc *c; struct ihk_ikc_channel_desc *c;
int cpu; int cpu;
ihk_os_t os = param->channel->remote_os;
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
c = param->channel; c = param->channel;
cpu = c->send.queue->read_cpu; cpu = c->send.queue->read_cpu;
if (cpu < 0 || cpu >= num_channels) { if (cpu < 0 || cpu >= usrdata->num_channels) {
kprintf("Invalid connect source processor: %d\n", cpu); kprintf("Invalid connect source processor: %d\n", cpu);
return 1; return 1;
} }
param->packet_handler = syscall_packet_handler; param->packet_handler = syscall_packet_handler;
init_waitqueue_head(&channels[cpu].wq_syscall); init_waitqueue_head(&usrdata->channels[cpu].wq_syscall);
channels[cpu].c = c; usrdata->channels[cpu].c = c;
kprintf("syscall: MC CPU %d connected.\n", cpu); kprintf("syscall: MC CPU %d connected.\n", cpu);
return 0; return 0;
@@ -196,9 +208,11 @@ static struct ihk_ikc_listen_param listen_param = {
int prepare_ikc_channels(ihk_os_t os) int prepare_ikc_channels(ihk_os_t os)
{ {
struct ihk_cpu_info *info; struct ihk_cpu_info *info;
struct mcctrl_usrdata *usrdata;
mcctrl_doorbell_va = (void *)__get_free_page(GFP_KERNEL); usrdata = kzalloc(sizeof(struct mcctrl_usrdata), GFP_KERNEL);
mcctrl_doorbell_pa = virt_to_phys(mcctrl_doorbell_va); usrdata->mcctrl_doorbell_va = (void *)__get_free_page(GFP_KERNEL);
usrdata->mcctrl_doorbell_pa = virt_to_phys(usrdata->mcctrl_doorbell_va);
info = ihk_os_get_cpu_info(os); info = ihk_os_get_cpu_info(os);
if (!info) { if (!info) {
@@ -210,15 +224,19 @@ int prepare_ikc_channels(ihk_os_t os)
return -EINVAL; return -EINVAL;
} }
num_channels = info->n_cpus; usrdata->num_channels = info->n_cpus;
channels = kzalloc(sizeof(struct mcctrl_channel) * num_channels, usrdata->channels = kzalloc(sizeof(struct mcctrl_channel) * usrdata->num_channels,
GFP_KERNEL); GFP_KERNEL);
if (!channels) { if (!usrdata->channels) {
printk("Error: cannot allocate channels.\n"); printk("Error: cannot allocate channels.\n");
return -ENOMEM; return -ENOMEM;
} }
ihk_ikc_listen_port(os, &listen_param); usrdata->os = os;
init_waitqueue_head(&usrdata->wq_prepare);
ihk_host_os_set_usrdata(os, usrdata);
memcpy(&usrdata->listen_param, &listen_param, sizeof listen_param);
ihk_ikc_listen_port(os, &usrdata->listen_param);
return 0; return 0;
} }
@@ -243,16 +261,20 @@ void __destroy_ikc_channel(ihk_os_t os, struct mcctrl_channel *pmc)
void destroy_ikc_channels(ihk_os_t os) void destroy_ikc_channels(ihk_os_t os)
{ {
int i; int i;
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
for (i = 0; i < num_channels; i++) { ihk_host_os_set_usrdata(os, NULL);
if (channels[i].c) {
// ihk_ikc_disconnect(channels[i].c); for (i = 0; i < usrdata->num_channels; i++) {
ihk_ikc_free_channel(channels[i].c); if (usrdata->channels[i].c) {
__destroy_ikc_channel(os, channels + i); // ihk_ikc_disconnect(usrdata->channels[i].c);
ihk_ikc_free_channel(usrdata->channels[i].c);
__destroy_ikc_channel(os, usrdata->channels + i);
printk("Channel #%d freed.\n", i); printk("Channel #%d freed.\n", i);
} }
} }
free_page((unsigned long)mcctrl_doorbell_va); free_page((unsigned long)usrdata->mcctrl_doorbell_va);
kfree(channels); kfree(usrdata->channels);
kfree(usrdata);
} }

View File

@@ -4,6 +4,8 @@
#include <ihk/ihk_host_driver.h> #include <ihk/ihk_host_driver.h>
#include <uprotocol.h> #include <uprotocol.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <ihk/ikc.h>
#include <ikc/master.h>
#define SCD_MSG_PREPARE_PROCESS 0x1 #define SCD_MSG_PREPARE_PROCESS 0x1
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2 #define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
@@ -62,7 +64,22 @@ struct mcctrl_channel {
wait_queue_head_t wq_syscall; wait_queue_head_t wq_syscall;
}; };
int mcctrl_ikc_send(int cpu, struct ikc_scd_packet *pisp); struct mcctrl_usrdata {
int mcctrl_ikc_send_msg(int cpu, int msg, int ref, unsigned long arg); struct ihk_ikc_listen_param listen_param;
int mcctrl_ikc_is_valid_thread(int cpu); ihk_os_t os;
int num_channels;
struct mcctrl_channel *channels;
unsigned long *mcctrl_doorbell_va;
unsigned long mcctrl_doorbell_pa;
int remaining_job;
int base_cpu;
int job_pos;
int mcctrl_dma_abort;
unsigned long last_thread_exec;
wait_queue_head_t wq_prepare;
};
int mcctrl_ikc_send(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp);
int mcctrl_ikc_send_msg(ihk_os_t os, int cpu, int msg, int ref, unsigned long arg);
int mcctrl_ikc_is_valid_thread(ihk_os_t os, int cpu);
#endif #endif

View File

@@ -14,7 +14,7 @@
//#define SC_DEBUG //#define SC_DEBUG
#ifdef SC_DEBUG #ifdef SC_DEBUG
static struct ihk_dma_request last_request; //static struct ihk_dma_request last_request;
static void print_dma_lastreq(void) static void print_dma_lastreq(void)
{ {
@@ -26,9 +26,30 @@ static void print_dma_lastreq(void)
} }
#endif #endif
unsigned long last_thread_exec = 0; //unsigned long last_thread_exec = 0;
#ifndef DO_USER_MODE #ifndef DO_USER_MODE
static struct {
long (*do_sys_open)(int, const char __user *, int, int);
long (*sys_lseek)(unsigned int, off_t, unsigned int);
long (*sys_read)(unsigned int, char __user *, size_t);
long (*sys_write)(unsigned int, const char __user *, size_t);
} syscalls;
void
mcctrl_syscall_init(void)
{
printk("mcctrl_syscall_init\n");
syscalls.do_sys_open = (void *)kallsyms_lookup_name("do_sys_open");
syscalls.sys_lseek = (void *)kallsyms_lookup_name("sys_lseek");
syscalls.sys_read = (void *)kallsyms_lookup_name("sys_read");
syscalls.sys_write = (void *)kallsyms_lookup_name("sys_write");
printk("syscalls.do_sys_open=%lx\n", (long)syscalls.do_sys_open);
printk("syscalls.sys_lseek=%lx\n", (long)syscalls.sys_lseek);
printk("syscalls.sys_read=%lx\n", (long)syscalls.sys_read);
printk("syscalls.sys_write=%lx\n", (long)syscalls.sys_write);
}
static int do_async_copy(ihk_os_t os, unsigned long dest, unsigned long src, static int do_async_copy(ihk_os_t os, unsigned long dest, unsigned long src,
unsigned long size, unsigned int inbound) unsigned long size, unsigned int inbound)
{ {
@@ -60,12 +81,13 @@ static int do_async_copy(ihk_os_t os, unsigned long dest, unsigned long src,
return 0; return 0;
} }
int mcctrl_dma_abort; //int mcctrl_dma_abort;
static void async_wait(unsigned char *p, int size) static void async_wait(ihk_os_t os, unsigned char *p, int size)
{ {
int asize = ALIGN_WAIT_BUF(size); int asize = ALIGN_WAIT_BUF(size);
unsigned long long s, w; unsigned long long s, w;
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
rdtscll(s); rdtscll(s);
while (!p[asize]) { while (!p[asize]) {
@@ -75,12 +97,15 @@ static void async_wait(unsigned char *p, int size)
if (w > s + 1024UL * 1024 * 1024 * 10) { if (w > s + 1024UL * 1024 * 1024 * 10) {
printk("DMA Timed out : %p (%p + %d) => %d\n", printk("DMA Timed out : %p (%p + %d) => %d\n",
p + asize, p, size, p[asize]); p + asize, p, size, p[asize]);
#ifdef SC_DEBUG
print_dma_lastreq(); print_dma_lastreq();
mcctrl_dma_abort = 1; #endif
usrdata->mcctrl_dma_abort = 1;
return; return;
} }
} }
} }
static void clear_wait(unsigned char *p, int size) static void clear_wait(unsigned char *p, int size)
{ {
//int asize = ALIGN_WAIT_BUF(size); //int asize = ALIGN_WAIT_BUF(size);
@@ -117,7 +142,7 @@ static unsigned long translate_remote_va(struct mcctrl_channel *c,
return -EFAULT; return -EFAULT;
} }
extern struct mcctrl_channel *channels; //extern struct mcctrl_channel *channels;
int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c, int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c,
struct syscall_request *sc) struct syscall_request *sc)
@@ -125,6 +150,7 @@ int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c,
int ret; int ret;
mm_segment_t fs; mm_segment_t fs;
unsigned long pa; unsigned long pa;
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
switch (sc->number) { switch (sc->number) {
case 0: /* read */ case 0: /* read */
@@ -140,13 +166,13 @@ int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c,
clear_wait(c->dma_buf, sc->args[2]); clear_wait(c->dma_buf, sc->args[2]);
fs = get_fs(); fs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_read(sc->args[0], c->dma_buf, sc->args[2]); ret = syscalls.sys_read(sc->args[0], c->dma_buf, sc->args[2]);
if (ret > 0) { if (ret > 0) {
do_async_copy(os, sc->args[1], virt_to_phys(c->dma_buf), do_async_copy(os, sc->args[1], virt_to_phys(c->dma_buf),
sc->args[2], 0); sc->args[2], 0);
set_fs(fs); set_fs(fs);
async_wait(c->dma_buf, sc->args[2]); async_wait(os, c->dma_buf, sc->args[2]);
} }
__return_syscall(c, ret); __return_syscall(c, ret);
return 0; return 0;
@@ -166,9 +192,9 @@ int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c,
sc->args[2], 1); sc->args[2], 1);
fs = get_fs(); fs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
async_wait(c->dma_buf, sc->args[2]); async_wait(os, c->dma_buf, sc->args[2]);
ret = sys_write(sc->args[0], c->dma_buf, sc->args[2]); ret = syscalls.sys_write(sc->args[0], c->dma_buf, sc->args[2]);
set_fs(fs); set_fs(fs);
__return_syscall(c, ret); __return_syscall(c, ret);
@@ -189,9 +215,9 @@ int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c,
256, 1); 256, 1);
fs = get_fs(); fs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
async_wait(c->dma_buf, 256); async_wait(os, c->dma_buf, 256);
ret = do_sys_open(AT_FDCWD, c->dma_buf, sc->args[1], ret = syscalls.do_sys_open(AT_FDCWD, c->dma_buf, sc->args[1],
sc->args[2]); sc->args[2]);
set_fs(fs); set_fs(fs);
@@ -204,21 +230,21 @@ int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c,
return 0; return 0;
case 8: /* lseek */ case 8: /* lseek */
ret = sys_lseek(sc->args[0], sc->args[1], sc->args[2]); ret = syscalls.sys_lseek(sc->args[0], sc->args[1], sc->args[2]);
__return_syscall(c, ret); __return_syscall(c, ret);
return 0; return 0;
case 56: /* Clone */ case 56: /* Clone */
last_thread_exec++; usrdata->last_thread_exec++;
if (mcctrl_ikc_is_valid_thread(last_thread_exec)) { if (mcctrl_ikc_is_valid_thread(usrdata->last_thread_exec)) {
printk("Clone notification: %lx\n", sc->args[0]); printk("Clone notification: %lx\n", sc->args[0]);
if (channels[last_thread_exec].param.post_va) { if (channels[usrdata->last_thread_exec].param.post_va) {
memcpy(channels[last_thread_exec].param.post_va, memcpy(usrdata->channels[usrdata->last_thread_exec].param.post_va,
c->param.post_va, PAGE_SIZE); c->param.post_va, PAGE_SIZE);
} }
mcctrl_ikc_send_msg(last_thread_exec, mcctrl_ikc_send_msg(usrdata->last_thread_exec,
SCD_MSG_SCHEDULE_PROCESS, SCD_MSG_SCHEDULE_PROCESS,
last_thread_exec, sc->args[0]); usrdata->last_thread_exec, sc->args[0]);
} }
__return_syscall(c, 0); __return_syscall(c, 0);

View File

@@ -327,6 +327,9 @@ int main(int argc, char **argv)
struct program_load_desc *desc; struct program_load_desc *desc;
char *envs; char *envs;
char *args; char *args;
char dev[64];
char **a;
char *p;
int i; int i;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
@@ -335,8 +338,19 @@ int main(int argc, char **argv)
__glob_argv = argv; __glob_argv = argv;
#endif #endif
strcpy(dev, "/dev/mcos0");
if(argv[1]){
for(p = argv[1]; *p && *p >= '0' && *p <= '9'; p++);
if(!*p){
sprintf(dev, "/dev/mcos%s", argv[1]);
for(a = argv + 2; *a; a++)
a[-1] = a[0];
a[-1] = NULL;
argc--;
}
}
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "Usage: %s (program) [args...]\n", fprintf(stderr, "Usage: %s [<mcos-id>] (program) [args...]\n",
argv[0]); argv[0]);
return 1; return 1;
} }
@@ -364,9 +378,9 @@ int main(int argc, char **argv)
desc->args = args; desc->args = args;
//print_flat(args); //print_flat(args);
fd = open("/dev/mcos0", O_RDWR); fd = open(dev, O_RDWR);
if (fd < 0) { if (fd < 0) {
fprintf(stderr, "Error: Failed to open /dev/mcctrl.\n"); fprintf(stderr, "Error: Failed to open %s.\n", dev);
return 1; return 1;
} }

View File

@@ -1,5 +1,5 @@
#BUILD_TARGET = builtin-mic attached-mic #BUILD_TARGET = builtin-mic attached-mic
BUILD_TARGET = attached-mic BUILD_TARGET ?= attached-mic
SRC = $(CURDIR) SRC = $(CURDIR)
IHKBASE ?= $(SRC)/../../ihk/cokernel IHKBASE ?= $(SRC)/../../ihk/cokernel

View File

@@ -14,6 +14,9 @@ include $(IHKBASE)/Makefile.common
SUBCMD_OPTS = TARGET=$(TARGET) O=$(CURDIR)/ihk CC=$(CC) LD=$(LD) SRC=$(SRC) SUBCMD_OPTS = TARGET=$(TARGET) O=$(CURDIR)/ihk CC=$(CC) LD=$(LD) SRC=$(SRC)
OBJDUMP ?= objdump
OBJCOPY ?= objcopy
ld_kern_cmd_base = $(LD) $(LDFLAGS) -o $@.elf $^ ld_kern_cmd_base = $(LD) $(LDFLAGS) -o $@.elf $^
mkimage_cmd_base = [ -f $(SRC)/script/mkimage.$(TARGET) ] && CC=$(CC) LD=$(LD) LDFLAGS="$(LDFLAGS_MKIMAGE)" OBJDUMP=$(OBJDUMP) OBJCOPY=$(OBJCOPY) sh $(SRC)/script/mkimage.$(TARGET) '$@.elf' '$@' '$(SRC)' || cp $@.elf $@ mkimage_cmd_base = [ -f $(SRC)/script/mkimage.$(TARGET) ] && CC=$(CC) LD=$(LD) LDFLAGS="$(LDFLAGS_MKIMAGE)" OBJDUMP=$(OBJDUMP) OBJCOPY=$(OBJCOPY) sh $(SRC)/script/mkimage.$(TARGET) '$@.elf' '$@' '$(SRC)' || cp $@.elf $@

View File

@@ -0,0 +1,33 @@
PHDRS
{
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(7);
}
SECTIONS
{
. = 0xffffffff80001000;
_head = .;
.text : {
*(.text);
} : text
. = ALIGN(4096);
.data : {
*(.data)
*(.data.*)
} :data
.rodata : {
*(.rodata .rodata.*)
} :data
.bss : {
*(.bss .bss.*)
}
. = ALIGN(4096);
_end = .;
/DISCARD/ : {
*(.eh_frame)
*(.note.gnu.build-id)
}
}

View File

@@ -0,0 +1,8 @@
CC = /opt/knc/linux-k1om-4.7/bin/x86_64-k1om-linux-gcc
LD = /opt/knc/linux-k1om-4.7/bin/x86_64-k1om-linux-ld
OBJDUMP = /opt/knc/linux-k1om-4.7/bin/x86_64-k1om-linux-objdump
OBJCOPY = /opt/knc/linux-k1om-4.7/bin/x86_64-k1om-linux-objcopy
CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow
LDFLAGS += -m elf_k1om -T $(SRC)/config/builtin-mic.lds
LDFLAGS_MKIMAGE = -m elf_k1om

View File

@@ -20,7 +20,9 @@
#define PS_NORMAL (PS_INTERRUPTIBLE | PS_UNINTERRUPTIBLE) #define PS_NORMAL (PS_INTERRUPTIBLE | PS_UNINTERRUPTIBLE)
#ifdef ATTACHED_MIC
#define USE_LARGE_PAGES #define USE_LARGE_PAGES
#endif
#include <waitq.h> #include <waitq.h>
#include <futex.h> #include <futex.h>

View File

@@ -7,8 +7,10 @@
#include <ihk/mm.h> #include <ihk/mm.h>
#include <ihk/page_alloc.h> #include <ihk/page_alloc.h>
#include <registers.h> #include <registers.h>
#ifdef ATTACHED_MIC
#include <sysdeps/mic/mic/micconst.h> #include <sysdeps/mic/mic/micconst.h>
#include <sysdeps/mic/mic/micsboxdefine.h> #include <sysdeps/mic/mic/micsboxdefine.h>
#endif
#include <cls.h> #include <cls.h>
//#define DEBUG_PRINT_MEM //#define DEBUG_PRINT_MEM
@@ -125,13 +127,15 @@ static void page_allocator_init(void)
pa_start &= PAGE_MASK; pa_start &= PAGE_MASK;
pa_end = (pa_end + PAGE_SIZE - 1) & PAGE_MASK; pa_end = (pa_end + PAGE_SIZE - 1) & PAGE_MASK;
/* #ifndef ATTACHED_MIC
page_map_pa = ihk_mc_get_memory_address(IHK_MC_GMA_HEAP_START, 0); page_map_pa = ihk_mc_get_memory_address(IHK_MC_GMA_HEAP_START, 0);
page_map = phys_to_virt(page_map_pa); #else
/*
* Can't allocate in reserved area * Can't allocate in reserved area
* TODO: figure this out automatically! * TODO: figure this out automatically!
*/ */
page_map_pa = 0x100000; page_map_pa = 0x100000;
#endif
page_map = phys_to_virt(page_map_pa); page_map = phys_to_virt(page_map_pa);
pa_allocator = __ihk_pagealloc_init(pa_start, pa_end - pa_start, pa_allocator = __ihk_pagealloc_init(pa_start, pa_end - pa_start,
@@ -209,6 +213,7 @@ void ihk_mc_unmap_virtual(void *va, int npages, int free_physical)
ihk_pagealloc_free(vmap_allocator, virt_to_phys(va), npages); ihk_pagealloc_free(vmap_allocator, virt_to_phys(va), npages);
} }
#ifdef ATTACHED_MIC
/* moved from ihk_knc/manycore/mic/setup.c */ /* moved from ihk_knc/manycore/mic/setup.c */
/*static*/ void *sbox_base = (void *)SBOX_BASE; /*static*/ void *sbox_base = (void *)SBOX_BASE;
void sbox_write(int offset, unsigned int value) void sbox_write(int offset, unsigned int value)
@@ -258,6 +263,7 @@ void ihk_mc_clean_micpa(void){
free_bitmap_micpa = ((~((1ULL<<(NUM_SMPT_ENTRIES_IN_USE - NUM_SMPT_ENTRIES_MICPA))-1))&((1ULL << NUM_SMPT_ENTRIES_IN_USE) - 1)); free_bitmap_micpa = ((~((1ULL<<(NUM_SMPT_ENTRIES_IN_USE - NUM_SMPT_ENTRIES_MICPA))-1))&((1ULL << NUM_SMPT_ENTRIES_IN_USE) - 1));
kprintf("ihk_mc_clean_micpa\n"); kprintf("ihk_mc_clean_micpa\n");
} }
#endif
void mem_init(void) void mem_init(void)
{ {

View File

@@ -0,0 +1,20 @@
#!/bin/sh
set -e
O=`pwd`
make -C $3/../arch/x86/kboot O=$O clean
#make -C $3/../kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x3a001000
make -C $3/../arch/x86/kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x21001000
#make -C $3/../kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x901001000
make -C $3/../arch/x86/elfboot O=$O clean
make -C $3/../arch/x86/elfboot O=$O
cat elfboot/elfboot kboot/kboot.elf > $2
make -C $3/../arch/x86/kboot O=$O clean
#make -C $3/../kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x3a001000
make -C $3/../arch/x86/kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x31001000
cat elfboot/elfboot kboot/kboot.elf > $2.768M

View File

@@ -4,9 +4,17 @@ set -e
O=`pwd` O=`pwd`
make -C $3/../kboot O=$O clean make -C $3/../arch/x86/kboot O=$O clean
#make -C $3/../kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x3a001000 #make -C $3/../kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x3a001000
make -C $3/../kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x101001000 make -C $3/../arch/x86/kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x101001000
#make -C $3/../kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x901001000 #make -C $3/../kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x901001000
cat $3/../elfboot/elfboot kboot/kboot.elf > $2 make -C $3/../arch/x86/elfboot O=$O clean
make -C $3/../arch/x86/elfboot O=$O
cat elfboot/elfboot kboot/kboot.elf > $2
make -C $3/../arch/x86/kboot O=$O clean
#make -C $3/../kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x3a001000
make -C $3/../arch/x86/kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x201001000
cat elfboot/elfboot kboot/kboot.elf > $2.8G

View File

@@ -27,6 +27,12 @@ enum ihk_perfctr_type {
APT_TYPE_ITLB_MISS, APT_TYPE_ITLB_MISS,
APT_TYPE_STALL, APT_TYPE_STALL,
APT_TYPE_CYCLE, APT_TYPE_CYCLE,
APT_TYPE_INSTRUCTIONS,
APT_TYPE_L1D_MISS,
APT_TYPE_L1I_MISS,
APT_TYPE_L2_MISS,
PERFCTR_MAX_TYPE, PERFCTR_MAX_TYPE,
}; };

56
make.sh
View File

@@ -1,4 +1,6 @@
#!/bin/sh #!/bin/sh
MOPT=
OPT=
ihkdir=`pwd`/../ihk ihkdir=`pwd`/../ihk
installdir= installdir=
kerneldir= kerneldir=
@@ -45,10 +47,24 @@ if [ "X$target" = X ]; then
target=attached-mic target=attached-mic
fi fi
if [ "X$kerneldir" = X ]; then
if [ -f $ihkdir/kerneldir ]; then
kerneldir="`cat $ihkdir/kerneldir`"
fi
fi
if [ "X$kerneldir" != X ]; then
MOPT="KDIR=$kerneldir"
fi
if [ "X$target" = "Xbuiltin-mic" ]; then
MOPT="$MOPT ARCH=k1om"
OPT="CC=x86_64-k1om-linux-gcc"
fi
if [ "X$installdir" != X ]; then if [ "X$installdir" != X ]; then
mkdir -p "$installdir" mkdir -p "$installdir"
fi fi
(cd executer/kernel; make) (cd executer/kernel; make $MOPT)
if [ -f executer/kernel/mcctrl.ko ]; then if [ -f executer/kernel/mcctrl.ko ]; then
if [ "X$installdir" != X ]; then if [ "X$installdir" != X ]; then
cp executer/kernel/mcctrl.ko "$installdir" cp executer/kernel/mcctrl.ko "$installdir"
@@ -58,28 +74,26 @@ else
exit 1 exit 1
fi fi
for tgt in $target; do case "$target" in
case "$tgt" in attached-mic | builtin-x86 | builtin-mic)
attached-mic) (cd kernel; mkdir -p build; make O=`pwd`/build BUILD_TARGET=$target)
(cd kernel; mkdir -p build; make O=`pwd`/build) krn=kernel/build/$target/kernel.img
krn=kernel/build/$tgt/kernel.img ;;
;; *)
*) echo "unknown target $target" >&2
echo "unknown target $tgt" >&2 exit 1
exit 1 ;;
;; esac
esac if [ -f $krn ]; then
if [ -f $krn ]; then if [ "X$installdir" != X ]; then
if [ "X$installdir" != X ]; then cp $krn "$installdir"
cp $krn "$installdir"
fi
else
echo "$krn could not be built" >&2
exit 1
fi fi
done else
echo "$krn could not be built" >&2
exit 1
fi
(cd executer/user; make) (cd executer/user; make $OPT)
if [ -f executer/user/mcexec ]; then if [ -f executer/user/mcexec ]; then
if [ "X$installdir" != X ]; then if [ "X$installdir" != X ]; then
cp executer/user/mcexec "$installdir" cp executer/user/mcexec "$installdir"