summaryrefslogtreecommitdiff
path: root/os/mpc/pit.c
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
commit74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (patch)
treec6e220ba61db3a6ea4052e6841296d829654e664 /os/mpc/pit.c
parent46439007cf417cbd9ac8049bb4122c890097a0fa (diff)
20060303
Diffstat (limited to 'os/mpc/pit.c')
-rw-r--r--os/mpc/pit.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/os/mpc/pit.c b/os/mpc/pit.c
new file mode 100644
index 00000000..bfc8bc8d
--- /dev/null
+++ b/os/mpc/pit.c
@@ -0,0 +1,68 @@
+/*
+ * programmable interrupt timer
+ */
+
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "ureg.h"
+
+enum {
+ /* piscr */
+ PTE = 1<<0,
+ PITF = 1<<1,
+ PIE = 1<<2,
+ PS = 1<<7,
+};
+
+static void
+pitinterrupt(Ureg*, void*)
+{
+ IMM *io;
+
+ io = m->iomem;
+ if(io->piscr & PS){
+ io->piscr |= PS; /* clear by writing 1 */
+ /* do whatever is required */
+ }
+}
+
+static void
+pitreset(void)
+{
+ IMM *io;
+
+ io = ioplock();
+ io->piscrk = KEEP_ALIVE_KEY;
+ io->piscr = (PITlevel<<8) | PS | PITF;
+ if(0)
+ io->piscrk = ~KEEP_ALIVE_KEY;
+ /* piscrk is left unlocked for interrupt routine */
+ iopunlock();
+ intrenable(PITlevel, pitinterrupt, nil, BUSUNKNOWN, "pit");
+}
+
+static ulong
+pitload(ulong usec)
+{
+ IMM *io;
+ ulong v;
+
+ v = ((usec*m->oscclk)/512);
+ if(v == 0 || v >= (1<<16))
+ return 0; /* can't do */
+ io = ioplock();
+ io->pitck = KEEP_ALIVE_KEY;
+ io->pitc = (v-1)<<16;
+ io->pitck = ~KEEP_ALIVE_KEY;
+ io->piscrk = KEEP_ALIVE_KEY;
+ io->piscr = (PITlevel<<8) | PS | PIE | PITF | PTE;
+ if(0)
+ io->piscrk = ~KEEP_ALIVE_KEY;
+ /* piscrk is left unlocked for interrupt routine */
+ iopunlock();
+ return (v*512)/m->oscclk;
+}