Beispiel #1
0
static uint8_t*
vbesetup(Ureg *u, int ax)
{
	// Yes, it's a PA, but it's a real mode PA, and 32 bits are fine.
	uint32_t pa;

	pa = PADDR(RMBUF);
	memset(modebuf, 0, sizeof modebuf);
	memset(u, 0, sizeof *u);
	u->ax = ax;
	u->es = (pa>>4)&0xF000;
	u->di = pa&0xFFFF;
	return modebuf;
}
plugload::plugload(MODULE *module) : residential_enduse(module)
{
	// first time init
	if (oclass==NULL)
	{
		// register the class definition
		oclass = gl_register_class(module,"plugload",sizeof(plugload),PC_BOTTOMUP);
		if (oclass==NULL)
			throw "unable to register class plugload";
		else
			oclass->trl = TRL_QUALIFIED;

		// publish the class properties
		if (gl_publish_variable(oclass,
			PT_INHERIT, "residential_enduse",
			PT_double,"circuit_split",PADDR(circuit_split),
			PT_double,"demand[unit]",PADDR(shape.load),
			PT_double,"installed_power[kW]",PADDR(shape.params.analog.power), PT_DESCRIPTION, "installed plugs capacity",
			PT_complex,"actual_power[kVA]",PADDR(plugs_actual_power),PT_DESCRIPTION,"actual power demand",
			NULL)<1) 
			GL_THROW("unable to publish properties in %s",__FILE__);
	}
}
Beispiel #3
0
// Switch TSS and h/w page table to correspond to process p.
void
switchuvm(struct proc *p)
{
  pushcli();
  cpu->gdt[SEG_TSS] = SEG16(STS_T32A, &cpu->ts, sizeof(cpu->ts)-1, 0);
  cpu->gdt[SEG_TSS].s = 0;
  cpu->ts.ss0 = SEG_KDATA << 3;
  cpu->ts.esp0 = (uint)proc->kstack + KSTACKSIZE;
  ltr(SEG_TSS << 3);
  if(p->pgdir == 0)
    panic("switchuvm: no pgdir");
  lcr3(PADDR(p->pgdir));  // switch to new address space
  popcli();
}
Beispiel #4
0
void
mkmultiboot(void)
{
	MMap *lmmap;

	/* reuse the bios table memory */
	multibootheader = (Mbi *)KADDR(BIOSTABLES);
	memset(multibootheader, 0, sizeof *multibootheader);

	lmmap = (MMap *)(multibootheader + 1);
	memmove(lmmap, mmap, sizeof mmap);

	multibootheader->cmdline = PADDR(BOOTLINE);
	multibootheader->flags |= Fcmdline;
	if(nmmap != 0){
		multibootheader->mmapaddr = PADDR(lmmap);
		multibootheader->mmaplength = nmmap*sizeof(MMap);
		multibootheader->flags |= Fmmap;
	}
	multibootheader = (Mbi *)PADDR(multibootheader);
	if(v_flag)
		print("PADDR(&multibootheader) %#p\n", multibootheader);
}
Beispiel #5
0
void
page_init(void)
{
	int i;
	LIST_INIT (&page_free_list);
	printf("freemem:\t%x\n", freemem);
	freemem = ROUND(freemem, BY2PG);
	printf("freemem:\t%x\n", freemem);

	for (i = 0; i < PADDR(freemem) / BY2PG; i++) {
		pages[i].pp_ref = 1;
	}

	printf("allocated pages:\t%d\n", i - 1);

	for (i = PADDR(freemem) / BY2PG; i < npage; i++) {
		pages[i].pp_ref = 0;
		LIST_INSERT_HEAD(&page_free_list, &pages[i], pp_link);
	}

	printf("free pages:\t%d\n", npage - PADDR(freemem) / BY2PG);

}
Beispiel #6
0
/* XXX naive */
static void shootdown_tlb_all(pgd_t *pgdir)
{
	int i;
	//dump_processors();
	for(i=0;i<sysconf.lcpu_count;i++){
		struct cpu *cpu = per_cpu_ptr(cpus, i);
		if(cpu->id == myid())
			continue;
		if(cpu->arch_data.tlb_cr3 != PADDR(pgdir))
			continue;
		//kprintf("XX_TLB_SHUTDOWN %d %d\n", myid(), i);
		lapic_send_ipi(cpu, T_TLBFLUSH);
	}
}
Beispiel #7
0
static void
check_boot_pgdir(void) {
    pte_t *ptep;
    int i;
    for (i = 0; i < npage; i += PGSIZE) {
        assert((ptep = get_pte(boot_pgdir, (uintptr_t)KADDR(i), 0)) != NULL);
        assert(PTE_ADDR(*ptep) == i);
    }


    assert(PDE_ADDR(boot_pgdir[PDX(VPT)]) == PADDR(boot_pgdir));
    //cprintf("%08x\n",boot_pgdir[PDX(VPT)]);
    //cprintf("%08x\n",PADDR(boot_pgdir));

    assert(boot_pgdir[256] == 0);

    struct Page *p;

    p = alloc_page();

    assert(page_insert(boot_pgdir, p, 0x40000100, PTE_TYPE_SRW) == 0);
    assert(page_ref(p) == 1);
    assert(page_insert(boot_pgdir, p, 0x40000100 + PGSIZE, PTE_TYPE_SRW) == 0);
    assert(page_ref(p) == 2);

    const char *str = "ucore: Hello world!!";

    strcpy((void *)0x40000100, str);
    assert(strcmp((void *)0x40000100, (void *)(0x40000100 + PGSIZE)) == 0);
    cprintf("%s\n\n",(char*)0x40000100);
    //cprintf("mstatus=%08x\n",read_mstatus_field(MSTATUS_PRV));
//    cprintf("bageyalusilasiladi%s\n",((char*)0x40000100));
    *(char *)(page2kva(p) + 0x100) = '\0';
    //asm volatile("nop");
    //asm volatile("nop");
    //cprintf("\0\n");
 //   cprintf("%d\n",strlen((char *)0x40000100));
    assert(strlen((const char *)0x40000100) == 0);
    //assert(((const char *)0x30000100) == '\0');

    //asm volatile("nop");
//    asm volatile("nop");
    free_page(p);
    free_page(pde2page(boot_pgdir[256]));
    //cprintf("haah2\n");

    boot_pgdir[256] = 0;

    cprintf("check_boot_pgdir() succeeded!\n");
}
Beispiel #8
0
static void
sdioiosetup(int write, void *buf, int bsize, int bcount)
{
	int len;
	uintptr pa;

	pa = PADDR(buf);
	if(write && !PIOwrite){
		WR(DmaLSB, pa);
		WR(DmaMSB, pa>>16);
		len = bsize * bcount;
		cachedwbse(buf, len);
		l2cacheuwbse(buf, len);
	}else if(!write && !PIOread){
series_reactor::series_reactor(MODULE *mod) : link_object(mod)
{
	if(oclass == NULL)
	{
		pclass = link_object::oclass;

		oclass = gl_register_class(mod,"series_reactor",sizeof(series_reactor),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT|PC_AUTOLOCK);
		if (oclass==NULL)
			throw "unable to register class series_reactor";
		else
			oclass->trl = TRL_PROVEN;

        if(gl_publish_variable(oclass,
			PT_INHERIT, "link",
			PT_complex, "phase_A_impedance[Ohm]",PADDR(phase_A_impedance),PT_DESCRIPTION,"Series impedance of reactor on phase A",
			PT_double, "phase_A_resistance[Ohm]",PADDR(phase_A_impedance.Re()),PT_DESCRIPTION,"Resistive portion of phase A's impedance",
			PT_double, "phase_A_reactance[Ohm]",PADDR(phase_A_impedance.Im()),PT_DESCRIPTION,"Reactive portion of phase A's impedance",
			PT_complex, "phase_B_impedance[Ohm]",PADDR(phase_B_impedance),PT_DESCRIPTION,"Series impedance of reactor on phase B",
			PT_double, "phase_B_resistance[Ohm]",PADDR(phase_B_impedance.Re()),PT_DESCRIPTION,"Resistive portion of phase B's impedance",
			PT_double, "phase_B_reactance[Ohm]",PADDR(phase_B_impedance.Im()),PT_DESCRIPTION,"Reactive portion of phase B's impedance",
			PT_complex, "phase_C_impedance[Ohm]",PADDR(phase_C_impedance),PT_DESCRIPTION,"Series impedance of reactor on phase C",
			PT_double, "phase_C_resistance[Ohm]",PADDR(phase_C_impedance.Re()),PT_DESCRIPTION,"Resistive portion of phase C's impedance",
			PT_double, "phase_C_reactance[Ohm]",PADDR(phase_C_impedance.Im()),PT_DESCRIPTION,"Reactive portion of phase C's impedance",
			PT_double, "rated_current_limit[A]",PADDR(rated_current_limit),PT_DESCRIPTION,"Rated current limit for the reactor",
            NULL) < 1) GL_THROW("unable to publish properties in %s",__FILE__);

		//Publish deltamode functions
		if (gl_publish_function(oclass,	"interupdate_pwr_object", (FUNCTIONADDR)interupdate_link)==NULL)
			GL_THROW("Unable to publish series reactor deltamode function");

		//Publish restoration-related function (current update)
		if (gl_publish_function(oclass,	"update_power_pwr_object", (FUNCTIONADDR)updatepowercalc_link)==NULL)
			GL_THROW("Unable to publish series reactor external power calculation function");
		if (gl_publish_function(oclass,	"check_limits_pwr_object", (FUNCTIONADDR)calculate_overlimit_link)==NULL)
			GL_THROW("Unable to publish series reactor external power limit calculation function");
    }
}
Beispiel #10
0
void
meminit(u32int)
{
	MMap *map;
	u32int modend;
	u64int addr, last, len;

	umbscan();

	modend = PADDR(memstart);
	last = 0;
	for(map = mmap; map < &mmap[nmmap]; map++){
		addr = (((u64int)map->base[1])<<32)|map->base[0];
		len = (((u64int)map->length[1])<<32)|map->length[0];

		switch(map->type){
		default:
		case 2:				/* reserved */
		case 3:				/* ACPI Reclaim Memory */
		case 4:				/* ACPI NVS Memory */
			break;
		case 1:				/* Memory */
			if(addr < 1*MiB || addr+len < modend)
				break;
			if(addr < modend){
				len -= modend - addr;
				addr = modend;
			}
			mapraminit(addr, len);
			break;
		}

		if(addr != last && addr > modend){
			/*
			 * See the comments in main about space < 1MiB.
			 */
			if(addr >= 1*MiB || addr < 0x000A0000)
				mapupainit(last, addr-last);
		}
		last = addr+len;
	}

	/*
	changeconf("*noe820scan=1\n");
	 */

	if(MEMDEBUG)
		memdebug();
}
Beispiel #11
0
static Page*
mmuptpalloc(void)
{
    void* va;
    Page *page;

    /*
     * Do not really need a whole Page structure,
     * but it makes testing this out a lot easier.
     * Could keep a cache and free excess.
     * Have to maintain any fiction for pexit?
     */
    lock(&mmuptpfreelist.l);
    if((page = mmuptpfreelist.next) != nil) {
        mmuptpfreelist.next = page->next;
        mmuptpfreelist.ref--;
        unlock(&mmuptpfreelist.l);

        if(page->ref++ != 0)
            panic("mmuptpalloc ref\n");
        page->prev = page->next = nil;
        memset(UINT2PTR(page->va), 0, PTSZ);

        if(page->pa == 0)
            panic("mmuptpalloc: free page with pa == 0");
        return page;
    }
    unlock(&mmuptpfreelist.l);

    if((page = malloc(sizeof(Page))) == nil) {
        print("mmuptpalloc Page\n");

        return nil;
    }
    if((va = mallocalign(PTSZ, PTSZ, 0, 0)) == nil) {
        print("mmuptpalloc va\n");
        free(page);

        return nil;
    }

    page->va = PTR2UINT(va);
    page->pa = PADDR(va);
    page->ref = 1;

    if(page->pa == 0)
        panic("mmuptpalloc: no pa");
    return page;
}
Beispiel #12
0
void initialize_vm_64(void){
	uint64_t* pml4e;
    pages = boot_alloc(npages*sizeof(struct PageStruct));
    procs = boot_alloc(NPROCS*sizeof(struct ProcStruct)); 
    proc_free_list = procs;

	pml4e = boot_alloc(PGSIZE);
	boot_pml4e = pml4e;
	boot_cr3 = (physaddr_t*)PADDR(pml4e);
	kmemset(boot_pml4e,0,PGSIZE);
         initialize_page_lists();
    printf("Total free=%d",free_pages); 

  //    while(i--);
   if(  map_vm_pm(boot_pml4e, (uint64_t)PHYSBASE,PADDR(PHYSBASE),(uint64_t)(boot_alloc(0)-PHYSBASE),PTE_P|PTE_W)==-1)
       while(1);
   if(  map_vm_pm(boot_pml4e, (uint64_t)KERNBASE+PGSIZE,0x1000,0x7000000-0x1000,PTE_P|PTE_W)==-1)//KERNELSTACK =tss.rspp0       
   while(1);
   if( map_vm_pm(boot_pml4e, (uint64_t)VIDEO_START,PADDR(VIDEO_START),10*0x1000,PTE_P|PTE_W)==-1)
    while(1);
    printf("TotalFREE=%d",free_pages);
   
     lcr3(boot_cr3);
}
Beispiel #13
0
//test function to see if the Tx Buffers are properly linked.
void test_tx_blocks()
{
    uint32_t start = e100_tx_info.tx_buff_va;
    struct command_block * ptrcb;
    int i ;

    cprintf(" base va %x base Pa %x \n",start,PADDR(start));
    cprintf("\n=====================================\n");
    for ( i=0; i < E100_MAX_TX_BUFFERS ; i++)
    {
        ptrcb =(struct command_block * ) (  start + i * PGSIZE  ) ;
        cprintf(" [%d] : status %d , cmd : %d , link : %x \n",i,ptrcb->status,ptrcb->cmd,ptrcb->link);
    }
    cprintf("\n=====================================\n");
}
static int  ohci_rtl8652_init(void)
{
	/*register platform device*/
	int retval;
	//static struct platform_device *usb_dev_host = NULL;

	if(usb_dev_host!=NULL)
	{	printk("Ohci-rtl8652.c: OHCI device already init\n");
		return -1;
	}
	struct resource r[2];
	memset(&r, 0, sizeof(r));

	r[0].start = PADDR(OHCI_RTL8652_USB_BASE);
	r[0].end =  PADDR(OHCI_RTL8652_USB_BASE)+sizeof(struct ohci_regs);
	r[0].flags = IORESOURCE_MEM; 

	r[1].start = r[1].end = RTL8652_USB_IRQ;
	r[1].flags = IORESOURCE_IRQ;

	usb_dev_host = platform_device_register_simple("rtl8652-ohci", 0, r, 2);

	usb_dev_host->dev.coherent_dma_mask = 0xffffffffUL;
       usb_dev_host->dev.dma_mask = &usb_dev_host->dev.coherent_dma_mask;
	
	if (IS_ERR(usb_dev_host)) 
	{
		retval = PTR_ERR(usb_dev_host);
		usb_dev_host=NULL;  //wei add
		goto err;
	}
	
	return 0;
	err:
	return retval;
}
Beispiel #15
0
//
// Frees env e and all memory it uses.
//
void
env_free(struct Env *e)
{
	pde_t *pgdir;
	pte_t *pt;
	uint32_t pdeno, pteno;
	physaddr_t pa;

	// If freeing the current environment, switch to kern_pgdir
	// before freeing the page directory, just in case the page
	// gets reused.
	if (e == curenv)
		lcr3(PADDR(kern_pgdir));

	// Note the environment's demise.
	cprintf("[%08x] free env %08x\n", curenv ? curenv->env_id : 0, e->env_id);

	// Flush all mapped pages in the user portion of the address space
	static_assert(UTOP % PTSIZE == 0);
	pgdir = e->env_pgdir;
	for (pdeno = 0; pdeno < PDX(UTOP); pdeno++) {
		// only look at mapped page tables
		if (!(pgdir[pdeno] & PTE_P))
			continue;

		// find the pa and va of the page table
		pt = (pte_t *) KADDR(PTE_ADDR(pgdir[pdeno]));

		// unmap all PTEs in this page table
		for (pteno = 0; pteno <= PTX(~0); pteno++) {
			if (pt[pteno] & PTE_P)
				page_remove(pgdir, PGADDR(pdeno, pteno, 0));
		}

		// free the page table itself
		pgdir[pdeno] = 0;
		page_decref(kva2page(pt));
	}

	// free the page directory
	e->env_pgdir = 0;
	page_decref(kva2page(pgdir));

	// return the environment to the free list
	e->env_status = ENV_FREE;
	e->env_link = env_free_list;
	env_free_list = e;
}
Beispiel #16
0
void
screeninit(void)
{
	uchar *fb;

	fb = xspanalloc(Dx(xgscreen.r) * Dy(xgscreen.r) * 3, 64, 0);
	print("%p\n", PADDR(fb));
	memsetchan(&xgscreen, BGR24);
	conf.monitor = 1;
	xgdata.bdata = fb;
	xgdata.ref = 1;
	gscreen = &xgscreen;
	gscreen->width = wordsperline(gscreen->r, gscreen->depth);

	memimageinit();
}
Beispiel #17
0
static uintptr*
mmucreate(uintptr *table, uintptr va, int level, int index)
{
	uintptr *page, flags;
	MMU *p;
	
	flags = PTEWRITE|PTEVALID;
	if(va < VMAP){
		assert(up != nil);
		assert((va < TSTKTOP) || (va >= KMAP && va < KMAP+KMAPSIZE));

		p = mmualloc();
		p->index = index;
		p->level = level;
		if(va < TSTKTOP){
			flags |= PTEUSER;
			if(level == PML4E){
				if((p->next = up->mmuhead) == nil)
					up->mmutail = p;
				up->mmuhead = p;
				m->mmumap[index/MAPBITS] |= 1ull<<(index%MAPBITS);
			} else {
				up->mmutail->next = p;
				up->mmutail = p;
			}
			up->mmucount++;
		} else {
			if(level == PML4E){
				up->kmaptail = p;
				up->kmaphead = p;
			} else {
				up->kmaptail->next = p;
				up->kmaptail = p;
			}
			up->kmapcount++;
		}
		page = p->page;
	} else if(conf.mem[0].npage != 0) {
		page = mallocalign(PTSZ, BY2PG, 0, 0);
	} else {
		page = rampage();
	}
	memset(page, 0, PTSZ);
	table[index] = PADDR(page) | flags;
	return page;
}
Beispiel #18
0
void test_rx_blocks()
{
    uint32_t start = e100_rx_info.tx_buff_va;
    struct rfd * ptrrfd;
    int *ptr;
    int i ;

    cprintf(" base va %x base Pa %x \n",start,PADDR(start));
    cprintf("\n=====================================\n");
    for ( i=0; i < E100_MAX_RX_BUFFERS ; i++)
    {
        ptrrfd =(struct rfd * ) (  start + i * PGSIZE  ) ;
        ptr = (int * ) ptrrfd;
        cprintf(" [%d] : status %x , cmd : %x , link : %x  size %x\n",i,ptrrfd->status,ptrrfd->cmd,ptrrfd->link,ptr[3]);
    }
    cprintf("\n=====================================\n");
}
Beispiel #19
0
Datei: cpm.c Projekt: 8l/inferno
/*
 * initialise receive and transmit buffer rings.
 */
int
ioringinit(Ring* r, int nrdre, int ntdre, int bufsize)
{
	int i, x;

	/* the ring entries must be aligned on sizeof(BD) boundaries */
	r->nrdre = nrdre;
	if(r->rdr == nil)
		r->rdr = bdalloc(nrdre);
	/* the buffer size must align with cache lines since the cache doesn't snoop */
	bufsize = (bufsize+CACHELINESZ-1)&~(CACHELINESZ-1);
	if(r->rrb == nil)
		r->rrb = malloc(nrdre*bufsize);
	if(r->rdr == nil || r->rrb == nil)
		return -1;
	dcflush(r->rrb, nrdre*bufsize);
	x = PADDR(r->rrb);
	for(i = 0; i < nrdre; i++){
		r->rdr[i].length = 0;
		r->rdr[i].addr = x;
		r->rdr[i].status = BDEmpty|BDInt;
		x += bufsize;
	}
	r->rdr[i-1].status |= BDWrap;
	r->rdrx = 0;

	r->ntdre = ntdre;
	if(r->tdr == nil)
		r->tdr = bdalloc(ntdre);
	if(r->txb == nil)
		r->txb = malloc(ntdre*sizeof(Block*));
	if(r->tdr == nil || r->txb == nil)
		return -1;
	for(i = 0; i < ntdre; i++){
		r->txb[i] = nil;
		r->tdr[i].addr = 0;
		r->tdr[i].length = 0;
		r->tdr[i].status = 0;
	}
	r->tdr[i-1].status |= BDWrap;
	r->tdrh = 0;
	r->tdri = 0;
	r->ntq = 0;
	return 0;
}
Beispiel #20
0
//
// Initialize page structure and memory free list.
// After this is done, NEVER use boot_alloc again.  ONLY use the page
// allocator functions below to allocate and deallocate physical
// memory via the page_free_list.
//
void
page_init(void)
{
	// LAB 4:
	// Change your code to mark the physical page at MPENTRY_PADDR
	// as in use

	// The example code here marks all physical pages as free.
	// However this is not truly the case.  What memory is free?
	//  1) Mark physical page 0 as in use.
	//     This way we preserve the real-mode IDT and BIOS structures
	//     in case we ever need them.  (Currently we don't, but...)
	//  2) The rest of base memory, [PGSIZE, npages_basemem * PGSIZE)
	//     is free.
	//  3) Then comes the IO hole [IOPHYSMEM, EXTPHYSMEM), which must
	//     never be allocated.
	//  4) Then extended memory [EXTPHYSMEM, ...).
	//     Some of it is in use, some is free. Where is the kernel
	//     in physical memory?  Which pages are already in use for
	//     page tables and other data structures?
	//
	// Change the code to reflect this.
	// NB: DO NOT actually touch the physical memory corresponding to
	// free pages!
	/*size_t i;
	for (i = 0; i < npages; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}*/
	uint32_t page_mp_entry = MPENTRY_PADDR / PGSIZE;
	uint32_t i;
	page_free_list = NULL;
	for (i = 1; i < npages_basemem && i != page_mp_entry; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}
	for (i = PGNUM(PADDR(boot_alloc(0))); i < npages; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}
	chunk_list = NULL;
}
Beispiel #21
0
int receive_packet (void* buffer)
{
	if (!buffer)
		return -E_NIC_RECEIVE;
	// Check if there is a valid packet in the buffer pointed by index ru_ind
	if (check_rfd(&ring_rfd[ru_ind]) == 0)
		return 0;
	// Set count variable as the actual count of bytes in the packet
	// Mask is needed to mask off EOF and F bits
	// Open SDM: Figure 25
	uint16_t count = ring_rfd[ru_ind].actual_count & (~RFD_COUNT_MASK);

	// Copy the "count" no of bytes from "packet_data" to the "buffer"	
	memmove(buffer, ring_rfd[ru_ind].packet_data, count);
	
	// This buffer can be reused now, clear it
	clear_rfd (&ring_rfd[ru_ind]);
	
	// Clear the EL bit in the last buffer, move the "last buffer" index
	ring_rfd[ru_ind_last].cb.cmd &= ~CB_EL;
	ru_ind_last = ru_ind;

	// Move the index ru_ind
	ru_ind = (ru_ind + 1) % RFD_BUFFERS;

	int base = store.reg_base[1]; 		// for I/O Port Base
	uint8_t status =  inb(base);
	status = status & SCBST_RU_MASK;		
	 
	if ((status == SCBST_RU_IDLE))
	{
		// Start the RU
		cprintf("\n Starting the RU");
		outl(base + 0x4, PADDR((uint32_t)&ring_rfd[ru_ind]));
		outw(base + 0x2, SCB_RU_START);	
	} 
	
	if (status ==  SCBST_RU_SUSPENDED)
	{
		// Resume the RU
		outw(base + 0x2, SCB_RU_RESUME);				
	}

	return count;
}	
Beispiel #22
0
Datei: env.c Projekt: gzs715/JOS
//
// Initialize the kernel virtual memory layout for environment e.
// Allocate a page directory, set e->env_pgdir and e->env_cr3 accordingly,
// and initialize the kernel portion of the new environment's address space.
// Do NOT (yet) map anything into the user portion
// of the environment's virtual address space.
//
// Returns 0 on success, < 0 on error.  Errors include:
//	-E_NO_MEM if page directory or table could not be allocated.
//
static int
env_setup_vm(struct Env *e)
{
	int i;
	int r;
	struct Page *p = NULL;
	//cprintf("env begin to set up vm\n");

	// Allocate a page for the page directory
	if ((r = page_alloc(&p)) < 0)
		return r;

	// Now, set e->env_pgdir and e->env_cr3,
	// and initialize the page directory.
	//
	// Hint:
	//    - The VA space of all envs is identical above UTOP
	//      (except at VPT and UVPT, which we've set below).
	//	See inc/memlayout.h for permissions and layout.
	//	Can you use boot_pgdir as a template?  Hint: Yes.
	//	(Make sure you got the permissions right in Lab 2.)
	//    - The initial VA below UTOP is empty.
	//    - You do not need to make any more calls to page_alloc.
	//    - Note: pp_ref is not maintained for most physical pages
	//	mapped above UTOP -- but you do need to increment
	//	env_pgdir's pp_ref!

	// LAB 3: Your code here.
	e->env_pgdir = page2kva(p);
	e->env_cr3 = PADDR(e->env_pgdir);
	memset(e->env_pgdir, 0x0, PGSIZE);
	p->pp_ref++;
	//get all the kernel page table's physical address from boot page directory
	//i.e. in the kernel part, every envs are the same.
	//But below the UTOP, they have their own space
	for(i = UTOP; i < 0xFFFFFFFF; i += PGSIZE)
	       e->env_pgdir[PDX(i)] = boot_pgdir[PDX(i)];	

	// VPT and UVPT map the env's own page table, with
	// different permissions.
	e->env_pgdir[PDX(VPT)]  = e->env_cr3 | PTE_P | PTE_W;
	e->env_pgdir[PDX(UVPT)] = e->env_cr3 | PTE_P | PTE_U;

	return 0;
}
Beispiel #23
0
fuse::fuse(MODULE *mod) : link_object(mod)
{
	if(oclass == NULL)
	{
		pclass = link_object::oclass;
		
		oclass = gl_register_class(mod,"fuse",sizeof(fuse),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT|PC_AUTOLOCK);
		if (oclass==NULL)
			throw "unable to register class fuse";
		else
			oclass->trl = TRL_QUALIFIED;
        
        if(gl_publish_variable(oclass,
			PT_INHERIT, "link",
			PT_enumeration, "phase_A_status", PADDR(phase_A_state),
				PT_KEYWORD, "BLOWN", (enumeration)BLOWN,
				PT_KEYWORD, "GOOD", (enumeration)GOOD,
			PT_enumeration, "phase_B_status", PADDR(phase_B_state),
				PT_KEYWORD, "BLOWN", (enumeration)BLOWN,
				PT_KEYWORD, "GOOD", (enumeration)GOOD,
			PT_enumeration, "phase_C_status", PADDR(phase_C_state),
				PT_KEYWORD, "BLOWN", (enumeration)BLOWN,
				PT_KEYWORD, "GOOD", (enumeration)GOOD,
			PT_enumeration, "repair_dist_type", PADDR(restore_dist_type),
				PT_KEYWORD, "NONE", (enumeration)NONE,
				PT_KEYWORD, "EXPONENTIAL", (enumeration)EXPONENTIAL,
			PT_double, "current_limit[A]", PADDR(current_limit),
			PT_double, "mean_replacement_time[s]",PADDR(mean_replacement_time),	//Retains compatibility with older files
			PT_double, "fuse_resistance[Ohm]",PADDR(fuse_resistance), PT_DESCRIPTION,"The resistance value of the fuse when it is not blown.",
			NULL) < 1) GL_THROW("unable to publish properties in %s",__FILE__);

		if (gl_publish_function(oclass,"change_fuse_state",(FUNCTIONADDR)change_fuse_state)==NULL)
			GL_THROW("Unable to publish fuse state change function");
		if (gl_publish_function(oclass,"reliability_operation",(FUNCTIONADDR)fuse_reliability_operation)==NULL)
			GL_THROW("Unable to publish fuse reliability operation function");
		if (gl_publish_function(oclass,	"create_fault", (FUNCTIONADDR)create_fault_fuse)==NULL)
			GL_THROW("Unable to publish fault creation function");
		if (gl_publish_function(oclass,	"fix_fault", (FUNCTIONADDR)fix_fault_fuse)==NULL)
			GL_THROW("Unable to publish fault restoration function");
		if (gl_publish_function(oclass,	"change_fuse_faults", (FUNCTIONADDR)fuse_fault_updates)==NULL)
			GL_THROW("Unable to publish fuse fault correction function");

		//Publish deltamode functions
		if (gl_publish_function(oclass,	"interupdate_pwr_object", (FUNCTIONADDR)interupdate_link)==NULL)
			GL_THROW("Unable to publish fuse deltamode function");
    }
}
Beispiel #24
0
static int
readedata(Boot *b)
{
	Phdr *php;

	php = phdr+curphdr;
	if(debug)
		print("readedata %d\n", curphdr);
	if(php->filesz < php->memsz){
		print("%lud",  php->memsz-php->filesz);
		elftotal += php->memsz-php->filesz;
		memset((char*)(PADDR(php->paddr)+php->filesz), 0, php->memsz-php->filesz);
	}
	curoff = php->offset+php->filesz;
	curphdr++;

	return nextphdr(b);
}
Beispiel #25
0
int
setupt_proc_vm(ProcStruct* NewProc)
{
    PageStruct* pa=allocate_page();
    if(!pa)
        return 0;
     NewProc->pml4e=(uint64_t*)KADDR(pageToPhysicalAddress(pa));
    //printf("userpml4=%p",NewProc->pml4e);
    NewProc->cr3 = (physaddr_t*)PADDR(NewProc->pml4e);
    
    /*
    CHANGE THIS LATER. SET extries at indexes less than UTOP to 0
    */
    NewProc->pml4e[PML4(PHYSBASE)]=boot_pml4e[PML4(PHYSBASE)];
    NewProc->pml4e[PML4(VIDEO_START)]=boot_pml4e[PML4(VIDEO_START)];
        
    return 1;
}
Beispiel #26
0
// the constructor registers the class and properties and sets the defaults
network::network(MODULE *mod) 
{
	// first time init
	if (oclass==NULL)
	{
		// register the class definition
		oclass = gl_register_class(mod,"network",sizeof(network),PC_BOTTOMUP);
		if (oclass==NULL)
			GL_THROW("unable to register object class implemented by %s",__FILE__);
			/* TROUBLESHOOT
				The registration for the network class failed.   This is usually caused
				by a coding error in the core implementation of classes or the module implementation.
				Please report this error to the developers.
			 */

		// publish the class properties
		if (gl_publish_variable(oclass,
			//PT_loadshape,"shape",PADDR(shape),
			PT_double, "latency[s]", PADDR(latency),
			PT_char32, "latency_mode", PADDR(latency_mode),
			PT_double, "latency_period[s]", PADDR(latency_period),
			PT_double, "latency_arg1", PADDR(latency_arg1),
			PT_double, "latency_arg2", PADDR(latency_arg2),
			PT_double, "bandwidth[MB/s]", PADDR(bandwidth),
			PT_enumeration, "queue_resolution", PADDR(queue_resolution),
				PT_KEYWORD, "REJECT", QR_REJECT,
				PT_KEYWORD, "QUEUE", QR_QUEUE,
			PT_double, "buffer_size[MB]", PADDR(buffer_size),
			PT_double, "bandwidth_used[MB/s]", PADDR(bandwidth_used), PT_ACCESS, PA_REFERENCE,
			NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
			/* TROUBLESHOOT
				The registration for the network properties failed.   This is usually caused
				by a coding error in the core implementation of classes or the module implementation.
				Please report this error to the developers.
			 */
	}
}
Beispiel #27
0
// Allocate memory to the process to bring its size from oldsz to
// newsz. Allocates physical memory and page table entries. oldsz and
// newsz need not be page-aligned, nor does newsz have to be larger
// than oldsz.  Returns the new process size or 0 on error.
int
allocuvm(pde_t *pgdir, uint oldsz, uint newsz)
{
  if(newsz > USERTOP)
    return 0;
  char *a = (char *)PGROUNDUP(oldsz);
  char *last = PGROUNDDOWN(newsz - 1);
  for (; a <= last; a += PGSIZE){
    char *mem = kalloc();
    if(mem == 0){
      cprintf("allocuvm out of memory\n");
      deallocuvm(pgdir, newsz, oldsz);
      return 0;
    }
    memset(mem, 0, PGSIZE);
    mappages(pgdir, a, PGSIZE, PADDR(mem), PTE_W|PTE_U);
  }
  return newsz > oldsz ? newsz : oldsz;
}
Beispiel #28
0
// Modify mappings in kern_pgdir to support SMP
//   - Map the per-CPU stacks in the region [KSTACKTOP-PTSIZE, KSTACKTOP)
//
static void
mem_init_mp(void)
{
	// Map per-CPU stacks starting at KSTACKTOP, for up to 'NCPU' CPUs.
	//
	// For CPU i, use the physical memory that 'percpu_kstacks[i]' refers
	// to as its kernel stack. CPU i's kernel stack grows down from virtual
	// address kstacktop_i = KSTACKTOP - i * (KSTKSIZE + KSTKGAP), and is
	// divided into two pieces, just like the single stack you set up in
	// mem_init:
	//     * [kstacktop_i - KSTKSIZE, kstacktop_i)
	//          -- backed by physical memory
	//     * [kstacktop_i - (KSTKSIZE + KSTKGAP), kstacktop_i - KSTKSIZE)
	//          -- not backed; so if the kernel overflows its stack,
	//             it will fault rather than overwrite another CPU's stack.
	//             Known as a "guard page".
	//     Permissions: kernel RW, user NONE
	//
	// LAB 4: Your code here:

    int i = 0;
    for ( ; i < NCPU; i++) {
        // For each cpu, map the space described above but subtract
        // KSTKSIZE because it grows down and we need the start from bottom
        boot_map_region(
                kern_pgdir, 
                KSTACKTOP - i * (KSTKSIZE + KSTKGAP) - KSTKSIZE, 
                KSTKSIZE, 
                PADDR(percpu_kstacks[i]),
                PTE_P | PTE_W
                );

        // Map this region that is not backed by phsyical memory
        boot_map_region(
                kern_pgdir, 
                KSTACKTOP - i * (KSTKSIZE + KSTKGAP) - KSTKSIZE - KSTKGAP, 
                KSTKGAP, 
                0,
                0
                );
    }

}
Beispiel #29
0
fuse::fuse(MODULE *mod) : link(mod)
{
	// first time init
	if (oclass==NULL)
	{
		// register the class definition
		fuse_class = oclass = gl_register_class(mod,"fuse",sizeof(fuse),PC_BOTTOMUP);
		if (oclass==NULL)
			throw "unable to register class fuse";
		else
			oclass->trl = TRL_STANDALONE;

		// publish the class properties
		if (gl_publish_variable(oclass,
			PT_double, "TimeConstant", PADDR(TimeConstant),
			PT_double, "SetCurrent", PADDR(SetCurrent),
			PT_double, "SetBase", PADDR(SetBase),
			PT_double, "SetScale", PADDR(SetScale),
			PT_double, "SetCurve", PADDR(SetCurve),
			PT_double, "TresetAvg", PADDR(TresetAvg),
			PT_double, "TresetStd", PADDR(TresetStd),
			PT_enumeration,"State",PADDR(State),
				PT_KEYWORD,"FS_GOOD",FS_GOOD,
				PT_KEYWORD,"FS_BLOWN",FS_BLOWN,
				PT_KEYWORD,"FS_FAULT",FS_FAULT,
			NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);

		// setup the default values
		defaults = this;
		Y = 100;			// no effective resistance
		TimeConstant = 1.0;	// equivalent to SEL551 TimeDial setting
		SetCurrent = 1000;	// amps above which fusing occurs
		SetBase = 0.05;		// roughly like a SEL551 U3 relay
		SetScale = 4.0;		// roughly like a SEL551 U3 relay
		SetCurve = 2;		// roughly like a SEL551 U3 relay
		TresetAvg = 3600*4;	// about 4 hours avg
		TresetStd = 3600;	// about 1 hours stdev
		State = FS_GOOD;	// fuse state
	}
}
Beispiel #30
0
// Free env e and all memory it uses.
void
env_free(struct Env *e)
{
	pte_t *pt;
	uint32_t pdeno, pteno;
	physaddr_t pa;

	// Note the environment's demise.
	cprintf("[%08x] free env %08x\n", curenv ? curenv->env_id : 0, e->env_id);

	// Flush all mapped pages in the user portion of the address space
	static_assert(UTOP % PTSIZE == 0);
	for (pdeno = 0; pdeno < PDX(UTOP); pdeno++) {

		// only look at mapped page tables
		if (!(e->env_pgdir[pdeno] & PTE_P))
			continue;

		// find the pa and va of the page table
		pa = PTE_ADDR(e->env_pgdir[pdeno]);
		pt = (pte_t*) KADDR(pa);

		// unmap all PTEs in this page table
		for (pteno = 0; pteno <= PTX(~0); pteno++) {
			if (pt[pteno] & PTE_P)
				page_remove(e->env_pgdir, PGADDR(pdeno, pteno, 0));
		}

		// free the page table itself
		e->env_pgdir[pdeno] = 0;
		page_decref(pa2page(pa));
	}

	// free the page directory
	pa = PADDR(e->env_pgdir);
	e->env_pgdir = 0;
	page_decref(pa2page(pa));

	// return the environment to the free list
	e->env_status = ENV_FREE;
	LIST_INSERT_HEAD(&env_free_list, e, env_link);
}