summaryrefslogtreecommitdiff
path: root/sys/src/boot/alphapc/cons.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/boot/alphapc/cons.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/boot/alphapc/cons.c')
-rwxr-xr-xsys/src/boot/alphapc/cons.c243
1 files changed, 243 insertions, 0 deletions
diff --git a/sys/src/boot/alphapc/cons.c b/sys/src/boot/alphapc/cons.c
new file mode 100755
index 000000000..d41cedc0f
--- /dev/null
+++ b/sys/src/boot/alphapc/cons.c
@@ -0,0 +1,243 @@
+#include "u.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "lib.h"
+
+enum {
+ /* prom operations */
+ Promop_getc = 1,
+ Promop_puts = 2,
+ Promop_open = 0x10,
+ Promop_close = 0x11,
+ Promop_read = 0x13,
+ Promop_write = 0x14,
+ Promop_getenv = 0x22,
+
+ /* environment variable indices for getenv */
+ /* auto_action might be 1; it looks that way. */
+ Promenv_booted_dev = 4,
+ Promenv_booted_file = 6,
+ Promenv_booted_osflags = 8,
+ Promenv_tty_dev = 0xf,
+};
+
+Hwrpb *hwrpb;
+
+static uvlong dispatchf;
+static ulong clk2ms;
+
+void
+consinit(void)
+{
+ Procdesc *p;
+ Hwcrb *crb;
+ Hwdsr *dsr;
+ char *s;
+
+ hwrpb = (Hwrpb*)0x10000000;
+
+ crb = (Hwcrb*)((ulong)hwrpb + hwrpb->crboff);
+ p = (Procdesc*)(crb->dispatchva);
+ dispatchf = p->addr;
+ clk2ms = hwrpb->cfreq/1000;
+
+ print("\nAlpha Plan 9 secondary boot\n");
+ if (hwrpb->rev >= 6) {
+ dsr = (Hwdsr*)((ulong)hwrpb + hwrpb->dsroff);
+ s = (char*)dsr + dsr->sysnameoff + 8;
+ print("%s\n", s);
+ }
+}
+
+uvlong
+dispatch(uvlong r16, uvlong r17, uvlong r18, uvlong r19, uvlong r20)
+{
+ return gendispatch(dispatchf, r16, r17, r18, r19, r20);
+};
+
+int
+devopen(char *s)
+{
+ vlong ret;
+ int n;
+
+ n = strlen(s);
+ ret = dispatch(0x10, (uvlong)s, n, 0, 0);
+ if (ret < 0)
+ return -1;
+ return (int) ret;
+}
+
+int
+devclose(int fd)
+{
+ vlong ret;
+
+ ret = dispatch(0x11, fd, 0, 0, 0);
+ if (ret < 0)
+ return -1;
+ return 0;
+}
+
+int
+devread(int fd, uchar *buf, int len, int blkno)
+{
+ vlong ret;
+
+ ret = dispatch(0x13, fd, len, (uvlong)buf, blkno);
+ if (ret < 0)
+ return -1;
+ return (int) ret;
+}
+
+int
+devwrite(int fd, uchar *buf, int len, int blkno)
+{
+ vlong ret;
+
+ ret = dispatch(0x14, fd, len, (uvlong)buf, blkno);
+ if (ret < 0)
+ return -1;
+ return (int) ret;
+}
+
+void
+dumpenv(void)
+{
+ int id, n;
+ static char buf[256];
+
+ /* old upper bound was 0x100, which blows up on my 164LX. 50 works. */
+ for (id = 1; id < 50; id++) {
+ n = dispatch(Promop_getenv, id, (uvlong)buf, sizeof(buf)-1, 0);
+ if (n == 0)
+ continue;
+ if (n < 0) {
+ print("dispatch failed at id %d\n", id);
+ break;
+ }
+ buf[n] = 0;
+ print("env[0x%x]: %s\n", id, buf);
+ }
+}
+
+char *
+getenv(char *name)
+{
+ int id, n;
+ static char buf[256];
+
+ if (strcmp(name, "booted_dev") == 0)
+ id = Promenv_booted_dev;
+ else
+ return 0;
+ n = dispatch(Promop_getenv, id, (uvlong)buf, sizeof(buf), 0);
+ if (n < 0)
+ return 0;
+ buf[n] = 0;
+ return buf;
+}
+
+void
+putstrn0(char *s, int n)
+{
+ uvlong ret;
+ int cnt;
+
+ for (;;) {
+ ret = dispatch(2, 0, (uvlong)s, n, 0);
+ cnt = (int) ret;
+ s += cnt;
+ n -= cnt;
+ if (n <= 0)
+ break;
+ }
+}
+
+void
+putstrn(char *s, int n)
+{
+ char *p;
+
+ for (;;) {
+ if (n == 0)
+ return;
+ p = memchr(s, '\n', n);
+ if (p == 0) {
+ putstrn0(s, n);
+ return;
+ }
+ putstrn0(s, p-s);
+ putstrn0("\r\n", 2);
+ n -= p-s+1;
+ s = p+1;
+ }
+}
+
+int
+snprint(char *s, int n, char *fmt, ...)
+{
+ va_list arg;
+
+ va_start(arg, fmt);
+ n = doprint(s, s+n, fmt, arg) - s;
+ va_end(arg);
+ return n;
+}
+
+int
+sprint(char *s, char *fmt, ...)
+{
+ int n;
+ va_list arg;
+
+ va_start(arg, fmt);
+ n = doprint(s, s+PRINTSIZE, fmt, arg) - s;
+ va_end(arg);
+ return n;
+}
+
+int
+print(char *fmt, ...)
+{
+ int n;
+ va_list arg;
+ char buf[PRINTSIZE];
+
+ va_start(arg, fmt);
+ n = doprint(buf, buf+sizeof(buf), fmt, arg) - buf;
+ va_end(arg);
+ putstrn(buf, n);
+
+ return n;
+}
+
+void
+panic(char *fmt, ...)
+{
+ int n;
+ va_list arg;
+ char buf[PRINTSIZE];
+
+ strcpy(buf, "panic: ");
+ va_start(arg, fmt);
+ n = doprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf;
+ va_end(arg);
+ buf[n] = '\n';
+ putstrn(buf, n+1);
+ firmware();
+}
+
+ulong
+msec(void)
+{
+ static ulong last, wrap;
+ ulong cnt;
+
+ cnt = pcc_cnt();
+ if (cnt < last)
+ wrap++;
+ last = cnt;
+ return (((uvlong)wrap << 32) + cnt)/clk2ms;
+}