コード例 #1
0
ファイル: environment.c プロジェクト: fenollp/kaneton
t_status		architecture_environment_server(i_as	id)
{
  i_segment	        segment;
  i_region		region;
  o_as*			as;
  at_pd			pd;
  o_region*		r;
  o_segment*		s;

  /*
   * 1)
   */

  if (as_get(id, &as) != STATUS_OK)
    MACHINE_ESCAPE("unable to retrieve the address space object");

  /*
   * 2)
   */

  if (segment_reserve(as->id,
		      ___kaneton$pagesz,
		      PERMISSION_READ | PERMISSION_WRITE,
		      SEGMENT_OPTION_SYSTEM,
		      &segment) != STATUS_OK)
    MACHINE_ESCAPE("unable to reserve a segment");

  if (segment_get(segment, &s) != STATUS_OK)
    MACHINE_ESCAPE("unable to retrieve the segment object");

  /*
   * 3)
   */

  as->machine.pd = s->address;

  /*
   * 4)
   */

  if (architecture_pd_map(as->machine.pd, &pd) != STATUS_OK)
    MACHINE_ESCAPE("unable to map the page directory");

  if (architecture_pd_build(pd) != STATUS_OK)
    MACHINE_ESCAPE("unable to build the page directory");

  if (architecture_pd_unmap(pd) != STATUS_OK)
    MACHINE_ESCAPE("unable to unmap the page directory");

  /*
   * 5)
   */

  if (region_locate(_kernel.as,
		    _thread.machine.tss,
		    &region) == FALSE)
    MACHINE_ESCAPE("unable to locate the region in which the TSS lies");

  if (region_get(_kernel.as, region, &r) != STATUS_OK)
    MACHINE_ESCAPE("unable to retrieve the region object");

  if (region_reserve(as->id,
		     r->segment,
		     0x0,
		     REGION_OPTION_FORCE |
		     REGION_OPTION_NONE,
		     _thread.machine.tss,
		     r->size,
		     &region) != STATUS_OK)
    MACHINE_ESCAPE("unable to reserve the region mapping the TSS");

  /*
   * 6)
   */

  if (region_locate(_kernel.as,
		    (t_vaddr)_segment.machine.gdt.table,
		    &region) == FALSE)
    MACHINE_ESCAPE("unable to locate the region in which the GDT lies");

  if (region_get(_kernel.as, region, &r) != STATUS_OK)
    MACHINE_ESCAPE("unable to retrieve the region object");

  if (region_reserve(as->id,
		     r->segment,
		     0x0,
		     REGION_OPTION_FORCE |
		     REGION_OPTION_NONE,
		     (t_vaddr)_segment.machine.gdt.table,
		     ___kaneton$pagesz,
		     &region) != STATUS_OK)
    MACHINE_ESCAPE("unable to reserve the region mapping the GDT");

  /*
   * 7)
   */

  if (region_locate(_kernel.as,
		    (t_vaddr)_event.machine.idt.table,
		    &region) == FALSE)
    MACHINE_ESCAPE("unable to locate the region in which the IDT lies");

  if (region_get(_kernel.as, region, &r) != STATUS_OK)
    MACHINE_ESCAPE("unable to retrieve the region object");

  if (region_reserve(as->id,
		     r->segment,
		     0x0,
		     REGION_OPTION_FORCE |
		     REGION_OPTION_NONE,
		     (t_vaddr)_event.machine.idt.table,
		     ___kaneton$pagesz,
		     &region) != STATUS_OK)
    MACHINE_ESCAPE("unable to reserve the region mapping the IDT");

  /*
   * 8)
   */

  if (region_reserve(as->id,
                     _init->kcode,
                     ARCHITECTURE_LINKER_SYMBOL(_handler_code_begin) -
                       _init->kcode,
                     REGION_OPTION_FORCE,
                     ARCHITECTURE_LINKER_SYMBOL(_handler_code_begin),
                     ARCHITECTURE_LINKER_SYMBOL(_handler_code_end) -
                     ARCHITECTURE_LINKER_SYMBOL(_handler_code_begin),
                     &region) != STATUS_OK)
    MACHINE_ESCAPE("unable to map the handler code section");

  /*
   * 9)
   */

  if (region_reserve(as->id,
                     _init->kcode,
                     ARCHITECTURE_LINKER_SYMBOL(_handler_data_begin) -
                       _init->kcode,
                     REGION_OPTION_FORCE,
                     ARCHITECTURE_LINKER_SYMBOL(_handler_data_begin),
                     ARCHITECTURE_LINKER_SYMBOL(_handler_data_end) -
                     ARCHITECTURE_LINKER_SYMBOL(_handler_data_begin),
                     &region) != STATUS_OK)
    MACHINE_ESCAPE("unable to map the handler data section");

  MACHINE_LEAVE();
}
コード例 #2
0
// FIXME: lot of code has been removed here
t_error			map_page(t_paddr paddr, t_vaddr *vaddr)
{
  o_as*			kas;
  t_ia32_pde		pde;
  t_ia32_pde		pte;
  t_ia32_directory	dir;
  t_ia32_table		table;
  t_ia32_page		page;
  o_region*		oreg;
  i_segment		segid;
  o_segment*		segment;
  int			clear = 0;

  REGION_ENTER(region);

  if (as_get(kasid, &kas) != ERROR_NONE)
    REGION_LEAVE(region, ERROR_UNKNOWN);

  if (region_space(kas, PAGESZ, vaddr) != ERROR_NONE)
    REGION_LEAVE(region, ERROR_UNKNOWN);

  if ((oreg = malloc(sizeof(o_region))) == NULL)
    REGION_LEAVE(region, ERROR_UNKNOWN);

  oreg->address = *vaddr;
  oreg->regid = (i_region)oreg->address;
  oreg->opts = REGION_OPT_PRIVILEGED;
  oreg->size = PAGESZ;
  oreg->offset = 0;
  oreg->segid = (i_segment) paddr;

  if (region_inject(kasid, oreg) != ERROR_NONE)
    REGION_LEAVE(region, ERROR_UNKNOWN);

  // Page Dir
  dir = kas->machdep.pd;
  pde = PDE_ENTRY(*vaddr);

  if (pd_get_table(&dir, pde, &table) == ERROR_UNKNOWN)
    {
      segment_reserve(kasid, PAGESZ, PERM_READ | PERM_WRITE, &segid);
      if (segment_get(segid, &segment) != ERROR_NONE)
	REGION_LEAVE(region, ERROR_UNKNOWN);
      table.rw = PT_WRITABLE;
      pt_build(segment->address, &table, 0);
      pd_add_table(&dir, pde, table);
      clear = 1;
    }
  table.entries = ENTRY_ADDR(PD_MIRROR, pde);
  //fixme
  if (clear)
    memset((void *)ENTRY_ADDR(PD_MIRROR, pde), '\0', PAGESZ);
  // Page Table
  pte = PTE_ENTRY(*vaddr);
  page.present = 1;
  page.addr = paddr;
  page.rw = PG_WRITABLE;
  pt_add_page(&table, pte, page);

  tlb_invalidate(*vaddr);

  REGION_LEAVE(region, ERROR_NONE);
}
コード例 #3
0
ファイル: 01.c プロジェクト: fenollp/kaneton
void			test_core_as_copy_01(void)
{
  i_task		task1;
  i_task		task2;
  i_as			as1;
  i_as			as2;
  i_segment		seg1;
  i_segment		seg2;
  i_segment		seg3;
  i_segment		seg4;
  i_segment		seg5;
  i_segment		seg6;
  i_segment		useless;
  i_region		reg;
  t_uint32		i;
  t_uint8		buff[4 * ___kaneton$pagesz];

  TEST_ENTER();

  /*
   * first address space
   */

  if (task_reserve(TASK_CLASS_GUEST,
		   TASK_BEHAVIOUR_INTERACTIVE,
		   TASK_PRIORITY_INTERACTIVE,
		   &task1) != STATUS_OK)
    TEST_ERROR("[task_reserve] error");

  if (as_reserve(task1, &as1) != STATUS_OK)
    TEST_ERROR("[as_reserve] error");

  if (segment_reserve(as1,
		      2 * ___kaneton$pagesz,
		      PERMISSION_READ | PERMISSION_WRITE,
		      SEGMENT_OPTION_NONE,
		      &seg1) != STATUS_OK)
    TEST_ERROR("[segment_reserve] error");

  if (segment_reserve(as1,
		      ___kaneton$pagesz,
		      PERMISSION_READ | PERMISSION_WRITE,
		      SEGMENT_OPTION_NONE,
		      &useless) != STATUS_OK)
    TEST_ERROR("[segment_reserve] error");

  if (segment_reserve(as1,
		      4 * ___kaneton$pagesz,
		      PERMISSION_READ | PERMISSION_WRITE,
		      SEGMENT_OPTION_NONE,
		      &seg2) != STATUS_OK)
    TEST_ERROR("[segment_reserve] error");

  if (segment_reserve(as1,
		      ___kaneton$pagesz,
		      PERMISSION_READ | PERMISSION_WRITE,
		      SEGMENT_OPTION_NONE,
		      &useless) != STATUS_OK)
    TEST_ERROR("[segment_reserve] error");

  if (segment_reserve(as1,
		      2 * ___kaneton$pagesz,
		      PERMISSION_READ | PERMISSION_WRITE,
		      SEGMENT_OPTION_NONE,
		      &seg3) != STATUS_OK)
    TEST_ERROR("[segment_reserve] error");

  if (region_reserve(as1,
		     seg1,
		     ___kaneton$pagesz,
		     REGION_OPTION_FORCE,
		     0x20000000,
		     ___kaneton$pagesz,
		     &reg) != STATUS_OK)
    TEST_ERROR("[region_reserve] error");

  if (region_reserve(as1,
		     seg2,
		     ___kaneton$pagesz,
		     REGION_OPTION_FORCE,
		     0x20001000,
		     2 * ___kaneton$pagesz,
		     &reg) != STATUS_OK)
    TEST_ERROR("[region_reserve] error");

  if (region_reserve(as1,
		     seg3,
		     0,
		     REGION_OPTION_FORCE,
		     0x20003000,
		     ___kaneton$pagesz,
		     &reg) != STATUS_OK)
    TEST_ERROR("[region_reserve] error");

  /*
   * second address space
   */

  if (task_reserve(TASK_CLASS_GUEST,
		   TASK_BEHAVIOUR_INTERACTIVE,
		   TASK_PRIORITY_INTERACTIVE,
		   &task2) != STATUS_OK)
    TEST_ERROR("[task_reserve] error");

  if (as_reserve(task2, &as2) != STATUS_OK)
    TEST_ERROR("[as_reserve] error");

  if (segment_reserve(as2,
		      2 * ___kaneton$pagesz,
		      PERMISSION_READ | PERMISSION_WRITE,
		      SEGMENT_OPTION_NONE,
		      &seg4) != STATUS_OK)
    TEST_ERROR("[segment_reserve] error");

  if (segment_reserve(as2,
		      ___kaneton$pagesz,
		      PERMISSION_READ | PERMISSION_WRITE,
		      SEGMENT_OPTION_NONE,
		      &useless) != STATUS_OK)
    TEST_ERROR("[segment_reserve] error");

  if (segment_reserve(as2,
		      4 * ___kaneton$pagesz,
		      PERMISSION_READ | PERMISSION_WRITE,
		      SEGMENT_OPTION_NONE,
		      &seg5) != STATUS_OK)
    TEST_ERROR("[segment_reserve] error");

  if (segment_reserve(as2,
		      ___kaneton$pagesz,
		      PERMISSION_READ | PERMISSION_WRITE,
		      SEGMENT_OPTION_NONE,
		      &useless) != STATUS_OK)
    TEST_ERROR("[segment_reserve] error");

  if (segment_reserve(as2,
		      2 * ___kaneton$pagesz,
		      PERMISSION_READ | PERMISSION_WRITE,
		      SEGMENT_OPTION_NONE,
		      &seg6) != STATUS_OK)
    TEST_ERROR("[segment_reserve] error");

  if (region_reserve(as2,
		     seg4,
		     0,
		     REGION_OPTION_FORCE,
		     0x40000000,
		     ___kaneton$pagesz,
		     &reg) != STATUS_OK)
    TEST_ERROR("[region_reserve] error");

  if (region_reserve(as2,
		     seg5,
		     2 * ___kaneton$pagesz,
		     REGION_OPTION_FORCE,
		     0x40001000,
		     ___kaneton$pagesz,
		     &reg) != STATUS_OK)
    TEST_ERROR("[region_reserve] error");

  if (region_reserve(as2,
		     seg6,
		     0,
		     REGION_OPTION_FORCE,
		     0x40002000,
		     2 * ___kaneton$pagesz,
		     &reg) != STATUS_OK)
    TEST_ERROR("[region_reserve] error");

  /*
   * operations
   */

  for (i = 0; i < 4 * ___kaneton$pagesz; i++)
    buff[i] = (i * 2 + 4) % 256;

  if (as_write(as1, buff, 4 * ___kaneton$pagesz, 0x20000000) != STATUS_OK)
    TEST_ERROR("[as_write] error");

  for (i = 0; i < 4 * ___kaneton$pagesz; i++)
    buff[i] = 0;

  if (as_copy(as1, 0x20000000, as2, 0x40000000, 4 * ___kaneton$pagesz) != STATUS_OK)
    TEST_ERROR("[as_copy] error");

  if (as_read(as2, 0x40000000, 4 * ___kaneton$pagesz, buff) != STATUS_OK)
    TEST_ERROR("[as_read] error");

  for (i = 0; i < 4 * ___kaneton$pagesz; i++)
    if (buff[i] != (i * 2 + 4) % 256)
      TEST_ERROR("the data appears invalid once read from the "
		 "address space\n");

  TEST_SIGNATURE(rr3fiw3w20aafi9gre9g);

  TEST_LEAVE();
}
コード例 #4
0
t_error			ia32_region_reserve(i_as			asid,
					i_segment		segid,
				     	t_paddr			offset,
				     	t_opts			opts,
				     	t_vaddr			address,
				     	t_vsize			size,
				     	i_region*		regid)
{
  t_ia32_pde			pde_start;
  t_ia32_pde			pde_end;
  t_ia32_pte			pte_start;
  t_ia32_pte			pte_end;
  t_ia32_table			table;
  t_ia32_directory		pd;
  o_as*				oas;
  t_ia32_page			page;
  t_paddr			base;
  t_paddr			ram_paddr;
  t_vaddr			pd_addr;
  t_paddr			pt_addr;
  o_segment*			oseg;
  o_region*			oreg;
  int				i = 0;
  int				j = 0;
  int				x = 0;
  int				clear = 0;

  REGION_ENTER(region);
  if (as_get(asid, &oas) != ERROR_NONE)
    REGION_LEAVE(region, ERROR_UNKNOWN);

  if (region_get(asid, *regid, &oreg) != ERROR_NONE)
    REGION_LEAVE(region, ERROR_UNKNOWN);

  if (segment_get(segid, &oseg) != ERROR_NONE)
    REGION_LEAVE(region, ERROR_UNKNOWN);

  ram_paddr = oseg->address;
  pd = oas->machdep.pd;
  base = MK_BASE(pd);
  // Mapping PD into Kernel
  map_page(base, &pd_addr);

  /*   printf("pd %x\n", pd_addr); */

  /*   printf("%x\n", oreg->address); */

  pde_start = PDE_ENTRY(oreg->address);
  pde_end = PDE_ENTRY(oreg->address + size);
  pte_start = PTE_ENTRY(oreg->address);
  pte_end = PTE_ENTRY(oreg->address + size);

  for (i = pde_start; i <= pde_end; i++)
    {
      if (pd_get_table((t_ia32_directory *) &pd_addr, i, &table) == ERROR_UNKNOWN)
	{
	  segment_reserve(asid, PAGESZ, PERM_READ | PERM_WRITE, &segid);
	  if (segment_get(segid, &oseg) != ERROR_NONE)
	    REGION_LEAVE(region, ERROR_UNKNOWN);
	  table.rw = PDE_FLAG_RW;
	  table.present = 1;
	  table.user = (opts & REGION_OPT_USER) ? PT_USER : PT_PRIVILEGED;
	  table.writeback = PT_CACHED;
	  table.cached = 1;
	  pt_build(oseg->address, &table, 0);
	  pd_add_table((t_ia32_directory *) &pd_addr, i, table);
	  clear = 1;
	}
      else
	clear = 0;
      map_page(table.entries, &pt_addr);

      table.entries = pt_addr;

      if (clear)
	memset((void*)pt_addr, '\0', PAGESZ);
      for (j = (i == pde_start ? pte_start : 0); j <= (i == pde_end ? pte_end : 1023); j++)
	{
	  page.addr = x + (offset + ram_paddr);
	  page.present = 1;
	  page.rw = (oseg->perms & PERM_WRITE) ? PG_WRITABLE : PG_READONLY;
	  page.present = 1;
	  page.user = (opts & REGION_OPT_USER) ? PG_USER : PG_PRIVILEGED;
	  page.cached = PG_CACHED;
	  pt_add_page(&table, j, page);
	  x += PAGESZ;
	}
      unmap_page(&pt_addr);
    }

  tlb_flush();
      unmap_page(&pd_addr);
  REGION_LEAVE(region, ERROR_NONE);
}
コード例 #5
0
ファイル: handler.c プロジェクト: fenollp/kaneton
t_status		architecture_handler_setup(void)
{
  t_uint16		selector;
  i_segment		segment;
  i_region		region;
  as_idt		idt;
  o_region*		o;
  t_uint32		i;

  /*
   * 1)
   */

  if (segment_reserve(_kernel.as,
		      ___kaneton$pagesz,
		      PERMISSION_READ | PERMISSION_WRITE,
		      SEGMENT_OPTION_SYSTEM,
		      &segment) != STATUS_OK)
    MACHINE_ESCAPE("unable to reserve a segment");

  if (region_reserve(_kernel.as,
		     segment,
		     0x0,
		     REGION_OPTION_NONE,
		     0x0,
		     ___kaneton$pagesz,
		     &region) != STATUS_OK)
    MACHINE_ESCAPE("unable to reserve a region for the segment");

  if (region_get(_kernel.as, region, &o) != STATUS_OK)
    MACHINE_ESCAPE("unable to retrieve the region object");

  /*
   * 2)
   */

  if (architecture_idt_build(o->address,
			     ARCHITECTURE_IDT_SIZE,
			     &idt) != STATUS_OK)
    MACHINE_ESCAPE("unable to build the IDT at the given address");

  if (architecture_idt_import(&idt) != STATUS_OK)
    MACHINE_ESCAPE("unable to import the built IDT");

  /*
   * 3)
   */

  if (architecture_gdt_selector(ARCHITECTURE_GDT_INDEX_KERNEL_CODE,
				ARCHITECTURE_PRIVILEGE_KERNEL,
				&selector) != STATUS_OK)
    MACHINE_ESCAPE("unable to build the kernel code segment selector");

  /*
   * 4)
   */

  for (i = ARCHITECTURE_IDT_EXCEPTION_BASE;
       i < ARCHITECTURE_IDT_EXCEPTION_BASE + ARCHITECTURE_IDT_EXCEPTION_SIZE;
       i++)
    {
      if (architecture_idt_insert(i,
				  (t_vaddr)_architecture_handler_shells[i],
				  selector,
				  ARCHITECTURE_IDTE_DPL_SET(
				    ARCHITECTURE_PRIVILEGE_RING0) |
				  ARCHITECTURE_IDTE_32BIT |
				  ARCHITECTURE_IDTE_INTERRUPT) != STATUS_OK)
	MACHINE_ESCAPE("unable to register the exception handler '%u'",
		       i);
    }

  /*
   * 5)
   */

  for (i = ARCHITECTURE_IDT_IRQ_BASE;
       i < ARCHITECTURE_IDT_IRQ_BASE + ARCHITECTURE_IDT_IRQ_SIZE;
       i++)
    {
      if (architecture_idt_insert(i,
				  (t_vaddr)_architecture_handler_shells[i],
				  selector,
				  ARCHITECTURE_IDTE_DPL_SET(
				    ARCHITECTURE_PRIVILEGE_RING0) |
				  ARCHITECTURE_IDTE_32BIT |
				  ARCHITECTURE_IDTE_INTERRUPT) != STATUS_OK)
	MACHINE_ESCAPE("unable to register the exception handler '%u'",
		       i);
    }

  /*
   * 6)
   */

  for (i = ARCHITECTURE_IDT_SYSCALL_BASE;
       i < ARCHITECTURE_IDT_SYSCALL_BASE + ARCHITECTURE_IDT_SYSCALL_SIZE;
       i++)
    {
      if (architecture_idt_insert(i,
				  (t_vaddr)_architecture_handler_shells[i],
				  selector,
				  ARCHITECTURE_IDTE_DPL_SET(
				    ARCHITECTURE_PRIVILEGE_RING3) |
				  ARCHITECTURE_IDTE_32BIT |
				  ARCHITECTURE_IDTE_INTERRUPT) != STATUS_OK)
	MACHINE_ESCAPE("unable to register the exception handler '%u'",
		       i);
    }

  MACHINE_LEAVE();
}