Esempio n. 1
0
int
mon_showvm(int argc, char **argv, struct Trapframe *tf)
{
	uintptr_t begin_va, end_va, va, next_va;
	pde_t *pgdir;
	pte_t *pte;
	int i, j;

	if (argc != 3) {
		cprintf("usage: dumpvm begin_va end_va\n");
		return 0;
	}

	begin_va = (uintptr_t) strtol(argv[1], NULL, 0);
	end_va = (uintptr_t) strtol(argv[2], NULL, 0);
	if (begin_va > end_va) {
		cprintf("begin va (0x%x) is greater than end va (0x%x)\n", begin_va, end_va);
		return 0;
	}

	pgdir = (pde_t *) KADDR(rcr3());
	for (i = j = 0, va = begin_va; va <= end_va; va += PGSIZE) {
		pte = pgdir_walk(pgdir, (void *) va, 0);
		next_va = MIN(ROUNDDOWN(va + PGSIZE, PGSIZE) - 1, end_va);
		show_page(pgdir, va, next_va, *pte && (*pte & PTE_P), &i, &j);
	}
	if (i)
		cprintf("\n");
	return 0;
}
Esempio n. 2
0
int
mon_modpageperms(int argc, char **argv, struct Trapframe *tf)
{
	uintptr_t va_arg;
	int perms;
	pde_t *pgdir;
	pte_t *pte;

	if (argc != 3) {
		cprintf("usage: modpageperms va perms\n");
		return 0;
	}

	va_arg = (uintptr_t) strtol(argv[1], NULL, 0);

	perms = (uintptr_t) strtol(argv[2], NULL, 0);
	if (PTE_ADDR(perms)) {
		cprintf("perms 0x%03x is invalid\n", perms);
		return 0;
	}

	pgdir = (pde_t *) KADDR(rcr3());
	pte = pgdir_walk(pgdir, (void *) va_arg, 0);
	if (!pte) {
		cprintf("va 0x%x is not mapped\n", va_arg);
		return 0;
	}

	cprintf("va 0x%x existing pte ");
	pte_show(*pte);
	*pte = PTE_ADDR(*pte) | perms;
	cprintf("va 0x%x changed pte ");
	pte_show(*pte);
	return 0;
}
Esempio n. 3
0
int MPTIntro_test1()
{
  set_pdir_base(0);
  if ((unsigned int)PDirPool[0] != rcr3()) {
    dprintf("test 1 failed.\n");
    return 1;
  }
  set_pdir_entry_identity(1, 1);
  set_pdir_entry(1, 2, 100);
  if (get_pdir_entry(1, 1) != (unsigned int)IDPTbl[1] +   7) {
    dprintf("test 1 failed.\n");
    return 1;
  }
  if (get_pdir_entry(1, 2) != 409607) {
    dprintf("test 1 failed.\n");
    return 1;
  }
  rmv_pdir_entry(1, 1);
  rmv_pdir_entry(1, 2);
  if (get_pdir_entry(1, 1) != 0 || get_pdir_entry(1, 2) != 0) {
    dprintf("test 1 failed.\n");
    return 1;
  }
  dprintf("test 1 passed.\n");
  return 0;
}
Esempio n. 4
0
File: pmap.c Progetto: yahu/JOS
// map physcical memory [0,PGSIZE*npages] to [KERNBASE,KERNBASE+PGSIZE*npages] ,in case
// one physical memory can't find its virtual address
static void
boot_phys_map()
{
    uintptr_t sp=KERNBASE+0X400000;
    int i,j;
    pte_t* pgtable;
    pde_t* entry_pgdir=(pde_t*)(rcr3()+KERNBASE);

    int npts= (npages / 1024)+1;

    int actual_top=KERNBASE+npages*PGSIZE;

    for(i=0; i<npts && sp<actual_top; i++){

        pgtable=boot_alloc(PGSIZE);
        memset(pgtable, 0, PGSIZE);

        entry_pgdir[PDX(sp)]=((int)pgtable-KERNBASE) | PTE_P | PTE_U | PTE_W;
       // cprintf("the entry_pgdir'%dth pde is  %x\n ",PDX(sp),(int)entry_pgdir[PDX(sp)]);

        for(j=0;j<1024 && sp<actual_top;j++){

            pgtable[j]=((uint32_t)sp-KERNBASE) | PTE_P | PTE_U | PTE_W;
            sp+=PGSIZE;
        }

    }

}
Esempio n. 5
0
void refresh_tlb(pgd_t *pgdir, viraddr_t va)
{
	// Flush the entry only if we're modifying the current address space.
	//if (!curenv || curenv->env_pgdir == pgdir)
	invlpg((void*)va);
	int cr3 = rcr3();
	lcr3(cr3);
}
Esempio n. 6
0
void
kmm_pgfault(struct trapframe *tf)
{
	// uint64_t  err  = tf->tf_err;
	uintptr_t addr = rcr2();

	if (addr >= PBASE && addr < PBASE + PSIZE)
	{
		pgd_t *pgd = KADDR_DIRECT(PTE_ADDR(rcr3()));
		pud_t *pud;
		pmd_t *pmd;
		pte_t *ptd;
		
		/* PHYSICAL ADDRRESS ACCESSING */
		if (last_pgd != NULL)
		{
			pud = KADDR_DIRECT(PGD_ADDR(last_pgd[PGX(last_addr)]));
			pmd = KADDR_DIRECT(PUD_ADDR(pud[PUX(last_addr)]));
			ptd = KADDR_DIRECT(PMD_ADDR(pmd[PMX(last_addr)]));

			ptd[PTX(last_addr)] = 0;
			if (ptd == temp_ptd)
			{
				pmd[PUX(last_addr)] = 0;
				if (pmd == temp_pmd)
				{
					pud[PUX(last_addr)] = 0;
					if (pud == temp_pud)
						last_pgd[PGX(last_addr)] = 0;
				}
				
				if (last_pgd == pgd)
				{
					invlpg((void *)last_addr);
				}
			}
		}

		if (pgd[PGX(last_addr)] == 0)
			pgd[PGX(last_addr)] = PADDR_DIRECT(temp_pud) | PTE_W | PTE_P;
		pud = KADDR_DIRECT(PGD_ADDR(pgd[PGX(last_addr)]));
		if (pud[PUX(last_addr)] == 0)
			pud[PUX(last_addr)] = PADDR_DIRECT(temp_pmd) | PTE_W | PTE_P;
		pmd = KADDR_DIRECT(PUD_ADDR(pud[PUX(last_addr)]));
		if (pmd[PMX(last_addr)] == 0)
			pmd[PMX(last_addr)] = PADDR_DIRECT(temp_ptd) | PTE_W | PTE_P;
		ptd = KADDR_DIRECT(PMD_ADDR(pmd[PMX(last_addr)]));

		ptd[PTX(last_addr)] = PADDR_DIRECT(addr) | PTE_W | PTE_P;

		last_pgd = pgd;
		last_addr = addr;

		/* XXX? */
		// invlpg((void *)addr);
	}
}
Esempio n. 7
0
File: pmap.c Progetto: 7perl/akaros
/* Flushes a TLB, including global pages.  We should always have the CR4_PGE
 * flag set, but just in case, we'll check.  Toggling this bit flushes the TLB.
 */
void tlb_flush_global(void)
{
	uint32_t cr4 = rcr4();
	if (cr4 & CR4_PGE) {
		lcr4(cr4 & ~CR4_PGE);
		lcr4(cr4);
	} else 
		lcr3(rcr3());
}
Esempio n. 8
0
unsigned int mmu_inicializar_dir_tarea(taskType tipo, unsigned int fisica){
	int *page_directory = mmu_proxima_pagina_fisica_libre();

	// Limpiamos el directorio
	int i = 0;
	while (i < 1024) {
		page_directory[i] = 0;
		i++;
	}
	
	// Registramos la primer pagina en el directorio
	int *page_table = mmu_proxima_pagina_fisica_libre(); 
	page_directory[0] = (int)page_table + ATTR_KERN; 

	// En la tabla de paginas registramos las primeras 1024 con bloques
	// de 4kb
	
	int base_page_addr = 0;
	i = 0;
	while(i < 1024) {
		page_table[i] = base_page_addr + ATTR_KERN;
		base_page_addr += 4096;						
		i++;
	}

	unsigned int cr3Tarea = (int) page_directory;

	mmu_mapear_pagina(fisica, rcr3(), fisica, ATTR_KERN);

	//tipo de tarea
	int* codigo_fuente = (int*) (IDLE_TASK + (inMemoryCodeOrder(tipo) * PAGE_SIZE));
	mmu_copiar_pagina(codigo_fuente, (int*) fisica);

	mmu_unmapear_pagina(fisica, rcr3());
	

	
	mmu_mapear_pagina(TASK_CODE, cr3Tarea, fisica, ATTR_USER);

	//En principio se mapea a si misma
	//No esta atacando a nadie
	mmu_mapear_pagina(TASK_CODE + PAGE_SIZE, cr3Tarea, fisica, ATTR_USER);
	return cr3Tarea;
}
Esempio n. 9
0
void mover_pirata(uint pos_orig, uint pos_nueva, pirata_t* pirata){
	if (pirata->type == PIRATA_MINERO) {
		if ( posicion_mapeada(pos_nueva, pirata->jugador) ) {
			mmu_mover_codigo_pirata(rcr3(), game_pos2mem_fisica(pos_nueva), game_pos2mem_fisica(pos_orig));
			pintar_pirata(pos_nueva, pos_orig, pirata->type);
			pirata->pos = pos_nueva;
		} else {
			tarea_suicidarse();
		}
	} else {
		mmu_mover_codigo_pirata(rcr3(), game_pos2mem_fisica(pos_nueva), game_pos2mem_fisica(pos_orig));
		pirata->pos = pos_nueva;
		pintar_pirata(pos_nueva, pos_orig, pirata->type);
		
		int x = 0, y = 0;
		game_lineal2xy(pos_nueva, &x, &y); //transformo a x e y
		game_explorar_posicion(pirata, x, y);
	}
}
Esempio n. 10
0
// Allocate a page of memory and map it at 'va' with permission
// 'perm' in the address space of 'envid'.
// The page's contents are set to 0.
// If a page is already mapped at 'va', that page is unmapped as a
// side effect.
//
// perm -- PTE_U | PTE_P must be set, PTE_AVAIL | PTE_W may or may not be set,
//         but no other bits may be set.
//
// Return 0 on success, < 0 on error.  Errors are:
//	-E_BAD_ENV if environment envid doesn't currently exist,
//		or the caller doesn't have permission to change envid.
//	-E_INVAL if va >= UTOP, or va is not page-aligned.
//	-E_INVAL if perm is inappropriate (see above).
//	-E_NO_MEM if there's no memory to allocate the new page,
//		or to allocate any necessary page tables.
static int
sys_page_alloc(envid_t envid, void *va, int perm)
{
	// Hint: This function is a wrapper around page_alloc() and
	//   page_insert() from kern/pmap.c.
	//   Most of the new code you write should be to check the
	//   parameters for correctness.
	//   If page_insert() fails, remember to free the page you
	//   allocated!

	// LAB 4: Your code here.

	struct Env *e;
	int r;
	struct Page *p;
	uint32_t cr3;

	if ((r = envid2env(envid, &e, 1)) < 0)	
		return r;

	if ((uintptr_t)va >= UTOP || (uintptr_t)va % PGSIZE != 0)	
		return -E_INVAL;
	
	
	if ( (perm & (PTE_U | PTE_P) ) != (PTE_U | PTE_P) )	//PTE_U | PTE_P  MUST be set - ren
		return -E_INVAL;
	
		
	if(perm & ~PTE_USER)
		return	-E_INVAL;		//some disallowed bits are set - ren


	if (page_alloc(&p) < 0)
		return -E_NO_MEM;

	if (page_insert(e->env_pgdir, p, va, perm) < 0){
		page_free(p);
		return -E_NO_MEM;
	}
	

	//sets physical page's contents to 0 - ren
	
	//switch to envid's page directory - ren
	cr3 = rcr3(); 
	lcr3(e->env_cr3);

	//now we can use known va to get to physical page - ren
	memset(va, 0, PGSIZE);

	//switch back to curenv page directory - ren
	lcr3(cr3);
	
	return 0;
}
Esempio n. 11
0
//cambia el contexto del directorio de paginas, invalida la cache de direcciones y retorna el contenido viejo de CR3
unsigned int changePaginationContext(pagedir_entry* newDirContext){
    //usando estos "getters" y "setters" del registro del cpu CR3 voy a cambiar el contexto de memoria virtual
    //void lcr3(unsigned int val); => escribe a CR3
    //unsigned int rcr3(void); => lee el contenido de CR3
    unsigned int oldCR3 = rcr3();
    lcr3((unsigned int) newDirContext);

    //invalido la cache de traduccion de direcciones
    tlbflush();
    return oldCR3;
}
Esempio n. 12
0
File: pmap.c Progetto: yahu/JOS
static void
addr_info(uintptr_t va)
{
    extern pte_t entry_pgdir[];
    uint32_t cr3=rcr3();
    pde_t pde=((pde_t*)cr3)[PDX(va)];
    pte_t pte;

    cprintf("mem Page info:\n");
    cprintf("cr3=%x\n",cr3);
    cprintf("KERNBASE=%x \n",KERNBASE);
    cprintf("entry_pgdir=%x\n",(int)entry_pgdir);

    cprintf("va=%x\n",va);
    cprintf("correspond pde = %x\n",pde);
}
Esempio n. 13
0
File: sched.c Progetto: somodi/tp3
void init_idle(){

	tarea_idle.ss = 0x10;
	tarea_idle.ds = 0x10;
	tarea_idle.es = 0x10;
	tarea_idle.fs = 0x10;
	tarea_idle.gs = 0x10;
	tarea_idle.cs = 0x8;
	
	tarea_idle.cr3 = (unsigned int) rcr3();
	
        tarea_idle.eip = TASK_CODE;
        
	tarea_idle.ebp = 0;
	tarea_idle.esp = TASK_STACK + 0x1000;

	tarea_idle.eflags = 0x202; //Bit obligado, con interrupciones
	
	tarea_idle.iomap = 0xFFFF;
	tarea_idle.dtrap = 0x0;
}
Esempio n. 14
0
int
mon_showmappings(int argc, char **argv, struct Trapframe *tf)
{
	int i;
	uintptr_t va_arg[2], va;
	pde_t *pgdir;
	pte_t *pte;

	if (argc != 3) {
		cprintf("usage: showmappings begin_va end_va\n");
		return 0;
	}

	for (i = 1; i < argc; i++) {
		va_arg[i - 1] = (uintptr_t) strtol(argv[i], NULL, 0);
	}

	if (va_arg[0] > va_arg[1]) {
		cprintf("begin va (0x%x) is greater than end va (0x%x)\n", va_arg[0], va_arg[1]);
		return 0;
	}

	pgdir = (pde_t *) KADDR(rcr3());
	for (va = va_arg[0]; va <= va_arg[1]; va += PGSIZE) {
		pte = pgdir_walk(pgdir, (void *) va, 0);
		if (!pte || !(*pte & PTE_P)) {
			cprintf("va 0x%x is not mapped\n", va);
		} else {
			cprintf("va 0x%x ", va);
			pte_show(*pte);
		}

		if (va + PGSIZE < va)
			break;
	}
	return 0;
}
Esempio n. 15
0
File: loader.c Progetto: emancu/pso
void loader_init(void) {
  int i;
  // Inicializamos la cola de peeds libres
  free_pids[0] = -1; // La IDLE ocupa la 0, nadie deberia apuntar a la 0
  for (i = 1; i < MAX_PID - 1; i++)
    free_pids[i] = i + 1;
  free_pids[MAX_PID - 1] = -1; // es la ultima

  next_free = 1;
  cur_pid = 0;

  //NOTE: Deberiamos contar la IDLE Task?
  tasks_running = tasks_blocked = 0;

  for(i=0; i < MAX_PID; i++)
    task_table[i].cr3 = 0;
  //hay que generar la tarea actual.. que dps se convierte en idle
  task_table[0].cr3 = rcr3();

  //registro las syscalls (UNIFICAR UN LUGAR O CADA UNA EN SU MODULO)
  syscall_list[0x31] = (uint_32) &sys_getpid;
  syscall_list[0x32] = (uint_32) &sys_exit;
  syscall_list[0x38] = (uint_32) &sys_fork;
}
Esempio n. 16
0
// invalidate a TLB entry, but only if the page tables being
// edited are the ones currently in use by the processor.
void
tlb_invalidate(pde_t *pgdir, uintptr_t la) {
    if (rcr3() == PADDR(pgdir)) {
        invlpg((void *)la);
    }
}
// Allocates a new env and loads the named user program into it.
struct Env* env_create(char* user_program_name, unsigned int page_WS_size)
{
	//[1] get pointer to the start of the "user_program_name" program in memory
	// Hint: use "get_user_program_info" function,
	// you should set the following "ptr_program_start" by the start address of the user program
	uint8* ptr_program_start = 0;

	struct UserProgramInfo* ptr_user_program_info = get_user_program_info(user_program_name);
	if(ptr_user_program_info == 0) return NULL;
	ptr_program_start = ptr_user_program_info->ptr_start ;
	//	if(ptr_user_program_info->environment != NULL)
	//	{
	//		cprintf("env_create: an old environment already exist for [%s]!! \nfreeing the old one by calling start_env_free....\n", ptr_user_program_info->environment->prog_name);
	//		start_env_free(ptr_user_program_info->environment);
	//
	//		//return ptr_user_program_info;
	//	}


	//[2] allocate new environment, (from the free environment list)
	//if there's no one, return NULL
	// Hint: use "allocate_environment" function
	struct Env* e = NULL;
	if(allocate_environment(&e) < 0)
	{
		return 0;
	}

	//[2.5 - 2012] Set program name inside the environment
	e->prog_name = ptr_user_program_info->name ;

	//[3] allocate a frame for the page directory, Don't forget to set the references of the allocated frame.
	//REMEMBER: "allocate_frame" should always return a free frame
	uint32* ptr_user_page_directory;
	unsigned int phys_user_page_directory;
	if(USE_KHEAP)
	{
		ptr_user_page_directory = create_user_directory();
		phys_user_page_directory = kheap_physical_address((uint32)ptr_user_page_directory);
	}
	else
	{
		int r;
		struct Frame_Info *p = NULL;

		allocate_frame(&p) ;
		p->references = 1;

		ptr_user_page_directory = STATIC_KERNEL_VIRTUAL_ADDRESS(to_physical_address(p));
		phys_user_page_directory = to_physical_address(p);
	}

	//[4] initialize the new environment by the virtual address of the page directory
	// Hint: use "initialize_environment" function

	//2016
	e->page_WS_max_size = page_WS_size;

	initialize_environment(e, ptr_user_page_directory, phys_user_page_directory);

	// We want to load the program into the user virtual space
	// each program is constructed from one or more segments,
	// each segment has the following information grouped in "struct ProgramSegment"
	//	1- uint8 *ptr_start: 	start address of this segment in memory
	//	2- uint32 size_in_file: size occupied by this segment inside the program file,
	//	3- uint32 size_in_memory: actual size required by this segment in memory
	// 	usually size_in_file < or = size_in_memory
	//	4- uint8 *virtual_address: start virtual address that this segment should be copied to it

	//[6] switch to user page directory
	// Hint: use rcr3() and lcr3()
	uint32 kern_phys_pgdir = rcr3() ;
	lcr3(e->env_cr3) ;

	//[7] load each program segment into user virtual space
	struct ProgramSegment* seg = NULL;  //use inside PROGRAM_SEGMENT_FOREACH as current segment information
	int segment_counter=0;
	uint32 remaining_ws_pages = (e->page_WS_max_size)-1; // we are reserving 1 page of WS for the stack that will be allocated just before the end of this function
	uint32 lastTableNumber=0xffffffff;

	PROGRAM_SEGMENT_FOREACH(seg, ptr_program_start)
	{
		segment_counter++;
		//allocate space for current program segment and map it at seg->virtual_address then copy its content
		// from seg->ptr_start to seg->virtual_address
		//Hint: use program_segment_alloc_map_copy_workingset()

		//cprintf("SEGMENT #%d, dest start va = %x, dest end va = %x\n",segment_counter, seg->virtual_address, (seg->virtual_address + seg->size_in_memory));
		LOG_STRING("===============================================================================");
		LOG_STATMENT(cprintf("SEGMENT #%d, size_in_file = %d, size_in_memory= %d, dest va = %x",segment_counter,seg->size_in_file,
				seg->size_in_memory, seg->virtual_address));
		LOG_STRING("===============================================================================");

		uint32 allocated_pages=0;
		program_segment_alloc_map_copy_workingset(e, seg, &allocated_pages, remaining_ws_pages, &lastTableNumber);

		remaining_ws_pages -= allocated_pages;
		LOG_STATMENT(cprintf("SEGMENT: allocated pages in WS = %d",allocated_pages));
		LOG_STATMENT(cprintf("SEGMENT: remaining WS pages after allocation = %d",remaining_ws_pages));


		///[1] temporary initialize 1st page in memory then writing it on page file
		uint32 dataSrc_va = (uint32) seg->ptr_start;
		uint32 seg_va = (uint32) seg->virtual_address ;

		uint32 start_first_page = ROUNDDOWN(seg_va , PAGE_SIZE);
		uint32 end_first_page = ROUNDUP(seg_va , PAGE_SIZE);
		uint32 offset_first_page = seg_va  - start_first_page ;

		memset(ptr_temp_page , 0, PAGE_SIZE);
		uint8 *src_ptr =  (uint8*) dataSrc_va;
		uint8 *dst_ptr =  (uint8*) (ptr_temp_page + offset_first_page);
		int i;
		for (i = seg_va ; i < end_first_page ; i++, src_ptr++,dst_ptr++ )
		{
			*dst_ptr = *src_ptr ;
		}

		if (pf_add_env_page(e, start_first_page, ptr_temp_page) == E_NO_PAGE_FILE_SPACE)
			panic("ERROR: Page File OUT OF SPACE. can't load the program in Page file!!");

		//LOG_STRING(" -------------------- PAGE FILE: 1st page is written");


		///[2] Start writing the segment ,from 2nd page until before last page, to page file ...

		uint32 start_last_page = ROUNDDOWN(seg_va  + seg->size_in_file, PAGE_SIZE) ;
		uint32 end_last_page = seg_va  + seg->size_in_file;

		for (i = end_first_page ; i < start_last_page ; i+= PAGE_SIZE, src_ptr+= PAGE_SIZE)
		{
			if (pf_add_env_page(e, i, src_ptr) == E_NO_PAGE_FILE_SPACE)
				panic("ERROR: Page File OUT OF SPACE. can't load the program in Page file!!");

		}
		//LOG_STRING(" -------------------- PAGE FILE: 2nd page --> before last page are written");

		///[3] temporary initialize last page in memory then writing it on page file

		dst_ptr =  (uint8*) ptr_temp_page;
		memset(dst_ptr, 0, PAGE_SIZE);

		for (i = start_last_page ; i < end_last_page ; i++, src_ptr++,dst_ptr++ )
		{
			*dst_ptr = *src_ptr;
		}
		if (pf_add_env_page(e, start_last_page, ptr_temp_page) == E_NO_PAGE_FILE_SPACE)
			panic("ERROR: Page File OUT OF SPACE. can't load the program in Page file!!");


		//LOG_STRING(" -------------------- PAGE FILE: last page is written");

		///[4] writing the remaining seg->size_in_memory pages to disk

		uint32 start_remaining_area = ROUNDUP(seg_va + seg->size_in_file,PAGE_SIZE) ;
		uint32 remainingLength = (seg_va + seg->size_in_memory) - start_remaining_area ;

		for (i=0 ; i < ROUNDUP(remainingLength,PAGE_SIZE) ;i+= PAGE_SIZE, start_remaining_area += PAGE_SIZE)
		{
			if (pf_add_empty_env_page(e, start_remaining_area, 1) == E_NO_PAGE_FILE_SPACE)
				panic("ERROR: Page File OUT OF SPACE. can't load the program in Page file!!");
		}
		//LOG_STRING(" -------------------- PAGE FILE: segment remaining area is written (the zeros) ");
	}
int
acpi_sleep_machdep(struct acpi_softc *sc, int state)
{
	ACPI_STATUS		status;
	struct pmap		*pm;
	int			ret;
	uint32_t		cr3;
	u_long			ef;

	ret = 0;
	if (sc->acpi_wakeaddr == 0)
		return (0);

	AcpiSetFirmwareWakingVector(sc->acpi_wakephys);

	ef = read_eflags();

	/*
	 * Temporarily switch to the kernel pmap because it provides an
	 * identity mapping (setup at boot) for the low physical memory
	 * region containing the wakeup code.
	 */
	pm = kernel_pmap;
	cr3 = rcr3();
#ifdef PAE
	load_cr3(vtophys(pm->pm_pdpt));
#else
	load_cr3(vtophys(pm->pm_pdir));
#endif

	ret_addr = 0;
	ACPI_DISABLE_IRQS();
	if (acpi_savecpu()) {
		/* Execute Sleep */
		intr_suspend();

		p_gdt = (struct region_descriptor *)
				(sc->acpi_wakeaddr + physical_gdt);
		p_gdt->rd_limit = saved_gdt.rd_limit;
		p_gdt->rd_base = vtophys(saved_gdt.rd_base);

		WAKECODE_FIXUP(physical_esp, uint32_t, vtophys(r_esp));
		WAKECODE_FIXUP(previous_cr0, uint32_t, r_cr0);
		WAKECODE_FIXUP(previous_cr2, uint32_t, r_cr2);
		WAKECODE_FIXUP(previous_cr3, uint32_t, r_cr3);
		WAKECODE_FIXUP(previous_cr4, uint32_t, r_cr4);

		WAKECODE_FIXUP(resume_beep, uint32_t, acpi_resume_beep);
		WAKECODE_FIXUP(reset_video, uint32_t, acpi_reset_video);

		WAKECODE_FIXUP(previous_tr,  uint16_t, r_tr);
		WAKECODE_BCOPY(previous_gdt, struct region_descriptor, saved_gdt);
		WAKECODE_FIXUP(previous_ldt, uint16_t, saved_ldt);
		WAKECODE_BCOPY(previous_idt, struct region_descriptor, saved_idt);

		WAKECODE_FIXUP(where_to_recover, void *, acpi_restorecpu);

		WAKECODE_FIXUP(previous_ds,  uint16_t, r_ds);
		WAKECODE_FIXUP(previous_es,  uint16_t, r_es);
		WAKECODE_FIXUP(previous_fs,  uint16_t, r_fs);
		WAKECODE_FIXUP(previous_gs,  uint16_t, r_gs);
		WAKECODE_FIXUP(previous_ss,  uint16_t, r_ss);

		if (bootverbose)
			acpi_printcpu();

		/* Call ACPICA to enter the desired sleep state */
		if (state == ACPI_STATE_S4 && sc->acpi_s4bios)
			status = AcpiEnterSleepStateS4bios();
		else
			status = AcpiEnterSleepState(state);

		if (status != AE_OK) {
			device_printf(sc->acpi_dev,
				"AcpiEnterSleepState failed - %s\n",
				AcpiFormatException(status));
			ret = -1;
			goto out;
		}

		for (;;) ;
	} else {
		/* Execute Wakeup */
		intr_resume();

		if (bootverbose) {
			acpi_savecpu();
			acpi_printcpu();
		}
	}

out:
	load_cr3(cr3);
	write_eflags(ef);

	/* If we beeped, turn it off after a delay. */
	if (acpi_resume_beep)
		timeout(acpi_stop_beep, NULL, 3 * hz);

	return (ret);
}
Esempio n. 19
0
File: env.c Progetto: ren85/jos2006
//
// Set up the initial program binary, stack, and processor flags
// for a user process.
// This function is ONLY called during kernel initialization,
// before running the first user-mode environment.
//
// This function loads all loadable segments from the ELF binary image
// into the environment's user memory, starting at the appropriate
// virtual addresses indicated in the ELF program header.
// At the same time it clears to zero any portions of these segments
// that are marked in the program header as being mapped
// but not actually present in the ELF file - i.e., the program's bss section.
//
// All this is very similar to what our boot loader does, except the boot
// loader also needs to read the code from disk.  Take a look at
// boot/main.c to get ideas.
//
// Finally, this function maps one page for the program's initial stack.
//
// load_icode panics if it encounters problems.
//  - How might load_icode fail?  What might be wrong with the given input?
//
static void
load_icode(struct Env *e, uint8_t *binary, size_t size)
{
	// Hints: 
	//  Load each program segment into virtual memory
	//  at the address specified in the ELF section header.
	//  You should only load segments with ph->p_type == ELF_PROG_LOAD.
	//  Each segment's virtual address can be found in ph->p_va
	//  and its size in memory can be found in ph->p_memsz.
	//  The ph->p_filesz bytes from the ELF binary, starting at
	//  'binary + ph->p_offset', should be copied to virtual address
	//  ph->p_va.  Any remaining memory bytes should be cleared to zero.
	//  (The ELF header should have ph->p_filesz <= ph->p_memsz.)
	//  Use functions from the previous lab to allocate and map pages.
	//
	//  All page protection bits should be user read/write for now.
	//  ELF segments are not necessarily page-aligned, but you can
	//  assume for this function that no two segments will touch
	//  the same virtual page.
	//
	//  You may find a function like segment_alloc useful.
	//
	//  Loading the segments is much simpler if you can move data
	//  directly into the virtual addresses stored in the ELF binary.
	//  So which page directory should be in force during
	//  this function?
	//
	// Hint:
	//  You must also do something with the program's entry point,
	//  to make sure that the environment starts executing there.
	//  What?  (See env_run() and env_pop_tf() below.)

	// LAB 3: Your code here.


	struct Proghdr *ph, *eph; 
	struct Elf * header = (struct Elf *)binary;
	int i;
	uint32_t cr3;
	
	//switch to environment's page directory
	// (kernel part of which is the same as kernel's page directory's (except vpt, hm)) -ren
	cr3 = rcr3(); 
	lcr3(e->env_cr3);
	
	// is this a valid ELF?
	if (header->e_magic != ELF_MAGIC)
		panic("load_icode - magic number is bad!");

	
	ph = (struct Proghdr *) (binary + header->e_phoff);
	eph = ph + header->e_phnum;
		

	for (; ph < eph; ph++){
		
		if (ph->p_type == ELF_PROG_LOAD){
					
			segment_alloc(e, (void *)ph->p_va, (size_t) ph->p_memsz);			
			memset( (void *) ph->p_va, 0, ph->p_memsz);	
			memcpy( (void *) ph->p_va, binary + ph->p_offset, ph->p_filesz);	
		}
	}
	
	
	e->env_tf.tf_eip=header->e_entry;
	//what about processor flags? (don't know) - ren
	//e->env_tf.tf_eflags 	
	
	// Now map one page for the program's initial stack
	// at virtual address USTACKTOP - PGSIZE.

	// LAB 3: Your code here.
	
	segment_alloc(e, (void *)USTACKTOP - PGSIZE, PGSIZE);

	
	
	//switch back to kernel's page directory - ren
	lcr3(cr3);
}
Esempio n. 20
0
//
// Set up the initial program binary, stack, and processor flags
// for a user process.
// This function is ONLY called during kernel initialization,
// before running the first user-mode environment.
//
// This function loads all loadable segments from the ELF binary image
// into the environment's user memory, starting at the appropriate
// virtual addresses indicated in the ELF program header.
// At the same time it clears to zero any portions of these segments
// that are marked in the program header as being mapped
// but not actually present in the ELF file - i.e., the program's bss section.
//
// All this is very similar to what our boot loader does, except the boot
// loader also needs to read the code from disk.  Take a look at
// boot/main.c to get ideas.
//
// Finally, this function maps one page for the program's initial stack.
//
// load_icode panics if it encounters problems.
//  - How might load_icode fail?  What might be wrong with the given input?
//
static void
load_icode(struct Env *e, uint8_t *binary, size_t size)
{
	// Hints: 
	//  Load each program segment into virtual memory
	//  at the address specified in the ELF section header.
	//  You should only load segments with ph->p_type == ELF_PROG_LOAD.
	//  Each segment's virtual address can be found in ph->p_va
	//  and its size in memory can be found in ph->p_memsz.
	//  The ph->p_filesz bytes from the ELF binary, starting at
	//  'binary + ph->p_offset', should be copied to virtual address
	//  ph->p_va.  Any remaining memory bytes should be cleared to zero.
	//  (The ELF header should have ph->p_filesz <= ph->p_memsz.)
	//  Use functions from the previous lab to allocate and map pages.
	//
	//  All page protection bits should be user read/write for now.
	//  ELF segments are not necessarily page-aligned, but you can
	//  assume for this function that no two segments will touch
	//  the same virtual page.
	//
	//  You may find a function like segment_alloc useful.
	//
	//  Loading the segments is much simpler if you can move data
	//  directly into the virtual addresses stored in the ELF binary.
	//  So which page directory should be in force during
	//  this function?
	//
	// Hint:
	//  You must also do something with the program's entry point,
	//  to make sure that the environment starts executing there.
	//  What?  (See env_run() and env_pop_tf() below.)

	// LAB 3: Your code here.
	struct Elf *env_elf = (struct Elf *)binary;
	struct Proghdr *ph, *eph;
	struct Page *pg;
	uint32_t old_cr3;

	// store the current cr3 and 
	// switch cr3 to the pgdir of the env
	old_cr3 = rcr3();
	lcr3(PADDR(e->env_pgdir));
	if(env_elf->e_magic != ELF_MAGIC){
		panic("elf header's magic is not correct\n");
	}
	ph = (struct Proghdr *)((uint8_t *)env_elf + env_elf->e_phoff);
	eph = ph + env_elf->e_phnum;
	
	for( ; ph < eph; ph++){
		if(ph->p_type == ELF_PROG_LOAD){
			segment_alloc(e, (void *)ph->p_va, ph->p_memsz);
			// cprintf("load_icode segment_alloc succeeded!\n");
			memset((void *)ph->p_va, 0, ph->p_memsz);
			memmove((void*)ph->p_va, (void *)((uint32_t) env_elf + ph->p_offset), ph->p_filesz);
		}
	}
	// cprintf("load_icode while loop succeeded!\n");
	e->env_tf.tf_eip = env_elf->e_entry;
	// cprintf("load_icode program entry point: %x\n", elf->e_entry);

	// Now map one page for the program's initial stack
	// at virtual address USTACKTOP - PGSIZE.

	// LAB 3: Your code here.
	if(page_alloc(&pg) != 0){
		panic("load_icode page_alloc fail!!!\n");
	}
	if(page_insert(e->env_pgdir, pg, (void *)(USTACKTOP - PGSIZE), PTE_U|PTE_W) != 0){
		panic("load_icode page_insert fail!!!\n");
	}

	lcr3(old_cr3);
	//cprintf("load_icode success!\n");
}
Esempio n. 21
0
void screen_pintar_info_debug(uint eax,
                              uint ebx,
                              uint ecx,
                              uint edx,
                              uint esi,
                              uint edi,
                              uint ebp,
                              uint cs,
                              uint ds,
                              uint fs,
                              uint gs,
                              uint ss,
                              uint eflags,
                              uint esp,
                              uint eip,
                              uint stack0,
                              uint stack1,
                              uint stack2,
                              uint stack3,
                              uint stack4){
    screen_guardar_atras_debug();

    screen_pintar_rect(' ', C_BG_BLACK, POSICION_CUADRO_DEBUG_Y, POSICION_CUADRO_DEBUG_X, ALTO_CUADRO_DEBUG, ANCHO_CUADRO_DEBUG);
    screen_pintar_rect(' ', C_BG_RED, POSICION_CUADRO_DEBUG_Y + 1, POSICION_CUADRO_DEBUG_X + 1, ALTO_BANDA_DEBUG, ANCHO_CUADRO_DEBUG - 2);
    screen_pintar_rect(' ', C_BG_LIGHT_GREY, POSICION_CUADRO_DEBUG_Y + 1 + ALTO_BANDA_DEBUG, POSICION_CUADRO_DEBUG_X + 1, ALTO_CUADRO_DEBUG - ALTO_BANDA_DEBUG - 2, ANCHO_CUADRO_DEBUG - 2);

    print("eax", POSICION_CUADRO_DEBUG_X + 2, POSICION_CUADRO_DEBUG_Y + 3, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(eax, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 3, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("ebx", POSICION_CUADRO_DEBUG_X + 2, POSICION_CUADRO_DEBUG_Y + 5, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(ebx, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 5, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("ecx", POSICION_CUADRO_DEBUG_X + 2, POSICION_CUADRO_DEBUG_Y + 7, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(ecx, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 7, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("edx", POSICION_CUADRO_DEBUG_X + 2, POSICION_CUADRO_DEBUG_Y + 9, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(edx, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 9, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("esi", POSICION_CUADRO_DEBUG_X + 2, POSICION_CUADRO_DEBUG_Y + 11, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(esi, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 11, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("edi", POSICION_CUADRO_DEBUG_X + 2, POSICION_CUADRO_DEBUG_Y + 13, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(edi, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 13, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("ebp", POSICION_CUADRO_DEBUG_X + 2, POSICION_CUADRO_DEBUG_Y + 15, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(ebp, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 15, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("esp", POSICION_CUADRO_DEBUG_X + 2, POSICION_CUADRO_DEBUG_Y + 17, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(esp, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 17, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("eip", POSICION_CUADRO_DEBUG_X + 2, POSICION_CUADRO_DEBUG_Y + 19, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(eip, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 19, C_BG_LIGHT_GREY | C_FG_WHITE);


    print("cs", POSICION_CUADRO_DEBUG_X + 3, POSICION_CUADRO_DEBUG_Y + 21, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(cs, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 21, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("ds", POSICION_CUADRO_DEBUG_X + 3, POSICION_CUADRO_DEBUG_Y + 23, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(ds, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 23, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("fs", POSICION_CUADRO_DEBUG_X + 3, POSICION_CUADRO_DEBUG_Y + 25, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(fs, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 25, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("gs", POSICION_CUADRO_DEBUG_X + 3, POSICION_CUADRO_DEBUG_Y + 27, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(gs, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 27, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("ss", POSICION_CUADRO_DEBUG_X + 3, POSICION_CUADRO_DEBUG_Y + 29, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(ss, 8, POSICION_CUADRO_DEBUG_X + 6, POSICION_CUADRO_DEBUG_Y + 29, C_BG_LIGHT_GREY | C_FG_WHITE);


    print("eflags", POSICION_CUADRO_DEBUG_X + 3, POSICION_CUADRO_DEBUG_Y + 31, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(eflags, 8, POSICION_CUADRO_DEBUG_X + 10, POSICION_CUADRO_DEBUG_Y + 31, C_BG_LIGHT_GREY | C_FG_WHITE);


    print("cr0", POSICION_CUADRO_DEBUG_X + 16, POSICION_CUADRO_DEBUG_Y + 3, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(rcr0(), 8, POSICION_CUADRO_DEBUG_X + 20, POSICION_CUADRO_DEBUG_Y + 3, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("cr2", POSICION_CUADRO_DEBUG_X + 16, POSICION_CUADRO_DEBUG_Y + 5, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(rcr2(), 8, POSICION_CUADRO_DEBUG_X + 20, POSICION_CUADRO_DEBUG_Y + 5, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("cr3", POSICION_CUADRO_DEBUG_X + 16, POSICION_CUADRO_DEBUG_Y + 7, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(rcr3(), 8, POSICION_CUADRO_DEBUG_X + 20, POSICION_CUADRO_DEBUG_Y + 7, C_BG_LIGHT_GREY | C_FG_WHITE);

    print("cr4", POSICION_CUADRO_DEBUG_X + 16, POSICION_CUADRO_DEBUG_Y + 9, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(rcr4(), 8, POSICION_CUADRO_DEBUG_X + 20, POSICION_CUADRO_DEBUG_Y + 9, C_BG_LIGHT_GREY | C_FG_WHITE);


    print("stack", POSICION_CUADRO_DEBUG_X + 16, POSICION_CUADRO_DEBUG_Y + 20, C_BG_LIGHT_GREY | C_FG_BLACK);
    print_hex(stack0, 8, POSICION_CUADRO_DEBUG_X + 16, POSICION_CUADRO_DEBUG_Y + 23, C_BG_LIGHT_GREY | C_FG_WHITE);
    print_hex(stack1, 8, POSICION_CUADRO_DEBUG_X + 16, POSICION_CUADRO_DEBUG_Y + 24, C_BG_LIGHT_GREY | C_FG_WHITE);
    print_hex(stack2, 8, POSICION_CUADRO_DEBUG_X + 16, POSICION_CUADRO_DEBUG_Y + 25, C_BG_LIGHT_GREY | C_FG_WHITE);
    print_hex(stack3, 8, POSICION_CUADRO_DEBUG_X + 16, POSICION_CUADRO_DEBUG_Y + 26, C_BG_LIGHT_GREY | C_FG_WHITE);
    print_hex(stack4, 8, POSICION_CUADRO_DEBUG_X + 16, POSICION_CUADRO_DEBUG_Y + 27, C_BG_LIGHT_GREY | C_FG_WHITE);
}
int
acpi_sleep_machdep(struct acpi_softc *sc, int state)
{
	struct savefpu	*stopfpu;
#ifdef SMP
	cpumask_t	wakeup_cpus;
#endif
	register_t	cr3, rf;
	ACPI_STATUS	status;
	int		ret;

	ret = -1;

	if (sc->acpi_wakeaddr == 0ul)
		return (ret);

#ifdef SMP
	wakeup_cpus = PCPU_GET(other_cpus);
#endif

	AcpiSetFirmwareWakingVector(WAKECODE_PADDR(sc));

	rf = intr_disable();
	intr_suspend();

	/*
	 * Temporarily switch to the kernel pmap because it provides
	 * an identity mapping (setup at boot) for the low physical
	 * memory region containing the wakeup code.
	 */
	cr3 = rcr3();
	load_cr3(KPML4phys);

	stopfpu = &stopxpcbs[0].xpcb_pcb.pcb_save;
	if (acpi_savecpu(&stopxpcbs[0])) {
		fpugetregs(curthread, stopfpu);

#ifdef SMP
		if (wakeup_cpus != 0 && suspend_cpus(wakeup_cpus) == 0) {
			device_printf(sc->acpi_dev,
			    "Failed to suspend APs: CPU mask = 0x%jx\n",
			    (uintmax_t)(wakeup_cpus & ~stopped_cpus));
			goto out;
		}
#endif

		WAKECODE_FIXUP(resume_beep, uint8_t, (acpi_resume_beep != 0));
		WAKECODE_FIXUP(reset_video, uint8_t, (acpi_reset_video != 0));

		WAKECODE_FIXUP(wakeup_xpcb, struct xpcb *, &stopxpcbs[0]);
		WAKECODE_FIXUP(wakeup_gdt, uint16_t,
		    stopxpcbs[0].xpcb_gdt.rd_limit);
		WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t,
		    stopxpcbs[0].xpcb_gdt.rd_base);
		WAKECODE_FIXUP(wakeup_cpu, int, 0);

		/* Call ACPICA to enter the desired sleep state */
		if (state == ACPI_STATE_S4 && sc->acpi_s4bios)
			status = AcpiEnterSleepStateS4bios();
		else
			status = AcpiEnterSleepState(state);

		if (status != AE_OK) {
			device_printf(sc->acpi_dev,
			    "AcpiEnterSleepState failed - %s\n",
			    AcpiFormatException(status));
			goto out;
		}

		for (;;)
			ia32_pause();
	} else {
Esempio n. 23
0
File: loader.c Progetto: emancu/pso
uint_32 sys_fork(uint_32 org_eip, uint_32 org_esp) {
  //me guardo el cr3 viejo.
  uint_32 old_cr3 = rcr3();
  printf(" >sys_fork: org_eip (%x), org_esp (%x)", org_eip, org_esp);

  //pido un directorio para la nueva tarea
  void* new_cr3 = mm_dir_fork((mm_page*) old_cr3);
  if (new_cr3 == NULL) { //No pudo hacerse fork de la estrucutra de paginación
    printf("! >sys_fork: no se pudo crear el directorio de la nueva tarea");
    return -1;
  }

  printf(" >sys_fork: new_cr3 = %x", new_cr3);
   //stacks de anillo 3 y 0 para la tarea
  void* task_stack3 = mm_mem_alloc();
  void* task_stack0 = mm_mem_alloc();
  printf(" >sys_fork: paginas stack_ kernel %x | usr %x", task_stack0, task_stack3);

  //ver esto donde van mapeados los stacks
  mm_page_map(STACK_3_VIRTUAL, new_cr3, (uint_32) task_stack3, 0, USR_STD_ATTR);
  mm_page_map(STACK_0_VIRTUAL, new_cr3, (uint_32) task_stack0, 0, MM_ATTR_RW | MM_ATTR_US_S);

  //TODO ver estas direcciones temporales donde ponerlas
  mm_page_map(KERNEL_TEMP_PAGE,(mm_page *) old_cr3, (uint_32) task_stack0, 0, MM_ATTR_RW | MM_ATTR_US_S);

  //inicializamos la pila de nivel 0 para que tenga el contexto para
  //poder volver del switchto
  uint_32* stack0 = (uint_32*) (KERNEL_TEMP_PAGE + 0xffC);
  *stack0-- = 0x23;
  *stack0-- = org_esp;
  *stack0-- = 0x202;
  *stack0-- = 0x1B;
  *stack0-- = org_eip;
  *stack0-- = (uint_32) &fork_ret;
  *stack0-- = resp();
  *stack0-- = 0x0;
  *stack0-- = 0x0;
  *stack0-- = 0x0;

  //Copio la pila de usuario como está //Innecesario, ya lo hace el fork
  mm_copy_vf((uint_32*)STACK_3_VIRTUAL, (uint_32)task_stack3, PAGE_SIZE);


  mm_page_free(KERNEL_TEMP_PAGE, (mm_page*) old_cr3);
  tlbflush();


  //tengo que armar la estructura de proceso
  uint_32 requested_pid = get_new_pid();
  task_table[requested_pid].cr3 = (uint_32) new_cr3;
  task_table[requested_pid].esp0 = STACK_0_VIRTUAL + 0xFD8;

  //Duplico los file descriptor actualizando referencias
  device_fork_descriptors(cur_pid, requested_pid);


  // esto esta mal.. tiene q decidir q numero devolver creo q necesitamos un semaforo!
  sched_load(requested_pid);
  tasks_running++;

  printf(" >sys_fork: forkeo finalizado en pid %d", requested_pid);
  mm_dump();
  return requested_pid;
}
Esempio n. 24
0
File: loader.c Progetto: emancu/pso
pid loader_load(pso_file* f, int pl) {


  //me guardo el cr3 viejo.
  uint_32 old_cr3 = rcr3();

  //pido un directorio para la nueva tarea
  void* task_dir = mm_dir_new();
  printf(" >loader_load: task_dir = %x", task_dir);

  //TODO VER CUANTA MEMORIA NECESITA REALMENTE
  void* puntero_page_tarea = mm_mem_alloc();
  printf(" >loader_load: puntero page tarea : %x", (uint_32) puntero_page_tarea);

  //stacks de anillo 3 y 0 para la tarea
  void* task_stack3 = mm_mem_alloc();
  void* task_stack0 = mm_mem_alloc();

  printf(" >loader_load: pfi after allocs: kernel = %x | usr = %x", *kernel_pf_info, *usr_pf_info);

  //ver esto donde van mapeados los stacks
  mm_page_map(STACK_3_VIRTUAL, task_dir, (uint_32) task_stack3, 0, USR_STD_ATTR);
  mm_page_map(STACK_0_VIRTUAL, task_dir, (uint_32) task_stack0, 0, MM_ATTR_RW | MM_ATTR_US_S);

  //TODO ver estas direcciones temporales donde ponerlas
  mm_page_map(KERNEL_TEMP_PAGE,(mm_page *) old_cr3, (uint_32) task_stack0, 0, MM_ATTR_RW | MM_ATTR_US_S);

  //inicializamos la pila de nivel 0 para que tenga el contexto para
  //poder volver del switchto
  uint_32* stack0 = (uint_32*) (KERNEL_TEMP_PAGE + 0xffC);
  *stack0-- = 0x23;
  *stack0-- = STACK_3_VIRTUAL + 0x1000;
  *stack0-- = 0x202;
  *stack0-- = (pl)? 0x1B : 0x08; //Elijo el selector de segmento según el privilegio de la tarea
  *stack0-- = (uint_32) f->_main;
  *stack0-- = (uint_32) &task_ret;
  *stack0-- = resp();
  *stack0-- = 0x0;
  *stack0-- = 0x0;
  *stack0-- = 0x0;

  mm_page_map((uint_32) f->mem_start, task_dir, (uint_32) puntero_page_tarea, 0, USR_STD_ATTR);

  //mapeo la direccion virtual temporal para copiar en la pagina que recien se me asigno.
  mm_page_map((uint_32) KERNEL_TEMP_PAGE,(mm_page *) old_cr3, (uint_32) puntero_page_tarea, 0, USR_STD_ATTR);
  tlbflush();


  //copio la tarea desde donde esta a la pagina que acabo de mapear.
  uint_8* addr_to_copy = (uint_8*) KERNEL_TEMP_PAGE;
  uint_8* task_to_copy = (uint_8*) f;
  uint_32 cant_to_copy = f->mem_end_disk - f->mem_start;
  int i;

  printf(" >loader_load: task_to_copy = %x", task_to_copy);

  for (i = 0; i < cant_to_copy; i++) {
    *addr_to_copy++ = *task_to_copy++;
  }


  //tengo que armar la estreuctura
  uint_32 requested_pid = get_new_pid();
  task_table[requested_pid].cr3 = (uint_32) task_dir;
  task_table[requested_pid].esp0 = STACK_0_VIRTUAL + 0xFD8;

  mm_page_free(KERNEL_TEMP_PAGE, (mm_page *) old_cr3);
  tlbflush();

  sched_load(requested_pid);

  tasks_running++;
  printf(" >loader_load: finished loading to new pid %d", requested_pid);
  return requested_pid;
}