Not clear if this is working, since we don't have a interrupt source yet.
Signed-off-by: Lukas Humbel <lukas.humbel@inf.ethz.ch>
"fat_bpb",
"fat_direntry",
"gic_v3",
+ "gic_v3_cpu",
"hpet",
"ia32",
"ixp2800_icp_pic0",
--- /dev/null
+/*
+ * Memory mapped GIC v3 CPU Interface. Sysreg mapped CPUs should
+ * definitions in armv8.dev.
+ * Source: ARM IHI 0069B, page 8-560
+ */
+device gic_v3_cpu msbfirst (addr cpuif) "MMIO mapped GIC CPU interface" {
+
+ register CTLR rw addr(cpuif, 0x0) "CPU Interface Control Register - secure" {
+ _ 21 mbz;
+ EOImodeNS 1;
+ EOImodeS 1;
+ IRQBypDisGrp1 1;
+ FIQBypDisGrp1 1;
+ IRQBypDisGrp0 1;
+ FIQBypDisGrp0 1;
+ CBPR 1;
+ FIQEn 1;
+ _ 1 mbz;
+ EnableGrp1 1;
+ EnableGrp0 1;
+ };
+
+ register CTLR_NS rw also addr(cpuif, 0x0) "CPU Interface Control Register - Non-secure" {
+ _ 22 mbz;
+ EOImodeNS 1;
+ RES0 2;
+ IRQBypDisGrp1 1;
+ FIQBypDisGrp1 1;
+ _ 4 mbz;
+ EnableGrp1 1;
+ };
+
+ register PMR rw addr(cpuif, 0x0004) "Interrupt Controller Interrupt Priority Mask Register" {
+ _ 24;
+ priority 8 "Priority mask level";
+ };
+
+ register BPR rw addr(cpuif, 0x0008) "Interrupt Controller Binray Point Register" {
+ _ 29;
+ binary_point 3;
+ };
+
+ register IAR rw addr(cpuif, 0x000C) "Interrupt Controller Interrupt Acknowledge Register" {
+ _ 8;
+ intid 24 "INTID of the signaled interrupt";
+ };
+
+ register EOIR wo addr(cpuif, 0x0010) "Interrupt Controller End Of Interrupt Register" {
+ _ 8;
+ intid 24 "INTID from the corresponding ICC_IAR0_EL1 access";
+ };
+
+
+ register RPR ro addr(cpuif, 0x0014) "Running Priority Register" {
+
+ _ 24;
+ priority 8 "Running priority";
+ };
+
+
+ register HPPIR ro addr(cpuif, 0x0018) "Highest Priority Pending Interrupt Register" {
+ _ 8;
+ intid 24 "INTID of the highest priority pending interrupt";
+ };
+
+ register ABPR rw addr(cpuif, 0x001c) "Aliased Binary Point Register" {
+ _ 29;
+ binary_point 3;
+ };
+
+ register AIAR ro addr(cpuif, 0x0020) "Aliased Interrupt Acknowledge Register" {
+ _ 8;
+ intid 24 "INTID of the signaled interrupt";
+ };
+
+ register AEOIR wo addr(cpuif, 0x0024) "Aliased End of Interrupt Register" {
+ _ 8;
+ intid 24 "INTID from the corresponding ICC_IAR0_EL1 access";
+ };
+
+ register AHPPIR ro addr(cpuif, 0x0028) "Aliased Highest Priority Pending Interrupt Register" {
+ _ 8;
+ intid 24 "INTID of the highest priority pending interrupt";
+ };
+
+ register STATUSR rw addr(cpuif, 0x002C) "Error Reporting Status Register" {
+ _ 27;
+ asv 1 "Attempted security violation";
+ wrod 1 "Write to an RO location";
+ rwod 1 "Read of a WO location";
+ wrd 1 "Write to a reserved location";
+ rrd 1 "Read of a reserved location";
+ };
+
+ register APR1 rw addr(cpuif, 0x00D0) "CPU Interface Active Priorities Registers" {
+ impl 32;
+ };
+
+ register APR2 rw addr(cpuif, 0x00D4) "CPU Interface Active Priorities Registers" {
+ impl 32;
+ };
+
+ register APR3 rw addr(cpuif, 0x00D8) "CPU Interface Active Priorities Registers" {
+ impl 32;
+ };
+
+ register APR4 rw addr(cpuif, 0x00DC) "CPU Interface Active Priorities Registers" {
+ impl 32;
+ };
+
+ register NSAPR1 rw addr(cpuif, 0x00E0) "Non-secure CPU Interface Active Priorities Registers" {
+ impl 32;
+ };
+
+ register NSAPR2 rw addr(cpuif, 0x00E4) "Non-secure CPU Interface Active Priorities Registers" {
+ impl 32;
+ };
+
+ register NSAPR3 rw addr(cpuif, 0x00E8) "Non-secure CPU Interface Active Priorities Registers" {
+ impl 32;
+ };
+
+ register NSAPR4 rw addr(cpuif, 0x00EC) "Non-secure CPU Interface Active Priorities Registers" {
+ impl 32;
+ };
+
+ register IIDR ro addr(cpuif, 0x00FC) "CPU Interface Identification Register" {
+ ProductID 8 "Product identifier";
+ _ 4 mbz;
+ Variant 4 "Variant number";
+ Revision 4 "Revision number";
+ Implementer 12 "JEP106 code of implementing company";
+ };
+
+ register DIR wo addr(cpuif, 0x1000) "Deactivate Interrupt Register" {
+ _ 8;
+ intid 24 "INTID of the highest priority pending interrupt";
+ };
+
+};
"arch/arm/gdb_arch.c",
"arch/armv8/plat_apm88xxxx.c",
"arch/armv8/plat_apm88xxxx_consts.c",
- "arch/armv8/plat_a57mpcore.c",
"arch/armv8/init.c",
"arch/armv8/gdb_arch.c",
- "arch/armv8/gic_v3.c",
+ "arch/armv8/gic_v3_mmio.c",
-----
"arch/armv8/kernel_multiboot2.c",
"arch/armv8/dispatch.c",
mackerelDevices = [
"arm",
"armv8",
+ "gic_v3",
+ "gic_v3_cpu",
"armv8/armv8_generic_timer",
"armv8/armv8_cache_ctrl",
"pl130_gic",
mackerelDevices = [
"arm",
"armv8",
+ "gic_v3",
+ "gic_v3_cpu",
"armv8/armv8_generic_timer",
"armv8/armv8_cache_ctrl",
"pl011_uart",
--- /dev/null
+/*
+ * Copyright (c) 2016, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetstr 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <kernel.h>
+#include <sysreg.h>
+#include <dev/armv8_dev.h>
+#include <dev/gic_v3_dev.h>
+#include <dev/gic_v3_cpu_dev.h>
+#include <platform.h>
+#include <paging_kernel_arch.h>
+#include <arch/armv8/gic_v3.h>
+
+static gic_v3_t gic_v3_dev;
+static gic_v3_cpu_t gic_v3_cpu_dev;
+
+/*
+ * Initialize the global interrupt controller
+ *
+ * There are three types of interrupts
+ * 1) Software generated Interrupts (SGI) - IDs 0-15
+ * 2) Private Peripheral Interrupts (PPI) - IDs 16-31
+ * 3) Shared Peripheral Interrups (SPI) - IDs 32...
+ */
+errval_t gicv3_init(void)
+{
+ printk(LOG_NOTE, "gicv3_init (mem-mapped CPU if) enter\n");
+
+ lvaddr_t gic_cpu = local_phys_to_mem(platform_get_gic_cpu_address());
+ gic_v3_initialize(&gic_v3_dev, (char *)gic_cpu);
+
+ lvaddr_t gic_dist = local_phys_to_mem(platform_get_distributor_address());
+ gic_v3_cpu_initialize(&gic_v3_cpu_dev, (char *)gic_dist);
+
+ printk(LOG_NOTE, "gicv3_init done\n");
+ return SYS_ERR_OK;
+}
+
+/*
+ * Returns active interrupt of group 1
+ */
+uint32_t gicv3_get_active_irq(void)
+{
+ return gic_v3_cpu_IAR_intid_rdf(&gic_v3_cpu_dev);
+}
+
+/*
+ * ACKs group 1 interrupt
+ */
+void gicv3_ack_irq(uint32_t irq)
+{
+ gic_v3_cpu_EOIR_t reg = 0;
+ reg = gic_v3_cpu_EOIR_intid_insert(reg, irq);
+ gic_v3_cpu_EOIR_rawwr(&gic_v3_cpu_dev, irq);
+}
+
+/*
+ * Raise an SGI on a core.
+ */
+void gicv3_raise_softirq(coreid_t cpuid, uint8_t irq)
+{
+ // assuming affinity routing DISABLED
+ assert(irq <= 15);
+ gic_v3_GICD_SGIR_t reg = 0;
+ reg = gic_v3_GICD_SGIR_INTID_insert(reg, irq);
+ reg = gic_v3_GICD_SGIR_CPUTargetList_insert(reg, 1<<(cpuid-1));
+ gic_v3_GICD_SGIR_wr(&gic_v3_dev, reg);
+ /*
+ armv8_ICC_SGI1R_EL1_t reg = 0;
+ reg = armv8_ICC_SGI1R_EL1_intid_insert(reg, 1);
+ // TODO: make that work for cpuids > 15
+ reg = armv8_ICC_SGI1R_EL1_target_insert(reg, 1<<(cpuid-1));
+ reg = armv8_ICC_SGI1R_EL1_aff3_insert(reg, 0);
+ reg = armv8_ICC_SGI1R_EL1_aff2_insert(reg, 0);
+ reg = armv8_ICC_SGI1R_EL1_aff1_insert(reg, 0);
+ armv8_ICC_SGI1R_EL1_wr(NULL, reg);
+ */
+}
+
+/*
+ * Enable GIC CPU-IF and local distributor
+ */
+errval_t gicv3_cpu_interface_enable(void)
+{
+ printk(LOG_NOTE, "gicv3_cpu_interface_enable: enabling group 1 int\n");
+
+ // Linux does:
+ // sets priority mode: PMR to 0xf0
+ gic_v3_cpu_PMR_wr(&gic_v3_cpu_dev, 0xf0);
+ // Set binary point to 1, 6 group priority bits, 2 subpriority bits
+ gic_v3_cpu_BPR_wr(&gic_v3_cpu_dev, 1);
+
+ //Enable group 1
+ gic_v3_cpu_CTLR_NS_wr(&gic_v3_cpu_dev, 0x1);
+ printk(LOG_NOTE, "gicv3_cpu_interface_enable: group 1 int enabled\n");
+
+ printk(LOG_NOTE, "gicv3_cpu_interface_enable: configuring distributor\n");
+ printk(LOG_NOTE, "GICD IIDR "
+ "implementer=0x%x, revision=0x%x, variant=0x%x,prodid=0x%x\n",
+ gic_v3_GICD_IIDR_Implementer_rdf(&gic_v3_dev),
+ gic_v3_GICD_IIDR_Revision_rdf(&gic_v3_dev),
+ gic_v3_GICD_IIDR_Variant_rdf(&gic_v3_dev),
+ gic_v3_GICD_IIDR_ProductID_rdf(&gic_v3_dev)
+ );
+
+ gic_v3_GICD_CTLR_secure_t ctrl = 0;
+ // Set affinity routing
+ ctrl = gic_v3_GICD_CTLR_secure_ARE_NS_insert(ctrl, 1);
+ // Enable group 1 interrupts
+ ctrl = gic_v3_GICD_CTLR_secure_EnableGrp1NS_insert(ctrl, 1);
+ gic_v3_GICD_CTLR_secure_wr(&gic_v3_dev, ctrl);
+
+ return SYS_ERR_OK;
+}
+
+
#include <barrelfish_kpi/arm_core_data.h>
#include <psci.h>
#include <arch/armv8/global.h>
+#include <arch/armv8/gic_v3.h>
+#include <paging_kernel_arch.h>
/* the maximum number of UARTS supported */
#define MAX_NUM_UARTS 4
}
+/* GIC */
+
errval_t platform_gic_init(void) {
- gic_init();
+ gicv3_init();
return SYS_ERR_OK;
}
errval_t platform_gic_cpu_interface_enable(void) {
- gic_cpu_interface_enable();
+ gicv3_cpu_interface_enable();
return SYS_ERR_OK;
}
+/**
+ * @brief obtain the address of the GIC CPU interface
+ *
+ * @return physical address of the CBAR region
+ */
+lpaddr_t platform_get_gic_cpu_address(void) {
+ assert(paging_mmu_enabled());
+ return platform_gic_cpu_base;
+}
+
+/**
+ * @brief obtain the address of the GIC distributor interface
+ *
+ * @return physical address of the CBAR region
+ */
+lpaddr_t platform_get_distributor_address(void) {
+ assert(paging_mmu_enabled());
+ return platform_gic_dist_base;
+}
+
+
errval_t platform_boot_core(hwid_t target, genpaddr_t gen_entry, genpaddr_t context)
{
printf("Invoking PSCI on: cpu=0x%lx, entry=0x%lx, context=0x%lx\n", target, gen_entry, context);
*
*
*/
+
+ gicv3_raise_softirq(target, 1);
+
return SYS_ERR_OK;
}
+
* ----------------------------------------------------------------------------
*/
-lpaddr_t platform_gic_cpu_base = 0x0000000078010000;
-lpaddr_t platform_gic_dist_base = 0x0000000078020000;
+lpaddr_t platform_gic_cpu_base = 0x0000000078020000;
+lpaddr_t platform_gic_dist_base = 0x0000000078010000;
/*