#ifndef SRC_HARDWARE_IBEX_H_
#define SRC_HARDWARE_IBEX_H_

enum {
	MSTATUS_IE = 1U << 3,   //< Interrupt Enable
	MSTATUS_PIE = 1U << 7,  //< Previous Interrupt Enable
	MSTATUS_PP0 = 0U << 11, //< Machine Previous Privilege mode
	MSTATUS_PP1 = 1U << 11, //< Machine Previous Privilege mode
	MSTATUS_PP2 = 2U << 11, //< Machine Previous Privilege mode
	MSTATUS_PP3 = 3U << 11, //< Machine Previous Privilege mode
	MSTATUS_PRV = 1U << 17, //< Modify Privilege
	MSTATUS_TW = 1U << 21,  //< Timeout Wait
};

enum {
	MIE_SIO = 1U << 3,      //< Machine Software Interrupt Enable
	MIE_TIE = 1U << 7,      //< Machine Timer Interrupt Enable
	MIE_EIE = 1U << 11,     //< Machine External Interrupt Enable
	MIE_FIE16 = 1U << 16,   //< Machine Fast 16 Interrupt Enables
	MIE_FIE17 = 1U << 17,   //< Machine Fast 17 Interrupt Enables
	MIE_FIE18 = 1U << 18,   //< Machine Fast 18 Interrupt Enables
	MIE_FIE19 = 1U << 19,   //< Machine Fast 19 Interrupt Enables
	MIE_FIE20 = 1U << 20,   //< Machine Fast 20 Interrupt Enables
	MIE_FIE21 = 1U << 21,   //< Machine Fast 21 Interrupt Enables
	MIE_FIE22 = 1U << 22,   //< Machine Fast 22 Interrupt Enables
	MIE_FIE23 = 1U << 23,   //< Machine Fast 23 Interrupt Enables
	MIE_FIE24 = 1U << 24,   //< Machine Fast 24 Interrupt Enables
	MIE_FIE25 = 1U << 25,   //< Machine Fast 25 Interrupt Enables
	MIE_FIE26 = 1U << 26,   //< Machine Fast 26 Interrupt Enables
	MIE_FIE27 = 1U << 27,   //< Machine Fast 27 Interrupt Enables
	MIE_FIE28 = 1U << 28,   //< Machine Fast 28 Interrupt Enables
	MIE_FIE29 = 1U << 29,   //< Machine Fast 29 Interrupt Enables
	MIE_FIE30 = 1U << 30,   //< Machine Fast 30 Interrupt Enables
};

static inline void mstatusSet(unsigned val) {
	asm("csrs mstatus, %0" : : "r"(val) :);
}

static inline void mstatusClr(unsigned val) {
	asm("csrc mstatus, %0" : : "r"(val) :);
}

static inline void mstatusWrite(unsigned val) {
	asm("csrw mstatus, %0" : : "r"(val) :);
}

static inline unsigned mstatusRead() {
	unsigned val = 0;
	asm("csrr %0, mstatus" : "=r"(val) : :);
	return val;
}

static inline void mieSet(unsigned val) {
	asm("csrs mie, %0" : : "r"(val) :);
}

static inline void mieClr(unsigned val) {
	asm("csrc mie, %0" : : "r"(val) :);
}

static inline void mieWrite(unsigned val) {
	asm("csrw mie, %0" : : "r"(val) :);
}

static inline unsigned mieRead() {
	unsigned val = 0;
	asm("csrr %0, mie" : "=r"(val) : :);
	return val;
}

#endif /* SRC_HARDWARE_IBEX_H_ */
