vcpu example problem

雷雷健 <[email protected]>
Newsgroups gmane.comp.micro-kernel.l4.devel
Message-ID <CAO8z81nPKgs73hWF6vREiP_JyAigQajkmBBJWD_j97tEnewh_A@mail.gmail.com>
Hi,
       I  am trying  to modify the vcpu example of l4re-snapshot to
switch registers to execute my C function.But It doesn't work.
       I have read some papers about l4linux tranplantion.and follow it .
       To switch the process, I fill the vcpu_state_t structure with
its registers.and call vcpu_resume_commit action.Then Jump to the ASM
Code.
       But problem arises when I want to jump from asm code to C
function. What's the Problem? The Code is as following:
/*
 * (c) 2009 Technische Universität Dresden
 * This file is part of TUD:OS, which is distributed under the terms of the
 * GNU General Public License 2. Please see the COPYING file for details.
 */
#include <l4/sys/ipc.h>
#include <l4/sys/thread>
#include <l4/sys/factory>
#include <l4/sys/scheduler>
#include <l4/sys/utcb.h>
#include <l4/sys/kdebug.h>
#include <l4/util/util.h>
#include <l4/re/env>
#include <l4/re/util/cap_alloc>
#include <l4/re/util/kumem_alloc>
#include <l4/sys/debugger.h>
#include <l4/vcpu/vcpu>
#include <l4/cxx/iostream>

#include <l4/re/error_helper>

#include <l4/sys/task>
#include <l4/sys/irq>
#include <l4/sys/vcpu.h>

#include <cstdlib>
#include <cstdio>
#include <cstring>
#define PSR_T_BIT       0x00000000
#define SVC_MODE	0x00000013
#define PSR_E_BIT	0x00000200
#define PSR_I_BIT	0x00000000
#define USR_MODE	0x00000010
using L4Re::chksys;
using L4Re::chkcap;

static L4::Cap<L4::Irq> irq;

static char thread_stack[8 << 10];
static char hdl_stack[8 << 10];
static char idle_stack[8<<10];
static L4::Cap<L4::Task> vcpu_task;
static L4vcpu::Vcpu *vcpu;

const l4_addr_t super_code_map_addr = 0x10000;
const l4_addr_t idle_code_map_addr  = 0x20000;
const l4_addr_t stack_map_addr = 0x12000;
const l4_addr_t exit_map_addr=0x13000;
extern char my_super_code[];
extern char my_super_code_excp[];
extern char my_super_code_excp_after[];
extern char exit_code[];



void idle_code(void)
{
;
while(1)
{
__asm__ volatile("swi 0");
 l4_sleep(500);
}
}
asm(
".global exit_code \t\n"
"exit_code: \t\n"
"b exit_code \t\n"
);

asm volatile
(
  ".pushsection .text\n"
  ".p2align 12         \t\n"
  ".global my_super_code  \t\n"
  "my_super_code:   \t\n"
"	msr	cpsr_c, r7\t\n"
"	mov	lr, r6   \t\n"
"	mov	pc, r5   \t\n"
//"       b       my_super_code \t\n"
".popsection"
);
static void setup_user_state_arch(L4vcpu::Vcpu *) { }
static void handler_prolog() {}




static void handler(void)
{
  handler_prolog();

  vcpu->state()->clear(L4_VCPU_F_EXCEPTIONS);
  printf("hello handler\n");
    //vcpu->print_state();

  // very simple page-fault handling
  // we're just replying with the only page we have, without checking any
  // values
  if (vcpu->is_page_fault_entry())
    {
      printf("page fault\n");
      vcpu_task->map(L4Re::This_task, l4_fpage((l4_addr_t)my_super_code,
                                                L4_PAGESHIFT, L4_FPAGE_RWX),
                                               super_code_map_addr);

     vcpu_task->map(L4Re::This_task, l4_fpage((l4_addr_t)idle_code,
                                                L4_PAGESHIFT, L4_FPAGE_RWX),
                                               idle_code_map_addr);
      vcpu_task->map(L4Re::This_task, l4_fpage((l4_addr_t)exit_code,
                                                L4_PAGESHIFT, L4_FPAGE_RWX),
                                               exit_map_addr);

      vcpu->saved_state()->add(L4_VCPU_F_PAGE_FAULTS);
    }
  else if (vcpu->is_irq_entry())
    {
      // We use the label 2000 for our IRQ
      if (vcpu->i()->label == 2000)
        printf("Our triggered IRQ\n");
      else if (vcpu->i()->label == 0)
        // direct IPC message to vCPU without
        // going through an IPCgate, label is set to 0
        printf("IPC: %lx\n", vcpu->i()->tag.label());
      else
        printf("Unclassifiable message\n");
    }
    else
        printf("unhandled exception\n");


  printf("resume\n");
  L4::Cap<L4::Thread> self;
  self->vcpu_resume_commit(self->vcpu_resume_start());
  //vcpu->state()->set(0);
  while(1)
    ;
}

static void vcpu_thread(void)
{
  printf("Hello vCPU\n");
    l4_umword_t label;
  memset(hdl_stack, 0, sizeof(hdl_stack));
  //memset(super_stack,0,sizeof(super_stack));
//  memset(idle_stack,0,sizeof(idle_stack));
  setup_user_state_arch(vcpu);
  l4_touch_rw(stack,sizeof(stack));
  l4_touch_rw(idle_stack,sizeof(idle_stack));
  vcpu->saved_state()->set(L4_VCPU_F_USER_MODE
                           | L4_VCPU_F_EXCEPTIONS
                           | L4_VCPU_F_PAGE_FAULTS
                           | L4_VCPU_F_IRQ);
  vcpu->r()->flags=(l4_umword_t)SVC_MODE;
  vcpu->r()->r[7]=(l4_umword_t)SVC_MODE;
  vcpu->r()->r[0]=(l4_umword_t)0;
  vcpu->r()->r[4]=(l4_umword_t)(idle_stack+sizeof(idle_stack)-1);
  vcpu->r()->r[6]=(l4_umword_t)exit_map_addr;
  vcpu->r()->ip =(l4_umword_t)super_code_map_addr;
  vcpu->r()->r[5] = (l4_umword_t)idle_code_map_addr;
  vcpu->r()->sp = (l4_umword_t)0x30000;
  L4::Cap<L4::Thread> self;
  printf("IRET\n");
  vcpu->task(vcpu_task);
  self->vcpu_resume_commit(self->vcpu_resume_start());
  printf("IRET: failed!\n");
  while(1);

}

int run(void)
{
  l4_utcb_t *u = l4_utcb();
  L4::Cap<L4::Thread> vcpu_cap;

  printf("vCPU example\n");

  l4_debugger_set_object_name(l4re_env()->main_thread, "vcputest");

  // new task
  vcpu_task = chkcap(L4Re::Util::cap_alloc.alloc<L4::Task>(),
                     "Task cap alloc");

  chksys(L4Re::Env::env()->factory()->create_task(vcpu_task,
                                                  l4_fpage_invalid()),
         "create task");
  l4_debugger_set_object_name(vcpu_task.cap(), "vcpu 'user' task");

  /* new thread/vCPU */
  vcpu_cap = chkcap(L4Re::Util::cap_alloc.alloc<L4::Thread>(),
                    "vCPU cap alloc");

  l4_touch_rw(thread_stack, sizeof(thread_stack));
  //l4_touch_rw(hdl_stack,sizeof(hdl_stack));
  chksys(L4Re::Env::env()->factory()->create_thread(vcpu_cap), "create thread");
  l4_debugger_set_object_name(vcpu_cap.cap(), "vcpu thread");

  // get an IRQ
  irq = chkcap(L4Re::Util::cap_alloc.alloc<L4::Irq>(),
               "Irq cap alloc");
  chksys(L4Re::Env::env()->factory()->create_irq(irq), "irq");
  l4_debugger_set_object_name(irq.cap(), "some irq");

  // get memory for vCPU state
  l4_addr_t kumem;
  if (0)
    kumem = (l4_addr_t)l4re_env()->first_free_utcb;
  else
    {
      if (L4Re::Util::kumem_alloc(&kumem, 0))
        exit(1);
    }
  l4_utcb_t *vcpu_utcb = (l4_utcb_t *)kumem;
  vcpu = L4vcpu::Vcpu::cast(kumem + L4_UTCB_OFFSET);
  vcpu->entry_sp((l4_umword_t)hdl_stack + sizeof(hdl_stack));
  vcpu->entry_ip((l4_umword_t)handler);

  printf("VCPU: utcb = %p, vcpu = %p\n", vcpu_utcb, vcpu);

  // Create and start vCPU thread
  L4::Thread::Attr attr;
  attr.pager(L4::cap_reinterpret_cast<L4::Thread>(L4Re::Env::env()->rm()));
  attr.exc_handler(L4Re::Env::env()->main_thread());
  attr.bind(vcpu_utcb, L4Re::This_task);
  chksys(vcpu_cap->control(attr), "control");
  chksys(vcpu_cap->vcpu_control((l4_addr_t)vcpu), "enable VCPU");

  chksys(vcpu_cap->ex_regs((l4_umword_t)vcpu_thread,
                           (l4_umword_t)thread_stack + sizeof(thread_stack),
                           0));

  chksys(L4Re::Env::env()->scheduler()->run_thread(vcpu_cap,
                                                   l4_sched_param(2)));

  // Attach irq to our vCPU thread
  chksys(irq->attach(2000, vcpu_cap));

  // Send some IPCs to the vCPU
   l4_sleep(10);
  while (1)
    {
   //  printf("triger irq\n");
     // irq->trigger();
      l4_sleep(500);
    }


  l4_sleep_forever();
  return 0;
}

int main()
{
  try { return run(); }
  catch (L4::Runtime_error &e)
    {
      L4::cerr << "FATAL uncought exception: " << e
               << "\nterminating...\n";
    }
  catch (...)
    {
      L4::cerr << "FATAL uncought exception of unknown type\n"
               << "terminating...\n";
    }
  return 1;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.