Пример #1
0
static int
mmio_read_x(int argc, const char *argv[], const struct cmd_info *info)
{
	int ret;
	data_store data;
	struct mmap_info mmap_addr;
	const struct mmap_file_flags *mmf;

	mmf = info->privdata;

	mmap_addr.addr = strtoull(argv[1], NULL, 0);

	if (open_mapping(&mmap_addr, O_RDONLY | mmf->flags, sizeof(data)) < 0) {
		return -1;
	}

	ret = 0;

	#define DO_READ(mem_, off_, size_)\
		data.u ##size_ = *(typeof(data.u ##size_) *)(mem_ + off_); \
		fprintf(stdout, "0x%0*llx\n", (int)sizeof(data.u ##size_)*2, \
		        (unsigned long long)data.u ##size_)

	switch (get_command_size(info)) {
	case SIZE8:
		DO_READ(mmap_addr.mem, mmap_addr.off, 8);
		break;
	case SIZE16:
		DO_READ(mmap_addr.mem, mmap_addr.off, 16);
		break;
	case SIZE32:
		DO_READ(mmap_addr.mem, mmap_addr.off, 32);
		break;
	case SIZE64:
		if (sizeof(void *) != sizeof(uint64_t)) {
			fprintf(stderr, "warning: 64 bit operations might "
			        "not be atomic on 32 bit builds\n");
		}
		DO_READ(mmap_addr.mem, mmap_addr.off, 64);
		break;
	default:
		fprintf(stderr, "invalid mmio_read parameter\n");
		ret = -1;
	}

	close_mapping(&mmap_addr);

	return ret;
}
Пример #2
0
static int
mmio_write_x(int argc, const char *argv[], const struct cmd_info *info)
{
	int ret;
	unsigned long ldata;
	data_store data;
	struct mmap_info mmap_addr;

	mmap_addr.addr = strtoull(argv[1], NULL, 0);
	ldata = strtoul(argv[2], NULL, 0);

	if (open_mapping(&mmap_addr, O_RDWR, sizeof(data)) < 0) {
		return -1;
	}

	ret = 0;

	#define DO_WRITE(mem_, off_, size_)\
		data.u ##size_ = (typeof(data.u ##size_))ldata;\
		*(typeof(data.u ##size_) *)(mem_+off_) = data.u ##size_

	switch (get_command_size(info)) {
	case SIZE8:
		DO_WRITE(mmap_addr.mem, mmap_addr.off, 8);
		break;
	case SIZE16:
		DO_WRITE(mmap_addr.mem, mmap_addr.off, 16);
		break;
	case SIZE32:
		DO_WRITE(mmap_addr.mem, mmap_addr.off, 32);
		break;
	case SIZE64:
		if (sizeof(void *) != sizeof(uint64_t)) {
			fprintf(stderr, "warning: 64 bit operations might "
			        "not be atomic on 32 bit builds\n");
		}
		DO_WRITE(mmap_addr.mem, mmap_addr.off, 64);
		break;
	default:
		fprintf(stderr, "invalid mmio_write parameter\n");
		ret = -1;
	}

	close_mapping(&mmap_addr);

	return ret;
}
Пример #3
0
/*
 * DANG_BEGIN_FUNCTION low_mem_init
 *
 * description:
 *  Initializes the lower 1Meg via mmap & sets up the HMA region
 *
 * DANG_END_FUNCTION
 */
void low_mem_init(void)
{
  void *lowmem, *result;
#ifdef __i386__
  PRIV_SAVE_AREA
#endif

  open_mapping(MAPPING_INIT_LOWRAM);
  g_printf ("DOS+HMA memory area being mapped in\n");
  lowmem = alloc_mapping(MAPPING_INIT_LOWRAM, LOWMEM_SIZE + HMASIZE, -1);
  if (lowmem == MAP_FAILED) {
    perror("LOWRAM alloc");
    leavedos(98);
  }

#ifdef __i386__
  /* we may need root to mmap address 0 */
  enter_priv_on();
  result = alias_mapping(MAPPING_INIT_LOWRAM, 0, LOWMEM_SIZE + HMASIZE,
			 PROT_READ | PROT_WRITE | PROT_EXEC, lowmem);
  leave_priv_setting();

  if (result == MAP_FAILED && (errno == EPERM || errno == EACCES)) {
#ifndef X86_EMULATOR
    perror ("LOWRAM mmap");
    fprintf(stderr, "Cannot map low DOS memory (the first 640k).\n"
	      "You can most likely avoid this problem by running\n"
	      "sysctl -w vm.mmap_min_addr=0\n"
	      "as root, or by changing the vm.mmap_min_addr setting in\n"
	      "/etc/sysctl.conf or a file in /etc/sysctl.d/ to 0.\n"
	      "If this doesn't help, disable selinux in /etc/selinux/config\n"
	      );
    exit(EXIT_FAILURE);
#else
    if (config.cpuemu < 3)
    {
      /* switch on vm86-only JIT CPU emulation to with non-zero base */
      config.cpuemu = 3;
      init_emu_cpu();
      c_printf("CONF: JIT CPUEMU set to 3 for %d86\n", (int)vm86s.cpu_type);
      error("Using CPU emulation because vm.mmap_min_addr > 0.\n"
	      "You can most likely avoid this problem by running\n"
	      "sysctl -w vm.mmap_min_addr=0\n"
	      "as root, or by changing the vm.mmap_min_addr setting in\n"
	      "/etc/sysctl.conf or a file in /etc/sysctl.d/ to 0.\n"
	      "If this doesn't help, disable selinux in /etc/selinux/config\n"
	      );
    }
    result = alias_mapping(MAPPING_INIT_LOWRAM, -1, LOWMEM_SIZE + HMASIZE,
			   PROT_READ | PROT_WRITE | PROT_EXEC, lowmem);
#endif
  }
#else
  result = alias_mapping(MAPPING_INIT_LOWRAM, -1, LOWMEM_SIZE + HMASIZE,
			   PROT_READ | PROT_WRITE | PROT_EXEC, lowmem);
  if (config.cpuemu < 3) {
    /* switch on vm86-only JIT CPU emulation to with non-zero base */
    config.cpuemu = 3;
    init_emu_cpu();
    c_printf("CONF: JIT CPUEMU set to 3 for %d86\n", (int)vm86s.cpu_type);
  }
#endif

  if (result == MAP_FAILED) {
    perror ("LOWRAM mmap");
    exit(EXIT_FAILURE);
  }

#ifdef X86_EMULATOR
  if (result) {
    warn("WARN: using non-zero memory base address %p.\n"
	 "WARN: You can use the better-tested zero based setup using\n"
	 "WARN: sysctl -w vm.mmap_min_addr=0\n"
	 "WARN: as root, or by changing the vm.mmap_min_addr setting in\n"
	 "WARN: /etc/sysctl.conf or a file in /etc/sysctl.d/ to 0.\n",
	    result);
  }
#endif

  /* keep conventional memory protected as long as possible to protect
     NULL pointer dereferences */
  mprotect_mapping(MAPPING_LOWMEM, result, config.mem_size * 1024, PROT_NONE);
}
Пример #4
0
static int
mmio_dump(int argc, const char *argv[], const struct cmd_info *info)
{
	unsigned long bytes_to_dump;
	unsigned long bytes_left;
	struct mmap_info mmap_addr;
	uint32_t *addr;
	uint64_t desired_addr;
	int fields_on_line;
	int write_binary;

	desired_addr = strtoull(argv[1], NULL, 0);
	bytes_to_dump = strtoul(argv[2], NULL, 0);

	write_binary = 0;
	if (argc == 4) {
		if (!strcmp(argv[3], "-b")) {
			write_binary = 1;
		} else {
			return -1;
		}
	}

	mmap_addr.addr = desired_addr;
	if (open_mapping(&mmap_addr, O_RDONLY, bytes_to_dump) < 0) {
		return -1;
	}

	if (write_binary) {
		void *buffer_to_write = (void *)mmap_addr.mem + mmap_addr.off;
		int ret = fwrite(buffer_to_write, bytes_to_dump, 1, stdout);
		close_mapping(&mmap_addr);
		return ret == 1 ? 0 : -1;
	}

	addr = (void *)mmap_addr.mem + mmap_addr.off;
	bytes_left = bytes_to_dump;

	fields_on_line = 0;
	while (bytes_left) {
		int bytes_printed = sizeof(*addr);
		/* Print out the current address. */
		if (!fields_on_line) {
			fprintf(stdout, "0x%016llx:",
			        (unsigned long long)desired_addr);
		}

		/* Print out the leftover bytes. */
		if (bytes_left < sizeof(*addr)) {
			unsigned char *ptr = (unsigned char *)addr;
			fprintf(stdout, " 0x%02x", *ptr);
			/* Adjust the working pointer and the bytes_printed */
			addr = (typeof(addr))++ptr;
			bytes_printed = sizeof(*ptr);
		} else {
			fprintf(stdout, " 0x%08x", *addr);
			addr++;
		}

		/* Keep track of statistics. */
		bytes_left -= bytes_printed;
		desired_addr += bytes_printed;

		/* Default to printing out 4 sets of 32-bit values. */
		fields_on_line = (fields_on_line + 1) % 4;

		/* Handle the new line once we are field 0 again. */
		if (!fields_on_line) {
			fprintf(stdout, "\n");
		}
	}

	/* Print newline if we stopped printing in the middle of a line. */
	if (fields_on_line) {
		fprintf(stdout, "\n");
	}

	close_mapping(&mmap_addr);

	return 0;
}