blob: 77831f27bbdb1282186120dae0993cb08f048add [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#include "sw/device/lib/irq.h"
#include "sw/device/lib/base/stdasm.h"
static const uint32_t IRQ_EXT_ENABLE_OFFSET = 11;
static const uint32_t IRQ_TIMER_ENABLE_OFFSET = 7;
static const uint32_t IRQ_SW_ENABLE_OFFSET = 3;
void irq_set_vector_offset(uintptr_t address) {
asm volatile("csrw mtvec, %0" ::"r"(address));
}
static void irq_mie_set(uint32_t value) {
asm volatile("csrrs zero, mie, %0" : : "r"(value) :);
}
static void irq_mie_clr(uint32_t value) {
asm volatile("csrrc zero, mie, %0" : : "r"(value) :);
}
void irq_global_ctrl(bool en) {
if (en) {
asm volatile("csrsi mstatus, 0x8" : : :);
} else {
asm volatile("csrci mstatus, 0x8" : : :);
}
}
void irq_external_ctrl(bool en) {
const uint32_t value = 1 << IRQ_EXT_ENABLE_OFFSET;
if (en) {
irq_mie_set(value);
} else {
irq_mie_clr(value);
}
}
void irq_timer_ctrl(bool en) {
const uint32_t value = 1 << IRQ_TIMER_ENABLE_OFFSET;
if (en) {
irq_mie_set(value);
} else {
irq_mie_clr(value);
}
}
void irq_software_ctrl(bool en) {
const uint32_t value = 1 << IRQ_SW_ENABLE_OFFSET;
if (en) {
irq_mie_set(value);
} else {
irq_mie_clr(value);
}
}