ssize_t write(int fdnum, const void *buf, size_t n) { int r; struct Dev *dev; struct Fd *fd; if ((r = fd_lookup(fdnum, &fd)) < 0 || (r = dev_lookup(fd->fd_dev_id, &dev)) < 0) return r; if ((fd->fd_omode & O_ACCMODE) == O_RDONLY) { cprintf("[%08x] write %d -- bad mode\n", thisenv->env_id, fdnum); return -E_INVAL; } if (debug) cprintf("write %d %p %d via dev %s\n", fdnum, buf, n, dev->dev_name); if (!dev->dev_write) return -E_NOT_SUPP; return (*dev->dev_write)(fd, buf, n); }
ssize_t read(int fdnum, void *buf, size_t n) { int r; struct Dev *dev; struct Fd *fd; struct Stat statbuf; if ((r = fd_lookup(fdnum, &fd)) < 0 || (r = dev_lookup(fd->fd_dev_id, &dev)) < 0) return r; if ((fd->fd_omode & O_ACCMODE) == O_WRONLY) { cprintf("[%08x] read %d -- bad mode\n", thisenv->env_id, fdnum); return -E_INVAL; } if (!dev->dev_read) return -E_NOT_SUPP; return (*dev->dev_read)(fd, buf, n); }
/* * MTS mapping. * * It is NOT inlined since it triggers a GCC bug on my config (x86, GCC 3.3.5) */ static no_inline MTS_ENTRY * MTS_PROTO(map)(cpu_mips_t *cpu,u_int op_type,mts_map_t *map, MTS_ENTRY *entry,MTS_ENTRY *alt_entry) { struct vdevice *dev; m_uint32_t offset; m_iptr_t host_ptr; int cow; if (!(dev = dev_lookup(cpu->vm,map->paddr,map->cached))) return NULL; if (dev->flags & VDEVICE_FLAG_SPARSE) { host_ptr = dev_sparse_get_host_addr(cpu->vm,dev,map->paddr,op_type,&cow); entry->gvpa = map->vaddr; entry->gppa = map->paddr; entry->hpa = host_ptr; entry->flags = (cow) ? MTS_FLAG_COW : 0; return entry; } if (!dev->host_addr || (dev->flags & VDEVICE_FLAG_NO_MTS_MMAP)) { offset = (map->paddr + map->offset) - dev->phys_addr; /* device entries are never stored in virtual TLB */ alt_entry->hpa = (dev->id << MTS_DEVID_SHIFT) + offset; alt_entry->flags = MTS_FLAG_DEV; return alt_entry; } entry->gvpa = map->vaddr; entry->gppa = map->paddr; entry->hpa = dev->host_addr + (map->paddr - dev->phys_addr); entry->flags = 0; return entry; }