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__); } }
// 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(); }
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); }
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); }
/* 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); } }
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"); }
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"); } }
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(); }
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; }
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); }
//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; }
// // 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; }
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(); }
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; }
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"); }
/* * 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; }
// // 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; }
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; }
// // 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; }
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"); } }
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); }
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; }
// 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. */ } }
// 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; }
// 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 ); } }
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 } }
// 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); }