Ejemplo n.º 1
0
/* Create the image package file */
static int pack_images(const char *fip_filename)
{
	int status;
	uint8_t *fip_base_address;
	void *entry_address;
	fip_toc_header_t *toc_header;
	fip_toc_entry_t *toc_entry;
	unsigned int entry_index;
	unsigned int toc_size;
	unsigned int fip_size;
	unsigned int entry_offset_address;
	unsigned int payload_size = 0;

	/* Validate filename */
	if ((fip_filename == NULL) || (strcmp(fip_filename, "") == 0)) {
		return EINVAL;
	}

	/* Payload size calculation */
	for (entry_index = 0; entry_index < file_info_count; entry_index++) {
		payload_size += files[entry_index].size;
	}

	/* Allocate memory for entire package, including the final null entry */
	toc_size = (sizeof(fip_toc_header_t) +
		    (sizeof(fip_toc_entry_t) * (file_info_count + 1)));
	fip_size = toc_size + payload_size;
	fip_base_address = malloc(fip_size);
	if (fip_base_address == NULL) {
		printf("Error: Can't allocate enough memory to create package."
		       "Process aborted.\n");
		return ENOMEM;
	}
	memset(fip_base_address, 0, fip_size);

	/* Create ToC Header */
	toc_header = (fip_toc_header_t *)fip_base_address;
	toc_header->name = TOC_HEADER_NAME;
	toc_header->serial_number = TOC_HEADER_SERIAL_NUMBER;
	toc_header->flags = 0;

	toc_entry = (fip_toc_entry_t *)(fip_base_address +
				      sizeof(fip_toc_header_t));

	/* Calculate the starting address of the first image, right after the
	 * toc header.
	 */
	entry_offset_address = toc_size;
	entry_index = 0;

	/* Create the package in memory. */
	for (entry_index = 0; entry_index < file_info_count; entry_index++) {
		entry_address = (fip_base_address + entry_offset_address);
		status = read_file_to_memory(entry_address,
					     &files[entry_index]);
		if (status != 0) {
			printf("Error: While reading \"%s\" from filesystem.\n",
				files[entry_index].filename);
			return status;
		}

		copy_uuid(&toc_entry->uuid, &files[entry_index].name_uuid);
		toc_entry->offset_address = entry_offset_address;
		toc_entry->size = files[entry_index].size;
		toc_entry->flags = 0;
		entry_offset_address += toc_entry->size;
		toc_entry++;
	}

	/* Add a null uuid entry to mark the end of toc entries */
	copy_uuid(&toc_entry->uuid, &uuid_null);
	toc_entry->offset_address = entry_offset_address;
	toc_entry->size = 0;
	toc_entry->flags = 0;

	/* Save the package to file */
	status = write_memory_to_file(fip_base_address, fip_filename, fip_size);
	if (status != 0) {
		printf("Error: Failed while writing package to file \"%s\" "
			"with status=%d.\n", fip_filename, status);
		return status;
	}
	return 0;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{
    struct core *core;
    int option;
    bool enable_memory_dump = false;
    uint32_t mem_dump_base = 0;
    uint32_t mem_dump_length = 0;
    char *mem_dump_filename = NULL;
    size_t mem_dump_filename_len = 0;
    bool verbose = false;
    uint32_t fb_width = 640;
    uint32_t fb_height = 480;
    bool block_device_open = false;
    bool enable_fb_window = false;
    uint32_t total_threads = 4;
    char *separator;
    uint32_t memory_size = 0x1000000;
    const char *shared_memory_file = NULL;
    struct stat st;

    enum
    {
        MODE_NORMAL,
        MODE_COSIMULATION,
        MODE_GDB_REMOTE_DEBUG
    } mode = MODE_NORMAL;

    while ((option = getopt(argc, argv, "f:d:vm:b:t:c:r:s:i:o:")) != -1)
    {
        switch (option)
        {
            case 'v':
                verbose = true;
                break;

            case 'r':
                screen_refresh_rate = parse_num_arg(optarg);
                break;

            case 'f':
                enable_fb_window = true;
                separator = strchr(optarg, 'x');
                if (!separator)
                {
                    fprintf(stderr, "Invalid frame buffer size %s\n", optarg);
                    return 1;
                }

                fb_width = parse_num_arg(optarg);
                fb_height = parse_num_arg(separator + 1);
                break;

            case 'm':
                if (strcmp(optarg, "normal") == 0)
                    mode = MODE_NORMAL;
                else if (strcmp(optarg, "cosim") == 0)
                    mode = MODE_COSIMULATION;
                else if (strcmp(optarg, "gdb") == 0)
                    mode = MODE_GDB_REMOTE_DEBUG;
                else
                {
                    fprintf(stderr, "Unkown execution mode %s\n", optarg);
                    return 1;
                }

                break;

            case 'd':
                // Memory dump, of the form: filename,start,length
                separator = strchr(optarg, ',');
                if (separator == NULL)
                {
                    fprintf(stderr, "bad format for memory dump\n");
                    usage();
                    return 1;
                }

                mem_dump_filename_len = (size_t)(separator - optarg);
                mem_dump_filename = (char*) malloc(mem_dump_filename_len + 1);
                strncpy(mem_dump_filename, optarg, mem_dump_filename_len);
                mem_dump_filename[mem_dump_filename_len] = '\0';
                mem_dump_base = parse_num_arg(separator + 1);

                separator = strchr(separator + 1, ',');
                if (separator == NULL)
                {
                    fprintf(stderr, "bad format for memory dump\n");
                    usage();
                    return 1;
                }

                mem_dump_length = parse_num_arg(separator + 1);
                enable_memory_dump = true;
                break;

            case 'b':
                if (open_block_device(optarg) < 0)
                    return 1;

                block_device_open = true;
                break;

            case 'c':
                memory_size = parse_num_arg(optarg);
                break;

            case 't':
                total_threads = parse_num_arg(optarg);
                if (total_threads < 1 || total_threads > 32)
                {
                    fprintf(stderr, "Total threads must be between 1 and 32\n");
                    return 1;
                }

                break;

            case 's':
                shared_memory_file = optarg;
                break;

            case 'i':
                recv_interrupt_fd = open(optarg, O_RDWR);
                if (recv_interrupt_fd < 0)
                {
                    perror("main: failed to open receive interrupt pipe");
                    return 1;
                }

                if (fstat(recv_interrupt_fd, &st) < 0)
                {
                    perror("main: stat failed on receive interrupt pipe");
                    return 1;
                }

                if ((st.st_mode & S_IFMT) != S_IFIFO)
                {
                    fprintf(stderr, "%s is not a pipe\n", optarg);
                    return 1;
                }

                break;

            case 'o':
                send_interrupt_fd = open(optarg, O_RDWR);
                if (send_interrupt_fd < 0)
                {
                    perror("main: failed to open send interrupt pipe");
                    return 1;
                }

                if (fstat(send_interrupt_fd, &st) < 0)
                {
                    perror("main: stat failed on send interrupt pipe");
                    return 1;
                }

                if ((st.st_mode & S_IFMT) != S_IFIFO)
                {
                    fprintf(stderr, "%s is not a pipe\n", optarg);
                    return 1;
                }

                break;

            case '?':
                usage();
                return 1;
        }
    }

    if (optind == argc)
    {
        fprintf(stderr, "No image filename specified\n");
        usage();
        return 1;
    }

    // Don't randomize memory for cosimulation mode, because
    // memory is checked against the hardware model to ensure a match

    core = init_core(memory_size, total_threads, mode != MODE_COSIMULATION,
                     shared_memory_file);
    if (core == NULL)
        return 1;

    if (load_hex_file(core, argv[optind]) < 0)
    {
        fprintf(stderr, "Error reading image %s\n", argv[optind]);
        return 1;
    }

    if (enable_fb_window)
    {
        if (init_frame_buffer(fb_width, fb_height) < 0)
            return 1;
    }

    switch (mode)
    {
        case MODE_NORMAL:
            if (verbose)
                enable_tracing(core);

            set_stop_on_fault(core, false);
            if (enable_fb_window)
            {
                while (execute_instructions(core, ALL_THREADS, screen_refresh_rate))
                {
                    update_frame_buffer(core);
                    poll_fb_window_event();
                    check_interrupt_pipe(core);
                }
            }
            else
            {
                while (execute_instructions(core, ALL_THREADS, 1000000))
                    check_interrupt_pipe(core);
            }

            break;

        case MODE_COSIMULATION:
            set_stop_on_fault(core, false);
            if (run_cosimulation(core, verbose) < 0)
                return 1;	// Failed

            break;

        case MODE_GDB_REMOTE_DEBUG:
            set_stop_on_fault(core, true);
            remote_gdb_main_loop(core, enable_fb_window);
            break;
    }

    if (enable_memory_dump)
        write_memory_to_file(core, mem_dump_filename, mem_dump_base, mem_dump_length);

    dump_instruction_stats(core);
    if (block_device_open)
        close_block_device();

    if (stopped_on_fault(core))
        return 1;

    return 0;
}