diff --git a/librs/src/arch/aarch64/gic.rs b/librs/src/arch/aarch64/gic.rs
new file mode 100644
index 0000000000000000000000000000000000000000..12557964f02b406bd9bf82f1255162ab0ebf9170
--- /dev/null
+++ b/librs/src/arch/aarch64/gic.rs
@@ -0,0 +1,127 @@
+pub const GICD_BASE: u64 = 1 << 39;
+pub const GICC_BASE: u64 = GICD_BASE + GICD_SIZE;
+pub const GIC_SIZE: u64 = GICD_SIZE + GICC_SIZE;
+pub const GICD_SIZE: u64 = 0x10000;
+pub const GICC_SIZE: u64 = 0x20000;
+
+pub const GICR_BASE: u32 = 0;
+
+/* GIC Distributor interface register offsets that are common to GICv3 & GICv2 */
+
+pub const GICD_CTLR: u32 = 0;
+pub const GICD_TYPER: u32 = 4;
+pub const GICD_IIDR: u32 = 8;
+pub const GICD_IGROUPR: u32 = 128;
+pub const GICD_ISENABLER: u32 = 256;
+pub const GICD_ICENABLER: u32 = 384;
+pub const GICD_ISPENDR: u32 = 512;
+pub const GICD_ICPENDR: u32 = 640;
+pub const GICD_ISACTIVER: u32 = 768;
+pub const GICD_ICACTIVER: u32 = 896;
+pub const GICD_IPRIORITYR: u32 = 1024;
+pub const GICD_ITARGETSR: u32 = 2048;
+pub const GICD_ICFGR: u32 = 3072;
+pub const GICD_NSACR: u32 = 3584;
+pub const GICD_SGIR: u32 = 3840;
+
+pub const GICD_CTLR_ENABLEGRP0: u32 = 1;
+pub const GICD_CTLR_ENABLEGRP1: u32 = 2;
+
+/* Physical CPU Interface registers */
+
+pub const GICC_CTLR: u32 = 0;
+pub const GICC_PMR: u32 = 4;
+pub const GICC_BPR: u32 = 8;
+pub const GICC_IAR: u32 = 12;
+pub const GICC_EOIR: u32 = 16;
+pub const GICC_RPR: u32 = 20;
+pub const GICC_HPPIR: u32 = 24;
+pub const GICC_AHPPIR: u32 = 40;
+pub const GICC_IIDR: u32 = 252;
+pub const GICC_DIR: u32 = 4096;
+pub const GICC_PRIODROP: u32 = 16;
+
+pub const GICC_CTLR_ENABLEGRP0: u32 = 1;
+pub const GICC_CTLR_ENABLEGRP1: u32 = 2;
+pub const GICC_CTLR_FIQEN: u32 = 8;
+pub const GICC_CTLR_ACKCTL: u32 = 4;
+
+pub struct Gicc;
+pub struct Gicd;
+
+impl Gicc {
+    #[inline]
+    fn read(off: usize) -> u32 {
+        let mut value: u32;
+        unsafe {
+            asm!("ldar $w0, [$1]" : "=r"(value) : "r"(GICD_BASE as usize + off) : "memory");
+        }
+        return value;
+    }
+
+    #[inline]
+    fn write(off: usize, value: u32) {
+        unsafe {
+            asm!("str $w0, [$1]" : : "rz"(value) , "r"(GICD_BASE as usize + off) : "memory");
+        }
+    }
+
+    pub fn enable() {
+        Gicc::write(
+            GICC_CTLR as usize,
+            GICC_CTLR_ENABLEGRP0 | GICC_CTLR_ENABLEGRP1 | GICC_CTLR_FIQEN | GICC_CTLR_ACKCTL,
+        );
+    }
+
+    pub fn disable() {
+        // Global disable signalling of interrupt from the cpu interface
+        Gicc::write(GICC_CTLR as usize, 0);
+    }
+
+    pub fn set_priority(priority: u32) {
+        Gicc::write(GICC_PMR as usize, priority & 0xFF);
+    }
+}
+
+impl Gicd {
+    #[inline]
+    fn read(off: usize) -> u32 {
+        let mut value: u32;
+        unsafe {
+            asm!("ldar $w0, [$1]" : "=r"(value) : "r"(GICC_BASE as usize + off) : "memory");
+        }
+        return value;
+    }
+
+    #[inline]
+    fn write(off: usize, value: u32) {
+        unsafe {
+            asm!("str $w0, [$1]" : : "rz"(value) , "r"(GICC_BASE as usize + off) : "memory");
+        }
+    }
+
+    pub fn enable() {
+        // Global enable forwarding interrupts from distributor to cpu interface
+        Gicd::write(
+            GICD_CTLR as usize,
+            GICD_CTLR_ENABLEGRP0 | GICD_CTLR_ENABLEGRP1,
+        );
+    }
+
+    pub fn disable() {
+        // Global disable forwarding interrupts from distributor to cpu interface
+        Gicd::write(GICD_CTLR as usize, 0);
+    }
+}
+
+pub fn gic_set_enable(vector: u32, enable: bool) {
+    let regoff = if enable {
+        GICD_ISENABLER + 4 * (vector / 32)
+    } else {
+        GICD_ICENABLER + 4 * (vector / 32)
+    };
+    Gicd::write(
+        regoff as usize,
+        Gicd::read(regoff as usize) | (1 << (vector % 32)),
+    );
+}
diff --git a/librs/src/arch/aarch64/irq.rs b/librs/src/arch/aarch64/irq.rs
index 447684e74dcd7d54a9f1e413086156606034bcef..6de87f971de9a417460279606020938ef39765cd 100644
--- a/librs/src/arch/aarch64/irq.rs
+++ b/librs/src/arch/aarch64/irq.rs
@@ -25,6 +25,12 @@ const IRQ_FLAG_F: usize = 1 << 6;
 const IRQ_FLAG_I: usize = 1 << 7;
 const IRQ_FLAG_A: usize = 1 << 8;
 
+pub const INT_PPI_VMAINT: u32 = 25;
+pub const INT_PPI_HYP_TIMER: u32 = 26;
+pub const INT_PPI_VIRT_TIMER: u32 = 27;
+pub const INT_PPI_SPHYS_TIMER: u32 = 29;
+pub const INT_PPI_NSPHYS_TIMER: u32 = 30;
+
 /// Enable Interrupts
 #[inline]
 pub fn enable() {
diff --git a/librs/src/arch/aarch64/mod.rs b/librs/src/arch/aarch64/mod.rs
index f1cc27f0086728391bf84c0ad527407de93d8844..525dcf9ace8f46fbd2589da39118a666a9dfdcae 100644
--- a/librs/src/arch/aarch64/mod.rs
+++ b/librs/src/arch/aarch64/mod.rs
@@ -23,6 +23,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 pub mod irq;
+mod gic;
 pub mod mm;
 pub mod percore;
 pub mod processor;