#include <arm/cpu.h>
#include <uk/intctlr.h>
#include <uk/intctlr/gic-v2.h>
+#include <uk/intctlr/limits.h>
#include <uk/ofw/fdt.h>
/* Max CPU interface for GICv2 */
#define GIC_MAX_CPUIF 8
+#define GIC_MAX_IRQ UK_INTCTLR_MAX_IRQ
+
#define GIC_CPU_REG(gdev, r) ((void *)(gdev.cpuif_mem_addr + (r)))
#ifdef CONFIG_HAVE_SMP
/**
* Set target CPU for an interrupt
*
- * @param irq interrupt number [GIC_SPI_BASE..GIC_MAX_IRQ-1]
+ * @param irq interrupt number [GIC_SPI_BASE..GIC_MAX_IRQ]
* @param targetlist an 8-bit bitmap with 1 bit per CPU 0-7. A `1` bit
* indicates that the SGI should be forwarded to the respective CPU
*/
static void gicv2_set_irq_target(uint32_t irq, uint32_t targetlist)
{
- UK_ASSERT(irq >= GIC_SPI_BASE && irq < GIC_MAX_IRQ);
+ UK_ASSERT(irq >= GIC_SPI_BASE && irq <= GIC_MAX_IRQ);
UK_ASSERT(targetlist <= __U8_MAX);
dist_lock(gicv2_drv);
/**
* Set priority for an interrupt
*
- * @param irq interrupt number [0..GIC_MAX_IRQ-1]
+ * @param irq interrupt number [0..GIC_MAX_IRQ]
* @param priority priority [0..255]. The GIC implementation may not support
* all levels. For example, if only 128 levels are supported every two levels
* (e.g., 0 and 1) map to the same effective value. Lower values correspond
*/
static void gicv2_set_irq_prio(uint32_t irq, uint8_t priority)
{
- UK_ASSERT(irq < GIC_MAX_IRQ);
+ UK_ASSERT(irq <= GIC_MAX_IRQ);
dist_lock(gicv2_drv);
write_gicd8(GICD_IPRIORITYR(irq), priority);
/**
* Enable an interrupt
*
- * @param irq interrupt number [0..GIC_MAX_IRQ-1]
+ * @param irq interrupt number [0..GIC_MAX_IRQ]
*/
static void gicv2_enable_irq(uint32_t irq)
{
- UK_ASSERT(irq < GIC_MAX_IRQ);
+ UK_ASSERT(irq <= GIC_MAX_IRQ);
dist_lock(gicv2_drv);
write_gicd32(GICD_ISENABLER(irq), UK_BIT(irq % GICD_I_PER_ISENABLERn));
/**
* Disable an interrupt
*
- * @param irq interrupt number [0..GIC_MAX_IRQ-1]
+ * @param irq interrupt number [0..GIC_MAX_IRQ]
*/
static void gicv2_disable_irq(uint32_t irq)
{
- UK_ASSERT(irq < GIC_MAX_IRQ);
+ UK_ASSERT(irq <= GIC_MAX_IRQ);
dist_lock(gicv2_drv);
write_gicd32(GICD_ICENABLER(irq), UK_BIT(irq % GICD_I_PER_ICENABLERn));
/**
* Config trigger type for an interrupt
*
- * @param irq interrupt number [GIC_PPI_BASE..GIC_MAX_IRQ-1]
+ * @param irq interrupt number [GIC_PPI_BASE..GIC_MAX_IRQ]
* @param trigger trigger type (UK_INTCTLR_IRQ_TRIGGER_*)
*/
static
{
uint32_t val, mask, oldmask;
- UK_ASSERT(irq >= GIC_PPI_BASE && irq < GIC_MAX_IRQ);
+ UK_ASSERT(irq >= GIC_PPI_BASE && irq <= GIC_MAX_IRQ);
UK_ASSERT(trigger == UK_INTCTLR_IRQ_TRIGGER_EDGE ||
trigger == UK_INTCTLR_IRQ_TRIGGER_LEVEL);
/* Ensure interrupt processing starts only after ACK */
isb();
- if (irq < GIC_MAX_IRQ) {
+ if (irq <= GIC_MAX_IRQ) {
uk_intctlr_irq_handle(regs, irq);
gicv2_eoi_irq(stat);
continue;
/* Get the maximum number of interrupts that the GIC supports */
irq_number = GICD_TYPER_LINE_NUM(val);
if (irq_number > GIC_MAX_IRQ)
- irq_number = GIC_MAX_IRQ;
+ irq_number = GIC_MAX_IRQ + 1;
uk_pr_info("GICv2 Max interrupt lines:%d\n", irq_number);
/* Set all SPI's interrupt target to all CPUs */
#include <uk/intctlr.h>
#include <uk/intctlr/gic.h>
#include <uk/intctlr/gic-v3.h>
+#include <uk/intctlr/limits.h>
#include <uk/ofw/fdt.h>
+#define GIC_MAX_IRQ UK_INTCTLR_MAX_IRQ
+
#define GIC_RDIST_REG(gdev, r) \
((void *)(gdev.rdist_mem_addr + (r) + \
lcpu_get_current()->idx * GICR_STRIDE))
/**
* Enable an interrupt
*
- * @param irq interrupt number [0..GIC_MAX_IRQ-1]
+ * @param irq interrupt number [0..GIC_MAX_IRQ]
*/
static void gicv3_enable_irq(uint32_t irq)
{
- UK_ASSERT(irq < GIC_MAX_IRQ);
+ UK_ASSERT(irq <= GIC_MAX_IRQ);
dist_lock(gicv3_drv);
/**
* Disable an interrupt
*
- * @param irq interrupt number [0..GIC_MAX_IRQ-1]
+ * @param irq interrupt number [0..GIC_MAX_IRQ]
*/
static void gicv3_disable_irq(uint32_t irq)
{
- UK_ASSERT(irq < GIC_MAX_IRQ);
+ UK_ASSERT(irq <= GIC_MAX_IRQ);
dist_lock(gicv3_drv);
/**
* Set interrupt affinity
*
- * @param irq interrupt number [GIC_SPI_BASE..GIC_MAX_IRQ-1]
+ * @param irq interrupt number [GIC_SPI_BASE..GIC_MAX_IRQ]
* @param affinity target CPU affinity in 32 bits format
* (AFF3|AFF2|AFF1|AFF0), as returned by get_cpu_affinity()
*/
static void gicv3_set_irq_affinity(uint32_t irq, uint32_t affinity)
{
- UK_ASSERT(irq >= GIC_SPI_BASE && irq < GIC_MAX_IRQ);
+ UK_ASSERT(irq >= GIC_SPI_BASE && irq <= GIC_MAX_IRQ);
dist_lock(gicv3_drv);
write_gicd64(GICD_IROUTER(irq), GIC_AFF_TO_ROUTER(affinity, 0));
/**
* Set priority for an interrupt
*
- * @param irq interrupt number [0..GIC_MAX_IRQ-1]
+ * @param irq interrupt number [0..GIC_MAX_IRQ]
* @param priority priority [0..255]. The GIC implementation may not support
* all levels. For example, if only 128 levels are supported every two levels
* (e.g., 0 and 1) map to the same effective value. Lower values correspond
/**
* Configure trigger type for an interrupt
*
- * @param irq interrupt number [GIC_PPI_BASE..GIC_MAX_IRQ-1]
+ * @param irq interrupt number [GIC_PPI_BASE..GIC_MAX_IRQ]
* @param trigger trigger type (UK_INTCTLR_IRQ_TRIGGER_*)
*/
static
{
uint32_t val, mask, oldmask;
- UK_ASSERT(irq >= GIC_PPI_BASE && irq < GIC_MAX_IRQ);
+ UK_ASSERT(irq >= GIC_PPI_BASE && irq <= GIC_MAX_IRQ);
UK_ASSERT(trigger == UK_INTCTLR_IRQ_TRIGGER_EDGE ||
trigger == UK_INTCTLR_IRQ_TRIGGER_LEVEL);
val = read_gicd32(GICD_TYPER);
irq_number = GICD_TYPER_LINE_NUM(val);
if (irq_number > GIC_MAX_IRQ)
- irq_number = GIC_MAX_IRQ;
+ irq_number = GIC_MAX_IRQ + 1;
uk_pr_info("GICv3 Max interrupt lines: %d\n", irq_number);
/* Check for LPI support */
/* Ensure interrupt processing starts only after ACK */
isb();
- if (irq < GIC_MAX_IRQ) {
+ if (irq <= GIC_MAX_IRQ) {
uk_intctlr_irq_handle(regs, irq);
gicv3_eoi_irq(stat);
-
continue;
}
#define GIC_PPI_TYPE 1
#define GIC_PPI_BASE 16
-/**
- * Max supported interrupt number for GIC
- * Interrupts 1020-1023 are reserved for special purposes, with 1023 being the
- * spurious interrupt
- */
-#define GIC_MAX_IRQ __MAX_IRQ
-
/** Distributor register address */
#define GIC_DIST_REG(gdev, r) ((void *)(gdev.dist_mem_addr + (r)))
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright (c) 2023, Unikraft GmbH and The Unikraft Authors.
+ * Licensed under the BSD-3-Clause License (the "License").
+ * You may not use this file except in compliance with the License.
+ */
+
+#ifndef __UK_INTCTLR_GIC_LIMITS__H__
+#define __UK_INTCTLR_GIC_LIMITS__H__
+
+/**
+ * Max usable INTID for GIC. INTIDs 1020 - 1023 are reseverd.
+ */
+#define UK_INTCTLR_MAX_IRQ 1019
+
+#endif /* __UK_INTCTLR_LIMITS_H__ */
#include <uk/config.h>
#include <uk/assert.h>
#include <uk/intctlr.h>
+#include <uk/intctlr/limits.h>
#include <uk/intctlr/gic-v2.h>
#include <uk/intctlr/gic-v3.h>
switch (type) {
case GIC_SPI_TYPE:
- UK_ASSERT((irq_num + GIC_SPI_BASE) <= UK_INTCTLR_GIC_MAX_IRQ);
+ UK_ASSERT((irq_num + GIC_SPI_BASE) <= UK_INTCTLR_MAX_IRQ);
irq->id = irq_num + GIC_SPI_BASE;
break;
case GIC_PPI_TYPE: