summaryrefslogtreecommitdiff
path: root/riscv.h
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-06-03 14:13:07 -0400
committerRobert Morris <[email protected]>2019-06-03 14:13:07 -0400
commita9c1a6f742886a9d45e5c625cf4f9b1b5c7a8cc4 (patch)
treeff50c8aa95dbdc5f35954e586933ad63676c69c4 /riscv.h
parent50cbc7510250a64674d619d13f5912edf08b767d (diff)
downloadxv6-labs-a9c1a6f742886a9d45e5c625cf4f9b1b5c7a8cc4.tar.gz
xv6-labs-a9c1a6f742886a9d45e5c625cf4f9b1b5c7a8cc4.tar.bz2
xv6-labs-a9c1a6f742886a9d45e5c625cf4f9b1b5c7a8cc4.zip
takes one uart input interrupt, then panics
Diffstat (limited to 'riscv.h')
-rw-r--r--riscv.h56
1 files changed, 55 insertions, 1 deletions
diff --git a/riscv.h b/riscv.h
index 5e54935..6ecee84 100644
--- a/riscv.h
+++ b/riscv.h
@@ -30,7 +30,11 @@ w_mepc(uint64 x)
// Supervisor Status Register, sstatus
-#define SSTATUS_SPP (1L << 8) // 1=Supervisor, 0=User
+#define SSTATUS_SPP (1L << 8) // Previous mode, 1=Supervisor, 0=User
+#define SSTATUS_SPIE (1L << 5) // Supervisor Previous Interrupt Enable
+#define SSTATUS_UPIE (1L << 4) // User Previous Interrupt Enable
+#define SSTATUS_SIE (1L << 1) // Supervisor Interrupt Enable
+#define SSTATUS_UIE (1L << 0) // User Interrupt Enable
static inline uint64
r_sstatus()
@@ -46,6 +50,33 @@ w_sstatus(uint64 x)
asm("csrw sstatus, %0" : : "r" (x));
}
+// Supervisor Interrupt Pending
+static inline uint64
+r_sip()
+{
+ uint64 x;
+ asm("csrr %0, sip" : "=r" (x) );
+ return x;
+}
+
+// Supervisor Interrupt Enable
+#define SIE_SEIE (1L << 9) // external
+#define SIE_STIE (1L << 5) // timer
+#define SIE_SSIE (1L << 1) // software
+static inline uint64
+r_sie()
+{
+ uint64 x;
+ asm("csrr %0, sie" : "=r" (x) );
+ return x;
+}
+
+static inline void
+w_sie(uint64 x)
+{
+ asm("csrw sie, %0" : : "r" (x));
+}
+
// machine exception program counter, holds the
// instruction address to which a return from
// exception will go.
@@ -147,6 +178,29 @@ r_stval()
return x;
}
+// enable interrupts
+static inline void
+intr_on()
+{
+ w_sie(r_sie() | SIE_SEIE | SIE_STIE | SIE_SSIE);
+ w_sstatus(r_sstatus() | SSTATUS_SIE);
+}
+
+// disable interrupts
+static inline void
+intr_off()
+{
+ w_sstatus(r_sstatus() & ~SSTATUS_SIE);
+}
+
+// are interrupts enabled?
+static inline int
+intr_get()
+{
+ uint64 x = r_sstatus();
+ return (x & SSTATUS_SIE) != 0;
+}
+
#define PGSIZE 4096 // bytes per page
#define PGSHIFT 12 // bits of offset within a page