LoongArch: Fix virtual machine startup error

Upstream: no

Signed-off-by: liuyun <liuyun@loongson.cn>
Signed-off-by: maobibo <maobibo@loongson.cn>
Signed-off-by: Ming Wang <wangming01@loongson.cn>
This commit is contained in:
liuyun 2023-12-02 10:08:32 +08:00 committed by aurelianliu
parent 4fe09071db
commit 09932ae2e4
4 changed files with 35 additions and 15 deletions

View File

@ -53,6 +53,7 @@ struct acpi_vector_group {
extern struct acpi_vector_group pch_group[MAX_IO_PICS]; extern struct acpi_vector_group pch_group[MAX_IO_PICS];
extern struct acpi_vector_group msi_group[MAX_IO_PICS]; extern struct acpi_vector_group msi_group[MAX_IO_PICS];
#define MAX_CORES_PER_EIO_NODE 256
#define CORES_PER_EIO_NODE 4 #define CORES_PER_EIO_NODE 4
#define LOONGSON_CPU_UART0_VEC 10 /* CPU UART0 */ #define LOONGSON_CPU_UART0_VEC 10 /* CPU UART0 */

View File

@ -171,6 +171,7 @@
/* IOCSR */ /* IOCSR */
#define iocsr_read32(reg) __iocsrrd_w(reg) #define iocsr_read32(reg) __iocsrrd_w(reg)
#define iocsr_read64(reg) __iocsrrd_d(reg) #define iocsr_read64(reg) __iocsrrd_d(reg)
#define iocsr_write8(val, reg) __iocsrwr_b(val, reg)
#define iocsr_write32(val, reg) __iocsrwr_w(val, reg) #define iocsr_write32(val, reg) __iocsrwr_w(val, reg)
#define iocsr_write64(val, reg) __iocsrwr_d(val, reg) #define iocsr_write64(val, reg) __iocsrwr_d(val, reg)

View File

@ -211,7 +211,7 @@ int setup_legacy_IRQ(void)
} }
pic_domain = get_pchpic_irq_domain(); pic_domain = get_pchpic_irq_domain();
if (pic_domain) if (pic_domain && !cpu_has_hypervisor)
pch_lpc_acpi_init(pic_domain, acpi_pchlpc); pch_lpc_acpi_init(pic_domain, acpi_pchlpc);
return 0; return 0;
@ -373,9 +373,12 @@ __init unsigned long legacy_boot_init(unsigned long argc, unsigned long cmdptr,
efi_bp = (struct boot_params *)bpi; efi_bp = (struct boot_params *)bpi;
bpi_version = get_bpi_version(&efi_bp->signature); bpi_version = get_bpi_version(&efi_bp->signature);
pr_info("BPI%d with boot flags %llx.\n", bpi_version, efi_bp->flags); pr_info("BPI%d with boot flags %llx.\n", bpi_version, efi_bp->flags);
if (bpi_version == BPI_VERSION_NONE) if (bpi_version == BPI_VERSION_NONE) {
panic("Fatal error, bpi ver BONE!\n"); if (cpu_has_hypervisor)
else if (bpi_version == BPI_VERSION_V2) pr_err(FW_BUG "Fatal error, bpi ver NONE!\n");
else
panic(FW_BUG "Fatal error, bpi ver NONE!\n");
} else if (bpi_version == BPI_VERSION_V2)
parse_bpi_flags(); parse_bpi_flags();
fw_init_cmdline(argc, cmdptr); fw_init_cmdline(argc, cmdptr);

View File

@ -56,7 +56,9 @@ static void eiointc_enable(void)
static int cpu_to_eio_node(int cpu) static int cpu_to_eio_node(int cpu)
{ {
return cpu_logical_map(cpu) / CORES_PER_EIO_NODE; int cores = (cpu_has_hypervisor ? MAX_CORES_PER_EIO_NODE : CORES_PER_EIO_NODE);
return cpu_logical_map(cpu) / cores;
} }
static void eiointc_set_irq_route(int pos, unsigned int cpu, unsigned int mnode, nodemask_t *node_map) static void eiointc_set_irq_route(int pos, unsigned int cpu, unsigned int mnode, nodemask_t *node_map)
@ -87,6 +89,11 @@ static void eiointc_set_irq_route(int pos, unsigned int cpu, unsigned int mnode,
static DEFINE_RAW_SPINLOCK(affinity_lock); static DEFINE_RAW_SPINLOCK(affinity_lock);
static void virt_extioi_set_irq_route(int irq, unsigned int cpu)
{
iocsr_write8(cpu_logical_map(cpu), EIOINTC_REG_ROUTE + irq);
}
static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity, bool force) static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity, bool force)
{ {
unsigned int cpu; unsigned int cpu;
@ -109,16 +116,22 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af
vector = d->hwirq; vector = d->hwirq;
regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2); regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2);
/* Mask target vector */ if (cpu_has_hypervisor) {
csr_any_send(regaddr, EIOINTC_ALL_ENABLE & (~BIT(vector & 0x1F)), iocsr_write32(EIOINTC_ALL_ENABLE & ~BIT(vector & 0x1F), regaddr);
0x0, priv->node * CORES_PER_EIO_NODE); virt_extioi_set_irq_route(vector, cpu);
iocsr_write32(EIOINTC_ALL_ENABLE, regaddr);
} else {
/* Mask target vector */
csr_any_send(regaddr, EIOINTC_ALL_ENABLE & (~BIT(vector & 0x1F)),
0x0, priv->node * CORES_PER_EIO_NODE);
/* Set route for target vector */ /* Set route for target vector */
eiointc_set_irq_route(vector, cpu, priv->node, &priv->node_map); eiointc_set_irq_route(vector, cpu, priv->node, &priv->node_map);
/* Unmask target vector */ /* Unmask target vector */
csr_any_send(regaddr, EIOINTC_ALL_ENABLE, csr_any_send(regaddr, EIOINTC_ALL_ENABLE,
0x0, priv->node * CORES_PER_EIO_NODE); 0x0, priv->node * CORES_PER_EIO_NODE);
}
irq_data_update_effective_affinity(d, cpumask_of(cpu)); irq_data_update_effective_affinity(d, cpumask_of(cpu));
@ -145,13 +158,14 @@ static int eiointc_router_init(unsigned int cpu)
uint32_t data; uint32_t data;
uint32_t node = cpu_to_eio_node(cpu); uint32_t node = cpu_to_eio_node(cpu);
int index = eiointc_index(node); int index = eiointc_index(node);
int cores = (cpu_has_hypervisor ? MAX_CORES_PER_EIO_NODE : CORES_PER_EIO_NODE);
if (index < 0) { if (index < 0) {
pr_err("Error: invalid nodemap!\n"); pr_err("Error: invalid nodemap!\n");
return -1; return -1;
} }
if ((cpu_logical_map(cpu) % CORES_PER_EIO_NODE) == 0) { if ((cpu_logical_map(cpu) % cores) == 0) {
eiointc_enable(); eiointc_enable();
for (i = 0; i < eiointc_priv[0]->vec_count / 32; i++) { for (i = 0; i < eiointc_priv[0]->vec_count / 32; i++) {
@ -168,7 +182,8 @@ static int eiointc_router_init(unsigned int cpu)
for (i = 0; i < eiointc_priv[0]->vec_count / 4; i++) { for (i = 0; i < eiointc_priv[0]->vec_count / 4; i++) {
/* Route to Node-0 Core-0 */ /* Route to Node-0 Core-0 */
if (index == 0) if (index == 0)
bit = BIT(cpu_logical_map(0)); bit = (cpu_has_hypervisor ? cpu_logical_map(0)
: BIT(cpu_logical_map(0)));
else else
bit = (eiointc_priv[index]->node << 4) | 1; bit = (eiointc_priv[index]->node << 4) | 1;