Пример #1
0
t_status		architecture_environment_kernel(i_as	id)
{
  struct
  {
    at_pdei		start;
    at_pdei		end;
    at_pdei		index;
  }			pde;
  struct
  {
    at_ptei		start;
    at_ptei		end;
    at_ptei		index;
  }			pte;
  i_region		useless;
  at_cr3		pdbr;
  o_as*			as;
  at_pd			pd;
  at_pt			pt;
  o_region*		r;
  t_uint32		i;

  /*
   * 1)
   */

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

  /*
   * 2)
   */

  as->machine.pd = _init->machine.pd;

  /*
   * 3)
   */

  if (architecture_paging_pdbr(as->machine.pd,
			       ARCHITECTURE_REGISTER_CR3_PCE |
			       ARCHITECTURE_REGISTER_CR3_PWB,
			       &pdbr) != STATUS_OK)
    MACHINE_ESCAPE("unable to build the CR3 register's content");

  /*
   * 4)
   */

  pd = (at_pd)as->machine.pd;

  /*
   * 5)
   */

  if (architecture_paging_import(pd,
				 pdbr) != STATUS_OK)
    MACHINE_ESCAPE("unable to import the kernel page directory");

  /*
   * 6)
   */

  if (architecture_pd_insert(pd,
			     ARCHITECTURE_PD_MIRROR,
			     as->machine.pd,
			     ARCHITECTURE_PDE_PRESENT |
			     ARCHITECTURE_PDE_RW |
			     ARCHITECTURE_PDE_SUPERVISOR |
			     ARCHITECTURE_PDE_PWB |
			     ARCHITECTURE_PDE_PCE) != STATUS_OK)
    MACHINE_ESCAPE("unable to insert the mirroring directory entry");

  /*
   * 7)
   */

  if ((r = malloc(sizeof (o_region))) == NULL)
    MACHINE_ESCAPE("unable to allocate memory for the region object");

  r->address = ARCHITECTURE_PAGING_ADDRESS(ARCHITECTURE_PD_MIRROR, 0);
  r->segment = ID_UNUSED;
  r->offset = 0x0;
  r->size = ARCHITECTURE_PT_SIZE * ___kaneton$pagesz;
  r->options = REGION_OPTION_NONE;

  if (region_inject(as->id, r, &useless) != STATUS_OK)
    MACHINE_ESCAPE("unable to inject the mirroring region");

  /*
   * 8)
   */

  pde.start = 0;
  pte.start = 0;

  for (i = 0; i < (_init->nregions + 1); i++)
    {
      /*
       * a)
       */

      if (i != _init->nregions)
	{
	  pde.end = ARCHITECTURE_PD_INDEX(_init->regions[i].address);
	  pte.end = ARCHITECTURE_PT_INDEX(_init->regions[i].address);
	}
      else
	{
	  pde.end = ARCHITECTURE_PD_SIZE - 1;
	  pte.end = ARCHITECTURE_PT_SIZE;
	}

      /*
       * b)
       */

      for (pde.index = pde.start;
	   pde.index <= pde.end;
	   pde.index++)
	{
	  /*
	   * i)
	   */

	  if ((pde.index != ARCHITECTURE_PD_MIRROR) &&
	      (pd[pde.index] & ARCHITECTURE_PDE_PRESENT))
	    {
	      /*
	       * #1)
	       */

	      pt = (at_pt)ARCHITECTURE_PDE_ADDRESS(pd[pde.index]);

	      /*
	       * #2)
	       */

	      for (pte.index = (pde.index == pde.start ? pte.start : 0);
		   pte.index < (pde.index == pde.end ?
				pte.end : ARCHITECTURE_PT_SIZE);
		   pte.index++)
		{
		  /*
		   * #a)
		   */

		  if (pt[pte.index] & ARCHITECTURE_PTE_PRESENT)
		    {
		      if (architecture_pt_delete(pt, pte.index) != STATUS_OK)
			MACHINE_ESCAPE("unable to delete the page "
				       "table entry");
		    }
		}
	    }
	}

      /*
       * c)
       */

      if (i != _init->nregions)
	{
	  pde.start = ARCHITECTURE_PD_INDEX(_init->regions[i].address +
					    _init->regions[i].size);
	  pte.start = ARCHITECTURE_PT_INDEX(_init->regions[i].address +
					    _init->regions[i].size);
	}
    }

  /*
   * 9)
   */

  if (architecture_tlb_flush() != STATUS_OK)
    MACHINE_ESCAPE("unable to flush the TLB");

  /*
   * 10)
   */

  _architecture.kernel.pdbr = pdbr;

  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);
}