Beispiel #1
0
void do_no_page(void *addr)
{
    pde_t *page_dir = (pde_t *)current->cr3;
    pte_t *page_tbl = 0;

    unsigned long page = alloc_one_page(0);
    assert(page != 0);

    int npde = get_npd(addr);
    int npte = get_npt(addr);

    if(page_dir[npde] == 0)
    {
        page_tbl = (pte_t *) alloc_one_page(0);
        assert(page_tbl != 0);

        memset((void *) page_tbl, 0, PAGE_SIZE);

        page_dir[npde] = va2pa(page_tbl) | PAGE_P | PAGE_WR | PAGE_US;
    }

    page_tbl = (pte_t *)pa2va(PAGE_ALIGN(page_dir[npde]));
    page_tbl[npte] = va2pa(page) | PAGE_P | PAGE_WR | PAGE_US;

    load_cr3(current);
}
Beispiel #2
0
long sys_lstat(const char* name, void* st)
{
  struct frontend_stat buf;
  size_t name_size = strlen(name)+1;
  long ret = frontend_syscall(SYS_lstat, va2pa(name), name_size, va2pa(&buf), 0, 0, 0, 0);
  copy_stat(st, &buf);
  return ret;
}
Beispiel #3
0
int ofmem_posix_memalign( void **memptr, size_t alignment, size_t size )
{
    ofmem_t *ofmem = ofmem_arch_get_private();
    alloc_desc_t *d, **pp;
    void *ret;
    ucell top;
    phys_addr_t pa;

    if( !size )
        return ENOMEM;

    if( !ofmem->next_malloc )
        ofmem->next_malloc = (char*)ofmem_arch_get_malloc_base();

    size = align_size(size + sizeof(alloc_desc_t), alignment);

    /* look in the freelist */
    for( pp=&ofmem->mfree; *pp && (**pp).size < size; pp = &(**pp).next ) {
    }

    /* waste at most 4K by taking an entry from the freelist */
    if( *pp && (**pp).size > size + 0x1000 ) {
        /* Alignment should be on physical not virtual address */
        pa = va2pa((uintptr_t)*pp + sizeof(alloc_desc_t));
        pa = align_ptr(pa, alignment);
        ret = (void *)pa2va(pa);

        memset( ret, 0, (**pp).size - sizeof(alloc_desc_t) );
        *pp = (**pp).next;

        *memptr = ret;
        return 0;
    }

    top = ofmem_arch_get_heap_top();

    /* Alignment should be on physical not virtual address */
    pa = va2pa((uintptr_t)ofmem->next_malloc + sizeof(alloc_desc_t));
    pa = align_ptr(pa, alignment);
    ret = (void *)pa2va(pa);

    if( pointer2cell(ret) + size > top ) {
        printk("out of malloc memory (%x)!\n", size );
        return ENOMEM;
    }

    d = (alloc_desc_t*)((uintptr_t)ret - sizeof(alloc_desc_t));
    ofmem->next_malloc += size;

    d->next = NULL;
    d->size = size;

    memset( ret, 0, size - sizeof(alloc_desc_t) );

    *memptr = ret;
    return 0;
}
Beispiel #4
0
int sys_renameat(int old_fd, const char *old_path, int new_fd, const char *new_path) {
  int old_kfd = at_kfd(old_fd);
  int new_kfd = at_kfd(new_fd);
  if(old_kfd != -1 && new_kfd != -1) {
    size_t old_size = strlen(old_path)+1;
    size_t new_size = strlen(new_path)+1;
    return frontend_syscall(SYS_renameat, old_kfd, va2pa(old_path), old_size,
                                           new_kfd, va2pa(new_path), new_size, 0);
  }
  return -EBADF;
}
Beispiel #5
0
long sys_fstatat(int dirfd, const char* name, void* st, int flags)
{
  int kfd = at_kfd(dirfd);
  if (kfd != -1) {
    struct frontend_stat buf;
    size_t name_size = strlen(name)+1;
    long ret = frontend_syscall(SYS_fstatat, kfd, va2pa(name), name_size, va2pa(&buf), flags, 0, 0);
    copy_stat(st, &buf);
    return ret;
  }
  return -EBADF;
}
Beispiel #6
0
long sys_linkat(int old_dirfd, const char* old_name, int new_dirfd, const char* new_name, int flags)
{
  int old_kfd = at_kfd(old_dirfd);
  int new_kfd = at_kfd(new_dirfd);
  if (old_kfd != -1 && new_kfd != -1) {
    size_t old_size = strlen(old_name)+1;
    size_t new_size = strlen(new_name)+1;
    return frontend_syscall(SYS_linkat, old_kfd, va2pa(old_name), old_size,
                                        new_kfd, va2pa(new_name), new_size,
                                        flags);
  }
  return -EBADF;
}
Beispiel #7
0
long sys_unlinkat(int dirfd, const char* name, int flags)
{
  int kfd = at_kfd(dirfd);
  if (kfd != -1) {
    size_t name_size = strlen(name)+1;
    return frontend_syscall(SYS_unlinkat, kfd, va2pa(name), name_size, flags, 0, 0, 0);
  }
  return -EBADF;
}
Beispiel #8
0
/*
 * Initialize IOMMU
 * This looks like initialization of CPU MMU but
 * the routine is higher in food chain.
 */
static struct iommu_regs *
iommu_init(struct iommu *t, uint64_t base)
{
    unsigned int *ptab;
    int ptsize;
#ifdef CONFIG_DEBUG_IOMMU
    unsigned int impl, vers;
#endif
    unsigned int tmp;
    struct iommu_regs *regs;
    int ret;
    unsigned long vasize;

    regs = (struct iommu_regs *)ofmem_map_io(base, IOMMU_REGS);
    if (regs == NULL) {
        DPRINTF("Cannot map IOMMU\n");
        for (;;) { }
    }
    t->regs = regs;
#ifdef CONFIG_DEBUG_IOMMU
    impl = (regs->control & IOMMU_CTRL_IMPL) >> 28;
    vers = (regs->control & IOMMU_CTRL_VERS) >> 24;
#endif

    tmp = regs->control;
    tmp &= ~(IOMMU_CTRL_RNGE);

    tmp |= (IOMMU_RNGE_32MB | IOMMU_CTRL_ENAB);
    t->plow = 0xfe000000;		/* End - 32 MB */
    /* Size of VA region that we manage */
    vasize = 0x2000000; /* 32 MB */

    regs->control = tmp;
    iommu_invalidate(regs);

    /* Allocate IOMMU page table */
    /* Tremendous alignment causes great waste... */
    ptsize = (vasize / PAGE_SIZE) * sizeof(int);
    ret = ofmem_posix_memalign((void *)&ptab, ptsize, ptsize);
    if (ret != 0) {
        DPRINTF("Cannot allocate IOMMU table [0x%x]\n", ptsize);
        for (;;) { }
    }
    t->page_table = ptab;

    /* flush_cache_all(); */
    /** flush_tlb_all(); **/
    tmp = (unsigned int)va2pa((unsigned long)ptab);
    regs->base = tmp >> 4;
    iommu_invalidate(regs);

    DPRINTF("IOMMU: impl %d vers %d page table at 0x%p (pa 0x%x) of size %d bytes\n",
            impl, vers, t->page_table, tmp, ptsize);

    mem_init(&cdvmem, (char*)t->plow, (char *)0xfffff000);
    return regs;
}
Beispiel #9
0
long sys_mkdirat(int dirfd, const char* name, int mode)
{
  int kfd = at_kfd(dirfd);
  if (kfd != -1) {
    size_t name_size = strlen(name)+1;
    return frontend_syscall(SYS_mkdirat, kfd, va2pa(name), name_size, mode, 0, 0, 0);
  }
  return -EBADF;
}
Beispiel #10
0
//--------------------------------------------------------------------------------------------------*/
// 文件系统主循环任务
void task_fs(void * pdata)
{
	MSG 	msg;
	FS_MSG* 	p_fs_msg;
	pdata = pdata;
	int src;
	init_fs();
	while(1)
	{
//--------------------------------------------------------------------------------------------------*/
//
		assert(recv(ANY,&msg) == 0);
		assert(	msg.type == FS_MSG_UNION	);
		src	= msg.sender;
		p_fs_msg	= &msg.msg_union.fs_msg;
		switch(p_fs_msg->para)
		{
			case FS_OPEN:
				p_fs_msg->fd = fs_open(p_fs_msg->pathname,p_fs_msg->flags,task_table + msg.sender);
				break;
			case FS_WRITE:
				p_fs_msg->count = fs_write(p_fs_msg->fd,p_fs_msg->buf,p_fs_msg->offset,p_fs_msg->count,task_table + msg.sender);
  				break;
			case FS_READ:
				p_fs_msg->count = fs_read(p_fs_msg->fd,p_fs_msg->buf,p_fs_msg->offset,p_fs_msg->count,task_table + msg.sender);
           			break;
			case FS_CLOSE:
				p_fs_msg->para = fs_close(p_fs_msg->fd,task_table + msg.sender);
				break;
			case FS_DEL:
				p_fs_msg->para = fs_delete(va2pa((task_table + msg.sender)->pdb,p_fs_msg->pathname),p_fs_msg->flags);
				break;
			case FS_RESUME:
				src = p_fs_msg->flags;	// 待解除阻塞的进程ID(利用了flags这个成员返回PID)
				assert(0 <= src && src < NR_TOTAL);
				break;			// p_fs_msg->count:-1 请求失败(有其他进程正在请求输入),其他值表示输入字节数
			case FS_FORK:
				p_fs_msg->para	= fs_do_fork(p_fs_msg->flags);
				break;
			case FS_EXIT:
				fs_do_exit(p_fs_msg->flags);
				break;
			case FS_LSEEK:
				p_fs_msg->para	= fs_do_lseek(p_fs_msg->fd,p_fs_msg->offset,p_fs_msg->flags,task_table + msg.sender);
				break;
			default:	break;
		}
		if(no_answer == 1)
			no_answer = 0;			// 解除下一个tty请求的阻塞
		else
			send(src,&msg);
//--------------------------------------------------------------------------------------------------*/
	}
}
Beispiel #11
0
static void
kni_allocate_mbufs(struct rte_kni *kni)
{
	int i, ret;
	struct rte_mbuf *pkts[MAX_MBUF_BURST_NUM];
	void *phys[MAX_MBUF_BURST_NUM];

	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pool) !=
			 offsetof(struct rte_kni_mbuf, pool));
	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_addr) !=
			 offsetof(struct rte_kni_mbuf, buf_addr));
	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, next) !=
			 offsetof(struct rte_kni_mbuf, next));
	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_off) !=
			 offsetof(struct rte_kni_mbuf, data_off));
	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) !=
			 offsetof(struct rte_kni_mbuf, data_len));
	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) !=
			 offsetof(struct rte_kni_mbuf, pkt_len));
	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, ol_flags) !=
			 offsetof(struct rte_kni_mbuf, ol_flags));

	/* Check if pktmbuf pool has been configured */
	if (kni->pktmbuf_pool == NULL) {
		RTE_LOG(ERR, KNI, "No valid mempool for allocating mbufs\n");
		return;
	}

	for (i = 0; i < MAX_MBUF_BURST_NUM; i++) {
		pkts[i] = rte_pktmbuf_alloc(kni->pktmbuf_pool);
		if (unlikely(pkts[i] == NULL)) {
			/* Out of memory */
			RTE_LOG(ERR, KNI, "Out of memory\n");
			break;
		}
		phys[i] = va2pa(pkts[i]);
	}

	/* No pkt mbuf alocated */
	if (i <= 0)
		return;

	ret = kni_fifo_put(kni->alloc_q, phys, i);

	/* Check if any mbufs not put into alloc_q, and then free them */
	if (ret >= 0 && ret < i && ret < MAX_MBUF_BURST_NUM) {
		int j;

		for (j = ret; j < i; j++)
			rte_pktmbuf_free(pkts[j]);
	}
}
Beispiel #12
0
static size_t parse_args(arg_buf* args)
{
  long r = frontend_syscall(SYS_getmainvars, va2pa(args), sizeof(*args), 0, 0, 0, 0, 0);
  kassert(r == 0);
  uint64_t* pk_argv = &args->buf[1];
  // pk_argv[0] is the proxy kernel itself.  skip it and any flags.
  size_t pk_argc = args->buf[0], arg = 1;
  for ( ; arg < pk_argc && *(char*)(uintptr_t)pk_argv[arg] == '-'; arg++)
    handle_option((const char*)(uintptr_t)pk_argv[arg]);

  for (size_t i = 0; arg + i < pk_argc; i++)
    args->argv[i] = (char*)(uintptr_t)pk_argv[arg + i];
  return pk_argc - arg;
}
Beispiel #13
0
unsigned
rte_kni_tx_burst(struct rte_kni *kni, struct rte_mbuf **mbufs, unsigned num)
{
	void *phy_mbufs[num];
	unsigned int ret;
	unsigned int i;

	for (i = 0; i < num; i++)
		phy_mbufs[i] = va2pa(mbufs[i]);

	ret = kni_fifo_put(kni->rx_q, phy_mbufs, num);

	/* Get mbufs from free_q and then free them */
	kni_free_mbufs(kni);

	return ret;
}
Beispiel #14
0
/*
 * XXX This is a problematic interface. We alloc _memory_ which is uncached.
 * So if we ever reuse allocations somebody is going to get uncached pages.
 * Returned address is always aligned by page.
 * BTW, we were not going to give away anonymous storage, were we not?
 */
void *
dvma_alloc(int size, unsigned int *pphys)
{
    void *va;
    unsigned int pa, ba;
    unsigned int npages;
    unsigned int mva, mpa;
    unsigned int i;
    unsigned int *iopte;
    struct iommu *t = &ciommu;
    int ret;

    npages = (size + (PAGE_SIZE-1)) / PAGE_SIZE;
    ret = ofmem_posix_memalign(&va, npages * PAGE_SIZE, PAGE_SIZE);
    if (ret != 0)
        return NULL;

    ba = (unsigned int)mem_alloc(&cdvmem, npages * PAGE_SIZE, PAGE_SIZE);
    if (ba == 0)
        return NULL;

    pa = (unsigned int)va2pa((unsigned long)va);

    /*
     * Change page attributes in MMU to uncached.
     */
    mva = (unsigned int) va;
    mpa = (unsigned int) pa;
    ofmem_arch_map_pages(mpa, mva, npages * PAGE_SIZE, ofmem_arch_io_translation_mode(mpa));

    /*
     * Map into IOMMU page table.
     */
    mpa = (unsigned int) pa;
    iopte = &t->page_table[(ba - t->plow) / PAGE_SIZE];
    for (i = 0; i < npages; i++) {
        *iopte++ = MKIOPTE(mpa);
        mpa += PAGE_SIZE;
    }

    *pphys = ba;

    return va;
}
Beispiel #15
0
void *
mem_alloc(struct mem *t, int size, int align)
{
    char *p;
    unsigned long pa;

    // The alignment restrictions refer to physical, not virtual
    // addresses
    pa = va2pa((unsigned long)t->curp) + (align - 1);
    pa &= ~(align - 1);
    p = (char *)pa2va(pa);

    if ((unsigned long)p >= (unsigned long)t->uplim ||
            (unsigned long)p + size > (unsigned long)t->uplim)
        return NULL;
    t->curp = p + size;

    return p;
}
Beispiel #16
0
/*
函数功能:读文件
输入参数:进程指针	p_tcb
	文件fd	fd
	读缓冲	buf
	读大小	count	字节
输出参数:对于普通文件,输出实际读取字节数。
	对于字符设备:0 请求成功,-1 请求失败(有其他进程正在请求输入)
*/
int fs_read(int fd,void * buf,int offset,int count,TCB* p_tcb)
{
	File_Desc*	p_fd;
	Inode*		p_inode;
	buf	= va2pa(p_tcb->pdb,buf);
	p_fd	= p_tcb->filp[fd];
	p_inode	= p_fd->fd_inode;
	//----------------------------------------------------------
	// 字符设备文件
	if(p_inode->i_mode == I_MODE_CHAR)
	{
		MSG 	msg;
		msg.type				= TTY_MSG_UNION;
		msg.msg_union.tty_msg.para		= DEV_READ;
		msg.msg_union.tty_msg.sub_device	= MINOR(p_inode->i_start_sect);
		msg.msg_union.tty_msg.req_caller	= TASK_FS_PID;
		msg.msg_union.tty_msg.req_PID		= p_tcb - task_table;
		msg.msg_union.tty_msg.req_buf		= buf;
		msg.msg_union.tty_msg.req_count	= count;
		disable_int();
		if(tty_has_msg_tmp == 0)
		{
			if(sendrecv(SEND,dd_map[MAJAR(p_inode->i_start_sect)],&msg) == 0)
			{
				no_answer	= 1;	// 通知主循环将用户进程挂起
				enable_int();
				return	0;	// 0 消息发送成功
			}			// 请求是否成功在这里还不能判断,需要在主循环中收到tty发来的消息才知道
		}
		enable_int();
		return	-1;			// -1 发送消息失败(可能构成死锁)
	}
	//----------------------------------------------------------
	// 以下是普通文件
	int	cnt = file_buff_read(	buf,
					p_fd->fd_inode,
					offset + p_fd->fd_pos,
					count);
	assert(cnt != -1);
	p_fd->fd_pos	+= offset + cnt;
	return	cnt;
}
Beispiel #17
0
ssize_t
ia64_copyout(vm_offset_t va, void *dst, size_t len)
{
	void *pa;
	ssize_t res;
	size_t sz;

	res = 0;
	while (len > 0) {
		sz = len;
		pa = va2pa(va, &sz);
		if (sz == 0)
			break;
		bcopy(pa, dst, sz);
		len -= sz;
		res += sz;
		va += sz;
	}
	return (res);
}
Beispiel #18
0
ssize_t
ia64_copyin(const void *src, vm_offset_t va, size_t len)
{
	void *pa;
	ssize_t res;
	size_t sz;

	res = 0;
	while (len > 0) {
		sz = len;
		pa = va2pa(va, &sz);
		if (sz == 0)
			break;
		bcopy(src, pa, sz);
		len -= sz;
		res += sz;
		va += sz;
	}
	return (res);
}
Beispiel #19
0
void do_wp_page(void *addr)
{
    //printk("%s   addr %08x current %08x\n", __func__, (unsigned long)addr, current);
    if((unsigned long) addr >= PAGE_OFFSET)
    {
        panic("%s invalid addr", __func__);
    }

    int npde = get_npd(addr);
    int npte = get_npt(addr);

    pde_t *page_dir = (pde_t *)current->cr3;
    pte_t *page_tbl = pa2va(PAGE_ALIGN(page_dir[npde]));

    unsigned long wp_pa_addr = PAGE_ALIGN(page_tbl[npte]);
   
    page_t *page = pa2page(wp_pa_addr);
    if(page->count > 0)
    {
        page->count --;
        unsigned long flags = PAGE_FLAGS(page_tbl[npte]);
        unsigned long wp_va_addr = (unsigned long) pa2va(wp_pa_addr);
        unsigned long newtbl = alloc_one_page(0);
        assert(newtbl != 0);

        memcpy((void *)newtbl, (void *)wp_va_addr, PAGE_SIZE);

        page_tbl[npte] = va2pa(newtbl) | flags;
    }

    page_tbl[npte] |= PAGE_WR;
#if 0
    page_tbl[npte] |= PAGE_US;
    page_dir[npde] |= PAGE_WR;
    page_dir[npde] |= PAGE_US;
#endif

    load_cr3(current);
}
Beispiel #20
0
ssize_t
ia64_readin(int fd, vm_offset_t va, size_t len)
{
	void *pa;
	ssize_t res, s;
	size_t sz;

	res = 0;
	while (len > 0) {
		sz = len;
		pa = va2pa(va, &sz);
		if (sz == 0)
			break;
		s = read(fd, pa, sz);
		if (s <= 0)
			break;
		len -= s;
		res += s;
		va += s;
	}
	return (res);
}
Beispiel #21
0
/*
函数功能:写文件
输入参数:进程指针	p_tcb
	文件fd	fd
	写缓冲	buf
	写大小	count	字节
输出参数:成功返回实际写入字节数,失败返回-1
*/
int fs_write(int fd,void * buf,int offset,int count,TCB* p_tcb)
{
	File_Desc*	p_fd;
	Inode*		p_inode;
	buf	= va2pa(p_tcb->pdb,buf);
	p_fd	= p_tcb->filp[fd];
	p_inode	= p_fd->fd_inode;
	//----------------------------------------------------------
	// 字符设备文件
	if(p_inode->i_mode == I_MODE_CHAR)
	{
		MSG 	msg;
		msg.type				= TTY_MSG_UNION;
		msg.msg_union.tty_msg.para		= DEV_WRITE;
		msg.msg_union.tty_msg.sub_device	= MINOR(p_inode->i_start_sect);
		msg.msg_union.tty_msg.req_buf		= buf;
		msg.msg_union.tty_msg.req_count	= count;
		disable_int();
		if(tty_has_msg_tmp == 0)
		{
			if(sendrecv(BOTH,dd_map[MAJAR(p_inode->i_start_sect)],&msg) == -1)
				msg.msg_union.tty_msg.req_count = -1;
			enable_int();
			return	msg.msg_union.tty_msg.req_count;
		}
		enable_int();
		return	-1;
	}
	//----------------------------------------------------------
	// 以下是普通文件
	int	cnt = file_buff_write(	buf,
					p_fd->fd_inode,
					offset + p_fd->fd_pos,
					count);
	assert(cnt != -1);
	p_fd->fd_pos	+= offset + cnt;
	return	cnt;
}
Beispiel #22
0
/*
 * sys_disk_request
 *
 * Disk I/O without going through the buffer cache.
 *
 * xn_user is the name of a pxn that grants access to the disk
 * reqbp is a list of scatter/gather requests
 * k is which capability in the env should be checked
 *
 * permission is granted to perform the operation if:
 * 1) the blocks in reqbp are covered by the pxn
 * 2) the capability gives access to the pxn
 *
 */
int
sys_disk_request (u_int sn, struct Xn_name *xn_user, struct buf *reqbp,
		  u_int k)
{
  struct Xn_name xn;
  struct Xn_xtnt xtnt;
  struct Pxn *pxn;
  cap c;
  int ret;
  int access;
  struct disk *di;
  int *resptr = NULL;
  u_int bcount = 0;
  struct buf *bp, *segbp, *nsegbp;
  int noncontigs = 0, nctemp;

#ifdef MEASURE_DISK_TIMES
  disk_pctr_start = rdtsc();
#endif

  /* XXX - use PFM or copyin instead of isreadable_* */

  /* bypass for direct scsi commands */
  if (reqbp->b_flags & B_SCSICMD) {
    return sys_disk_scsicmd (sn, k, reqbp);
  }

  /* get the capability */
  if ((ret = env_getcap (curenv, k, &c)) < 0)
    return ret;

  /* and the pxn */
  copyin (xn_user, &xn, sizeof (xn));
  if (! (pxn = lookup_pxn (&xn))) {
    warn ("sys_disk_request: no pxn found");
    return (-E_NOT_FOUND);
  }

  /* XXX - do we need to check that this is a physical disk? */
  /* get a refernce to the disk unit for this command */
  di = &(si->si_disks[xn.xa_dev]);

  /* Iterate over the request list checking:
     -- if the request is transfering data to/from
     memory that this user can read/write.
     -- if the pxn and capability specified give
     access to these blocks */
  for (segbp = reqbp; ; segbp = (struct buf *) segbp->b_sgnext) {
    if (! (isreadable_varange ((u_int)segbp, sizeof(struct buf)))) {
      warn ("sys_disk_request: bad reqbp (%p)", segbp);
      return (-E_FAULT);
    }

    if (segbp->b_flags & B_READ) {
      access = ACL_R;
    } else {
      access = ACL_W;
    }
    
    xtnt.xtnt_block = segbp->b_blkno;
    xtnt.xtnt_size = segbp->b_bcount / di->d_bsize;
    bcount += segbp->b_bcount;

    if (! pxn_authorizes_xtnt (pxn, &c, &xtnt, access, &ret)) {
      warn ("sys_disk_request: pxn/cap does not grant access to block(s)");
      return ret;
    }

    if (! ((reqbp->b_flags & B_READ) ? iswriteable_varange
	   : isreadable_varange) ((u_int) segbp->b_memaddr, segbp->b_bcount)) {
      warn ("sys_disk_request: bad b_memaddr: %p (b_bcount %d)",
	    segbp->b_memaddr, segbp->b_bcount);
      return (-E_FAULT);
    }

    if (! (segbp->b_flags & B_SCATGATH)) {
      if (segbp->b_resptr) {
	resptr = segbp->b_resptr;
	if ((((u_int) resptr) % sizeof(u_int)) || 
	    !(isvawriteable (resptr))) {
	  warn ("sys_disk_request: bad resptr (%p)", resptr);
	  return (-E_FAULT);
	}
	resptr = (int *) pa2kva (va2pa (resptr));
      }
      break;
    }
  }

  if ((reqbp->b_flags & B_SCATGATH) && bcount != reqbp->b_sgtot) {
    warn ("sys_disk_request: invalid scatter/gather, with total (%u) unequal "
	  "to sum of parts (%u)", reqbp->b_sgtot, bcount);
    return (-E_INVAL);
  }

  /* are we done before we've started? */
  if (bcount == 0) {
    if (resptr)
      (*resptr)--;
    return (0);
  }

  if (bcount & di->d_bmod) {
    warn ("sys_disk_request: bad bcount %u", bcount);
    return (-E_INVAL);
  }

  /* copy request into kernel buffer */
  segbp = reqbp;
  nsegbp = NULL;
  reqbp = NULL;
  do {
    segbp->b_dev = di->d_id;
    bp = copy_and_pin(segbp, segbp->b_bcount, &nctemp);
    if (!bp) {
      warn ("sys_disk_request: could not copy_and_pin");
      /* XXX - cleanup before returning */
      return (-E_NO_MEM);
    }
    noncontigs += nctemp;
    if (nsegbp) nsegbp->b_sgnext = bp;
    if (!reqbp) reqbp = bp;
    if (noncontigs >= DISK_MAX_SCATTER) {
      warn ("sys_disk_request: would require too many scatter/gather entries "
	    "(%d)", noncontigs);
      /* XXX - cleanup before returning */
      return (-E_INVAL);
    }
    nsegbp = bp;
    segbp = segbp->b_sgnext;
  } while (nsegbp->b_flags & B_SCATGATH);

  nsegbp->b_resptr = resptr;

  if (resptr) ppage_pin (kva2pp((u_int) resptr));

  /* call appropriate strategy routine */
  di->d_strategy (reqbp);

#ifdef MEASURE_DISK_TIMES
  disk_pctr_return = rdtsc();
#endif

  return (0);
}
Beispiel #23
0
/*
 * sys_disk_mbr
 *
 * Read/Write the master boot record of a disk.
 *
 * The mbr contains the bootstrap code that the BIOS
 * loads on startup. This is always in sector 0
 * of the disk being booted. The mbr also contains the
 * partition table for the disk.
 *
 */
int
sys_disk_mbr (u_int sn, int write, u_int dev, int k, char *buffer, int *resptr)
{
  cap c;
  int ret;
  struct buf *diskbuf;

  /* get the capability */
  if ((ret = env_getcap (curenv, k, &c)) < 0)
    return ret;

  /* make sure the root cap was passed in */
  if (!cap_isroot (&c))
    return -E_CAP_INSUFF;

  /* verify the dev */
  if (dev >= si->si_ndisks)
    return -E_NOT_FOUND;

  /* check and translate the buffers we were given */
  if ((((u_int) resptr) % sizeof(u_int)) || 
      !(isvawriteable (resptr))) {
    warn ("sys_disk_mrb: bad resptr (%p)", resptr);
    return (-E_FAULT);
  }
  ppage_pin (pa2pp ((va2pa (resptr))));
  resptr = (int *) pa2kva (va2pa (resptr));

  if (write) {
    if (! (iswriteable_varange ((u_int)buffer, 512))) {
      warn ("sys_disk_mbr: bad buffer (%p)", buffer);
      return (-E_FAULT);
    }
  } else {
    if (! (isreadable_varange ((u_int)buffer, 512))) {
      warn ("sys_disk_mbr: bad buffer (%p)", buffer);
      return (-E_FAULT);
    }
  }

  /* get a disk req buffer and fill it in */
  diskbuf = disk_buf_alloc ();
  if (!diskbuf)
    return -E_NO_MEM;

  diskbuf->b_next = NULL;
  diskbuf->b_sgnext = NULL;
  diskbuf->b_dev = dev;
  diskbuf->b_blkno = 0;
  diskbuf->b_bcount = 512;	/* only want to read the first sector */
  diskbuf->b_sgtot = 512;
  diskbuf->b_memaddr = buffer;
  diskbuf->b_envid = curenv->env_id;
  diskbuf->b_resid = 0;
  diskbuf->b_resptr = resptr;
  diskbuf->b_flags = B_ABSOLUTE;		/* bypass partitions table */
  if (write) {
    diskbuf->b_flags |= B_WRITE;
  } else {
    diskbuf->b_flags |= B_READ;
  }

  /* pin it in case the user frees it before the request completes.
     This will be unpinned when sched_reqcomplete is called which
     in turn calls disk_buf_free which calls ppage_unpin. */

  ppage_pin (pa2pp ((va2pa (buffer))));

  /* start the request */
  si->si_disks[dev].d_strategy (diskbuf);

  return 0;
}
Beispiel #24
0
/* XXX - we should use copyin, etc, instead of isreadable_* so that user will
   get pagefaults he can handle transparently */
static int
sys_disk_scsicmd (u_int sn, u_int k, struct buf *reqbp)
{
  struct buf *bp;
  struct scsicmd *scsicmd = (struct scsicmd *) reqbp->b_memaddr;
  struct scsicmd *scsicmd2;
  int noncontigs;
  struct disk *di;

  /* must have root capability for system to do a raw SCSI command!!   */
  /* XXX -- later, if desired, deeper checking of validity can reduce  */
  /* this restriction...                                               */
  if (k >= curenv->env_clen || ! curenv->env_clist[k].c_valid) {
    warn ("sys_disk_scsicmd: bad capability number %u\n", k);
    return (-E_CAP_INVALID);
  }
  if (! cap_isroot(&curenv->env_clist[k])) {
    warn ("sys_disk_scsicmd: cap %u is not root capability for system\n", k);
    return (-E_CAP_INSUFF);
  }

  /* must be able to read the reqbp ... */
  if (! (isreadable_varange ((u_int) reqbp, sizeof (struct buf)))) {
    warn ("sys_disk_scsicmd: bad reqbp (%p)", reqbp);
    return (-E_FAULT);
  }

  /* Should be a SCSICMD */
  if (! (reqbp->b_flags & B_SCSICMD)) {
    warn ("sys_disk_scsicmd: not a B_SCSICMD\n");
    return (-E_INVAL);
  }

  /* Must be proper environment */
  if (reqbp->b_envid != curenv->env_id) {
    warn ("sys_disk_scsicmd: bad envid\n");
    return (-E_INVAL);
  }

  /* no scatter/gather support for raw SCSI commands */
  if (reqbp->b_flags & B_SCATGATH) {
    warn ("sys_disk_scsicmd: B_SCATGATH not allowed with B_SCSICMD\n");
    return (-E_INVAL);
  }

  /* can't send request to non-existent disk... */
  if (reqbp->b_dev >= si->si_ndevs) {
    warn ("sys_disk_scsicmd: there is no disk %u in system\n", reqbp->b_dev);
    return (-E_NOT_FOUND);
  }

  /* check that everything is readable */
  if (! isreadable_varange ((u_int) reqbp->b_memaddr,
			    sizeof (struct scsicmd))) {
    warn ("sys_disk_scsicmd: SCSI command description is not readable\n");
    return (-E_FAULT);
  }

  if (! isreadable_varange ((u_int) scsicmd->scsi_cmd, scsicmd->cmdlen) ) {
    warn ("sys_disk_scsicmd: SCSI command itself is not readable\n");
    return (-E_FAULT);
  }

  if (! isreadable_varange ((u_int)scsicmd->data_addr, scsicmd->datalen) ) {
    warn ("sys_disk_scsicmd: data area for SCSI command is not readable\n");
    return (-E_FAULT);
  }

  /* length of SCSI command must not be greater than B_SCSICMD_MAXLEN */
  if (scsicmd->cmdlen > B_SCSICMD_MAXLEN) {
    /* XXX - why do we compare scsicmd->cmdlen, but we print out
       reqbp->b_bcount? */
    warn ("sys_disk_scsicmd: specified SCSI command too large (%d > %d)\n",
	  reqbp->b_bcount, B_SCSICMD_MAXLEN);
    return (-E_INVAL);
  }

  /* copy the SCSI command to avoid sharing it with app */
  bp = bp_copy (reqbp);
  if (bp == NULL) {
    warn ("sys_disk_scsicmd: kernel malloc for bp failed\n");
    return (-E_NO_MEM);
  }
  bp->b_memaddr = malloc (sizeof (struct scsicmd));
  if (bp->b_memaddr == NULL) {
    warn ("sys_disk_scsicmd: kernel malloc for scsicmd failed\n");
    free (bp);
    return (-E_NO_MEM);
  }
  scsicmd2 = (struct scsicmd *) bp->b_memaddr;
  bcopy (scsicmd, scsicmd2, sizeof (struct scsicmd));
  scsicmd2->scsi_cmd = (struct scsi_generic *) malloc (scsicmd->cmdlen);
  if (scsicmd2->scsi_cmd == NULL) {
    warn ("sys_disk_scsicmd: second kernel malloc failed\n");
    free (bp->b_memaddr);
    free (bp);
    return (-E_NO_MEM);
  }
  bcopy (scsicmd->scsi_cmd, scsicmd2->scsi_cmd, scsicmd->cmdlen);
  scsicmd2->bp = bp;
  bp->b_resid = scsicmd->datalen;
  bp->b_resptr = (int *) pa2kva (va2pa (reqbp->b_resptr));

  /* pin down the app pages that will later be used by the driver */
  ppage_pin (kva2pp ((u_int) bp->b_resptr));
  noncontigs = pin_and_count_noncontigs (scsicmd2->data_addr,
					 scsicmd2->datalen);
  if (noncontigs >= DISK_MAX_SCATTER) {
    warn ("sys_disk_scsicmd: will require too many scatter/gather entries "
	  "(%d)", noncontigs);
    disk_buf_free (bp);
    return (-E_TOO_BIG);
  }

  /* XXX */
  /* call down to the low-level driver.  GROK -- since the partition stuff   */
  /* creates and abstract disk that is separate from the real one, a hack    */
  /* is needed to get the actual disk strategy routine for raw SCSI commands */
  /* This is fine as long as all disks actually go to the same strategy      */
  /* routine.                                                                */
   di = &(si->si_disks[0]);
   di->d_strategy (bp);

   return (0);
}
Beispiel #25
0
static msgringent *
msgringent_setup (msgringent * u_msgringent)
{
  msgringent *ktmp;
  Pte *pte = NULL;
  int scatptr = 0;
  int total_len = 0;

  ktmp = (msgringent *) malloc (sizeof (msgringent));
  if (ktmp == NULL)
  {
    warn ("msgringent_setup: failed malloc");
    return (NULL);
  }

  ktmp->appaddr = u_msgringent;
  ktmp->owner = NULL;
  ktmp->body.n = 0;

  /* Verify and translate owner field */
  if ((((u_int) u_msgringent->owner % sizeof (int)) ||
       ! (pte = va2ptep ((u_int) u_msgringent->owner)) ||
         ((*pte & WRITE_MASK) != WRITE_MASK)))
  {
    warn ("msgringent_setup: owner field failed\n");
    msgringent_free (ktmp);
    return (NULL);
  }
  ktmp->owner = (u_int *) pa2kva (va2pa (u_msgringent->owner));
  ppage_pin (kva2pp ((u_long) ktmp->owner));

  
  /* Verify and translate data field */
  if (u_msgringent->body.n > 1)
  {
    warn ("msgringent_setup: not allowed to setup disjoint message body\n");
    msgringent_free (ktmp);
    return (NULL);
  }

  scatptr = 0;
  total_len = 0;
  
  {
    int len = u_msgringent->body.r[0].sz;
    caddr_t addr = u_msgringent->body.r[0].data;
    u_int pagebound = NBPG-(((u_long)addr)&(NBPG - 1));

    while (len > 0)
    {
      u_int slen = min (len, pagebound);
      if (!(pte = va2ptep ((u_int) addr)) || 
          ((*pte & READ_MASK) != READ_MASK))
      {
        /* physical page is not accessible */
        warn ("msgringent_setup: can't read scatter ptr\n");
        msgringent_free (ktmp);
        return (NULL);
      }
            
      ktmp->body.r[scatptr].data = (char *) pa2kva (va2pa (addr));
      ktmp->body.r[scatptr].sz = slen;
      ktmp->body.n++;
	
      /* pin the page to prevent re-allocation */
      ppage_pin (kva2pp ((u_long) ktmp->body.r[scatptr].data));
      len -= slen;
      addr += slen;
      total_len += slen;
      pagebound = NBPG;
      scatptr++;
    
      if (scatptr > IPC_MAX_SCATTER_PTR || total_len > IPC_MAX_MSG_SIZE)
      {
        msgringent_free (ktmp);
        warn ("msgringent_setup: message body too big\n");
        return (NULL);
      }
    }
  }

  return (ktmp);
}
Beispiel #26
0
int sys_chdir(const char *path)
{
  return frontend_syscall(SYS_chdir, va2pa(path), 0, 0, 0, 0, 0, 0);
}
Beispiel #27
0
/*
函数功能:打开文件
输入参数:文件名	pathname
	打开方式	flags
	进程指针	p_tcb
输出参数:成功返回进程filp中的fd下标,失败返回-1
*/
int fs_open(char * pathname,int flags,TCB* p_tcb)
{
	pathname		= va2pa(p_tcb->pdb,pathname);
	DEV_Inode*	p_devinode;
	int		inode_nr;
	File_Desc*	p_fd;
	Inode*		p_inode;
	Dir_Entry*	p_de;
	int		i,j;
	
	// 读目录文件,寻找pathname,获得其inode_nr
	int	file_offset	= 0;
	for(i = 0,inode_nr = 0;i < ROOT_SECTS;i++,file_offset += SECTOR_SIZE)
	{
		file_buff_read(fsbuf,p_inode_de,file_offset,SECTOR_SIZE);
		for(j = 0,p_de = (Dir_Entry*)fsbuf;j < DIR_ENT_PER_SECT;j++,p_de++)
		{
			if(strcmp(p_de->name,pathname) == 0)
			{
				inode_nr = p_de->inode_nr;
				break;
			}
		}
		if(inode_nr != 0)
			break;
	}
	// 目录中寻找结束
	if(inode_nr == 0)				// 没找到dev_inode
	{
		if(flags == O_CREATE)
		{
			// 这里应该判断待创建打开的是否是普通文件
			inode_nr = create_file(pathname);
			if(inode_nr == 0)
			{
				printk("create_file error! %s\n",pathname);
				return	-1;	// 创建文件失败
			}
		}
		else
		{
			printk("no file : %s\n",pathname);
			return	-1;		// 没有找到,也没有创建文件
		}
	}
	//printk("file : %s   inode_nr : %d\n",pathname,inode_nr);
	// 找到了dev_inode编号inode_nr
	// 查看内存里的inode_table中是否存在该inode
	int	i_dev = ROOT_DEV;
	Inode*	p_inode_empty = 0;
	Inode*	p_inode_empty1 = 0;
	for(p_inode = inode_table;p_inode < inode_table + MAX_ALL_INODE;p_inode++)
	{
		if(p_inode->i_cnt == 0)
		{
			if(p_inode_empty == 0)
				p_inode_empty = p_inode;	// 第一个空位
			
			if(p_inode_empty1 == 0 && p_inode->i_dev == 0 && p_inode->i_num == 0)
				p_inode_empty1 = p_inode;	// 第一个从未被使用过的空位
		}
		if(p_inode->i_dev != i_dev)		continue;
		if(p_inode->i_num != inode_nr)	continue;
		break;
	}
	int	new_inode	= 0;
	if(p_inode >= inode_table + MAX_ALL_INODE)		// 不在inode_table里,需要手动添加
	{	// 在inode_table中寻找一个空位
		if(p_inode_empty1 != 0)
		{
			p_inode		= p_inode_empty1;
		}
		else
		{
			if(p_inode_empty == 0)
			{
				printk("inode_table full : %s----",pathname);
				return	-1;	// inode_table无空位
			}
			p_inode		= p_inode_empty;
		}
		
		new_inode		= 1;	// 用于判断该inode是否是新添加的
	}
	// 此时p_inode的i_dev i_num正确,但是i_cnt可能是0。即:现在找到的inode可能是正在被其他进程共享的,也可能是被其他进程废弃的
	// 在file_table中寻找一个空位
	for(p_fd = file_table;p_fd < file_table + MAX_ALL_FILE;p_fd++)
	{
		if(p_fd->fd_inode == 0)
			break;
	}
	//printk(" p_fd : %d   \n",p_fd - file_table);
	if(p_fd >= file_table + MAX_ALL_FILE)
	{
		printk("file_table full : %s----",pathname);
		return	-1;	// file_table无空位
	}
	// 在进程filp数组中寻找一个空位
	for(i = 0;i < MAX_TASK_FILE;i++)
	{
		if(p_tcb->filp[i] == 0)
			break;
	}
	if(i >= MAX_TASK_FILE)
	{
		printk("filp full : %s----",pathname);
		return	-1;	// filp无空位
	}
	// 填充空位信息
	p_tcb->filp[i]		= p_fd;
	
	p_fd->fd_mode		= RD_WR;
	p_fd->fd_pos		= 0;
	p_fd->fd_inode		= p_inode;
	p_inode->i_cnt++;
	if(new_inode == 1)		// 新添加的inode,需要赋值
	{
		//printk("new inode : %d\n",inode_nr);
		// 获取dev_inode指针
		hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (INODE_1ST_SECTS + inode_nr  / INODE_PER_SECT),1);
		p_devinode = (DEV_Inode*)fsbuf;
		p_devinode += inode_nr % INODE_PER_SECT;
		// 赋值
		p_inode->i_mode		= p_devinode->i_mode;
		p_inode->i_size		= p_devinode->i_size;
		p_inode->i_start_sect	= p_devinode->i_start_sect;
		p_inode->i_nr_sects		= p_devinode->i_nr_sects;
		p_inode->i_dev		= ROOT_DEV;
		p_inode->i_num		= inode_nr;
	}
	// 返回filp中的下标
	//printk("file open : %s  ----",pathname);
	if(p_inode->i_mode == I_MODE_CHAR)			// 字符设备文件
	{
		MSG 	msg;
		msg.type				= TTY_MSG_UNION;
		msg.msg_union.tty_msg.para		= DEV_OPEN;
		msg.msg_union.tty_msg.sub_device	= MINOR(p_inode->i_start_sect);	// 字符设备的i_start_sect即设备号
		//printk("sub_device : %d       ",msg.msg_union.tty_msg.sub_device);
		disable_int();
		if(tty_has_msg_tmp == 0)
		{
			assert(sendrecv(BOTH,dd_map[MAJAR(p_inode->i_start_sect)],&msg) == 0);
		}
		enable_int();
		
	}
	//printk(" i : %d----",i);
	return	i;
}
Beispiel #28
0
static int sbromsw_toc1_traverse(void)
{
	sbrom_toc1_item_group item_group;
	int ret;
	uint len, i;
	u8 buffer[SUNXI_X509_CERTIFF_MAX_LEN];

	sunxi_certif_info_t  root_certif;
	sunxi_certif_info_t  sub_certif;
	u8  hash_of_file[256];
	//u8  hash_in_certif[256];

	//u8  key_certif_extension[260];
	//u8  content_certif_key[520];
	int out_to_ns;
        int ready_out_to_ns = 0;
	toc1_item_traverse();

	printf("probe root certif\n");
	sunxi_ss_open();

	memset(buffer, 0, SUNXI_X509_CERTIFF_MAX_LEN);
	len = toc1_item_read_rootcertif(buffer, SUNXI_X509_CERTIFF_MAX_LEN);
	if(!len)
	{
		printf("%s error: cant read rootkey certif\n", __func__);

		return -1;
	}
	if(sunxi_certif_verify_itself(&root_certif, buffer, len))
	{
		printf("certif invalid: root certif verify itself failed\n");

		return -1;
	}
	do
	{
		memset(&item_group, 0, sizeof(sbrom_toc1_item_group));
		ret = toc1_item_probe_next(&item_group);
		if(ret < 0)
		{
			printf("sbromsw_toc1_traverse err in toc1_item_probe_next\n");

			return -1;
		}
		else if(ret == 0)
		{
			printf("sbromsw_toc1_traverse find out all items\n");

			return 0;
		}
		if(item_group.bin_certif)
		{
			memset(buffer, 0, SUNXI_X509_CERTIFF_MAX_LEN);
			len = toc1_item_read(item_group.bin_certif, buffer, SUNXI_X509_CERTIFF_MAX_LEN);
			if(!len)
			{
				printf("%s error: cant read content key certif\n", __func__);

				return -1;
			}
			//证书内容进行自校验,确保没有被替换
			if(sunxi_certif_verify_itself(&sub_certif, buffer, len))
			{
				printf("%s error: cant verify the content certif\n", __func__);

				return -1;
			}
//			printf("key n:\n");
//			ndump(sub_certif.pubkey.n, sub_certif.pubkey.n_len);
//			printf("key e:\n");
//			ndump(sub_certif.pubkey.e, sub_certif.pubkey.e_len);
			//每当发现一个公钥证书,即在根证书中寻找匹配项目,找不到则认为有错误
			for(i=0;i<root_certif.extension.extension_num;i++)
			{
				if(!strcmp((const char *)root_certif.extension.name[i], item_group.bin_certif->name))
				{
					printf("find %s key stored in root certif\n", item_group.bin_certif->name);

					if(memcmp(root_certif.extension.value[i], sub_certif.pubkey.n+1, sub_certif.pubkey.n_len-1))
					{
						printf("%s key n is incompatible\n", item_group.bin_certif->name);
						printf(">>>>>>>key in rootcertif<<<<<<<<<<\n");
						ndump(root_certif.extension.value[i], sub_certif.pubkey.n_len-1);
						printf(">>>>>>>key in certif<<<<<<<<<<\n");
						ndump(sub_certif.pubkey.n+1, sub_certif.pubkey.n_len-1);

						return -1;
					}
					if(memcmp(root_certif.extension.value[i] + sub_certif.pubkey.n_len-1, sub_certif.pubkey.e, sub_certif.pubkey.e_len))
					{
						printf("%s key e is incompatible\n", item_group.bin_certif->name);
						printf(">>>>>>>key in rootcertif<<<<<<<<<<\n");
						ndump(root_certif.extension.value[i] + sub_certif.pubkey.n_len-1, sub_certif.pubkey.e_len);
						printf(">>>>>>>key in certif<<<<<<<<<<\n");
						ndump(sub_certif.pubkey.e, sub_certif.pubkey.e_len);

						return -1;
					}
					break;
				}
			}
			if(i==root_certif.extension.extension_num)
			{
				printf("cant find %s key stored in root certif", item_group.bin_certif->name);

				return -1;
			}
		}

		if(item_group.binfile)
		{
			//读出bin文件内容到内存
			len = sunxi_flash_read(item_group.binfile->data_offset/512, (item_group.binfile->data_len+511)/512, (void *)item_group.binfile->run_addr);
			//len = sunxi_flash_read(item_group.binfile->data_offset/512, (item_group.binfile->data_len+511)/512, (void *)0x2a000000);
			if(!len)
			{
				printf("%s error: cant read bin file\n", __func__);

				return -1;
			}
			//计算文件hash
			memset(hash_of_file, 0, sizeof(hash_of_file));
			ret = sunxi_sha_calc(hash_of_file, sizeof(hash_of_file), (u8 *)item_group.binfile->run_addr, item_group.binfile->data_len);
			//ret = sunxi_sha_calc(hash_of_file, sizeof(hash_of_file), (u8 *)0x2a000000, item_group.binfile->data_len);
			if(ret)
			{
				printf("sunxi_sha_calc: calc sha256 with hardware err\n");

				return -1;
			}
			//使用内容证书的扩展项,和文件hash进行比较
			//开始比较文件hash(小机端阶段计算得到)和证书hash(PC端计算得到)
			if(memcmp(hash_of_file, sub_certif.extension.value[0], 32))
			{
				printf("hash compare is not correct\n");
				printf(">>>>>>>hash of file<<<<<<<<<<\n");
				ndump(hash_of_file, 32);
				printf(">>>>>>>hash in certif<<<<<<<<<<\n");
				ndump(sub_certif.extension.value[0], 32);

				return -1;
			}

			printf("ready to run %s\n", item_group.binfile->name);
                        if(!toc0_config->secure_without_OS)
                        {
                            ready_out_to_ns = 1;
                        }
                        else
                        {
                            printf("secure_without_OS mode  \n");
                            ready_out_to_ns = 0;
                        }
			if(strcmp(item_group.binfile->name, "u-boot"))
			{
                                out_to_ns = SECURE_SWITCH_OTHER;
			}
			else
			{
                            if(!ready_out_to_ns)
				out_to_ns = SECURE_NON_SECUREOS;
                            else
                                out_to_ns = SECURE_SWITCH_NORMAL;
			}
			toc0_config->next_exe_pa   = va2pa(item_group.binfile->run_addr);
			go_exec(item_group.binfile->run_addr, CONFIG_TOC0_CONFIG_ADDR, out_to_ns);
		}
	}
	while(1);

	return 0;
}
Beispiel #29
0
void
page_check(void)
{
	struct Page *pp, *pp0, *pp1, *pp2;
	struct Page_list fl;

	// should be able to allocate three pages
	pp0 = pp1 = pp2 = 0;
	assert(page_alloc(&pp0) == 0);
	assert(page_alloc(&pp1) == 0);
	assert(page_alloc(&pp2) == 0);

	assert(pp0);
	assert(pp1 && pp1 != pp0);
	assert(pp2 && pp2 != pp1 && pp2 != pp0);

	// temporarily steal the rest of the free pages
	fl = page_free_list;
	LIST_INIT(&page_free_list);

	// should be no free memory
	assert(page_alloc(&pp) == -E_NO_MEM);

	// there is no free memory, so we can't allocate a page table
	assert(page_insert(boot_pgdir, pp1, 0x0, 0) < 0);

	// free pp0 and try again: pp0 should be used for page table
	page_free(pp0);
	assert(page_insert(boot_pgdir, pp1, 0x0, 0) == 0);
	assert(PTE_ADDR(boot_pgdir[0]) == page2pa(pp0));
	assert(va2pa(boot_pgdir, 0x0) == page2pa(pp1));
	assert(pp1->pp_ref == 1);

	// should be able to map pp2 at BY2PG because pp0 is already allocated for page table
	assert(page_insert(boot_pgdir, pp2, BY2PG, 0) == 0);
	assert(va2pa(boot_pgdir, BY2PG) == page2pa(pp2));
	assert(pp2->pp_ref == 1);
	// should be no free memory
	assert(page_alloc(&pp) == -E_NO_MEM);
	//printf("why\n");
	// should be able to map pp2 at BY2PG because it's already there
	assert(page_insert(boot_pgdir, pp2, BY2PG, 0) == 0);
	assert(va2pa(boot_pgdir, BY2PG) == page2pa(pp2));
	assert(pp2->pp_ref == 1);
	//printf("It is so unbelivable\n");
	// pp2 should NOT be on the free list
	// could happen in ref counts are handled sloppily in page_insert
	assert(page_alloc(&pp) == -E_NO_MEM);

	// should not be able to map at PDMAP because need free page for page table
	assert(page_insert(boot_pgdir, pp0, PDMAP, 0) < 0);

	// insert pp1 at BY2PG (replacing pp2)
	assert(page_insert(boot_pgdir, pp1, BY2PG, 0) == 0);

	// should have pp1 at both 0 and BY2PG, pp2 nowhere, ...
	assert(va2pa(boot_pgdir, 0x0) == page2pa(pp1));
	assert(va2pa(boot_pgdir, BY2PG) == page2pa(pp1));
	// ... and ref counts should reflect this
	assert(pp1->pp_ref == 2);
	assert(pp2->pp_ref == 0);

	// pp2 should be returned by page_alloc
	assert(page_alloc(&pp) == 0 && pp == pp2);

	// unmapping pp1 at 0 should keep pp1 at BY2PG
	page_remove(boot_pgdir, 0x0);
	assert(va2pa(boot_pgdir, 0x0) == ~0);
	assert(va2pa(boot_pgdir, BY2PG) == page2pa(pp1));
	assert(pp1->pp_ref == 1);
	assert(pp2->pp_ref == 0);

	// unmapping pp1 at BY2PG should free it
	page_remove(boot_pgdir, BY2PG);
	assert(va2pa(boot_pgdir, 0x0) == ~0);
	assert(va2pa(boot_pgdir, BY2PG) == ~0);
	assert(pp1->pp_ref == 0);
	assert(pp2->pp_ref == 0);

	// so it should be returned by page_alloc
	assert(page_alloc(&pp) == 0 && pp == pp1);

	// should be no free memory
	assert(page_alloc(&pp) == -E_NO_MEM);

	// forcibly take pp0 back
	assert(PTE_ADDR(boot_pgdir[0]) == page2pa(pp0));
	boot_pgdir[0] = 0;
	assert(pp0->pp_ref == 1);
	pp0->pp_ref = 0;

	// give free list back
	page_free_list = fl;

	// free the pages we took
	page_free(pp0);
	page_free(pp1);
	page_free(pp2);

	printf("page_check() succeeded!\n");
}
Beispiel #30
0
long sys_getcwd(const char* buf, size_t size)
{
  populate_mapping(buf, size, PROT_WRITE);
  return frontend_syscall(SYS_getcwd, va2pa(buf), size, 0, 0, 0, 0, 0);
}