Loongarch IPI is added here, it inherits from class TYPE_LOONGSON_IPI_COMMON, and two interfaces get_iocsr_as() and cpu_by_arch_id() are added for Loongarch 3A5000 machine. It can be used when ipi is emulated in userspace with KVM mode. Signed-off-by: Bibo Mao <maobibo@loongson.cn> [PMD: Rebased and simplified] Co-Developed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Bibo Mao <maobibo@loongson.cn> Tested-by: Bibo Mao <maobibo@loongson.cn> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Acked-by: Song Gao <gaosong@loongson.cn> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com> Tested-by: Jiaxun Yang <jiaxun.yang@flygoat.com> Message-Id: <20240805180622.21001-13-philmd@linaro.org>
		
			
				
	
	
		
			69 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* SPDX-License-Identifier: GPL-2.0-or-later */
 | 
						|
/*
 | 
						|
 * LoongArch IPI interrupt support
 | 
						|
 *
 | 
						|
 * Copyright (C) 2024 Loongson Technology Corporation Limited
 | 
						|
 */
 | 
						|
 | 
						|
#include "qemu/osdep.h"
 | 
						|
#include "hw/boards.h"
 | 
						|
#include "hw/intc/loongarch_ipi.h"
 | 
						|
#include "target/loongarch/cpu.h"
 | 
						|
 | 
						|
static AddressSpace *get_iocsr_as(CPUState *cpu)
 | 
						|
{
 | 
						|
    return LOONGARCH_CPU(cpu)->env.address_space_iocsr;
 | 
						|
}
 | 
						|
 | 
						|
static int archid_cmp(const void *a, const void *b)
 | 
						|
{
 | 
						|
   CPUArchId *archid_a = (CPUArchId *)a;
 | 
						|
   CPUArchId *archid_b = (CPUArchId *)b;
 | 
						|
 | 
						|
   return archid_a->arch_id - archid_b->arch_id;
 | 
						|
}
 | 
						|
 | 
						|
static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id)
 | 
						|
{
 | 
						|
    CPUArchId apic_id, *found_cpu;
 | 
						|
 | 
						|
    apic_id.arch_id = id;
 | 
						|
    found_cpu = bsearch(&apic_id, ms->possible_cpus->cpus,
 | 
						|
                        ms->possible_cpus->len,
 | 
						|
                        sizeof(*ms->possible_cpus->cpus),
 | 
						|
                        archid_cmp);
 | 
						|
 | 
						|
    return found_cpu;
 | 
						|
}
 | 
						|
 | 
						|
static CPUState *loongarch_cpu_by_arch_id(int64_t arch_id)
 | 
						|
{
 | 
						|
    MachineState *machine = MACHINE(qdev_get_machine());
 | 
						|
    CPUArchId *archid;
 | 
						|
 | 
						|
    archid = find_cpu_by_archid(machine, arch_id);
 | 
						|
    if (archid) {
 | 
						|
        return CPU(archid->cpu);
 | 
						|
    }
 | 
						|
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static void loongarch_ipi_class_init(ObjectClass *klass, void *data)
 | 
						|
{
 | 
						|
    LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_CLASS(klass);
 | 
						|
 | 
						|
    licc->get_iocsr_as = get_iocsr_as;
 | 
						|
    licc->cpu_by_arch_id = loongarch_cpu_by_arch_id;
 | 
						|
}
 | 
						|
 | 
						|
static const TypeInfo loongarch_ipi_types[] = {
 | 
						|
    {
 | 
						|
        .name               = TYPE_LOONGARCH_IPI,
 | 
						|
        .parent             = TYPE_LOONGSON_IPI_COMMON,
 | 
						|
        .class_init         = loongarch_ipi_class_init,
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
DEFINE_TYPES(loongarch_ipi_types)
 |