std1.0.0-beta-7 SafeC docs

Source interrupt/isr.sc

View in the repository

// SafeC Standard Library — ISR Vector Table
#pragma once
#include <std/interrupt/isr.h>

namespace std {

inline struct IsrTable IsrTable::new() {
    struct IsrTable t;
    t.count = 0;
    int i = 0;
    while (i < ISR_MAX) {
        t.handlers[i] = null;
        i = i + 1;
    }
    return t;
}

inline int IsrTable::register_(int irq, fn void() handler) {
    if (irq < 0 || irq >= ISR_MAX) { return 0; }
    // Re-registering an IRQ replaces its handler; count only new slots.
    if (self.handlers[irq].is_null()) { self.count = self.count + 1; }
    self.handlers[irq] = handler;
    return 1;
}

inline void IsrTable::unregister_(int irq) {
    if (irq >= 0 && irq < ISR_MAX) {
        if (!self.handlers[irq].is_null()) {
            self.handlers[irq] = null;
            self.count = self.count - 1;
        }
    }
}

inline int IsrTable::dispatch(int irq) {
    if (irq < 0 || irq >= ISR_MAX) { return 0; }
    match (self.handlers[irq]) {
        case some(handler): { handler(); return 1; }
        case null: return 0;
    }
    return 0;
}

// Masks/unmasks IRQs at the CPU on bare metal (privileged code). A hosted
// process can't touch the interrupt flag, so there (and on wasm) these are
// only compiler barriers.
inline void irq_disable() {
    unsafe {
#if !defined(__SAFEC_FREESTANDING__)
        asm volatile("" ::: "memory");
#elif defined(__aarch64__)
        asm volatile("msr daifset, #2" ::: "memory");
#elif defined(__arm__)
        asm volatile("cpsid i" ::: "memory");
#elif defined(__riscv)
        asm volatile("csrci mstatus, 8" ::: "memory");   // clear MIE
#elif defined(__x86_64__) || defined(__i386__)
        asm volatile("cli" ::: "memory");
#else
        asm volatile("" ::: "memory");
#endif
    }
}

inline void irq_enable() {
    unsafe {
#if !defined(__SAFEC_FREESTANDING__)
        asm volatile("" ::: "memory");
#elif defined(__aarch64__)
        asm volatile("msr daifclr, #2" ::: "memory");
#elif defined(__arm__)
        asm volatile("cpsie i" ::: "memory");
#elif defined(__riscv)
        asm volatile("csrsi mstatus, 8" ::: "memory");   // set MIE
#elif defined(__x86_64__) || defined(__i386__)
        asm volatile("sti" ::: "memory");
#else
        asm volatile("" ::: "memory");
#endif
    }
}

} // namespace std