int pci_read_msi(pci_addr_t *addr, pci_dev_header_t *pci_hdr,pci_bar_t *bars, uint32_t bars_total, struct pcicfg_msix *msix) { uint32_t ret; uint16_t buf; uint32_t val; uint32_t bar_offset; uint8_t pos=pci_hdr->capabilities_pointer; ret = pci_read(addr, pos, 2, &buf); ret = pci_read(addr, pos + PCIR_MSIX_CTRL, 2, &msix->msix_ctrl); msix->msix_msgnum = (msix->msix_ctrl & PCIM_MSIXCTRL_TABLE_SIZE) + 1; if (msix->msix_msgnum > 0) { msix->isr_vector = msi_start_vector; msi_start_vector = msi_start_vector + msix->msix_msgnum; ut_log(" msi vector start :%d num:%d \n",msix->isr_vector,msix->msix_msgnum); } else { msix->isr_vector = 0; } ret = pci_read(addr, pos + PCIR_MSIX_TABLE, 4, &bar_offset); msix->msix_table_bar = PCIR_BAR(bar_offset & PCIM_MSIX_BIR_MASK); if (bar_offset >= bars_total) return 0; msix->msix_table_res = bars[bar_offset].addr; msix->msix_table = vm_create_kmap("msix",0x1000,PROT_WRITE,MAP_FIXED,msix->msix_table_res); ut_log(" msix table :%x bar addr:%x baroffset:%d msix tableres:%x\n",msix->msix_table,bars[bar_offset].addr,bar_offset,msix->msix_table_res); ret = pci_read(addr, pos + PCIR_MSIX_PBA, 4, &val); msix->msix_pba_bar = PCIR_BAR(val & PCIM_MSIX_BIR_MASK); return msix->isr_vector; }
int init_memory(unsigned long arg1){ unsigned long virt_real_start_addr,virt_start_addr,virt_end_addr; unsigned long pc_size; unsigned long current_end_memused=&end; /* till this point memory is used*/ unsigned long phy_end_addr = g_phy_mem_size; ut_log(" Initializing memory phy_endaddr : %x current end:%x symbols_end:%x\n",phy_end_addr,current_end_memused,symbols_end); if (symbols_end != 0){ current_end_memused = symbols_end; } virt_start_addr=initialise_paging_new(phy_end_addr, current_end_memused,&virt_real_start_addr,&virt_end_addr); INIT_LOG(" After Paging initialized Virtual start_addr: %x virtual endaddr: %x current end:%x virtualreal_start:%x\n",virt_start_addr,virt_end_addr,current_end_memused,virt_real_start_addr); INIT_LOG(" code+data : %x -%x size:%dK",&_start,&_end); INIT_LOG(" free area : %x - %x size:%dM\n",virt_start_addr,virt_end_addr,(virt_end_addr-virt_start_addr)/1000000); virt_start_addr=init_free_area( virt_start_addr, virt_end_addr); pc_size = g_pagecache_size ; pc_init((unsigned char *)virt_start_addr,pc_size); ut_log(" pagecache : %x - %x size:%dM",virt_start_addr,virt_start_addr+pc_size,pc_size/1000000); virt_start_addr=virt_start_addr+pc_size; #if 0 /* reserve the test memory for testing */ if (virt_end_addr > (virt_start_addr + (600*1024*1024))){ test_mem_start = virt_start_addr; test_mem_end = virt_start_addr + 512 *1024 *1204 ; /* 512M */ virt_start_addr = test_mem_end + 4096; } #endif init_mem(virt_start_addr, virt_end_addr, virt_real_start_addr); INIT_LOG(" buddy pages: %x - %x size:%dM\n",virt_start_addr, virt_end_addr,(virt_end_addr-virt_start_addr)/1000000); return JSUCCESS; }
int Jcmd_logflush(unsigned char *arg1) { int ret = 0; if (init_log_file_done == 1) { int len = g_dmesg_index - dmesg_file_index; // TODO : need to take wrap arounds where len becomes negative if (len > 0) { ret = fs_write(log_fp, &g_dmesg[dmesg_file_index], len); dmesg_file_index = g_dmesg_index; } ut_log("flushed to log :%d ret:%d len:%d\n", dmesg_file_index, ret, len); } else { ut_log("Failed to flush to log\n"); } return 1; }
/*! * Returns the unit corresponding to the logarithmic \a base base * using this unit as a reference level. * For example, the following creates a decibel unit with a one milliwatt reference level: * \code * UdUnit milliWatt = ... * UdUnit decibel_1_mW = milliWatt.toLogarithmic(10.0).scaledBy(0.1); * \endcode */ UdUnit UdUnit::toLogarithmic(qreal base) const { ut_set_status(UT_SUCCESS); ut_unit *unit = ut_log(base, m_unit); int status = ut_get_status(); return UdUnit(unit, status); }
int pci_enable_msix(pci_addr_t *addr ,struct pcicfg_msix *msix,uint8_t capabilities_pointer){ update_msix_table(msix, 0); msix->msix_ctrl = msix->msix_ctrl | 0x8000; // enable msix pci_write(addr, capabilities_pointer + PCIR_MSIX_CTRL, 2, &msix->msix_ctrl); ut_log("MSIX... Configured ISR vector:%d numvector:%d ctrl:%x\n", msix->isr_vector, msix->msix_msgnum, msix->msix_ctrl); return 1; }
static void update_msix_table(struct pcicfg_msix *msix, int mask) { unsigned long address; int i; for (i = 0; i < msix->msix_msgnum; i++) { address = LAPIC_BASE; // address = address | 0x1008; /* Working apic-id=1 as destination, to send to the second cpu, */ address = address | 0x008; /* Working apic-id=0 as destination, to send to the first cpu, */ // address = address | 0xf00c; /* using logic mode for apic id's Working apic-id=1 as destination, to send to the second cpu, */ msix->msix_table[i].upper_add = address >> 32; msix->msix_table[i].lower_addr = address & 0xffffffff; msix->msix_table[i].data =( msix->isr_vector + i) | 0x100 ; /* lowest priority mode=0x100 */ msix->msix_table[i].control = mask; ut_log(" %d: MSIX data :%x address:%x \n",i,msix->msix_table[i].data,address); } return; }
static unsigned long setup_userstack(unsigned char **argv, unsigned char **env, unsigned long *stack_len, unsigned long *t_argc, unsigned long *t_argv, unsigned long *p_aux, unsigned char *elf_interp) { int i, len, total_args = 0; int total_envs =0; unsigned char *p, *stack; unsigned long real_stack, addr; unsigned char **target_argv; unsigned char **target_env; int max_stack_len=MAX_USERSPACE_STACK_TEMPLEN; int max_list_len=(PAGE_SIZE/sizeof(void *))-1; unsigned long ret=0; if (argv == 0 && env == 0) { ut_printf(" ERROR in setuo_userstack argv:0\n"); return 0; } target_argv = (unsigned char **) alloc_page(MEM_CLEAR); target_env = (unsigned char **) alloc_page(MEM_CLEAR); if (target_argv==0 || target_env==0){ BUG(); } stack = (unsigned char *) vmalloc(MAX_USERSPACE_STACK_TEMPLEN,MEM_CLEAR); if (stack ==0){ goto error; } ret = stack; p = stack + max_stack_len; len = 0; real_stack = USERSTACK_ADDR + USERSTACK_LEN; if (elf_interp != 0){ //BUG(); len = ut_strlen(elf_interp); p = p - len - 1; real_stack = real_stack - len - 1; ut_strcpy(p, elf_interp); target_argv[total_args] = (unsigned char *)real_stack; total_args++; } for (i = 0; argv[i] != 0 && i < max_list_len; i++) { len = ut_strlen(argv[i]); if ((p - len - 1) > stack) { p = p - len - 1; real_stack = real_stack - len - 1; DEBUG(" argument :%d address:%x \n",i,real_stack); ut_strcpy(p, argv[i]); target_argv[total_args] = (unsigned char *)real_stack; total_args++; } else { ret=0 ; goto error; } } target_argv[total_args] = 0; for (i = 0; env[i] != 0 && i < max_list_len; i++) { total_envs++; len = ut_strlen(env[i]); if ((p - len - 1) > stack) { p = p - len - 1; real_stack = real_stack - len - 1; DEBUG(" envs :%d address:%x \n",i,real_stack); ut_strcpy(p, env[i]); target_env[i] = (unsigned char *)real_stack; } else { ret=0 ; goto error; } } target_env[i] = 0; addr = (unsigned long)p; addr = (unsigned long)((addr / 8) * 8); p = (unsigned char *)addr; p = p - (MAX_AUX_VEC_ENTRIES * 16); real_stack = USERSTACK_ADDR + USERSTACK_LEN + p - (stack + max_stack_len); *p_aux = (unsigned long)p; len = (1+total_args + 1 + total_envs+1) * 8; /* total_args+args+0+envs+0 */ if ((p - len - 1) > stack) { unsigned long *t; p = p - (total_envs+1)*8; ut_memcpy(p, (unsigned char *)target_env, (total_envs+1)*8); p = p - (1+total_args+1)*8; ut_memcpy(p+8, (unsigned char *)target_argv, (total_args+1)*8); t = (unsigned long *)p; *t = total_args; /* store argc at the top of stack */ DEBUG("Target ARG arg0:%x arg1:%x arg2:%x len:%d \n",target_argv[0],target_argv[1],target_argv[2],len); DEBUG("Target ENV arg0:%x arg1:%x arg2:%x len:%d \n",target_env[0],target_env[1],target_env[2],len); real_stack = real_stack - len; } else { ret=0; goto error; } *stack_len = max_stack_len - (p - stack); *t_argc = total_args; *t_argv = real_stack; error: if (ret ==0 ){ ut_log(" Error: user stack creation failed :%s:\n",g_current_task->name); vfree((unsigned long)stack); } mm_putFreePages((unsigned long)target_argv, 0); mm_putFreePages((unsigned long)target_env, 0); return ret; }
//unsigned long fs_loadElfLibrary(struct file *file, unsigned long tmp_stack, unsigned long stack_len, unsigned long aux_addr) { unsigned long fs_elf_load(struct file *file,unsigned long tmp_stack, unsigned long stack_len, unsigned long aux_addr) { struct elf_phdr *elf_phdata; struct elf_phdr *eppnt; unsigned long elf_bss, bss_start, bss, len; int retval, error, i, j; struct elfhdr elf_ex; Elf64_Addr p_entry; unsigned long *aux_vec, aux_index, load_addr; struct task_struct *task=g_current_task; error = 0; fs_lseek(file, 0, 0); retval = fs_read(file, (unsigned char *) &elf_ex, sizeof(elf_ex)); if (retval != sizeof(elf_ex)) { error = -1; goto out; } if (ut_memcmp((unsigned char *) elf_ex.e_ident, (unsigned char *) ELFMAG, SELFMAG) != 0) { error = -2; goto out; } if (elf_ex.e_type == ET_DYN) elf_ex.e_type=ET_EXEC; /* First of all, some simple consistency checks */ //if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || if (elf_ex.e_type != ET_EXEC || !elf_check_arch(&elf_ex)) { DEBUG("error:(not executable type or mismatch in architecture %x %x %x \n",elf_ex.e_type,elf_ex.e_phnum,elf_check_arch(&elf_ex)); error = -3; goto out; } /* Now read in all of the header information */ j = sizeof(struct elf_phdr) * elf_ex.e_phnum; /* j < ELF_MIN_ALIGN because elf_ex.e_phnum <= 2 */ elf_phdata = mm_malloc(j, 0); if (!elf_phdata) { error = -4; goto out; } eppnt = elf_phdata; fs_lseek(file, (unsigned long) elf_ex.e_phoff, 0); retval = fs_read(file, (unsigned char *) eppnt, j); if (retval != j) { error = -5; goto out; } DEBUG("START address : %x offset :%x \n",ELF_PAGESTART(eppnt->p_vaddr),eppnt->p_offset); for (j = 0, i = 0; i < elf_ex.e_phnum; i++){ if ((eppnt + i)->p_type == PT_LOAD) j++; } if (j == 0) { error = -6; goto out; } load_addr = ELF_PAGESTART(eppnt->p_vaddr); p_entry = elf_ex.e_entry; task->mm->start_code = 0; task->mm->end_code =0; for (i = 0; i < elf_ex.e_phnum; i++, eppnt++) /* mmap all loadable program headers */ { if (eppnt->p_type != PT_LOAD) continue; //ut_log("%d: LOAD section: vaddr:%x filesz:%x offset:%x flags:%x \n",i,ELF_PAGESTART(eppnt->p_vaddr),eppnt->p_filesz,eppnt->p_offset,eppnt->p_flags); /* Now use mmap to map the library into memory. */ error = 1; if (eppnt->p_filesz > 0) { unsigned long addr; unsigned long start_addr = ELF_PAGESTART(eppnt->p_vaddr); unsigned long end_addr= eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr); addr = vm_mmap(file, start_addr, end_addr, eppnt->p_flags, 0, (eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr)),"text"); if (addr == 0) error = 0; if (task->mm->start_code ==0 || task->mm->start_code > start_addr ) task->mm->start_code = start_addr; if (task->mm->end_code < end_addr ) task->mm->end_code = end_addr; } //if (error != ELF_PAGESTART(eppnt->p_vaddr)) if (error != 1) { error = -6; goto out; } elf_bss = eppnt->p_vaddr + eppnt->p_filesz; // padzero(elf_bss); /* TODO : bss start address in not at the PAGE_ALIGN or ELF_MIN_ALIGN , need to club this partial page with the data */ // len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + ELF_MIN_ALIGN - 1); bss_start = eppnt->p_filesz + eppnt->p_vaddr; bss = eppnt->p_memsz + eppnt->p_vaddr; //ut_log(" bss start :%x end:%x memsz:%x elf_bss:%x \n",bss_start, bss,eppnt->p_memsz,elf_bss); if (bss > bss_start) { vm_setupBrk(bss_start, bss - bss_start); } error = 0; } out: if (elf_phdata) { mm_free(elf_phdata); } if (error != 0) { ut_log(" ERROR in elf loader filename :%s :%d\n",file->filename,-error); } else { task->mm->stack_bottom = USERSTACK_ADDR+USERSTACK_LEN; elf_initialize_userspace_stack(elf_ex,aux_addr,tmp_stack, stack_len,load_addr); vm_mmap(0, USER_SYSCALL_PAGE, 0x1000, PROT_READ | PROT_EXEC |PROT_WRITE, MAP_ANONYMOUS, 0,"fst_syscal"); //ut_memset((unsigned char *)SYSCALL_PAGE,(unsigned char )0xcc,0x1000); ut_memcpy((unsigned char *)USER_SYSCALL_PAGE,(unsigned char *)&__vsyscall_page,0x1000); if (g_conf_syscall_debug==1){ //pagetable_walk(4,g_current_task->mm->pgd,1,0); } } DEBUG(" Program start address(autod) : %x \n",elf_ex.e_entry); if (error == 0) return p_entry; else return 0; }
void ut_putchar_vga(unsigned char c, int device) { unsigned char *ptr; unsigned long flags; #if 0 //1. Serial output if (device == DEVICE_SERIAL1){ char buf[5]; if (c == '\n') { buf[0] = '\r'; buf[1] = '\0'; dr_serialWrite(buf, 1); buf[0] = '\n'; buf[1] = '\0'; dr_serialWrite(buf, 1); } else { buf[0] = (char) c; buf[1] = '\0'; dr_serialWrite(buf, 1); } return; } #endif //2. VGI output //log_putchar(c); if (g_video_ram == 0) return; if (1){ char buf[5]; buf[0] = (char) c; buf[1] = '\0'; time_print=0; ut_log("%s",buf); time_print=1; } spin_lock_irqsave(&putchar_lock, flags); // if (g_boot_completed) mutexLock(g_print_lock); ptr = &(video_buffer_g[0][0]); if (c == '\n' || c == '\r') { newline: xpos = 0; ypos++; if (ypos >= LINES) { if (1) { scroll(); ypos--; } else { ypos = 0; } } //if (g_boot_completed) mutexUnLock(g_print_lock); spin_unlock_irqrestore(&putchar_lock, flags); return; } *(g_video_ram + (xpos + ypos * COLUMNS) * 2) = c & 0xFF; *(g_video_ram + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE; *(ptr + (xpos + ypos * COLUMNS) * 2) = c & 0xFF; *(ptr + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE; xpos++; if (xpos >= COLUMNS) goto newline; // if (g_boot_completed) mutexUnLock(g_print_lock); spin_unlock_irqrestore(&putchar_lock, flags); }
unsigned long mm_getFreePages(int gfp_mask, unsigned long order) { unsigned long flags; unsigned long ret_address; unsigned long page_order ; stat_allocs++; ret_address = 0; page_order = order; if (order >= NR_MEM_LISTS) return ret_address; spin_lock_irqsave(&free_area_lock, flags); do { struct free_mem_area_struct * area = free_mem_area+order; unsigned long new_order = order; do { struct page *prev = memory_head(area), *ret = prev->next; while (memory_head(area) != ret) { if ( CAN_DMA(ret)) { unsigned long map_nr; (prev->next = ret->next)->prev = prev; map_nr = ret - g_mem_map; MARK_USED(map_nr, new_order, area); area->stat_count--; g_nr_free_pages -= 1 << order; EXPAND(ret, map_nr, order, new_order, area); DEBUG(" Page alloc return address: %x mask:%x order:%d \n",ADDRESS(map_nr),gfp_mask,order); if (gfp_mask & MEM_CLEAR) ut_memset(ADDRESS(map_nr),0,PAGE_SIZE<<order); if (!(gfp_mask & MEM_FOR_CACHE)) memleakHook_alloc(ADDRESS(map_nr),PAGE_SIZE<<order,0,0); ret_address = ADDRESS(map_nr); goto last; } prev = ret; ret = ret->next; } new_order++; area++; } while (new_order < NR_MEM_LISTS); } while (0); last: if (ret_address > 0) { unsigned long i = (1 << page_order); struct page *page = virt_to_page(ret_address); while (i--) { #ifdef MEMORY_DEBUG if (PageReferenced(page)){ ut_log("Page Backtrace in Alloc page :\n"); ut_printBackTrace(page->bt_addr_list,MAX_BACKTRACE_LENGTH); } #endif assert(!PageReferenced(page)); PageSetReferenced(page); #ifdef MEMORY_DEBUG ut_storeBackTrace(page->bt_addr_list,MAX_BACKTRACE_LENGTH); #endif page++; } } spin_unlock_irqrestore(&free_area_lock, flags); if (ret_address ==0) return ret_address; if ((ret_address >= (KADDRSPACE_START+g_phy_mem_size)) || (ret_address < KADDRSPACE_START)){ ut_log(" ERROR: frames execeeding the max frames :%x\n",ret_address); BUG(); } return ret_address; }
int mm_putFreePages(unsigned long addr, unsigned long order) { unsigned long map_nr = MAP_NR(addr); int ret = 0; int page_order = order; unsigned long flags; stat_frees++; #ifdef MEMLEAK_TOOL memleakHook_free(addr,0); #endif spin_lock_irqsave(&free_area_lock, flags); if (map_nr < g_max_mapnr) { page_struct_t * map = g_mem_map + map_nr; if (PageReserved(map)) { BUG(); } if (PageNetBuf(map)){ BUG(); } #ifdef MEMORY_DEBUG if (map->option_data != 0){ BUG(); } #endif if (atomic_dec_and_test(&map->count)) { if (PageSwapCache(map)){ ut_log("PANIC Freeing swap cache pages"); BUG(); } // map->flags &= ~(1 << PG_referenced); _free_pages_ok(map_nr, order); if (init_done == 1) { DEBUG(" Freeing memory addr:%x order:%d \n", addr, order); }else{ // BUG(); } ret = 1; } }else{ BUG(); } last: if (ret){ unsigned long i = (1 << page_order); struct page *page = virt_to_page(addr); while (i--) { #ifdef MEMORY_DEBUG if (!PageReferenced(page)){ ut_printf("Page Backtrace in Free Page :\n"); ut_printBackTrace(page->bt_addr_list,MAX_BACKTRACE_LENGTH); } #endif assert(PageReferenced(page)); PageClearReferenced(page); #ifdef MEMORY_DEBUG ut_storeBackTrace(page->bt_addr_list,MAX_BACKTRACE_LENGTH); #endif page++; } }else{ BUG(); } spin_unlock_irqrestore(&free_area_lock, flags); return ret; }