Commit 15f43ccd authored by Aurelien Jarno's avatar Aurelien Jarno
Browse files

Merge branch 'ppc-next' of git://repo.or.cz/qemu/agraf

* 'ppc-next' of git://repo.or.cz/qemu/agraf:
  PPC: Add description for the Freescale e500mc core.
  pseries: Check for duplicate addresses on the spapr-vio bus
  pseries: Populate "/chosen/linux,stdout-path" in the FDT
  pseries: Add a routine to find a stable "default" vty and use it
  pseries: Emit device tree nodes in reg order
  pseries: FDT NUMA extensions to support multi-node guests
  pseries: Remove hcalls callback
  kvm-ppc: halt secondary cpus when guest reset
  console: Fix segfault on screendump without VGA adapter
  PPC: monitor: add ability to dump SLB entries
parents c2780865 f7aa5583
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -186,8 +186,10 @@ void vga_hw_screen_dump(const char *filename)
        consoles[0]->hw_screen_dump(consoles[0]->hw, filename);
    }

    if (previous_active_console) {
        console_select(previous_active_console->index);
    }
}

void vga_hw_text_update(console_ch_t *chardata)
{
+1 −0
Original line number Diff line number Diff line
@@ -112,6 +112,7 @@ static void spin_kick(void *data)

    env->halted = 0;
    env->exception_index = -1;
    env->stopped = 0;
    qemu_cpu_kick(env);
}

+103 −11
Original line number Diff line number Diff line
@@ -97,6 +97,44 @@ qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num)
    return qirq;
}

static int spapr_set_associativity(void *fdt, sPAPREnvironment *spapr)
{
    int ret = 0, offset;
    CPUState *env;
    char cpu_model[32];
    int smt = kvmppc_smt_threads();

    assert(spapr->cpu_model);

    for (env = first_cpu; env != NULL; env = env->next_cpu) {
        uint32_t associativity[] = {cpu_to_be32(0x5),
                                    cpu_to_be32(0x0),
                                    cpu_to_be32(0x0),
                                    cpu_to_be32(0x0),
                                    cpu_to_be32(env->numa_node),
                                    cpu_to_be32(env->cpu_index)};

        if ((env->cpu_index % smt) != 0) {
            continue;
        }

        snprintf(cpu_model, 32, "/cpus/%s@%x", spapr->cpu_model,
                 env->cpu_index);

        offset = fdt_path_offset(fdt, cpu_model);
        if (offset < 0) {
            return offset;
        }

        ret = fdt_setprop(fdt, offset, "ibm,associativity", associativity,
                          sizeof(associativity));
        if (ret < 0) {
            return ret;
        }
    }
    return ret;
}

static void *spapr_create_fdt_skel(const char *cpu_model,
                                   target_phys_addr_t rma_size,
                                   target_phys_addr_t initrd_base,
@@ -107,9 +145,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
{
    void *fdt;
    CPUState *env;
    uint64_t mem_reg_property_rma[] = { 0, cpu_to_be64(rma_size) };
    uint64_t mem_reg_property_nonrma[] = { cpu_to_be64(rma_size),
                                           cpu_to_be64(ram_size - rma_size) };
    uint64_t mem_reg_property[2];
    uint32_t start_prop = cpu_to_be32(initrd_base);
    uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
    uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
@@ -119,6 +155,13 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
    int i;
    char *modelname;
    int smt = kvmppc_smt_threads();
    unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
    uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
    uint32_t associativity[] = {cpu_to_be32(0x4), cpu_to_be32(0x0),
                                cpu_to_be32(0x0), cpu_to_be32(0x0),
                                cpu_to_be32(0x0)};
    char mem_name[32];
    target_phys_addr_t node0_size, mem_start;

#define _FDT(exp) \
    do { \
@@ -146,6 +189,9 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
    /* /chosen */
    _FDT((fdt_begin_node(fdt, "chosen")));

    /* Set Form1_affinity */
    _FDT((fdt_property(fdt, "ibm,architecture-vec-5", vec5, sizeof(vec5))));

    _FDT((fdt_property_string(fdt, "bootargs", kernel_cmdline)));
    _FDT((fdt_property(fdt, "linux,initrd-start",
                       &start_prop, sizeof(start_prop))));
@@ -164,24 +210,54 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
    _FDT((fdt_end_node(fdt)));

    /* memory node(s) */
    _FDT((fdt_begin_node(fdt, "memory@0")));
    node0_size = (nb_numa_nodes > 1) ? node_mem[0] : ram_size;
    if (rma_size > node0_size) {
        rma_size = node0_size;
    }

    /* RMA */
    mem_reg_property[0] = 0;
    mem_reg_property[1] = cpu_to_be64(rma_size);
    _FDT((fdt_begin_node(fdt, "memory@0")));
    _FDT((fdt_property_string(fdt, "device_type", "memory")));
    _FDT((fdt_property(fdt, "reg", mem_reg_property_rma,
                       sizeof(mem_reg_property_rma))));
    _FDT((fdt_property(fdt, "reg", mem_reg_property,
        sizeof(mem_reg_property))));
    _FDT((fdt_property(fdt, "ibm,associativity", associativity,
        sizeof(associativity))));
    _FDT((fdt_end_node(fdt)));

    if (ram_size > rma_size) {
        char mem_name[32];
    /* RAM: Node 0 */
    if (node0_size > rma_size) {
        mem_reg_property[0] = cpu_to_be64(rma_size);
        mem_reg_property[1] = cpu_to_be64(node0_size - rma_size);

        sprintf(mem_name, "memory@%" PRIx64, (uint64_t)rma_size);
        sprintf(mem_name, "memory@" TARGET_FMT_lx, rma_size);
        _FDT((fdt_begin_node(fdt, mem_name)));
        _FDT((fdt_property_string(fdt, "device_type", "memory")));
        _FDT((fdt_property(fdt, "reg", mem_reg_property_nonrma,
                           sizeof(mem_reg_property_nonrma))));
        _FDT((fdt_property(fdt, "reg", mem_reg_property,
                           sizeof(mem_reg_property))));
        _FDT((fdt_property(fdt, "ibm,associativity", associativity,
                           sizeof(associativity))));
        _FDT((fdt_end_node(fdt)));
    }

    /* RAM: Node 1 and beyond */
    mem_start = node0_size;
    for (i = 1; i < nb_numa_nodes; i++) {
        mem_reg_property[0] = cpu_to_be64(mem_start);
        mem_reg_property[1] = cpu_to_be64(node_mem[i]);
        associativity[3] = associativity[4] = cpu_to_be32(i);
        sprintf(mem_name, "memory@" TARGET_FMT_lx, mem_start);
        _FDT((fdt_begin_node(fdt, mem_name)));
        _FDT((fdt_property_string(fdt, "device_type", "memory")));
        _FDT((fdt_property(fdt, "reg", mem_reg_property,
            sizeof(mem_reg_property))));
        _FDT((fdt_property(fdt, "ibm,associativity", associativity,
            sizeof(associativity))));
        _FDT((fdt_end_node(fdt)));
        mem_start += node_mem[i];
    }

    /* cpus */
    _FDT((fdt_begin_node(fdt, "cpus")));

@@ -194,6 +270,9 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
        modelname[i] = toupper(modelname[i]);
    }

    /* This is needed during FDT finalization */
    spapr->cpu_model = g_strdup(modelname);

    for (env = first_cpu; env != NULL; env = env->next_cpu) {
        int index = env->cpu_index;
        uint32_t servers_prop[smp_threads];
@@ -280,6 +359,9 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
    _FDT((fdt_property(fdt, "ibm,hypertas-functions", hypertas_prop,
                       sizeof(hypertas_prop))));

    _FDT((fdt_property(fdt, "ibm,associativity-reference-points",
        refpoints, sizeof(refpoints))));

    _FDT((fdt_end_node(fdt)));

    /* interrupt controller */
@@ -351,6 +433,16 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
        fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
    }

    /* Advertise NUMA via ibm,associativity */
    if (nb_numa_nodes > 1) {
        ret = spapr_set_associativity(fdt, spapr);
        if (ret < 0) {
            fprintf(stderr, "Couldn't set up NUMA device tree properties\n");
        }
    }

    spapr_populate_chosen_stdout(fdt, spapr->vio_bus);

    _FDT((fdt_pack(fdt)));

    cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ typedef struct sPAPREnvironment {
    target_ulong entry_point;
    int next_irq;
    int rtc_offset;
    char *cpu_model;
} sPAPREnvironment;

#define H_SUCCESS         0
+6 −11
Original line number Diff line number Diff line
@@ -474,16 +474,6 @@ static target_ulong h_multicast_ctrl(CPUState *env, sPAPREnvironment *spapr,
    return H_SUCCESS;
}

static void vlan_hcalls(VIOsPAPRBus *bus)
{
    spapr_register_hypercall(H_REGISTER_LOGICAL_LAN, h_register_logical_lan);
    spapr_register_hypercall(H_FREE_LOGICAL_LAN, h_free_logical_lan);
    spapr_register_hypercall(H_SEND_LOGICAL_LAN, h_send_logical_lan);
    spapr_register_hypercall(H_ADD_LOGICAL_LAN_BUFFER,
                             h_add_logical_lan_buffer);
    spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl);
}

static VIOsPAPRDeviceInfo spapr_vlan = {
    .init = spapr_vlan_init,
    .devnode = spapr_vlan_devnode,
@@ -491,7 +481,6 @@ static VIOsPAPRDeviceInfo spapr_vlan = {
    .dt_type = "network",
    .dt_compatible = "IBM,l-lan",
    .signal_mask = 0x1,
    .hcalls = vlan_hcalls,
    .qdev.name = "spapr-vlan",
    .qdev.size = sizeof(VIOsPAPRVLANDevice),
    .qdev.props = (Property[]) {
@@ -504,5 +493,11 @@ static VIOsPAPRDeviceInfo spapr_vlan = {
static void spapr_vlan_register(void)
{
    spapr_vio_bus_register_withprop(&spapr_vlan);
    spapr_register_hypercall(H_REGISTER_LOGICAL_LAN, h_register_logical_lan);
    spapr_register_hypercall(H_FREE_LOGICAL_LAN, h_free_logical_lan);
    spapr_register_hypercall(H_SEND_LOGICAL_LAN, h_send_logical_lan);
    spapr_register_hypercall(H_ADD_LOGICAL_LAN_BUFFER,
                             h_add_logical_lan_buffer);
    spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl);
}
device_init(spapr_vlan_register);
Loading