11322dc94SAlexei Fedorov /* 21322dc94SAlexei Fedorov * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. 31322dc94SAlexei Fedorov * 41322dc94SAlexei Fedorov * SPDX-License-Identifier: BSD-3-Clause 51322dc94SAlexei Fedorov */ 61322dc94SAlexei Fedorov 71322dc94SAlexei Fedorov #include <assert.h> 81322dc94SAlexei Fedorov 91322dc94SAlexei Fedorov #include <drivers/arm/gic_common.h> 101322dc94SAlexei Fedorov #include <lib/mmio.h> 110f76d0d5SNithin G #include <lib/utils_def.h> 121322dc94SAlexei Fedorov 131322dc94SAlexei Fedorov #include "../common/gic_common_private.h" 141322dc94SAlexei Fedorov 151322dc94SAlexei Fedorov /******************************************************************************* 161322dc94SAlexei Fedorov * GIC Distributor interface accessors for reading entire registers 171322dc94SAlexei Fedorov ******************************************************************************/ 181322dc94SAlexei Fedorov /* 191322dc94SAlexei Fedorov * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt 201322dc94SAlexei Fedorov * `id`, 32 interrupt ids at a time. 211322dc94SAlexei Fedorov */ 221322dc94SAlexei Fedorov unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id) 231322dc94SAlexei Fedorov { 241322dc94SAlexei Fedorov unsigned int n = id >> IGROUPR_SHIFT; 251322dc94SAlexei Fedorov 261322dc94SAlexei Fedorov return mmio_read_32(base + GICD_IGROUPR + (n << 2)); 271322dc94SAlexei Fedorov } 281322dc94SAlexei Fedorov 291322dc94SAlexei Fedorov /* 301322dc94SAlexei Fedorov * Accessor to read the GIC Distributor ISENABLER corresponding to the 311322dc94SAlexei Fedorov * interrupt `id`, 32 interrupt ids at a time. 321322dc94SAlexei Fedorov */ 331322dc94SAlexei Fedorov unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id) 341322dc94SAlexei Fedorov { 351322dc94SAlexei Fedorov unsigned int n = id >> ISENABLER_SHIFT; 361322dc94SAlexei Fedorov 371322dc94SAlexei Fedorov return mmio_read_32(base + GICD_ISENABLER + (n << 2)); 381322dc94SAlexei Fedorov } 391322dc94SAlexei Fedorov 401322dc94SAlexei Fedorov /* 411322dc94SAlexei Fedorov * Accessor to read the GIC Distributor ICENABLER corresponding to the 421322dc94SAlexei Fedorov * interrupt `id`, 32 interrupt IDs at a time. 431322dc94SAlexei Fedorov */ 441322dc94SAlexei Fedorov unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id) 451322dc94SAlexei Fedorov { 461322dc94SAlexei Fedorov unsigned int n = id >> ICENABLER_SHIFT; 471322dc94SAlexei Fedorov 481322dc94SAlexei Fedorov return mmio_read_32(base + GICD_ICENABLER + (n << 2)); 491322dc94SAlexei Fedorov } 501322dc94SAlexei Fedorov 511322dc94SAlexei Fedorov /* 521322dc94SAlexei Fedorov * Accessor to read the GIC Distributor ISPENDR corresponding to the 531322dc94SAlexei Fedorov * interrupt `id`, 32 interrupt IDs at a time. 541322dc94SAlexei Fedorov */ 551322dc94SAlexei Fedorov unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id) 561322dc94SAlexei Fedorov { 571322dc94SAlexei Fedorov unsigned int n = id >> ISPENDR_SHIFT; 581322dc94SAlexei Fedorov 591322dc94SAlexei Fedorov return mmio_read_32(base + GICD_ISPENDR + (n << 2)); 601322dc94SAlexei Fedorov } 611322dc94SAlexei Fedorov 621322dc94SAlexei Fedorov /* 631322dc94SAlexei Fedorov * Accessor to read the GIC Distributor ICPENDR corresponding to the 641322dc94SAlexei Fedorov * interrupt `id`, 32 interrupt IDs at a time. 651322dc94SAlexei Fedorov */ 661322dc94SAlexei Fedorov unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id) 671322dc94SAlexei Fedorov { 681322dc94SAlexei Fedorov unsigned int n = id >> ICPENDR_SHIFT; 691322dc94SAlexei Fedorov 701322dc94SAlexei Fedorov return mmio_read_32(base + GICD_ICPENDR + (n << 2)); 711322dc94SAlexei Fedorov } 721322dc94SAlexei Fedorov 731322dc94SAlexei Fedorov /* 741322dc94SAlexei Fedorov * Accessor to read the GIC Distributor ISACTIVER corresponding to the 751322dc94SAlexei Fedorov * interrupt `id`, 32 interrupt IDs at a time. 761322dc94SAlexei Fedorov */ 771322dc94SAlexei Fedorov unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id) 781322dc94SAlexei Fedorov { 791322dc94SAlexei Fedorov unsigned int n = id >> ISACTIVER_SHIFT; 801322dc94SAlexei Fedorov 811322dc94SAlexei Fedorov return mmio_read_32(base + GICD_ISACTIVER + (n << 2)); 821322dc94SAlexei Fedorov } 831322dc94SAlexei Fedorov 841322dc94SAlexei Fedorov /* 851322dc94SAlexei Fedorov * Accessor to read the GIC Distributor ICACTIVER corresponding to the 861322dc94SAlexei Fedorov * interrupt `id`, 32 interrupt IDs at a time. 871322dc94SAlexei Fedorov */ 881322dc94SAlexei Fedorov unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id) 891322dc94SAlexei Fedorov { 901322dc94SAlexei Fedorov unsigned int n = id >> ICACTIVER_SHIFT; 911322dc94SAlexei Fedorov 921322dc94SAlexei Fedorov return mmio_read_32(base + GICD_ICACTIVER + (n << 2)); 931322dc94SAlexei Fedorov } 941322dc94SAlexei Fedorov 951322dc94SAlexei Fedorov /* 961322dc94SAlexei Fedorov * Accessor to read the GIC Distributor IPRIORITYR corresponding to the 971322dc94SAlexei Fedorov * interrupt `id`, 4 interrupt IDs at a time. 981322dc94SAlexei Fedorov */ 991322dc94SAlexei Fedorov unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id) 1001322dc94SAlexei Fedorov { 1011322dc94SAlexei Fedorov unsigned int n = id >> IPRIORITYR_SHIFT; 1021322dc94SAlexei Fedorov 1031322dc94SAlexei Fedorov return mmio_read_32(base + GICD_IPRIORITYR + (n << 2)); 1041322dc94SAlexei Fedorov } 1051322dc94SAlexei Fedorov 1061322dc94SAlexei Fedorov /* 1071322dc94SAlexei Fedorov * Accessor to read the GIC Distributor ICGFR corresponding to the 1081322dc94SAlexei Fedorov * interrupt `id`, 16 interrupt IDs at a time. 1091322dc94SAlexei Fedorov */ 1101322dc94SAlexei Fedorov unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id) 1111322dc94SAlexei Fedorov { 1121322dc94SAlexei Fedorov unsigned int n = id >> ICFGR_SHIFT; 1131322dc94SAlexei Fedorov 1141322dc94SAlexei Fedorov return mmio_read_32(base + GICD_ICFGR + (n << 2)); 1151322dc94SAlexei Fedorov } 1161322dc94SAlexei Fedorov 1171322dc94SAlexei Fedorov /* 1181322dc94SAlexei Fedorov * Accessor to read the GIC Distributor NSACR corresponding to the 1191322dc94SAlexei Fedorov * interrupt `id`, 16 interrupt IDs at a time. 1201322dc94SAlexei Fedorov */ 1211322dc94SAlexei Fedorov unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id) 1221322dc94SAlexei Fedorov { 1231322dc94SAlexei Fedorov unsigned int n = id >> NSACR_SHIFT; 1241322dc94SAlexei Fedorov 1251322dc94SAlexei Fedorov return mmio_read_32(base + GICD_NSACR + (n << 2)); 1261322dc94SAlexei Fedorov } 1271322dc94SAlexei Fedorov 1281322dc94SAlexei Fedorov /******************************************************************************* 1291322dc94SAlexei Fedorov * GIC Distributor interface accessors for writing entire registers 1301322dc94SAlexei Fedorov ******************************************************************************/ 1311322dc94SAlexei Fedorov /* 1321322dc94SAlexei Fedorov * Accessor to write the GIC Distributor IGROUPR corresponding to the 1331322dc94SAlexei Fedorov * interrupt `id`, 32 interrupt IDs at a time. 1341322dc94SAlexei Fedorov */ 1351322dc94SAlexei Fedorov void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val) 1361322dc94SAlexei Fedorov { 1371322dc94SAlexei Fedorov unsigned int n = id >> IGROUPR_SHIFT; 1381322dc94SAlexei Fedorov 1391322dc94SAlexei Fedorov mmio_write_32(base + GICD_IGROUPR + (n << 2), val); 1401322dc94SAlexei Fedorov } 1411322dc94SAlexei Fedorov 1421322dc94SAlexei Fedorov /* 1431322dc94SAlexei Fedorov * Accessor to write the GIC Distributor ISENABLER corresponding to the 1441322dc94SAlexei Fedorov * interrupt `id`, 32 interrupt IDs at a time. 1451322dc94SAlexei Fedorov */ 1461322dc94SAlexei Fedorov void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val) 1471322dc94SAlexei Fedorov { 1481322dc94SAlexei Fedorov unsigned int n = id >> ISENABLER_SHIFT; 1491322dc94SAlexei Fedorov 1501322dc94SAlexei Fedorov mmio_write_32(base + GICD_ISENABLER + (n << 2), val); 1511322dc94SAlexei Fedorov } 1521322dc94SAlexei Fedorov 1531322dc94SAlexei Fedorov /* 1541322dc94SAlexei Fedorov * Accessor to write the GIC Distributor ICENABLER corresponding to the 1551322dc94SAlexei Fedorov * interrupt `id`, 32 interrupt IDs at a time. 1561322dc94SAlexei Fedorov */ 1571322dc94SAlexei Fedorov void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val) 1581322dc94SAlexei Fedorov { 1591322dc94SAlexei Fedorov unsigned int n = id >> ICENABLER_SHIFT; 1601322dc94SAlexei Fedorov 1611322dc94SAlexei Fedorov mmio_write_32(base + GICD_ICENABLER + (n << 2), val); 1621322dc94SAlexei Fedorov } 1631322dc94SAlexei Fedorov 1641322dc94SAlexei Fedorov /* 1651322dc94SAlexei Fedorov * Accessor to write the GIC Distributor ISPENDR corresponding to the 1661322dc94SAlexei Fedorov * interrupt `id`, 32 interrupt IDs at a time. 1671322dc94SAlexei Fedorov */ 1681322dc94SAlexei Fedorov void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val) 1691322dc94SAlexei Fedorov { 1701322dc94SAlexei Fedorov unsigned int n = id >> ISPENDR_SHIFT; 1711322dc94SAlexei Fedorov 1721322dc94SAlexei Fedorov mmio_write_32(base + GICD_ISPENDR + (n << 2), val); 1731322dc94SAlexei Fedorov } 1741322dc94SAlexei Fedorov 1751322dc94SAlexei Fedorov /* 1761322dc94SAlexei Fedorov * Accessor to write the GIC Distributor ICPENDR corresponding to the 1771322dc94SAlexei Fedorov * interrupt `id`, 32 interrupt IDs at a time. 1781322dc94SAlexei Fedorov */ 1791322dc94SAlexei Fedorov void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val) 1801322dc94SAlexei Fedorov { 1811322dc94SAlexei Fedorov unsigned int n = id >> ICPENDR_SHIFT; 1821322dc94SAlexei Fedorov 1831322dc94SAlexei Fedorov mmio_write_32(base + GICD_ICPENDR + (n << 2), val); 1841322dc94SAlexei Fedorov } 1851322dc94SAlexei Fedorov 1861322dc94SAlexei Fedorov /* 1871322dc94SAlexei Fedorov * Accessor to write the GIC Distributor ISACTIVER corresponding to the 1881322dc94SAlexei Fedorov * interrupt `id`, 32 interrupt IDs at a time. 1891322dc94SAlexei Fedorov */ 1901322dc94SAlexei Fedorov void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val) 1911322dc94SAlexei Fedorov { 1921322dc94SAlexei Fedorov unsigned int n = id >> ISACTIVER_SHIFT; 1931322dc94SAlexei Fedorov 1941322dc94SAlexei Fedorov mmio_write_32(base + GICD_ISACTIVER + (n << 2), val); 1951322dc94SAlexei Fedorov } 1961322dc94SAlexei Fedorov 1971322dc94SAlexei Fedorov /* 1981322dc94SAlexei Fedorov * Accessor to write the GIC Distributor ICACTIVER corresponding to the 1991322dc94SAlexei Fedorov * interrupt `id`, 32 interrupt IDs at a time. 2001322dc94SAlexei Fedorov */ 2011322dc94SAlexei Fedorov void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val) 2021322dc94SAlexei Fedorov { 2031322dc94SAlexei Fedorov unsigned int n = id >> ICACTIVER_SHIFT; 2041322dc94SAlexei Fedorov 2051322dc94SAlexei Fedorov mmio_write_32(base + GICD_ICACTIVER + (n << 2), val); 2061322dc94SAlexei Fedorov } 2071322dc94SAlexei Fedorov 2081322dc94SAlexei Fedorov /* 2091322dc94SAlexei Fedorov * Accessor to write the GIC Distributor IPRIORITYR corresponding to the 2101322dc94SAlexei Fedorov * interrupt `id`, 4 interrupt IDs at a time. 2111322dc94SAlexei Fedorov */ 2121322dc94SAlexei Fedorov void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) 2131322dc94SAlexei Fedorov { 2141322dc94SAlexei Fedorov unsigned int n = id >> IPRIORITYR_SHIFT; 2151322dc94SAlexei Fedorov 2161322dc94SAlexei Fedorov mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val); 2171322dc94SAlexei Fedorov } 2181322dc94SAlexei Fedorov 2191322dc94SAlexei Fedorov /* 2201322dc94SAlexei Fedorov * Accessor to write the GIC Distributor ICFGR corresponding to the 2211322dc94SAlexei Fedorov * interrupt `id`, 16 interrupt IDs at a time. 2221322dc94SAlexei Fedorov */ 2231322dc94SAlexei Fedorov void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val) 2241322dc94SAlexei Fedorov { 2251322dc94SAlexei Fedorov unsigned int n = id >> ICFGR_SHIFT; 2261322dc94SAlexei Fedorov 2271322dc94SAlexei Fedorov mmio_write_32(base + GICD_ICFGR + (n << 2), val); 2281322dc94SAlexei Fedorov } 2291322dc94SAlexei Fedorov 2301322dc94SAlexei Fedorov /* 2311322dc94SAlexei Fedorov * Accessor to write the GIC Distributor NSACR corresponding to the 2321322dc94SAlexei Fedorov * interrupt `id`, 16 interrupt IDs at a time. 2331322dc94SAlexei Fedorov */ 2341322dc94SAlexei Fedorov void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val) 2351322dc94SAlexei Fedorov { 2361322dc94SAlexei Fedorov unsigned int n = id >> NSACR_SHIFT; 2371322dc94SAlexei Fedorov 2381322dc94SAlexei Fedorov mmio_write_32(base + GICD_NSACR + (n << 2), val); 2391322dc94SAlexei Fedorov } 2401322dc94SAlexei Fedorov 2411322dc94SAlexei Fedorov /******************************************************************************* 2421322dc94SAlexei Fedorov * GIC Distributor functions for accessing the GIC registers 2431322dc94SAlexei Fedorov * corresponding to a single interrupt ID. These functions use bitwise 2441322dc94SAlexei Fedorov * operations or appropriate register accesses to modify or return 2451322dc94SAlexei Fedorov * the bit-field corresponding the single interrupt ID. 2461322dc94SAlexei Fedorov ******************************************************************************/ 2471322dc94SAlexei Fedorov unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id) 2481322dc94SAlexei Fedorov { 2491322dc94SAlexei Fedorov unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); 2501322dc94SAlexei Fedorov unsigned int reg_val = gicd_read_igroupr(base, id); 2511322dc94SAlexei Fedorov 2521322dc94SAlexei Fedorov return (reg_val >> bit_num) & 0x1U; 2531322dc94SAlexei Fedorov } 2541322dc94SAlexei Fedorov 2551322dc94SAlexei Fedorov void gicd_set_igroupr(uintptr_t base, unsigned int id) 2561322dc94SAlexei Fedorov { 2571322dc94SAlexei Fedorov unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); 2581322dc94SAlexei Fedorov unsigned int reg_val = gicd_read_igroupr(base, id); 2591322dc94SAlexei Fedorov 2600f76d0d5SNithin G gicd_write_igroupr(base, id, reg_val | BIT_32(bit_num)); 2611322dc94SAlexei Fedorov } 2621322dc94SAlexei Fedorov 2631322dc94SAlexei Fedorov void gicd_clr_igroupr(uintptr_t base, unsigned int id) 2641322dc94SAlexei Fedorov { 2651322dc94SAlexei Fedorov unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); 2661322dc94SAlexei Fedorov unsigned int reg_val = gicd_read_igroupr(base, id); 2671322dc94SAlexei Fedorov 2680f76d0d5SNithin G gicd_write_igroupr(base, id, reg_val & ~BIT_32(bit_num)); 2691322dc94SAlexei Fedorov } 2701322dc94SAlexei Fedorov 2711322dc94SAlexei Fedorov void gicd_set_isenabler(uintptr_t base, unsigned int id) 2721322dc94SAlexei Fedorov { 2731322dc94SAlexei Fedorov unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U); 2741322dc94SAlexei Fedorov 2750f76d0d5SNithin G gicd_write_isenabler(base, id, BIT_32(bit_num)); 2761322dc94SAlexei Fedorov } 2771322dc94SAlexei Fedorov 2781322dc94SAlexei Fedorov void gicd_set_icenabler(uintptr_t base, unsigned int id) 2791322dc94SAlexei Fedorov { 2801322dc94SAlexei Fedorov unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U); 2811322dc94SAlexei Fedorov 2820f76d0d5SNithin G gicd_write_icenabler(base, id, BIT_32(bit_num)); 2831322dc94SAlexei Fedorov } 2841322dc94SAlexei Fedorov 2851322dc94SAlexei Fedorov void gicd_set_ispendr(uintptr_t base, unsigned int id) 2861322dc94SAlexei Fedorov { 2871322dc94SAlexei Fedorov unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U); 2881322dc94SAlexei Fedorov 2890f76d0d5SNithin G gicd_write_ispendr(base, id, BIT_32(bit_num)); 2901322dc94SAlexei Fedorov } 2911322dc94SAlexei Fedorov 2921322dc94SAlexei Fedorov void gicd_set_icpendr(uintptr_t base, unsigned int id) 2931322dc94SAlexei Fedorov { 2941322dc94SAlexei Fedorov unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U); 2951322dc94SAlexei Fedorov 2960f76d0d5SNithin G gicd_write_icpendr(base, id, BIT_32(bit_num)); 2971322dc94SAlexei Fedorov } 2981322dc94SAlexei Fedorov 2991322dc94SAlexei Fedorov unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id) 3001322dc94SAlexei Fedorov { 3011322dc94SAlexei Fedorov unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); 3021322dc94SAlexei Fedorov unsigned int reg_val = gicd_read_isactiver(base, id); 3031322dc94SAlexei Fedorov 3041322dc94SAlexei Fedorov return (reg_val >> bit_num) & 0x1U; 3051322dc94SAlexei Fedorov } 3061322dc94SAlexei Fedorov 3071322dc94SAlexei Fedorov void gicd_set_isactiver(uintptr_t base, unsigned int id) 3081322dc94SAlexei Fedorov { 3091322dc94SAlexei Fedorov unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); 3101322dc94SAlexei Fedorov 3110f76d0d5SNithin G gicd_write_isactiver(base, id, BIT_32(bit_num)); 3121322dc94SAlexei Fedorov } 3131322dc94SAlexei Fedorov 3141322dc94SAlexei Fedorov void gicd_set_icactiver(uintptr_t base, unsigned int id) 3151322dc94SAlexei Fedorov { 3161322dc94SAlexei Fedorov unsigned int bit_num = id & ((1U << ICACTIVER_SHIFT) - 1U); 3171322dc94SAlexei Fedorov 3180f76d0d5SNithin G gicd_write_icactiver(base, id, BIT_32(bit_num)); 3191322dc94SAlexei Fedorov } 3201322dc94SAlexei Fedorov 3211322dc94SAlexei Fedorov void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) 3221322dc94SAlexei Fedorov { 323*0cd8e55fSMaheedhar Bollapalli uint8_t val = (uint8_t)(pri & GIC_PRI_MASK); 3241322dc94SAlexei Fedorov 3251322dc94SAlexei Fedorov mmio_write_8(base + GICD_IPRIORITYR + id, val); 3261322dc94SAlexei Fedorov } 3271322dc94SAlexei Fedorov 3281322dc94SAlexei Fedorov void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg) 3291322dc94SAlexei Fedorov { 3301322dc94SAlexei Fedorov /* Interrupt configuration is a 2-bit field */ 3311322dc94SAlexei Fedorov unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); 3321322dc94SAlexei Fedorov unsigned int bit_shift = bit_num << 1; 3331322dc94SAlexei Fedorov 3341322dc94SAlexei Fedorov uint32_t reg_val = gicd_read_icfgr(base, id); 3351322dc94SAlexei Fedorov 3361322dc94SAlexei Fedorov /* Clear the field, and insert required configuration */ 3371322dc94SAlexei Fedorov reg_val &= ~(GIC_CFG_MASK << bit_shift); 3381322dc94SAlexei Fedorov reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); 3391322dc94SAlexei Fedorov 3401322dc94SAlexei Fedorov gicd_write_icfgr(base, id, reg_val); 3411322dc94SAlexei Fedorov } 342