/** * Initializes memory mirror. * * Memory mirror allocates all available ram to specific range address. * If 1GB paging is supported, 1GB paging is used, otherwise only 4KB * paging is used, which means much more physical ram is used. */ void initialize_memory_mirror() { section_info_t* head = frame_pool; frame_pool = NULL; bool first_set = false; if (is_1GB_paging_supported() != 0) { for (puint_t start=0; start < maxram; start+=1<<30) { puint_t vaddress = start + ADDRESS_OFFSET(RESERVED_KBLOCK_RAM_MAPPINGS); v_address_t va; memcpy(&va, &vaddress, 8); puint_t* pml4 = (puint_t*)ALIGN(physical_to_virtual(get_active_page())); if (!PRESENT(pml4[va.pml])) { pdpt_t pdpt; memset(&pdpt, 0, sizeof(pdpt_t)); pdpt.number = get_free_frame(); pdpt.flaggable.present = 1; pdpt.flaggable.us = 0; pdpt.flaggable.rw = 1; pml4[va.pml] = pdpt.number; memset((void*)physical_to_virtual(ALIGN(pdpt.number)), 0, 0x1000); } puint_t* pdpt = (puint_t*)ALIGN(physical_to_virtual(pml4[va.pml])); page_directory1GB_t dir; memset(&dir, 0, sizeof(page_directory1GB_t)); dir.number = start; dir.flaggable.present = 1; dir.flaggable.ps = 1; dir.flaggable.rw = 1; pdpt[va.directory_ptr] = dir.number; if (!first_set) { first_set = true; frame_pool = head; } } } else { for (puint_t start=0; start < maxram; start+=0x1000) { puint_t kend = kernel_tmp_heap_start - 0xFFFFFFFF80000000 + 0x40000; if (kend+0x4000 >= tmp_heap && !first_set) { first_set = true; frame_pool = head; } puint_t vaddress = start + ADDRESS_OFFSET(RESERVED_KBLOCK_RAM_MAPPINGS); puint_t* paddress = get_page(vaddress, get_active_page(), true); page_t page; memset(&page, 0, sizeof(page_t)); page.address = start; page.flaggable.present = 1; page.flaggable.rw = 1; page.flaggable.us = 0; *paddress = page.address; } } }
int arp_register() { uint32_t output_size = 0; ncp_header m_ncp ; volatile frame * my_frame = get_free_frame(); create_arp_req(my_frame); TransmitPacket(my_frame->f_data, my_frame->f_len); release_frame(my_frame); return 0; }
int client_register() { uint32_t output_size = 0; ncp_header m_ncp ; volatile frame * my_frame = get_free_frame(); ncp_register(&m_ncp,NCP_HEADER_SIZE); my_frame->f_len = create_packiet(my_frame->f_data,ETHER_MAX_LEN,&m_ncp,NCP_HEADER_SIZE); TransmitPacket(my_frame->f_data, my_frame->f_len); release_frame(my_frame); return 0; }
/* get the output surface */ static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; QSVFrame *out_frame; int ret; clear_unused_frames(s->out_frame_list); out_frame = get_free_frame(&s->out_frame_list); if (!out_frame) return NULL; /* For video memory, get a hw frame; * For system memory, get a sw frame and map it into a mfx_surface. */ if (!IS_SYSTEM_MEMORY(s->out_mem_mode)) { out_frame->frame = av_frame_alloc(); if (!out_frame->frame) return NULL; ret = av_hwframe_get_buffer(outlink->hw_frames_ctx, out_frame->frame, 0); if (ret < 0) { av_log(ctx, AV_LOG_ERROR, "Can't allocate a surface.\n"); return NULL; } out_frame->surface = (mfxFrameSurface1 *)out_frame->frame->data[3]; } else { /* Get a frame with aligned dimensions. * Libmfx need system memory being 128x64 aligned */ out_frame->frame = ff_get_video_buffer(outlink, FFALIGN(outlink->w, 128), FFALIGN(outlink->h, 64)); if (!out_frame->frame) return NULL; out_frame->frame->width = outlink->w; out_frame->frame->height = outlink->h; ret = map_frame_to_surface(out_frame->frame, &out_frame->surface_internal); if (ret < 0) return NULL; out_frame->surface = &out_frame->surface_internal; } out_frame->surface->Info = s->vpp_param.vpp.Out; return out_frame; }
int arp_response(frame * arp) { frame *output; uint32_t output_size = 0; frame *m_frame = get_free_frame(); create_arp_res(arp,output); TransmitPacket(output->f_data, output->f_len); release_frame(output); return 0; }
void interrupt_memory(ExceptionStackFrame *frame){ dprintf("in interrupt_memory", 0); int f; int i; struct pte *page_table; unsigned int addr = ((long)frame->addr); int addr_page = get_page_index(addr); page_table = pcb_current->page_table_p; if(addr_page > pcb_current->brk_index && addr_page<pcb_current->stack_limit_index){ if(addr_page - pcb_current->brk_index <= 1){ printf("Stack overflow, address 0x%061x \n", addr); Exit(ERROR); } if(pcb_current->stack_limit_index - addr_page > len_free_frames()){ printf("Not enough physical memory. address 0x%061x \n", addr); Exit(ERROR); } int k = 0; for(i = 0; i<pcb_current->stack_limit_index - addr_page; i++){ f = get_free_frame(); (page_table + pcb_current->stack_limit_index - i-1)->valid = PTE_VALID; (page_table + pcb_current->stack_limit_index - i-1)->pfn = f; (page_table + pcb_current->stack_limit_index - i-1)->uprot = (PROT_READ | PROT_WRITE); (page_table + pcb_current->stack_limit_index - i-1)->kprot = (PROT_READ | PROT_WRITE); //Not sure about the actual index WriteRegister(REG_TLB_FLUSH, TLB_FLUSH_0); k++; } pcb_current->stack_limit_index = pcb_current->stack_limit_index - k - 1; } else{ printf("Process %d: NOOBS ACCESSING INVALID MEMORY AT 0x%061x WITH CODE %d\n", pcb_current->pid, addr, frame->code); Exit(ERROR); } }
static int submit_frame(QSVEncContext *q, const AVFrame *frame, mfxFrameSurface1 **surface) { QSVFrame *qf; int ret; ret = get_free_frame(q, &qf); if (ret < 0) return ret; if (frame->format == AV_PIX_FMT_QSV) { ret = av_frame_ref(qf->frame, frame); if (ret < 0) return ret; qf->surface = (mfxFrameSurface1*)qf->frame->data[3]; *surface = qf->surface; return 0; } /* make a copy if the input is not padded as libmfx requires */ if ( frame->height & (q->height_align - 1) || frame->linesize[0] & (q->width_align - 1)) { qf->frame->height = FFALIGN(frame->height, q->height_align); qf->frame->width = FFALIGN(frame->width, q->width_align); ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF); if (ret < 0) return ret; qf->frame->height = frame->height; qf->frame->width = frame->width; ret = av_frame_copy(qf->frame, frame); if (ret < 0) { av_frame_unref(qf->frame); return ret; } } else { ret = av_frame_ref(qf->frame, frame); if (ret < 0) return ret; } qf->surface_internal.Info = q->param.mfx.FrameInfo; qf->surface_internal.Info.PicStruct = !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE : frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF : MFX_PICSTRUCT_FIELD_BFF; if (frame->repeat_pict == 1) qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED; else if (frame->repeat_pict == 2) qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING; else if (frame->repeat_pict == 4) qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING; qf->surface_internal.Data.PitchLow = qf->frame->linesize[0]; qf->surface_internal.Data.Y = qf->frame->data[0]; qf->surface_internal.Data.UV = qf->frame->data[1]; qf->surface_internal.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000}); qf->surface = &qf->surface_internal; *surface = qf->surface; return 0; }
/* get the input surface */ static QSVFrame *submit_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picref) { QSVFrame *qsv_frame; AVFilterContext *ctx = inlink->dst; clear_unused_frames(s->in_frame_list); qsv_frame = get_free_frame(&s->in_frame_list); if (!qsv_frame) return NULL; /* Turn AVFrame into mfxFrameSurface1. * For video/opaque memory mode, pix_fmt is AV_PIX_FMT_QSV, and * mfxFrameSurface1 is stored in AVFrame->data[3]; * for system memory mode, raw video data is stored in * AVFrame, we should map it into mfxFrameSurface1. */ if (!IS_SYSTEM_MEMORY(s->in_mem_mode)) { if (picref->format != AV_PIX_FMT_QSV) { av_log(ctx, AV_LOG_ERROR, "QSVVPP gets a wrong frame.\n"); return NULL; } qsv_frame->frame = av_frame_clone(picref); qsv_frame->surface = (mfxFrameSurface1 *)qsv_frame->frame->data[3]; } else { /* make a copy if the input is not padded as libmfx requires */ if (picref->height & 31 || picref->linesize[0] & 31) { qsv_frame->frame = ff_get_video_buffer(inlink, FFALIGN(inlink->w, 32), FFALIGN(inlink->h, 32)); if (!qsv_frame->frame) return NULL; qsv_frame->frame->width = picref->width; qsv_frame->frame->height = picref->height; if (av_frame_copy(qsv_frame->frame, picref) < 0) { av_frame_free(&qsv_frame->frame); return NULL; } av_frame_copy_props(qsv_frame->frame, picref); av_frame_free(&picref); } else qsv_frame->frame = av_frame_clone(picref); if (map_frame_to_surface(qsv_frame->frame, &qsv_frame->surface_internal) < 0) { av_log(ctx, AV_LOG_ERROR, "Unsupported frame.\n"); return NULL; } qsv_frame->surface = &qsv_frame->surface_internal; } qsv_frame->surface->Info = s->frame_infos[FF_INLINK_IDX(inlink)]; qsv_frame->surface->Data.TimeStamp = av_rescale_q(qsv_frame->frame->pts, inlink->time_base, default_tb); qsv_frame->surface->Info.PicStruct = !qsv_frame->frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE : (qsv_frame->frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF : MFX_PICSTRUCT_FIELD_BFF); if (qsv_frame->frame->repeat_pict == 1) qsv_frame->surface->Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED; else if (qsv_frame->frame->repeat_pict == 2) qsv_frame->surface->Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING; else if (qsv_frame->frame->repeat_pict == 4) qsv_frame->surface->Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING; return qsv_frame; }
/******************************************************************************* * Page fault handler. When the CPU encounters an invalid address mapping in a * process' page table, it invokes the CPU via this handler. The OS then * allocates a physical frame for the requested page (either by using a free * frame or evicting one), changes the process' page table to reflect the * mapping and then restarts the interrupted process. * * @param vpn The virtual page number requested from the current process. * @param write If the CPU is writing to the page, this is 1. Otherwise, it's 0. * @return The physical frame the OS has mapped to the virtual page. */ pfn_t pagefault_handler(vpn_t request_vpn, int write) { pfn_t victim_pfn; vpn_t victim_vpn; pcb_t *victim_pcb; /* Sanity Check */ assert(current_pagetable != NULL); /* Find a free frame */ victim_pfn = get_free_frame(); assert(victim_pfn < CPU_NUM_FRAMES); /* make sure the victim_pfn is valid */ /* Use the reverse lookup table to find the victim. */ victim_vpn = rlt[victim_pfn].vpn; victim_pcb = rlt[victim_pfn].pcb; /* * FIX ME : Problem 4 * If victim page is occupied - if it is not the pcb will be NULL: * * 1) If it's dirty, save it to disk with page_to_disk() * 2) Invalidate the page's entry in the victim's page table. * 3) Clear the victim page's TLB entry using the function tlb_clearone(). */ pte_t *victim_entry; if (victim_pcb != NULL) { victim_entry = victim_pcb->pagetable + victim_vpn; if (victim_entry->dirty == 1) { page_to_disk(victim_pfn, victim_vpn, victim_pcb->pid); victim_entry->dirty = 0; } victim_entry->valid = 0; //victim_entry->used = 0; tlb_clearone(victim_vpn); } printf("PAGE FAULT (VPN %u), evicting (PFN %u VPN %u)\n", request_vpn, victim_pfn, victim_vpn); /* FIX ME */ /* Update the reverse lookup table to replace the victim entry info with this * process' info instead (pcb and vpn) * Update the current process' page table (pfn and valid) */ rlt_t *rlt_entry = rlt + victim_pfn; rlt_entry->vpn = request_vpn; rlt_entry->pcb = current; pte_t *current_entry = current_pagetable + request_vpn; current_entry->valid = 1; current_entry->pfn = victim_pfn; /* * Retreive the page from disk. Note that is really a lie: we save pages in * memory (since doing file I/O for this simulation would be annoying and * wouldn't add that much to the learning). Also, if the page technically * does't exist yet (i.e., the page has never been accessed yet, we return a * blank page. Real systems would check for invalid pages and possibly read * stuff like code pages from disk. For purposes of this simulation, we won't * worry about that. =) */ page_from_disk(victim_pfn, request_vpn, current->pid); return victim_pfn; }
/*------------------------------------------------------------------------ * sysinit -- initialize all Xinu data structeres and devices *------------------------------------------------------------------------ */ LOCAL sysinit() { static long currsp; int i,j, avail; struct pentry *pptr; struct sentry *sptr; struct mblock *mptr; SYSCALL pfintr(); /*********************/ set_evec(14, pfintr); pptr = &proctab[NULLPROC]; /* initialize null process entry */ /*********************/ numproc = 0; /* initialize system variables */ nextproc = NPROC-1; nextsem = NSEM-1; nextqueue = NPROC; /* q[0..NPROC-1] are processes */ /* initialize free memory list */ /* PC version has to pre-allocate 640K-1024K "hole" */ if (maxaddr+1 > HOLESTART) { memlist.mnext = mptr = (struct mblock *) roundmb(&end); mptr->mnext = (struct mblock *)HOLEEND; mptr->mlen = (int) truncew(((unsigned) HOLESTART - (unsigned)&end)); mptr->mlen -= 4; mptr = (struct mblock *) HOLEEND; mptr->mnext = 0; mptr->mlen = (int) truncew((unsigned)maxaddr - HOLEEND - NULLSTK); /* mptr->mlen = (int) truncew((unsigned)maxaddr - (4096 - 1024 ) * 4096 - HOLEEND - NULLSTK); */ } else { /* initialize free memory list */ memlist.mnext = mptr = (struct mblock *) roundmb(&end); mptr->mnext = 0; mptr->mlen = (int) truncew((unsigned)maxaddr - (int)&end - NULLSTK); } for (i=0 ; i<NPROC ; i++) /* initialize process table */ proctab[i].pstate = PRFREE; #ifdef MEMMARK _mkinit(); /* initialize memory marking */ #endif #ifdef RTCLOCK clkinit(); /* initialize r.t.clock */ #endif mon_init(); /* init monitor */ #ifdef NDEVS for (i=0 ; i<NDEVS ; i++ ) { init_dev(i); } #endif pptr = &proctab[NULLPROC]; /* initialize null process entry */ pptr->pstate = PRCURR; for (j=0; j<7; j++) pptr->pname[j] = "prnull"[j]; pptr->plimit = (WORD)(maxaddr + 1) - NULLSTK; pptr->pbase = (WORD) maxaddr - 3; /* pptr->plimit = (WORD)(maxaddr + 1) - NULLSTK - (4096 - 1024 )*4096; pptr->pbase = (WORD) maxaddr - 3 - (4096-1024)*4096; */ pptr->pesp = pptr->pbase-4; /* for stkchk; rewritten before used */ *( (int *)pptr->pbase ) = MAGIC; pptr->paddr = (WORD) nulluser; pptr->pargs = 0; pptr->pprio = 0; currpid = NULLPROC; for (i=0 ; i<NSEM ; i++) { /* initialize semaphores */ (sptr = &semaph[i])->sstate = SFREE; sptr->sqtail = 1 + (sptr->sqhead = newqueue()); } rdytail = 1 + (rdyhead=newqueue());/* initialize ready list */ init_bsm(); init_frm(); kprintf("initialize page tables for null process\n"); init_glb_pgs(glb_pg_tbl_frm_mapping); // init pg dir for proc 0 frame_t *pg_dir = get_free_frame(); init_pg_dir(pg_dir, NULLPROC); pptr->pdbr = pg_dir->frm_num; pptr->pd = pg_dir; return(OK); }
/** * Reciving singlas from ethernet controller - * TX - transmited packet * RX - recived packet * LinkChange - Connected/Diconncted Ethernet Cable * */ void ethernet_interrupts_simple() { frame *curr_frame = 0; int filtered; uint8_t interruption =ior(ISR); //which interruption packet_num++; iow(IMR, 0); // iow(IMR, PAR_set); // printf("ISR 0x%2X \n",interruption); if( interruption & 0x01 ) //RX { iow(ISR,0x01); curr_frame = get_free_frame(); if(curr_frame == 0) { return; //ERROR no more free frames } aaa=ReceivePacket(curr_frame->f_data,&curr_frame->f_len); if(aaa == 0) { filtered = filter_packiets(curr_frame->f_data,curr_frame->f_len); if (filtered == 0) { printf(" RX:UDP \n"); add_rx_frame(curr_frame); } else if (filtered == 10) //arp { printf(" RX:ARP \n"); add_rx_frame(curr_frame); } else { release_frame(curr_frame); } curr_frame = 0; } else { printf("%s Recived Bad Frame \n",__FUNCTION__); release_frame(curr_frame); curr_frame = 0; } /* ethernet_header *tmp = (ethernet_header *) RXT; ether_addr adres = { 0x01, 0x60, 0x6E, 0x11, 0x01, 0x1F }; tmp->eth_src_addr = adres; TransmitPacket(RXT,rx_len);*/ } if(interruption & 0x02) //TX { iow(ISR,0x02); tx_control = 0; } if(interruption & 0x20) //LinkChange { iow(ISR,0x20); /* iow(0x00,0x01); // software reset usleep(10); enable interrupts to activate DM9000 ~on iow(IMR, INTR_set2); IMR REG. FFH PAR=1 only, or + PTM=1& PRM=1 enable RxTx interrupts iow(0xFF, 0x80); enable RX (Broadcast/ ALL_MULTICAST) ~go iow(RCR , RCR_set | RX_ENABLE | PASS_MULTICAST); RCR REG. 05 RXEN Bit [0] = 1 to enable the RX machine/ filter */ //printf(" LinkCHange \n"); if(link_control == 0) link_control = 1; else link_control = 0; } iow(IMR, INTR_set2); }
/** * Returns page allocated for that virtual address. * * If allocate_new is specified to true, it will allocate substructures, * if not present.Otherwise returns NULL if page structures are not present * on the way to the virtual address. Returned pointer points to page in page * table. */ static puint_t* __get_page(uintptr_t vaddress, uintptr_t cr3, bool allocate_new, bool user) { v_address_t va; memcpy(&va, &vaddress, 8); puint_t* pml4 = (puint_t*)ALIGN(physical_to_virtual(cr3)); if (!PRESENT(pml4[va.pml])) { if (!allocate_new) { return 0; } pdpt_t pdpt; memset(&pdpt, 0, sizeof(pdpt_t)); pdpt.number = get_free_frame(); if (pdpt.number == 0) return 0; pdpt.flaggable.present = 1; pdpt.flaggable.us = user; pdpt.flaggable.rw = 1; pml4[va.pml] = pdpt.number; memset((void*)physical_to_virtual(ALIGN(pdpt.number)), 0, 0x1000); } puint_t* pdpt = (puint_t*)ALIGN(physical_to_virtual(pml4[va.pml])); if (!PRESENT(pdpt[va.directory_ptr])) { if (!allocate_new) return 0; page_directory_t dir; memset(&dir, 0, sizeof(page_directory_t)); dir.number = get_free_frame(); if (dir.number == 0) { return 0; } dir.flaggable.present = 1; dir.flaggable.us = user; dir.flaggable.rw = 1; pdpt[va.directory_ptr] = dir.number; memset((void*)physical_to_virtual(ALIGN(dir.number)), 0, 0x1000); } puint_t* pdir = (puint_t*)ALIGN(physical_to_virtual(pdpt[va.directory_ptr])); if (!PRESENT(pdir[va.directory])) { if (!allocate_new) return 0; page_table_t pt; memset(&pt, 0, sizeof(page_table_t)); pt.number = get_free_frame(); if (pt.number == 0) { return 0; } pt.flaggable.present = 1; pt.flaggable.us = user; pt.flaggable.rw = 1; pdir[va.directory] = pt.number; memset((void*)physical_to_virtual(ALIGN(pt.number)), 0, 0x1000); } puint_t* pt = (puint_t*)ALIGN(physical_to_virtual(pdir[va.directory])); return &pt[va.table]; }
/******************************************************************************* * Page fault handler. When the CPU encounters an invalid address mapping in a * process' page table, it invokes the CPU via this handler. The OS then * allocates a physical frame for the requested page (either by using a free * frame or evicting one), changes the process' page table to reflect the * mapping and then restarts the interrupted process. * * @param vpn The virtual page number requested. * @param write If the CPU is writing to the page, this is 1. Otherwise, it's 0. * @return The physical frame the OS has mapped to the virtual page. */ pfn_t pagefault_handler(vpn_t request_vpn, int write) { pfn_t victim_pfn; vpn_t victim_vpn; pcb_t *victim_pcb; /* Sanity Check */ assert(current_pagetable != NULL); /* Find a free frame */ victim_pfn = get_free_frame(); assert(victim_pfn < CPU_NUM_FRAMES); /* make sure the victim_pfn is valid */ /* Use the reverse lookup table to find the victim. */ victim_vpn = rlt[victim_pfn].vpn; victim_pcb = rlt[victim_pfn].pcb; /* * FIX ME : Problem 4 * If victim page is occupied: * * 1) If it's dirty, save it to disk with page_to_disk() * 2) Invalidate the page's entry in the victim's page table. * 3) Clear the victim page's TLB entry (hint: tlb_clearone()). */ pte_t* victim; pte_t current_v; if (victim_pcb != NULL) { victim = victim_pcb -> pagetable; current_v = victim[victim_vpn]; if (current_v.dirty && current_v.valid) { page_to_disk(victim_pfn, victim_vpn, victim_pcb ->pid); } victim[victim_vpn].valid = 0; tlb_clearone(victim_vpn); } printf("****PAGE FAULT has occurred at VPN %u. Evicting (PFN %u VPN %u) as victim.\n", request_vpn, victim_pfn, victim_vpn); /* Update the reverse lookup table so that it knows about the requesting process */ /* FIX ME */ rlt[victim_pfn].pcb = current; rlt[victim_pfn].vpn = request_vpn; /* Update the requesting process' page table */ /* FIX ME */ current_pagetable[request_vpn].pfn = victim_pfn; current_pagetable[request_vpn].valid = 1; current_pagetable[request_vpn].dirty = write; current_pagetable[request_vpn].used = 1; /* * Retreive the page from disk. Note that is really a lie: we save pages in * memory (since doing file I/O for this simulation would be annoying and * wouldn't add that much to the learning). Also, if the page technically * does't exist yet (i.e., the page has never been accessed yet, we return a * blank page. Real systems would check for invalid pages and possibly read * stuff like code pages from disk. For purposes of this simulation, we won't * worry about that. =) */ page_from_disk(victim_pfn, request_vpn, current->pid); return victim_pfn; }