예제 #1
0
  /**
   * Transfer data from the specified array to this process's virtual memory. This method handles
   * address translation details. This method must <i>not</i> destroy the current process if an
   * error occurs, but instead should return the number of bytes successfully copied (or zero if no
   * data could be copied).
   *
   * @param vaddr the first byte of virtual memory to write.
   * @param data the array containing the data to transfer.
   * @param offset the first byte to transfer from the array.
   * @param length the number of bytes to transfer from the array to virtual memory.
   * @return the number of bytes successfully transferred.
   */
  public int writeVirtualMemory(int vaddr, byte[] data, int offset, int length) {
    Lib.assertTrue(offset >= 0 && length >= 0 && offset + length <= data.length);

    byte[] memory = Machine.processor().getMemory();

    int transferred = 0;
    while (length > 0 && offset < data.length) {
      int addrOffset = vaddr % 1024;
      int virtualPage = vaddr / 1024;

      if (virtualPage >= pageTable.length || virtualPage < 0) {
        break;
      }

      TranslationEntry pte = pageTable[virtualPage];
      if (!pte.valid || pte.readOnly) {
        break;
      }
      pte.used = true;
      pte.dirty = true;

      int physPage = pte.ppn;
      int physAddr = physPage * 1024 + addrOffset;

      int transferLength = Math.min(data.length - offset, Math.min(length, 1024 - addrOffset));
      System.arraycopy(data, offset, memory, physAddr, transferLength);
      vaddr += transferLength;
      offset += transferLength;
      length -= transferLength;
      transferred += transferLength;
    }

    return transferred;
  }
예제 #2
0
  private int handleWrite(int a0, int bufaddr, int count) {
    OpenFile file = openfiles.get(a0);
    if (file == null) return -1;
    byte[] transfer_buffer = new byte[Processor.pageSize];
    int total_transfer = 0;
    while (count > 0) {
      int readlen = Math.min(Processor.pageSize, count);

      int actualread = readVirtualMemory(bufaddr, transfer_buffer, 0, readlen);
      if (actualread == -1) return -1;
      if (actualread < readlen) return -1;

      int written_bytes = file.write(transfer_buffer, 0, actualread);
      if (written_bytes != actualread) {
        return -1;
      }
      count -= actualread;
      bufaddr += actualread;
      total_transfer += actualread;
    }
    return total_transfer;
  }