• Home
  • Raw
  • Download

Lines Matching +full:non +full:- +full:secure +full:- +full:domain

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2013-2017 ARM Limited, All Rights Reserved.
24 #include <linux/irqchip/arm-gic-common.h>
25 #include <linux/irqchip/arm-gic-v3.h>
26 #include <linux/irqchip/irq-partition-percpu.h>
29 #include <linux/arm-smccc.h>
36 #include "irq-gic-common.h"
59 struct irq_domain *domain; member
83 * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the
87 * When security is enabled, non-secure priority values from the (re)distributor
91 * If SCR_EL3.FIQ == 1, the values written to/read from PMR and RPR at non-secure
97 * - section 4.8.1 Non-secure accesses to register fields for Secure interrupt
99 * - Figure 4-7 Secure read of the priority field for a Non-secure Group 1
108 * When the Non-secure world has access to group 0 interrupts (as a
113 * written by software is moved to the Non-secure range by the Distributor.
136 #define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base)
174 return __get_intid_range(d->hwirq); in get_intid_range()
179 return d->hwirq; in gic_irq()
201 * For the erratum T241-FABRIC-4, read accesses to GICD_In{E} in gic_dist_base_alias()
206 * Chip0 = 32-351 in gic_dist_base_alias()
207 * Chip1 = 352-671 in gic_dist_base_alias()
208 * Chip2 = 672-991 in gic_dist_base_alias()
209 * Chip3 = 4096-4415 in gic_dist_base_alias()
213 chip = (hwirq - 32) / 320; in gic_dist_base_alias()
233 /* SGI+PPI -> SGI_base for this CPU */ in gic_dist_base()
238 /* SPI -> dist_base */ in gic_dist_base()
251 count--; in gic_do_wait_for_rwp()
309 while (--count) { in gic_enable_redist()
330 *index = d->hwirq; in convert_offset_index()
338 *index = d->hwirq - EPPI_BASE_INTID + 32; in convert_offset_index()
341 *index = d->hwirq - ESPI_BASE_INTID; in convert_offset_index()
370 *index = d->hwirq; in convert_offset_index()
446 if (d->hwirq >= 8192) /* SGI/PPI/SPI only */ in gic_irq_set_irqchip_state()
447 return -EINVAL; in gic_irq_set_irqchip_state()
467 return -EINVAL; in gic_irq_set_irqchip_state()
477 if (d->hwirq >= 8192) /* PPI/SPI only */ in gic_irq_get_irqchip_state()
478 return -EINVAL; in gic_irq_get_irqchip_state()
494 return -EINVAL; in gic_irq_get_irqchip_state()
514 return hwirq - 16; in __gic_get_ppi_index()
516 return hwirq - EPPI_BASE_INTID + 16; in __gic_get_ppi_index()
524 return __gic_get_ppi_index(d->hwirq); in gic_get_ppi_index()
529 struct irq_desc *desc = irq_to_desc(d->irq); in gic_irq_nmi_setup()
532 return -EINVAL; in gic_irq_nmi_setup()
535 pr_err("Cannot set NMI property of enabled IRQ %u\n", d->irq); in gic_irq_nmi_setup()
536 return -EINVAL; in gic_irq_nmi_setup()
544 return -EINVAL; in gic_irq_nmi_setup()
553 desc->handle_irq = handle_percpu_devid_fasteoi_nmi; in gic_irq_nmi_setup()
556 desc->handle_irq = handle_fasteoi_nmi; in gic_irq_nmi_setup()
566 struct irq_desc *desc = irq_to_desc(d->irq); in gic_irq_nmi_teardown()
572 pr_err("Cannot set NMI property of enabled IRQ %u\n", d->irq); in gic_irq_nmi_teardown()
589 desc->handle_irq = handle_percpu_devid_irq; in gic_irq_nmi_teardown()
591 desc->handle_irq = handle_fasteoi_irq; in gic_irq_nmi_teardown()
659 return type != IRQ_TYPE_EDGE_RISING ? -EINVAL : 0; in gic_set_type()
664 return -EINVAL; in gic_set_type()
676 pr_warn("GIC: PPI INTID%d is secure or misconfigured\n", irq); in gic_set_type()
686 return -EINVAL; in gic_irq_set_vcpu_affinity()
771 if (generic_handle_domain_irq(gic_data.domain, irqnr)) { in __gic_handle_irq()
784 if (generic_handle_domain_nmi(gic_data.domain, irqnr)) { in __gic_handle_nmi()
785 WARN_ONCE(true, "Unexpected pseudo-NMI (irqnr %u)\n", irqnr); in __gic_handle_nmi()
890 * setting the highest possible, non-zero priority in PMR. in gic_has_group0()
894 * actual priority in the non-secure range. In the process, it in gic_has_group0()
899 gic_write_pmr(BIT(8 - gic_get_pribits())); in gic_has_group0()
919 * Configure SPIs as non-secure Group-1. This will only matter in gic_dist_init()
921 * do the right thing if the kernel is running in secure mode, in gic_dist_init()
969 int ret = -ENODEV; in gic_iterate_rdists()
1003 return ret ? -ENODEV : 0; in gic_iterate_rdists()
1025 u64 offset = ptr - region->redist_base; in __gic_populate_rdist()
1026 raw_spin_lock_init(&gic_data_rdist()->rd_lock); in __gic_populate_rdist()
1028 gic_data_rdist()->phys_base = region->phys_base + offset; in __gic_populate_rdist()
1032 (int)(region - gic_data.redist_regions), in __gic_populate_rdist()
1033 &gic_data_rdist()->phys_base); in __gic_populate_rdist()
1047 WARN(true, "CPU%d: mpidr %lx has no re-distributor!\n", in gic_populate_rdist()
1050 return -ENODEV; in gic_populate_rdist()
1059 /* Boot-time cleanup */ in __gic_update_rdist_properties()
1079 * doc says... :-/ And CTLR.IR implies another subset of DirectLPI in __gic_update_rdist_properties()
1092 /* Detect non-sensical configurations */ in __gic_update_rdist_properties()
1172 * any pre-emptive interrupts from working at all). Writing a zero in gic_cpu_sys_reg_init()
1241 * - The write is ignored. in gic_cpu_sys_reg_init()
1242 * - The RS field is treated as 0. in gic_cpu_sys_reg_init()
1281 /* Configure SGIs/PPIs as non-secure Group-1 */ in gic_cpu_init()
1326 cpu--; in gic_compute_target_list()
1358 if (WARN_ON(d->hwirq >= 16)) in gic_ipi_send_mask()
1372 gic_send_sgi(cluster_id, tlist, d->hwirq); in gic_ipi_send_mask()
1391 /* Register all 8 non-secure SGIs */ in gic_smp_init()
1392 base_sgi = irq_domain_alloc_irqs(gic_data.domain, 8, NUMA_NO_NODE, &sgi_fwspec); in gic_smp_init()
1414 return -EINVAL; in gic_set_affinity()
1417 return -EINVAL; in gic_set_affinity()
1531 irq_domain_set_info(d, irq, hw, chip, d->host_data, in gic_irq_domain_map()
1537 irq_domain_set_info(d, irq, hw, chip, d->host_data, in gic_irq_domain_map()
1545 return -EPERM; in gic_irq_domain_map()
1546 irq_domain_set_info(d, irq, hw, chip, d->host_data, in gic_irq_domain_map()
1551 return -EPERM; in gic_irq_domain_map()
1564 if (fwspec->param_count == 1 && fwspec->param[0] < 16) { in gic_irq_domain_translate()
1565 *hwirq = fwspec->param[0]; in gic_irq_domain_translate()
1570 if (is_of_node(fwspec->fwnode)) { in gic_irq_domain_translate()
1571 if (fwspec->param_count < 3) in gic_irq_domain_translate()
1572 return -EINVAL; in gic_irq_domain_translate()
1574 switch (fwspec->param[0]) { in gic_irq_domain_translate()
1576 *hwirq = fwspec->param[1] + 32; in gic_irq_domain_translate()
1579 *hwirq = fwspec->param[1] + 16; in gic_irq_domain_translate()
1582 *hwirq = fwspec->param[1] + ESPI_BASE_INTID; in gic_irq_domain_translate()
1585 *hwirq = fwspec->param[1] + EPPI_BASE_INTID; in gic_irq_domain_translate()
1588 *hwirq = fwspec->param[1]; in gic_irq_domain_translate()
1591 *hwirq = fwspec->param[1]; in gic_irq_domain_translate()
1592 if (fwspec->param[1] >= 16) in gic_irq_domain_translate()
1593 *hwirq += EPPI_BASE_INTID - 16; in gic_irq_domain_translate()
1598 return -EINVAL; in gic_irq_domain_translate()
1601 *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; in gic_irq_domain_translate()
1608 fwspec->param[0] != GIC_IRQ_TYPE_PARTITION); in gic_irq_domain_translate()
1612 if (is_fwnode_irqchip(fwspec->fwnode)) { in gic_irq_domain_translate()
1613 if(fwspec->param_count != 2) in gic_irq_domain_translate()
1614 return -EINVAL; in gic_irq_domain_translate()
1616 if (fwspec->param[0] < 16) { in gic_irq_domain_translate()
1618 fwspec->param[0]); in gic_irq_domain_translate()
1619 return -EINVAL; in gic_irq_domain_translate()
1622 *hwirq = fwspec->param[0]; in gic_irq_domain_translate()
1623 *type = fwspec->param[1]; in gic_irq_domain_translate()
1629 return -EINVAL; in gic_irq_domain_translate()
1632 static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, in gic_irq_domain_alloc() argument
1640 ret = gic_irq_domain_translate(domain, fwspec, &hwirq, &type); in gic_irq_domain_alloc()
1645 ret = gic_irq_domain_map(domain, virq + i, hwirq + i); in gic_irq_domain_alloc()
1653 static void gic_irq_domain_free(struct irq_domain *domain, unsigned int virq, in gic_irq_domain_free() argument
1659 struct irq_data *d = irq_domain_get_irq_data(domain, virq + i); in gic_irq_domain_free()
1673 if (!is_of_node(fwspec->fwnode)) in fwspec_is_partitioned_ppi()
1676 if (fwspec->param_count < 4 || !fwspec->param[3]) in fwspec_is_partitioned_ppi()
1694 if (fwspec->fwnode != d->fwnode) in gic_irq_domain_select()
1697 /* If this is not DT, then we have a single domain */ in gic_irq_domain_select()
1698 if (!is_of_node(fwspec->fwnode)) in gic_irq_domain_select()
1706 return d == gic_data.domain; in gic_irq_domain_select()
1709 * If this is a PPI and we have a 4th (non-null) parameter, in gic_irq_domain_select()
1710 * then we need to match the partition domain. in gic_irq_domain_select()
1734 return -ENOMEM; in partition_domain_translate()
1736 np = of_find_node_by_phandle(fwspec->param[3]); in partition_domain_translate()
1738 return -EINVAL; in partition_domain_translate()
1751 *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; in partition_domain_translate()
1765 d->flags |= FLAGS_WORKAROUND_GICR_WAKER_MSM8996; in gic_enable_quirk_msm8996()
1774 d->flags |= FLAGS_WORKAROUND_MTK_GICR_SAVE; in gic_enable_quirk_mtk_gicr()
1783 d->flags |= FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539; in gic_enable_quirk_cavium_38539()
1793 * HIP06 GICD_IIDR clashes with GIC-600 product number (despite in gic_enable_quirk_hip06_07()
1795 * that GIC-600 doesn't have ESPI, so nothing to do in that case. in gic_enable_quirk_hip06_07()
1799 if (d->rdists.gicd_typer & GICD_TYPER_ESPI) { in gic_enable_quirk_hip06_07()
1801 d->rdists.gicd_typer &= ~GENMASK(9, 8); in gic_enable_quirk_hip06_07()
1849 d->flags |= FLAGS_WORKAROUND_ASR_ERRATUM_8601001; in gic_enable_quirk_asr8601()
1864 d->rdists.flags |= RDIST_FLAGS_FORCE_NON_SHAREABLE; in rd_set_non_coherent()
1871 .compatible = "qcom,msm8996-gic-v3",
1876 .compatible = "asr,asr8601-gic-v3",
1881 .property = "mediatek,broken-save-restore-fw",
1900 * - ThunderX: CN88xx
1901 * - OCTEON TX: CN83xx, CN81xx
1902 * - OCTEON TX2: CN93xx, CN96xx, CN98xx, CNF95xx*
1910 .desc = "GICv3: NVIDIA erratum T241-FABRIC-4",
1917 * GIC-700: 2941627 workaround - IP variant [0,1]
1927 * GIC-700: 2941627 workaround - IP variant [2]
1935 .desc = "GICv3: non-coherent attribute",
1936 .property = "dma-noncoherent",
1962 pr_info("Pseudo-NMIs enabled using %s ICC_PMR_EL1 synchronisation\n", in gic_enable_nmi_support()
1968 * and if Group 0 interrupts can be delivered to Linux in the non-secure in gic_enable_nmi_support()
1974 * ----------------------------------------------------------- in gic_enable_nmi_support()
1975 * 1 | - | unchanged | unchanged in gic_enable_nmi_support()
1976 * ----------------------------------------------------------- in gic_enable_nmi_support()
1977 * 0 | 1 | non-secure | non-secure in gic_enable_nmi_support()
1978 * ----------------------------------------------------------- in gic_enable_nmi_support()
1979 * 0 | 0 | unchanged | non-secure in gic_enable_nmi_support()
1981 * where non-secure means that the value is right-shifted by one and the in gic_enable_nmi_support()
1982 * MSB bit set, to make it fit in the non-secure priority range. in gic_enable_nmi_support()
1989 * be in the non-secure range, we use a different PMR value to mask IRQs in gic_enable_nmi_support()
2035 pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32); in gic_init_bases()
2045 gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops, in gic_init_bases()
2049 /* Disable GICv4.x features for the erratum T241-FABRIC-4 */ in gic_init_bases()
2056 if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) { in gic_init_bases()
2057 err = -ENOMEM; in gic_init_bases()
2061 irq_domain_update_bus_token(gic_data.domain, DOMAIN_BUS_WIRED); in gic_init_bases()
2066 err = mbi_init(handle, gic_data.domain); in gic_init_bases()
2081 its_init(handle, &gic_data.rdists, gic_data.domain); in gic_init_bases()
2086 gicv2m_init(handle, gic_data.domain); in gic_init_bases()
2094 if (gic_data.domain) in gic_init_bases()
2095 irq_domain_remove(gic_data.domain); in gic_init_bases()
2105 return -ENODEV; in gic_validate_dist_version()
2118 parts_node = of_get_child_by_name(gic_node, "ppi-partitions"); in gic_populate_ppi_partitions()
2141 part->partition_id = of_node_to_fwnode(child_part); in gic_populate_ppi_partitions()
2172 cpumask_set_cpu(cpu, &part->mask); in gic_populate_ppi_partitions()
2220 if (of_property_read_u32(node, "#redistributor-regions", in gic_of_setup_kvm_info()
2252 gic_request_region(res->start, resource_size(res), name); in gic_of_iomap()
2255 return base ?: IOMEM_ERR_PTR(-ENOMEM); in gic_of_iomap()
2282 if (of_property_read_u32(node, "#redistributor-regions", &nr_redist_regions)) in gic_of_init()
2288 err = -ENOMEM; in gic_of_init()
2296 err = -ENODEV; in gic_of_init()
2302 if (of_property_read_u64(node, "redistributor-stride", &redist_stride)) in gic_of_init()
2308 nr_redist_regions, redist_stride, &node->fwnode); in gic_of_init()
2328 IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
2362 redist_base = ioremap(redist->base_address, redist->length); in gic_acpi_parse_madt_redist()
2364 pr_err("Couldn't map GICR region @%llx\n", redist->base_address); in gic_acpi_parse_madt_redist()
2365 return -ENOMEM; in gic_acpi_parse_madt_redist()
2367 gic_request_region(redist->base_address, redist->length, "GICR"); in gic_acpi_parse_madt_redist()
2369 gic_acpi_register_redist(redist->base_address, redist_base); in gic_acpi_parse_madt_redist()
2384 if (!(gicc->flags & ACPI_MADT_ENABLED)) in gic_acpi_parse_madt_gicc()
2387 redist_base = ioremap(gicc->gicr_base_address, size); in gic_acpi_parse_madt_gicc()
2389 return -ENOMEM; in gic_acpi_parse_madt_gicc()
2390 gic_request_region(gicc->gicr_base_address, size, "GICR"); in gic_acpi_parse_madt_gicc()
2392 gic_acpi_register_redist(gicc->gicr_base_address, redist_base); in gic_acpi_parse_madt_gicc()
2414 return -ENODEV; in gic_acpi_collect_gicr_base()
2434 if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address) { in gic_acpi_match_gicc()
2443 if (!(gicc->flags & ACPI_MADT_ENABLED)) in gic_acpi_match_gicc()
2446 return -ENODEV; in gic_acpi_match_gicc()
2482 if (dist->version != ape->driver_data) in acpi_validate_gic_table()
2503 if (!(gicc->flags & ACPI_MADT_ENABLED)) in gic_acpi_parse_virt_madt_gicc()
2506 maint_irq_mode = (gicc->flags & ACPI_MADT_VGIC_IRQ_MODE) ? in gic_acpi_parse_virt_madt_gicc()
2512 acpi_data.maint_irq = gicc->vgic_interrupt; in gic_acpi_parse_virt_madt_gicc()
2514 acpi_data.vcpu_base = gicc->gicv_base_address; in gic_acpi_parse_virt_madt_gicc()
2522 if ((acpi_data.maint_irq != gicc->vgic_interrupt) || in gic_acpi_parse_virt_madt_gicc()
2524 (acpi_data.vcpu_base != gicc->gicv_base_address)) in gic_acpi_parse_virt_madt_gicc()
2525 return -EINVAL; in gic_acpi_parse_virt_madt_gicc()
2566 vcpu->flags = IORESOURCE_MEM; in gic_acpi_setup_kvm_info()
2567 vcpu->start = acpi_data.vcpu_base; in gic_acpi_setup_kvm_info()
2568 vcpu->end = vcpu->start + ACPI_GICV2_VCPU_MEM_SIZE - 1; in gic_acpi_setup_kvm_info()
2592 acpi_data.dist_base = ioremap(dist->base_address, in gic_acpi_init()
2596 return -ENOMEM; in gic_acpi_init()
2598 gic_request_region(dist->base_address, ACPI_GICV3_DIST_MEM_SIZE, "GICD"); in gic_acpi_init()
2610 err = -ENOMEM; in gic_acpi_init()
2618 gsi_domain_handle = irq_domain_alloc_fwnode(&dist->base_address); in gic_acpi_init()
2620 err = -ENOMEM; in gic_acpi_init()
2624 err = gic_init_bases(dist->base_address, acpi_data.dist_base, in gic_acpi_init()