Exemple #1
0
static void generic_loader_reset(void *opaque)
{
    GenericLoaderState *s = GENERIC_LOADER(opaque);

    if (s->set_pc) {
        CPUClass *cc = CPU_GET_CLASS(s->cpu);
        cpu_reset(s->cpu);
        if (cc) {
            cc->set_pc(s->cpu, s->addr);
        }
    }

    if (s->data_len) {
        MemTxAttrs attrs = { .unspecified = 0,
                             .secure = 0,
                             .user = 0,
                             .debug = 0,
                             .requester_id = 0,
        };

        attrs.debug = s->attrs.debug;
        attrs.secure = s->attrs.secure;
        attrs.requester_id = s->attrs.requester_id;

        assert(s->data_len < sizeof(s->data));
        address_space_rw(s->cpu->as, s->addr, attrs, (uint8_t *)&s->data,
                         s->data_len, true);
    }
}
static void generic_loader_reset(void *opaque)
{
    GenericLoaderState *s = GENERIC_LOADER(opaque);

    if (s->set_pc) {
        CPUClass *cc = CPU_GET_CLASS(s->cpu);
        cpu_reset(s->cpu);
        if (cc) {
            cc->set_pc(s->cpu, s->addr);
        }
    }

    if (s->data_len) {
        assert(s->data_len < sizeof(s->data));
        dma_memory_write(s->cpu->as, s->addr, &s->data, s->data_len);
    }
}
Exemple #3
0
static void generic_loader_realize(DeviceState *dev, Error **errp)
{
    GenericLoaderState *s = GENERIC_LOADER(dev);
    hwaddr entry;
    int big_endian;
    int size = 0;

    s->set_pc = false;

    /* Perform some error checking on the user's options */
    if (s->data || s->data_len  || s->data_be) {
        /* User is loading memory values */
        if (s->file) {
            error_setg(errp, "Specifying a file is not supported when loading "
                       "memory values");
            return;
        } else if (s->force_raw) {
            error_setg(errp, "Specifying force-raw is not supported when "
                       "loading memory values");
            return;
        } else if (!s->data_len) {
            /* We can't check for !data here as a value of 0 is still valid. */
            error_setg(errp, "Both data and data-len must be specified");
            return;
        } else if (s->data_len > 8) {
            error_setg(errp, "data-len cannot be greater then 8 bytes");
            return;
        }
    } else if (s->file || s->force_raw)  {
        /* User is loading an image */
        if (s->data || s->data_len || s->data_be) {
            error_setg(errp, "data can not be specified when loading an "
                       "image");
            return;
        }
        /* The user specified a file, only set the PC if they also specified
         * a CPU to use.
         */
        if (s->cpu_num != CPU_NONE) {
            s->set_pc = true;
        }
    } else if (s->addr) {
        /* User is setting the PC */
        if (s->data || s->data_len || s->data_be) {
            error_setg(errp, "data can not be specified when setting a "
                       "program counter");
            return;
        } else if (!s->cpu_num) {
            error_setg(errp, "cpu_num must be specified when setting a "
                       "program counter");
            return;
        }
        s->set_pc = true;
    } else {
        /* Did the user specify anything? */
        error_setg(errp, "please include valid arguments");
        return;
    }

    qemu_register_reset_loader(generic_loader_reset, dev);

    if (s->cpu_num != CPU_NONE) {
        s->cpu = qemu_get_cpu(s->cpu_num);
        if (!s->cpu) {
            error_setg(errp, "Specified boot CPU#%d is nonexistent",
                       s->cpu_num);
            return;
        }
    } else {
        s->cpu = first_cpu;
    }

#ifdef TARGET_WORDS_BIGENDIAN
    big_endian = 1;
#else
    big_endian = 0;
#endif

    if (s->file) {
        AddressSpace *as = s->cpu ? s->cpu->as :  NULL;

        if (!s->force_raw) {
            size = load_elf_as(s->file, NULL, NULL, &entry, NULL, NULL,
                               big_endian, 0, 0, 0, as);

            if (size < 0) {
                size = load_uimage_as(s->file, &entry, NULL, NULL, NULL, NULL,
                                      as);
            }
        }

        if (size < 0 || s->force_raw) {
            /* Default to the maximum size being the machine's ram size */
            size = load_image_targphys_as(s->file, s->addr, ram_size, as);
        } else {
            s->addr = entry;
        }

        if (size < 0) {
            error_setg(errp, "Cannot load specified image %s", s->file);
            return;
        }
    }

    /* Convert the data endiannes */
    if (s->data_be) {
        s->data = cpu_to_be64(s->data);
    } else {
        s->data = cpu_to_le64(s->data);
    }

    /* Xilinx: If qdev_hotplug is set then the machine has already been
     * created. This means we are hot-plugging a device. We need to forefully
     * call the reset function to ensure the operation completes.
     */
    if (qdev_hotplug) {
        generic_loader_reset(dev);
    }
}
static void generic_loader_realize(DeviceState *dev, Error **errp)
{
    GenericLoaderState *s = GENERIC_LOADER(dev);
    hwaddr entry;
    int big_endian;
    int size = 0;

    s->set_pc = false;

    /* Xilinx: This is the old deprecated command line argument.
     * Print a warning to tell users that it will be removed.
     */
    if (s->cpu_num_dep != CPU_NONE) {
        fprintf(stderr, "The 'cpu=' command line option has been deprecated " \
                "and replaced with 'cpu-num='. Please update your command " \
                "line to use 'cpu-num=' as 'cpu=' will be removed after the " \
                "2017.4 release.\n");
        if (s->cpu_num == CPU_NONE) {
            s->cpu_num = s->cpu_num_dep;
        }
    }

    /* Perform some error checking on the user's options */
    if (s->data || s->data_len  || s->data_be) {
        /* User is loading memory values */
        if (s->file) {
            error_setg(errp, "Specifying a file is not supported when loading "
                       "memory values");
            return;
        } else if (s->force_raw) {
            error_setg(errp, "Specifying force-raw is not supported when "
                       "loading memory values");
            return;
        } else if (!s->data_len) {
            /* We can't check for !data here as a value of 0 is still valid. */
            error_setg(errp, "Both data and data-len must be specified");
            return;
        } else if (s->data_len > 8) {
            error_setg(errp, "data-len cannot be greater then 8 bytes");
            return;
        }
    } else if (s->file || s->force_raw)  {
        /* User is loading an image */
        if (s->data || s->data_len || s->data_be) {
            error_setg(errp, "data can not be specified when loading an "
                       "image");
            return;
        }
        /* The user specified a file, only set the PC if they also specified
         * a CPU to use.
         */
        if (s->cpu_num != CPU_NONE) {
            s->set_pc = true;
        }
    } else if (s->addr) {
        /* User is setting the PC */
        if (s->data || s->data_len || s->data_be) {
            error_setg(errp, "data can not be specified when setting a "
                       "program counter");
            return;
        } else if (!s->cpu_num) {
            error_setg(errp, "cpu_num must be specified when setting a "
                       "program counter");
            return;
        }
        s->set_pc = true;
    } else {
        /* Did the user specify anything? */
        error_setg(errp, "please include valid arguments");
        return;
    }

    qemu_register_reset(generic_loader_reset, dev);

    if (s->cpu_num != CPU_NONE) {
        s->cpu = qemu_get_cpu(s->cpu_num);
        if (!s->cpu) {
            error_setg(errp, "Specified boot CPU#%d is nonexistent",
                       s->cpu_num);
            return;
        }
    } else {
        s->cpu = first_cpu;
    }

#ifdef TARGET_WORDS_BIGENDIAN
    big_endian = 1;
#else
    big_endian = 0;
#endif

    if (s->file) {
        AddressSpace *as = s->cpu ? s->cpu->as :  NULL;

        if (!s->force_raw) {
            size = load_elf_as(s->file, NULL, NULL, &entry, NULL, NULL,
                               big_endian, 0, 0, 0, as);

            if (size < 0) {
                size = load_uimage_as(s->file, &entry, NULL, NULL, NULL, NULL,
                                      as);
            }
        }

        if (size < 0 || s->force_raw) {
            /* Default to the maximum size being the machine's ram size */
            size = load_image_targphys_as(s->file, s->addr, ram_size, as);
        } else {
            s->addr = entry;
        }

        if (size < 0) {
            error_setg(errp, "Cannot load specified image %s", s->file);
            return;
        }
    }

    /* Convert the data endiannes */
    if (s->data_be) {
        s->data = cpu_to_be64(s->data);
    } else {
        s->data = cpu_to_le64(s->data);
    }
}