summaryrefslogtreecommitdiff
path: root/os/fads
diff options
context:
space:
mode:
Diffstat (limited to 'os/fads')
-rw-r--r--os/fads/NOTICE4
-rw-r--r--os/fads/archfads.c619
-rw-r--r--os/fads/archfads.h33
-rw-r--r--os/fads/dat.h162
-rw-r--r--os/fads/fads121
-rw-r--r--os/fads/fns.h117
-rw-r--r--os/fads/io.h1
-rw-r--r--os/fads/main.c392
-rw-r--r--os/fads/mem.h157
-rw-r--r--os/fads/mkfile107
-rw-r--r--os/fads/mmu.c20
-rw-r--r--os/fads/tlb.s23
12 files changed, 1756 insertions, 0 deletions
diff --git a/os/fads/NOTICE b/os/fads/NOTICE
new file mode 100644
index 00000000..95589fda
--- /dev/null
+++ b/os/fads/NOTICE
@@ -0,0 +1,4 @@
+Inferno® Copyright © 1996-1999 Lucent Technologies Inc. All rights reserved.
+PowerPC support Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net). All rights reserved.
+MPC8xx Inferno PowerPC port Copyright © 1998-2003 Vita Nuova Holdings Limited. All rights reserved.
+FADS Inferno PowerPC port Copyright © 1998-2003 Vita Nuova Holdings Limited. All rights reserved.
diff --git a/os/fads/archfads.c b/os/fads/archfads.c
new file mode 100644
index 00000000..4ceb02a1
--- /dev/null
+++ b/os/fads/archfads.c
@@ -0,0 +1,619 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+
+#include "../port/netif.h"
+#include "../mpc/etherif.h"
+#include "../port/flashif.h"
+
+#include <draw.h>
+#include <memdraw.h>
+#include <cursor.h>
+#include "screen.h"
+
+#include "archfads.h"
+
+/*
+ * board-specific support for the 8xxFADS (including 860/21 development system)
+ */
+
+enum {
+ /* CS assignment on FADS boards */
+ BOOTCS = 0,
+ BCSRCS = 1,
+ DRAM1 = 2,
+ DRAM2 = 3,
+ SDRAM = 4,
+
+ /* sccr */
+ RTSEL = IBIT(8), /* =0, select main oscillator (OSCM); =1, select external crystal (EXTCLK) */
+ RTDIV = IBIT(7), /* =0, divide by 4; =1, divide by 512 */
+ CRQEN = IBIT(9), /* =1, switch to high frequency when CPM active */
+ PRQEN = IBIT(10), /* =1, switch to high frequency when interrupt pending */
+
+ /* plprcr */
+ CSRC = IBIT(21), /* =0, clock is DFNH; =1, clock is DFNL */
+};
+
+/*
+ * called early in main.c, after machinit:
+ * using board and architecture specific registers, initialise
+ * 8xx registers that need it and complete initialisation of the Mach structure.
+ */
+void
+archinit(void)
+{
+ IMM *io;
+ int mf;
+
+ m->bcsr = KADDR(PHYSBCSR);
+ m->bcsr[1] |= DisableRS232a | DisableIR | DisableEther | DisablePCMCIA | DisableRS232b;
+ m->bcsr[1] &= ~(DisableDRAM|DisableFlash);
+ m->bcsr[1] &= ~EnableSDRAM;
+ m->bcsr[4] &= ~EnableVideoClock;
+ m->bcsr[4] |= DisableVideoLamp;
+ io = m->iomem; /* run by reset code: no need to lock */
+ if(1 || (io->sccr & RTDIV) != 0){
+ /* oscillator frequency can't be determined independently: check a switch */
+ if((m->bcsr[2]>>19)&(1<<2))
+ m->clockgen = 5*MHz;
+ else
+ m->clockgen = 4*MHz;
+ } else
+ m->clockgen = 32768;
+ m->oscclk = m->clockgen/MHz; /* TO DO: 32k clock */
+ io->plprcrk = KEEP_ALIVE_KEY;
+ io->plprcr &= ~CSRC; /* general system clock is DFNH */
+ mf = (io->plprcr >> 20)+1; /* use timing set by bootstrap */
+ io->plprcrk = ~KEEP_ALIVE_KEY;
+ io->sccrk = KEEP_ALIVE_KEY;
+ io->sccr |= CRQEN | PRQEN;
+ io->sccr |= RTSEL; /* select EXTCLK */
+ io->sccrk = ~KEEP_ALIVE_KEY;
+ m->cpuhz = m->clockgen*mf;
+ m->speed = m->cpuhz/MHz;
+}
+
+static ulong
+banksize(int x, ulong *pa)
+{
+ IMM *io;
+
+ io = m->iomem;
+ if((io->memc[x].base & 1) == 0)
+ return 0; /* bank not valid */
+ *pa = io->memc[x].base & ~0x7FFF;
+ return -(io->memc[x].option&~0x7FFF);
+}
+
+/*
+ * initialise the kernel's memory configuration:
+ * there are two banks (base0, npage0) and (base1, npage1).
+ * initialise any other values in conf that are board-specific.
+ */
+void
+archconfinit(void)
+{
+ ulong nbytes, pa, ktop;
+
+ conf.nscc = 2;
+ conf.nocts2 = 1; /* not connected on the FADS board */
+
+ conf.npage0 = 0;
+ if((m->bcsr[1] & DisableDRAM) == 0){
+ nbytes = banksize(DRAM1, &pa);
+ if(nbytes){
+ conf.npage0 = nbytes/BY2PG;
+ conf.base0 = pa;
+ }
+ }
+
+ conf.npage1 = 0;
+ if(m->bcsr[1] & EnableSDRAM){
+ nbytes = banksize(SDRAM, &pa);
+ if(nbytes){
+ conf.npage1 = nbytes/BY2PG;
+ conf.base1 = pa;
+ }
+ }
+
+ /* the following assumes the kernel text and/or data is in bank 0 */
+ ktop = PGROUND((ulong)end);
+ ktop = PADDR(ktop) - conf.base0;
+ conf.npage0 -= ktop/BY2PG;
+ conf.base0 += ktop;
+}
+
+static void
+archidprint(void)
+{
+ int f, i;
+ ulong v;
+
+ /* 8xx and FADS specific */
+ print("IMMR: ");
+ v = getimmr() & 0xFFFF;
+ switch(v>>8){
+ case 0x00: print("MPC860/821"); break;
+ case 0x20: print("MPC823"); break;
+ case 0x21: print("MPC823A"); break;
+ default: print("Type #%lux", v>>8); break;
+ }
+ print(", mask #%lux\n", v&0xFF);
+ v = m->bcsr[3]>>16;
+ print("MPC8xxFADS rev %lud, DB: ", ((v>>4)&8)|((v>>1)&4)|(v&3));
+ f = (v>>8)&0x3F;
+ switch(f){
+ default: print("ID#%x", f); break;
+ case 0x00: print("MPC860/821"); break;
+ case 0x01: print("MPC813"); break;
+ case 0x02: print("MPC821"); break;
+ case 0x03: print("MPC823"); break;
+ case 0x20: print("MPC801"); break;
+ case 0x21: print("MPC850"); break;
+ case 0x22: print("MPC860"); break;
+ case 0x23: print("MPC860SAR"); break;
+ case 0x24: print("MPC860T"); break;
+ }
+ print("ADS, rev #%lux\n", (m->bcsr[2]>>16)&7);
+ for(i=0; i<=4; i++)
+ print("BCSR%d: %8.8lux\n", i, m->bcsr[i]);
+ v = m->bcsr[2];
+ f = (v>>28)&0xF;
+ switch(f){
+ default: print("Unknown"); break;
+ case 4: print("SM732A2000/SM73228 - 8M SIMM"); break;
+ case 5: print("SM732A1000A/SM73218 - 4M SIMM"); break;
+ case 6: print("MCM29080 - 8M SIMM"); break;
+ case 7: print("MCM29040 - 4M SIMM"); break;
+ case 8: print("MCM29020 - 2M SIMM"); break;
+ }
+ switch((m->bcsr[3]>>20)&7){
+ default: i = 0; break;
+ case 1: i = 150; break;
+ case 2: i = 120; break;
+ case 3: i = 90; break;
+ }
+ print(" flash, %dns\n", i);
+ f = (v>>23)&0xF;
+ switch(f&3){
+ case 0: i = 4; break;
+ case 1: i = 32; break;
+ case 2: i = 16; break;
+ case 3: i = 8; break;
+ }
+ print("%dM SIMM, ", i);
+ switch(f>>2){
+ default: i = 0; break;
+ case 2: i = 70; break;
+ case 3: i = 60; break;
+ }
+ print("%dns\n", i);
+ print("options: #%lux\n", (m->bcsr[2]>>19)&0xF);
+ print("plprcr=%8.8lux sccr=%8.8lux\n", m->iomem->plprcr, m->iomem->sccr);
+}
+
+void
+cpuidprint(void)
+{
+ print("PVR: ");
+ switch(m->cputype){
+ case 0x01: print("MPC601"); break;
+ case 0x03: print("MPC603"); break;
+ case 0x04: print("MPC604"); break;
+ case 0x06: print("MPC603e"); break;
+ case 0x07: print("MPC603e-v7"); break;
+ case 0x50: print("MPC8xx"); break;
+ default: print("PowerPC version #%x", m->cputype); break;
+ }
+ print(", revision #%lux\n", getpvr()&0xffff);
+ archidprint();
+ print("%lud MHz system\n", m->cpuhz/MHz);
+ print("\n");
+}
+
+/*
+ * provide value for #r/switch (devrtc.c)
+ */
+int
+archoptionsw(void)
+{
+ return (m->bcsr[2]>>19)&0xF; /* value of switch DS1 */
+}
+
+/*
+ * invoked by clock.c:/^clockintr
+ */
+static void
+twinkle(void)
+{
+ if(m->ticks%MS2TK(1000) == 0)
+ m->bcsr[4] ^= DisableLamp;
+}
+
+void (*archclocktick)(void) = twinkle;
+
+/*
+ * invoked by ../port/taslock.c:/^ilock:
+ * reset watchdog timer here, if there is one and it is enabled
+ * (qboot currently disables it on the FADS board)
+ */
+void
+clockcheck(void)
+{
+}
+
+/*
+ * for devflash.c:/^flashreset
+ * retrieve flash type, virtual base and length and return 0;
+ * return -1 on error (no flash)
+ */
+int
+archflashreset(int bank, Flash *f)
+{
+ char *t;
+ int mbyte;
+
+ if(bank != 0)
+ return -1;
+ switch((m->bcsr[2]>>28)&0xF){
+ default: return -1; /* unknown or not there */
+ case 4: mbyte=8; t = "SM732x8"; break;
+ case 5: mbyte=4; t = "SM732x8"; break;
+ case 6: mbyte=8; t = "AMD29F0x0"; break;
+ case 7: mbyte=4; t = "AMD29F0x0"; break;
+ case 8: mbyte=2; t = "AMD29F0x0"; break;
+ }
+ f->type = t;
+ f->addr = KADDR(PHYSFLASH);
+ f->size = mbyte*1024*1024;
+ f->width = 4;
+ f->interleave = 3;
+ return 0;
+}
+
+void
+archflashwp(Flash*, int)
+{
+}
+
+int
+archether(int ctlrno, Ether *ether)
+{
+ if(isaconfig("ether", ctlrno, ether) == 0)
+ return -1;
+ return 1;
+}
+
+/*
+ * enable the clocks for the given SCC ether and reveal them to the caller.
+ * do anything else required to prepare the transceiver (eg, set full-duplex, reset loopback).
+ */
+int
+archetherenable(int cpmid, int *rcs, int *tcs, int mbps, int fullduplex)
+{
+ IMM *io;
+
+ USED(mbps, fullduplex); /* TO DO */
+ switch(cpmid){
+ default:
+ /* no other SCCs are wired on the FADS board */
+ return -1;
+
+ case CPscc2: /* assume 8xxFADS board with 823DABS */
+ io = ioplock();
+ m->bcsr[1] |= DisableIR|DisableRS232b;
+ m->bcsr[1] &= ~DisableEther;
+ io->papar |= SIBIT(6)|SIBIT(5); /* enable CLK2 and CLK3 */
+ io->padir &= ~(SIBIT(6)|SIBIT(5));
+ /* ETHLOOP etc reset in BCSR elsewhere */
+ iopunlock();
+ *rcs = CLK2;
+ *tcs = CLK3;
+ break;
+
+ case CPscc1: /* assume 860/21 development board */
+ io = ioplock();
+ m->bcsr[1] |= DisableIR|DisableRS232b; /* TO DO: might not be shared with RS232b */
+ m->bcsr[1] &= ~DisableEther;
+ io->papar |= SIBIT(6)|SIBIT(7); /* enable CLK2 and CLK1 */
+ io->padir &= ~(SIBIT(6)|SIBIT(7));
+
+ /* settings peculiar to 860/821 development board */
+ io->pcpar &= ~(SIBIT(4)|SIBIT(5)|SIBIT(6)); /* ETHLOOP, TPFULDL~, TPSQEL~ */
+ io->pcdir |= SIBIT(4)|SIBIT(5)|SIBIT(6);
+ io->pcdat &= ~SIBIT(4);
+ io->pcdat |= SIBIT(5)|SIBIT(6);
+ iopunlock();
+ *rcs = CLK2;
+ *tcs = CLK1;
+ break;
+ }
+ return 0;
+}
+
+/*
+ * do anything extra required to enable the UART on the given CPM port
+ */
+void
+archenableuart(int id, int irda)
+{
+ switch(id){
+ case CPsmc1:
+ m->bcsr[1] &= ~DisableRS232a;
+ break;
+ case CPscc2:
+ m->bcsr[1] |= DisableEther|DisableIR|DisableRS232b;
+ if(irda)
+ m->bcsr[1] &= ~DisableIR;
+ else
+ m->bcsr[1] &= ~DisableRS232b;
+ break;
+ default:
+ /* nothing special */
+ break;
+ }
+}
+
+/*
+ * do anything extra required to disable the UART on the given CPM port
+ */
+void
+archdisableuart(int id)
+{
+ switch(id){
+ case CPsmc1:
+ m->bcsr[1] |= DisableRS232a;
+ break;
+ case CPscc2:
+ m->bcsr[1] |= DisableIR|DisableRS232b;
+ break;
+ default:
+ /* nothing special */
+ break;
+ }
+}
+
+/*
+ * enable the external USB transceiver
+ * speed is 12MHz if highspeed is non-zero; 1.5MHz if zero
+ * master is non-zero if the node is acting as USB Host and should provide power
+ */
+void
+archenableusb(int highspeed, int master)
+{
+ if(highspeed)
+ m->bcsr[4] |= USBFullSpeed;
+ else
+ m->bcsr[4] &= ~USBFullSpeed;
+ if(master)
+ m->bcsr[4] &= ~DisableUSBVcc;
+ else
+ m->bcsr[4] |= DisableUSBVcc;
+ eieio();
+ m->bcsr[4] &= ~DisableUSB;
+}
+
+/*
+ * shut down the USB transceiver
+ */
+void
+archdisableusb(void)
+{
+ m->bcsr[4] |= DisableUSBVcc | DisableUSB;
+}
+
+/*
+ * set the external infrared transceiver to the given speed
+ */
+void
+archsetirxcvr(int highspeed)
+{
+ if(!highspeed){
+ /* force low edge after enable to put TFDS6000 xcvr in low-speed mode (see 4.9.2.1 in FADS manual) */
+ m->bcsr[1] |= DisableIR;
+ microdelay(2);
+ }
+ m->bcsr[1] &= ~DisableIR;
+}
+
+/*
+ * force hardware reset/reboot
+ */
+void
+archreboot(void)
+{
+ IMM *io;
+
+ io = m->iomem;
+ io->plprcrk = KEEP_ALIVE_KEY;
+ io->plprcr |= 1<<7; /* checkstop reset enable */
+ io->plprcrk = ~KEEP_ALIVE_KEY;
+ m->iomem->padat &= ~SIBIT(4); /* drop backlight */
+ eieio();
+ io->sdcr = 1;
+ eieio();
+ io->lccr = 0;
+ eieio();
+ firmware(0);
+}
+
+/*
+ * board-specific PCMCIA support: assumes slot B on 82xFADS
+ */
+
+int
+pcmslotavail(int slotno)
+{
+ return slotno == 1;
+}
+
+void
+pcmenable(void)
+{
+ ioplock();
+ m->bcsr[1] = (m->bcsr[1] | PCCVPPHiZ) & ~PCCVPP5V;
+ m->bcsr[1] |= PCCVCC0V;
+ m->bcsr[1] &= ~DisablePCMCIA;
+ m->bcsr[1] &= ~PCCVCC5V; /* apply Vcc */
+ iopunlock();
+}
+
+int
+pcmpowered(int)
+{
+ ulong r;
+
+ r = ~m->bcsr[1]&PCCVCCMask; /* active low */
+ if(r == PCCVCC5V)
+ return 5;
+ if(r == PCCVCC3V)
+ return 3;
+ return 0;
+}
+
+void
+pcmsetvcc(int, int v)
+{
+ if(v == 5)
+ v = PCCVCC5V;
+ else if(v == 3)
+ v = PCCVCC3V;
+ else
+ v = 0;
+ ioplock();
+ m->bcsr[1] = (m->bcsr[1] | PCCVCCMask) & ~v; /* active low */
+ iopunlock();
+}
+
+void
+pcmsetvpp(int, int v)
+{
+ if(v == 5)
+ v = PCCVPP5V;
+ else if(v == 12)
+ v = PCCVPP12V;
+ else if(v == 0)
+ v = PCCVPP0V;
+ else
+ v = 0; /* Hi-Z */
+ ioplock();
+ m->bcsr[1] = (m->bcsr[1] | PCCVPPHiZ) & ~v; /* active low */
+ iopunlock();
+}
+
+void
+pcmpower(int slotno, int on)
+{
+ if(!on){
+ pcmsetvcc(slotno, 0); /* turn off card power */
+ pcmsetvpp(slotno, -1); /* turn off programming voltage (Hi-Z) */
+ }else
+ pcmsetvcc(slotno, 5);
+}
+
+/*
+ * enable/disable the LCD panel's backlight via
+ * York touch panel interface (does no harm without it)
+ */
+void
+archbacklight(int on)
+{
+ IMM *io;
+
+ delay(2);
+ io = ioplock();
+ io->papar &= ~SIBIT(4);
+ io->padir |= SIBIT(4);
+ if(on)
+ io->padat |= SIBIT(4);
+ else
+ io->padat &= ~SIBIT(4);
+ iopunlock();
+}
+
+/*
+ * set parameters to describe the screen
+ */
+int
+archlcdmode(Mode *m)
+{
+ m->x = 640;
+ m->y = 480;
+ m->d = 3;
+ m->lcd.freq = 25000000;
+ m->lcd.ac = 0;
+ m->lcd.vpw = 2;
+ m->lcd.wbf = 34;
+ m->lcd.wbl = 106;
+ m->lcd.flags = IsColour | IsTFT | OELow | HsyncLow | VsyncLow;
+ m->lcd.notpdpar = SIBIT(6);
+ return 0;
+}
+
+/*
+ * reset 823 video port for devvid.c
+ */
+void
+archresetvideo(void)
+{
+ ioplock();
+ m->bcsr[4] &= ~DisableVideoLamp;
+ m->bcsr[4] |= EnableVideoPort;
+ eieio();
+ m->bcsr[4] &= ~EnableVideoPort; /* falling edge to reset */
+ iopunlock();
+ delay(6);
+ ioplock();
+ m->bcsr[4] |= EnableVideoPort;
+ iopunlock();
+ delay(6);
+}
+
+/*
+ * enable 823 video port and clock
+ */
+void
+archenablevideo(void)
+{
+ ioplock();
+ m->bcsr[4] |= EnableVideoClock|EnableVideoPort; /* enable AFTER pdpar/pddir to avoid damage */
+ iopunlock();
+}
+
+/*
+ * disable 823 video port and clock
+ */
+void
+archdisablevideo(void)
+{
+ ioplock();
+ m->bcsr[4] &= ~(EnableVideoClock|EnableVideoPort);
+ m->bcsr[4] |= DisableVideoLamp;
+ iopunlock();
+}
+
+/*
+ * allocate a frame buffer for the video, aligned on 16 byte boundary
+ */
+uchar*
+archvideobuffer(long nbytes)
+{
+ /* we shall use the on-board SDRAM if the kernel hasn't grabbed it */
+ if((m->bcsr[1] & EnableSDRAM) == 0){
+ m->bcsr[1] |= EnableSDRAM;
+ return KADDR(PHYSSDRAM);
+ }
+ return xspanalloc(nbytes, 16, 0);
+}
+
+/*
+ * there isn't a hardware keyboard port
+ */
+void
+archkbdinit(void)
+{
+}
diff --git a/os/fads/archfads.h b/os/fads/archfads.h
new file mode 100644
index 00000000..a35230f9
--- /dev/null
+++ b/os/fads/archfads.h
@@ -0,0 +1,33 @@
+
+enum {
+ /* BCSR1 bits */
+ DisableFlash= IBIT(0),
+ DisableDRAM= IBIT(1),
+ DisableEther= IBIT(2),
+ DisableIR= IBIT(3),
+ DisableRS232a= IBIT(7),
+ DisablePCMCIA= IBIT(8),
+ PCCVCCMask= IBIT(9)|IBIT(15),
+ PCCVPPMask= IBIT(10)|IBIT(11),
+ DisableRS232b= IBIT(13),
+ EnableSDRAM= IBIT(14),
+
+ PCCVCC0V= IBIT(15)|IBIT(9),
+ PCCVCC5V= IBIT(9), /* active low */
+ PCCVCC3V= IBIT(15), /* active low */
+ PCCVPP0V= IBIT(10)|IBIT(11), /* active low */
+ PCCVPP5V= IBIT(10), /* active low */
+ PCCVPP12V= IBIT(11), /* active low */
+ PCCVPPHiZ= IBIT(10)|IBIT(11),
+
+ /* BCSR4 bits */
+ DisableTPDuplex= IBIT(1),
+ DisableLamp= IBIT(3),
+ DisableUSB= IBIT(4),
+ USBFullSpeed= IBIT(5),
+ DisableUSBVcc= IBIT(6),
+ DisableVideoLamp= IBIT(8),
+ EnableVideoClock= IBIT(9),
+ EnableVideoPort= IBIT(10),
+ DisableModem= IBIT(11),
+};
diff --git a/os/fads/dat.h b/os/fads/dat.h
new file mode 100644
index 00000000..19d7c560
--- /dev/null
+++ b/os/fads/dat.h
@@ -0,0 +1,162 @@
+typedef struct Conf Conf;
+typedef struct FPU FPU;
+typedef struct FPenv FPenv;
+typedef struct IMM IMM;
+typedef struct Irqctl Irqctl;
+typedef struct ISAConf ISAConf;
+typedef struct Label Label;
+typedef struct Lock Lock;
+typedef struct Mach Mach;
+typedef struct Map Map;
+typedef struct Power Power;
+typedef struct RMap RMap;
+typedef struct Ureg Ureg;
+
+typedef ulong Instr;
+
+#define MACHP(n) (n==0? &mach0 : *(Mach**)0)
+
+struct Lock
+{
+ ulong key;
+ ulong pc;
+ ulong sr;
+ int pri;
+};
+
+struct Label
+{
+ ulong sp;
+ ulong pc;
+};
+
+/*
+ * Proc.fpstate
+ */
+enum
+{
+ FPINIT,
+ FPACTIVE,
+ FPINACTIVE,
+};
+
+/*
+ * This structure must agree with FPsave and FPrestore asm routines
+ */
+struct FPenv
+{
+ union {
+ double fpscrd;
+ struct {
+ ulong pad;
+ ulong fpscr;
+ };
+ };
+ int fpistate; /* emulated fp */
+ ulong emreg[32][3]; /* emulated fp */
+};
+/*
+ * This structure must agree with fpsave and fprestore asm routines
+ */
+struct FPU
+{
+ double fpreg[32];
+ FPenv env;
+};
+
+struct Conf
+{
+ ulong nmach; /* processors */
+ ulong nproc; /* processes */
+ ulong npage0; /* total physical pages of memory */
+ ulong npage1; /* total physical pages of memory */
+ ulong npage; /* total physical pages of memory */
+ ulong base0; /* base of bank 0 */
+ ulong base1; /* base of bank 1 */
+ ulong ialloc; /* max interrupt time allocation in bytes */
+
+ int nscc; /* number of SCCs implemented */
+ ulong smcuarts; /* bits for SMCs to define as eiaN */
+ ulong sccuarts; /* bits for SCCs to define as eiaN */
+ int nocts2; /* CTS2 and CD2 aren't connected */
+ uchar* nvrambase; /* virtual address of nvram */
+ ulong nvramsize; /* size in bytes */
+};
+
+#include "../port/portdat.h"
+
+/*
+ * machine dependent definitions not used by ../port/dat.h
+ */
+
+struct Mach
+{
+ /* OFFSETS OF THE FOLLOWING KNOWN BY l.s */
+ int machno; /* physical id of processor (unused) */
+ ulong splpc; /* pc of last caller to splhi (unused) */
+ int mmask; /* 1<<m->machno (unused) */
+
+ /* ordering from here on irrelevant */
+ ulong ticks; /* of the clock since boot time */
+ Proc *proc; /* current process on this processor */
+ Label sched; /* scheduler wakeup */
+ Lock alarmlock; /* access to alarm list */
+ void *alarm; /* alarms bound to this clock */
+ int nrdy;
+ int speed; /* general system clock in MHz */
+ long oscclk; /* oscillator frequency (MHz) */
+ long cpuhz; /* general system clock (cycles) */
+ long clockgen; /* clock generator frequency (cycles) */
+ int cputype;
+ ulong delayloop;
+ ulong* bcsr;
+ IMM* iomem; /* MPC8xx internal i/o control memory */
+
+ /* MUST BE LAST */
+ int stack[1];
+};
+extern Mach mach0;
+
+
+/*
+ * a parsed .ini line
+ */
+#define NISAOPT 8
+
+struct ISAConf {
+ char* type;
+ ulong port;
+ ulong irq;
+ ulong mem;
+ int dma;
+ ulong size;
+ ulong freq;
+ uchar bus;
+
+ int nopt;
+ char* opt[NISAOPT];
+};
+
+struct Map {
+ int size;
+ ulong addr;
+};
+
+struct RMap {
+ char* name;
+ Map* map;
+ Map* mapend;
+
+ Lock;
+};
+
+struct Power {
+ Dev* dev;
+ int (*powerdown)(Power*);
+ int (*powerup)(Power*);
+ int state;
+ void* arg;
+};
+
+extern register Mach *m;
+extern register Proc *up;
diff --git a/os/fads/fads b/os/fads/fads
new file mode 100644
index 00000000..1f1a2959
--- /dev/null
+++ b/os/fads/fads
@@ -0,0 +1,121 @@
+# fads board with remote file system on ether or ppp
+dev
+ root
+ cons archfads screen
+ env
+ mnt
+ pipe
+ prog
+ rtc
+ srv
+ dup
+ ssl
+ cap
+
+ draw
+ pointer
+
+ ip bootp ip ipv6 ipaux iproute arp netlog ptclbsum iprouter plan9 nullmedium pktmedium
+ ether netif netaux
+ uart
+ flash
+# usb
+ touch spi
+# pcmcia cis
+# ata inb
+
+ ftl
+# kfs chk kcon console dat dentry fcall fs fswren iobuf kfs sub uid
+# kprof
+
+# vid i2c
+ i2c i2c
+
+ip
+ il
+ tcp
+ udp
+ ipifc
+ icmp
+ icmp6
+ ipmux
+
+lib
+ interp
+ tk
+ draw
+ memlayer
+ memdraw
+ keyring
+ sec
+ mp
+ math
+ kern
+
+link
+ etherscc
+ ethermedium
+ flashamd29f0x0
+# pppmedium ppp compress
+
+mod
+ sys
+ draw
+ tk
+ math
+ keyring
+
+port
+ alarm
+ alloc
+ allocb
+ chan
+ dev
+ dial
+ dis
+ discall
+ exception
+ exportfs
+ inferno
+ latin1
+ nocache
+ nodynld
+ parse
+ pgrp
+ print
+ proc
+ qio
+ qlock
+ random
+ sysfile
+ taslock
+ xalloc
+
+code
+ int cflag = 0;
+ int consoleprint = 1;
+ int panicreset = 0;
+ int kernel_pool_pcnt = 10;
+ int main_pool_pcnt = 40;
+ int heap_pool_pcnt = 20;
+ int image_pool_pcnt = 40;
+
+init
+ mpcinit
+
+root
+ /chan
+ /dev
+ /dis
+ /env
+ /fd /
+ /n
+ /net
+ /nvfs /
+ /prog
+ /icons
+ /osinit.dis
+ /dis/lib/auth.dis
+ /dis/lib/ssl.dis
+ /n/local /
+ /nvfs/default /usr/inferno/keyring/default
diff --git a/os/fads/fns.h b/os/fads/fns.h
new file mode 100644
index 00000000..c4892a82
--- /dev/null
+++ b/os/fads/fns.h
@@ -0,0 +1,117 @@
+#include "../port/portfns.h"
+
+void addpower(Power*);
+void archbacklight(int);
+void archconfinit(void);
+void archdisableuart(int);
+void archdisableusb(void);
+void archdisablevideo(void);
+void archenableuart(int, int);
+void archenableusb(int, int);
+void archenablevideo(void);
+void archkbdinit(void);
+void archresetvideo(void);
+int archetherenable(int, int*, int*, int, int);
+void archinit(void);
+int archoptionsw(void);
+void archreboot(void);
+void archsetirxcvr(int);
+uchar* archvideobuffer(long);
+ulong baudgen(int, int);
+int brgalloc(void);
+void brgfree(int);
+int cistrcmp(char*, char*);
+int cistrncmp(char*, char*, int);
+void clockcheck(void);
+void clockinit(void);
+void clockintr(Ureg*);
+void clrfptrap(void);
+#define coherence() /* nothing needed for uniprocessor */
+void cpminit(void);
+void cpuidprint(void);
+void dcflush(void*, ulong);
+void dcinval(void*, ulong);
+void delay(int);
+void dtlbmiss(void);
+void dumplongs(char*, ulong*, int);
+void dumpregs(Ureg*);
+void eieio(void);
+void faultpower(Ureg*);
+void firmware(int);
+void fpinit(void);
+int fpipower(Ureg*);
+void fpoff(void);
+void fprestore(FPU*);
+void fpsave(FPU*);
+ulong fpstatus(void);
+char* getconf(char*);
+ulong getdar(void);
+ulong getdec(void);
+ulong getdepn(void);
+ulong getdsisr(void);
+ulong getimmr(void);
+ulong getmsr(void);
+ulong getpvr(void);
+ulong gettbl(void);
+ulong gettbu(void);
+void gotopc(ulong);
+void icflush(void*, ulong);
+void idle(void);
+#define idlehands() /* nothing to do in the runproc */
+void intr(Ureg*);
+void intrenable(int, void (*)(Ureg*, void*), void*, int, char*);
+void intrdisable(int, void (*)(Ureg*, void*), void*, int, char*);
+int intrstats(char*, int);
+void intrvec(void);
+int isaconfig(char*, int, ISAConf*);
+int isvalid_va(void*);
+void itlbmiss(void);
+void kbdinit(void);
+void kbdreset(void);
+void lcdpanel(int);
+void links(void);
+void mapfree(RMap*, ulong, int);
+void mapinit(RMap*, Map*, int);
+void mathinit(void);
+void mmuinit(void);
+ulong* mmuwalk(ulong*, ulong, int);
+void pcmenable(void);
+void pcmintrenable(int, void (*)(Ureg*, void*), void*);
+int pcmpin(int slot, int type);
+void pcmpower(int, int);
+int pcmpowered(int);
+void pcmsetvcc(int, int);
+void pcmsetvpp(int, int);
+int pcmslotsavail(int);
+void procsave(Proc*);
+void procsetup(Proc*);
+void putdec(ulong);
+void putmsr(ulong);
+void puttwb(ulong);
+ulong rmapalloc(RMap*, ulong, int, int);
+void screeninit(void);
+int screenprint(char*, ...); /* debugging */
+void screenputs(char*, int);
+int segflush(void*, ulong);
+void setpanic(void);
+long spioutin(void*, long, void*);
+void spireset(void);
+ulong _tas(ulong*);
+void trapinit(void);
+void trapvec(void);
+void uartinstall(void);
+void uartspecial(int, int, Queue**, Queue**, int (*)(Queue*, int));
+void uartwait(void); /* debugging */
+void videoreset(void);
+void videotest(void);
+void wbflush(void);
+
+#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
+ulong getcallerpc(void*);
+
+#define KADDR(a) ((void*)((ulong)(a)|KZERO))
+#define PADDR(a) ((((ulong)(a)&KSEGM)!=KSEG0)?(ulong)(a):((ulong)(a)&~KZERO))
+
+/* IBM bit field order */
+#define IBIT(b) ((ulong)1<<(31-(b)))
+#define SIBIT(n) ((ushort)1<<(15-(n)))
diff --git a/os/fads/io.h b/os/fads/io.h
new file mode 100644
index 00000000..30312c68
--- /dev/null
+++ b/os/fads/io.h
@@ -0,0 +1 @@
+#include "../mpc/800io.h"
diff --git a/os/fads/main.c b/os/fads/main.c
new file mode 100644
index 00000000..93ba7f95
--- /dev/null
+++ b/os/fads/main.c
@@ -0,0 +1,392 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "ureg.h"
+#include "version.h"
+
+/* where b.com or qboot leaves configuration info */
+#define BOOTARGS ((char*)CONFADDR)
+#define BOOTARGSLEN 1024
+#define MAXCONF 32
+
+extern ulong kerndate;
+extern int cflag;
+int remotedebug;
+
+extern int main_pool_pcnt;
+extern int heap_pool_pcnt;
+extern int image_pool_pcnt;
+
+char bootargs[BOOTARGSLEN+1];
+char bootdisk[KNAMELEN];
+char *confname[MAXCONF];
+char *confval[MAXCONF];
+int nconf;
+
+extern void addconf(char *, char *);
+
+/*
+ * arguments passed to initcode and /boot
+ */
+char argbuf[128];
+
+static void
+options(void)
+{
+ long i, n;
+ char *cp, *line[MAXCONF], *p, *q;
+
+ /*
+ * parse configuration args from bootstrap
+ */
+ memmove(bootargs, BOOTARGS, BOOTARGSLEN); /* where b.com leaves its config */
+ cp = bootargs;
+ cp[BOOTARGSLEN-1] = 0;
+
+ /*
+ * Strip out '\r', change '\t' -> ' '.
+ */
+ p = cp;
+ for(q = cp; *q; q++){
+ if(*q == '\r')
+ continue;
+ if(*q == '\t')
+ *q = ' ';
+ *p++ = *q;
+ }
+ *p = 0;
+
+ n = getfields(cp, line, MAXCONF, 1, "\n");
+ for(i = 0; i < n; i++){
+ if(*line[i] == '#')
+ continue;
+ cp = strchr(line[i], '=');
+ if(cp == 0)
+ continue;
+ *cp++ = 0;
+ confname[nconf] = line[i];
+ confval[nconf] = cp;
+ nconf++;
+ }
+}
+
+void
+doc(char *m)
+{
+ USED(m);
+ print("%s...\n", m); uartwait();
+}
+
+static void
+poolsizeinit(void)
+{
+ ulong nb;
+
+ nb = conf.npage*BY2PG;
+ poolsize(mainmem, (nb*main_pool_pcnt)/100, 0);
+ poolsize(heapmem, (nb*heap_pool_pcnt)/100, 0);
+ poolsize(imagmem, (nb*image_pool_pcnt)/100, 1);
+}
+
+static void
+serialconsole(void)
+{
+ char *p;
+ int port, baud;
+
+ p = getconf("console");
+ if(p == nil)
+ p = "0";
+ if(p != nil && !remotedebug){
+ port = strtol(p, nil, 0);
+ baud = 9600;
+ p = getconf("baud");
+ if(p != nil){
+ baud = strtol(p, nil, 0);
+ if(baud < 9600)
+ baud = 9600;
+ }
+ uartspecial(port, baud, &kbdq, &printq, kbdcr2nl);
+ }
+}
+
+void
+main(void)
+{
+ machinit();
+ options();
+ archinit();
+ quotefmtinstall();
+ confinit();
+ cpminit();
+ xinit();
+ poolsizeinit();
+ trapinit();
+ mmuinit();
+ printinit();
+ uartinstall();
+ serialconsole();
+ doc("screeninit");
+ screeninit();
+ doc("kbdinit");
+ kbdinit();
+ doc("clockinit");
+ clockinit();
+ doc("procinit");
+ procinit();
+ cpuidprint();
+ doc("links");
+ links();
+ doc("chandevreset");
+ chandevreset();
+
+ eve = strdup("inferno");
+
+ print("\nInferno %s\n", VERSION);
+ print("Vita Nuova\n");
+ print("conf %s (%lud) jit %d\n\n",conffile, kerndate, cflag);
+
+ doc("userinit");
+ userinit();
+ doc("schedinit");
+ schedinit();
+}
+
+void
+machinit(void)
+{
+ int n;
+
+ n = m->machno;
+ memset(m, 0, sizeof(Mach));
+ m->machno = n;
+ m->mmask = 1<<m->machno;
+ m->iomem = KADDR(getimmr() & ~0xFFFF);
+ m->cputype = getpvr()>>16;
+ m->delayloop = 20000; /* initial estimate only; set by clockinit */
+ m->speed = 50; /* initial estimate only; set by archinit */
+}
+
+void
+init0(void)
+{
+ Osenv *o;
+ int i;
+ char buf[2*KNAMELEN];
+
+ up->nerrlab = 0;
+
+ spllo();
+
+ if(waserror())
+ panic("init0");
+ /*
+ * These are o.k. because rootinit is null.
+ * Then early kproc's will have a root and dot.
+ */
+ o = up->env;
+ o->pgrp->slash = namec("#/", Atodir, 0, 0);
+ cnameclose(o->pgrp->slash->name);
+ o->pgrp->slash->name = newcname("/");
+ o->pgrp->dot = cclone(o->pgrp->slash);
+
+ chandevinit();
+
+ if(!waserror()){
+ ksetenv("cputype", "power", 0);
+ snprint(buf, sizeof(buf), "power %s", conffile);
+ ksetenv("terminal", buf, 0);
+ poperror();
+ }
+ for(i = 0; i < nconf; i++)
+ if(confname[i][0] != '*'){
+ if(!waserror()){
+ ksetenv(confname[i], confval[i], 0);
+ poperror();
+ }
+ }
+
+ poperror();
+ disinit("/osinit.dis");
+}
+
+void
+userinit(void)
+{
+ Proc *p;
+ Osenv *o;
+
+ p = newproc();
+ o = p->env;
+
+ o->fgrp = newfgrp(nil);
+
+ o->pgrp = newpgrp();
+ o->egrp = newegrp();
+ kstrdup(&o->user, eve);
+
+ strcpy(p->text, "interp");
+
+ /*
+ * Kernel Stack
+ */
+ p->sched.pc = (ulong)init0;
+ p->sched.sp = (ulong)p->kstack+KSTACK;
+
+ ready(p);
+}
+
+Conf conf;
+
+void
+addconf(char *name, char *val)
+{
+ if(nconf >= MAXCONF)
+ return;
+ confname[nconf] = name;
+ confval[nconf] = val;
+ nconf++;
+}
+
+char*
+getconf(char *name)
+{
+ int i;
+
+ for(i = 0; i < nconf; i++)
+ if(cistrcmp(confname[i], name) == 0)
+ return confval[i];
+ return 0;
+}
+
+void
+confinit(void)
+{
+ char *p;
+ int pcnt;
+
+ if(p = getconf("*kernelpercent"))
+ pcnt = 100 - strtol(p, 0, 0);
+ else
+ pcnt = 0;
+
+ conf.nscc = 4;
+ conf.smcuarts = 1<<0; /* SMC1 (usual console) */
+ conf.sccuarts = 1<<1; /* SCC2 available by default */
+
+ archconfinit();
+
+ conf.npage = conf.npage0 + conf.npage1;
+ if(pcnt < 10)
+ pcnt = 70;
+ conf.ialloc = (((conf.npage*(100-pcnt))/100)/2)*BY2PG;
+
+ conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
+ conf.nmach = MAXMACH;
+}
+
+void
+exit(int ispanic)
+{
+ up = 0;
+ spllo();
+ print("cpu %d exiting\n", m->machno);
+
+ /* Shutdown running devices */
+ chandevshutdown();
+
+ delay(1000);
+ splhi();
+ if(ispanic)
+ for(;;);
+ archreboot();
+}
+
+void
+reboot(void)
+{
+ exit(0);
+}
+
+void
+halt(void)
+{
+ print("cpu halted\n");
+ microdelay(1000);
+ for(;;)
+ ;
+}
+
+int
+isaconfig(char *class, int ctlrno, ISAConf *isa)
+{
+ char cc[KNAMELEN], *p;
+ int i;
+
+ snprint(cc, sizeof cc, "%s%d", class, ctlrno);
+ p = getconf(cc);
+ if(p == nil)
+ return 0;
+
+ isa->nopt = tokenize(p, isa->opt, NISAOPT);
+ for(i = 0; i < isa->nopt; i++){
+ p = isa->opt[i];
+ if(cistrncmp(p, "type=", 5) == 0)
+ isa->type = p + 5;
+ else if(cistrncmp(p, "port=", 5) == 0)
+ isa->port = strtoul(p+5, &p, 0);
+ else if(cistrncmp(p, "irq=", 4) == 0)
+ isa->irq = strtoul(p+4, &p, 0);
+ else if(cistrncmp(p, "mem=", 4) == 0)
+ isa->mem = strtoul(p+4, &p, 0);
+ else if(cistrncmp(p, "size=", 5) == 0)
+ isa->size = strtoul(p+5, &p, 0);
+ else if(cistrncmp(p, "freq=", 5) == 0)
+ isa->freq = strtoul(p+5, &p, 0);
+ else if(cistrncmp(p, "dma=", 4) == 0)
+ isa->dma = strtoul(p+4, &p, 0);
+ }
+ return 1;
+}
+
+/*
+ * Save the mach dependent part of the process state.
+ */
+void
+procsave(Proc*)
+{
+}
+
+void
+uartputs(char *s, int n)
+{
+// screenputs(buf, n);
+ putstrn(s, n);
+ uartwait();
+}
+
+/* stubs */
+void
+setfsr(ulong)
+{
+}
+
+ulong
+getfsr()
+{
+ return 0;
+}
+
+void
+setfcr(ulong)
+{
+}
+
+ulong
+getfcr()
+{
+ return 0;
+}
diff --git a/os/fads/mem.h b/os/fads/mem.h
new file mode 100644
index 00000000..02cf8f43
--- /dev/null
+++ b/os/fads/mem.h
@@ -0,0 +1,157 @@
+/*
+ * Memory and machine-specific definitions. Used in C and assembler.
+ */
+
+/*
+ * Sizes
+ */
+
+#define BI2BY 8 /* bits per byte */
+#define BI2WD 32 /* bits per word */
+#define BY2WD 4 /* bytes per word */
+#define BY2V 8 /* bytes per double word */
+#define BY2PG 4096 /* bytes per page */
+#define WD2PG (BY2PG/BY2WD) /* words per page */
+#define PGSHIFT 12 /* log(BY2PG) */
+#define ROUND(s, sz) (((s)+(sz-1))&~(sz-1))
+#define PGROUND(s) ROUND(s, BY2PG)
+#define CACHELINELOG 4
+#define CACHELINESZ (1<<CACHELINELOG)
+
+#define MAXMACH 1 /* max # cpus system can run */
+#define MACHSIZE BY2PG
+
+/*
+ * Time
+ */
+#define HZ 100 /* clock frequency */
+#define MS2HZ (1000/HZ) /* millisec per clock tick */
+#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
+#define MS2TK(t) ((t)/MS2HZ) /* milliseconds to ticks */
+#define MHz 1000000
+
+/*
+ * MSR bits
+ */
+
+#define POW 0x40000 /* enable power mgmt */
+#define TGPR 0x20000 /* GPR0-3 remapped; 603/603e specific */
+#define ILE 0x10000 /* interrupts little endian */
+#define EE 0x08000 /* enable external/decrementer interrupts */
+#define PR 0x04000 /* =1, user mode */
+#define FPE 0x02000 /* enable floating point */
+#define ME 0x01000 /* enable machine check exceptions */
+#define FE0 0x00800
+#define SE 0x00400 /* single-step trace */
+#define BE 0x00200 /* branch trace */
+#define FE1 0x00100
+#define MSR_IP 0x00040 /* =0, vector to nnnnn; =1, vector to FFFnnnnn */
+#define IR 0x00020 /* enable instruction address translation */
+#define DR 0x00010 /* enable data address translation */
+#define RI 0x00002 /* exception is recoverable */
+#define LE 0x00001 /* little endian mode */
+
+#define KMSR (ME|FE0|FE1|FPE)
+#define UMSR (KMSR|PR|EE|IR|DR)
+
+/*
+ * Magic registers
+ */
+
+#define MACH 30 /* R30 is m-> */
+#define USER 29 /* R29 is up-> */
+#define IOMEMR 28 /* R28 will be iomem-> */
+
+/*
+ * Fundamental addresses
+ */
+
+#define UREGSIZE ((8+32)*4)
+
+/*
+ * MMU
+ */
+
+/* L1 table entry and Mx_TWC flags */
+#define PTEVALID (1<<0)
+#define PTEWT (1<<1) /* write through */
+#define PTE4K (0<<2)
+#define PTE512K (1<<2)
+#define PTE8MB (3<<2)
+#define PTEG (1<<4) /* guarded */
+
+/* L2 table entry and Mx_RPN flags (also PTEVALID) */
+#define PTECI (1<<1) /* cache inhibit */
+#define PTESH (1<<2) /* page is shared; ASID ignored */
+#define PTELPS (1<<3) /* large page size */
+#define PTEWRITE 0x9F0
+
+/* TLB and MxEPN flag */
+#define TLBVALID (1<<9)
+
+/*
+ * Address spaces
+ */
+
+#define KUSEG 0x00000000
+#define KSEG0 0x20000000
+#define KSEGM 0xE0000000 /* mask to check which seg */
+
+#define KZERO KSEG0 /* base of kernel address space */
+#define KTZERO (KZERO+0x3000) /* first address in kernel text */
+#define KSTACK 8192 /* Size of kernel stack */
+
+#define CONFADDR (KZERO|0x200000) /* where qboot leaves configuration info */
+
+/*
+ * Exception codes (trap vectors)
+ */
+#define CRESET 0x01
+#define CMCHECK 0x02
+#define CDSI 0x03
+#define CISI 0x04
+#define CEI 0x05
+#define CALIGN 0x06
+#define CPROG 0x07
+#define CFPU 0x08
+#define CDEC 0x09
+#define CSYSCALL 0x0C
+#define CTRACE 0x0D
+#define CFPA 0x0E
+/* rest are power-implementation dependent (8xx) */
+#define CEMU 0x10
+#define CIMISS 0x11
+#define CDMISS 0x12
+#define CITLBE 0x13
+#define CDTLBE 0x14
+#define CDBREAK 0x1C
+#define CIBREAK 0x1D
+#define CPBREAK 0x1E
+#define CDPORT 0x1F
+
+/*
+ * MPC8xx physical addresses
+ */
+
+/* those encouraged by mpc8bug */
+#define PHYSDRAM 0x00000000
+#define PHYSBCSR 0x02100000
+#define PHYSIMM 0x02200000
+#define PHYSFLASH 0x02800000
+
+/* remaining ones are our choice */
+#define PHYSSDRAM 0x03000000
+#define PHYSPCMCIA 0x04000000
+#define PCMCIALEN (8*MB) /* chosen to allow mapping by single TLB entry */
+#define ISAIO (KZERO|PHYSPCMCIA) /* for inb.s */
+
+/*
+ * MPC8xx dual-ported CPM memory physical addresses
+ */
+#define PHYSDPRAM (PHYSIMM+0x2000)
+#define DPLEN1 0x200
+#define DPLEN2 0x400
+#define DPLEN3 0x800
+#define DPBASE (PHYSDPRAM+DPLEN1)
+
+#define KEEP_ALIVE_KEY 0x55ccaa33 /* clock and rtc register key */
diff --git a/os/fads/mkfile b/os/fads/mkfile
new file mode 100644
index 00000000..afc241a1
--- /dev/null
+++ b/os/fads/mkfile
@@ -0,0 +1,107 @@
+SYSTARG=Inferno
+OBJTYPE=power
+<../../mkconfig
+
+#Configurable parameters
+
+CONF=fads #default configuration
+CONFLIST=fads fadskfs fads2
+CLEANCONFLIST=paq
+KZERO=0x20003020
+
+SYSTARG=$OSTARG
+OBJTYPE=power
+INSTALLDIR=$ROOT/Inferno/$OBJTYPE/bin #path of directory where kernel is installed
+#INSTALLDIR=/$OBJTYPE
+
+#end configurable parameters
+
+<$ROOT/mkfiles/mkfile-$SYSTARG-$OBJTYPE #set vars based on target system
+
+<| $SHELLNAME ../port/mkdevlist $CONF #sets $IP, $DEVS, $ETHERS, $VGAS, $PORT, $MISC, $LIBS, $OTHERS
+
+OBJ=\
+ l.$O\
+ tlb.$O\
+ nofp.$O\
+ clock.$O\
+ cpm.$O\
+ faultpower.$O\
+ fpi.$O\
+ fpimem.$O\
+ fpipower.$O\
+ kbd.$O\
+ main.$O\
+ mmu.$O\
+ rmap.$O\
+ trap.$O\
+ $CONF.root.$O\
+ $IP\
+ $DEVS\
+ $ETHERS\
+ $LINKS\
+ $VGAS\
+ $PORT\
+ $MISC\
+ $OTHERS\
+
+LIBNAMES=${LIBS:%=lib%.a}
+
+HFILES=\
+ mem.h\
+ dat.h\
+ fns.h\
+ io.h\
+ ../mpc/800io.h\
+ ../mpc/screen.h\
+
+CFLAGS=-wFV -I. -I../mpc -I../port -I$ROOT/Inferno/$OBJTYPE/include -I$ROOT/include -I$ROOT/libinterp
+KERNDATE=`{$NDATE}
+
+#default:V: i$CONF.sq
+default:V: i$CONF
+
+i$CONF: $OBJ $CONF.c $CONF.root.h $LIBNAMES
+ $CC $CFLAGS '-DKERNDATE='$KERNDATE $CONF.c
+ $LD -o $target -T$KZERO -l $OBJ $CONF.$O $LIBFILES
+ $KSIZE $target
+
+i$CONF.sq: i$CONF
+ sqz -w i$CONF >$target
+
+install:V: i$CONF # i$CONF.sq
+ cp i$CONF $INSTALLDIR/i$CONF
+ #cp i$CONF.sq $INSTALLDIR/i$CONF.sq
+
+uninstall:V:
+ rm -f $ROOT/$OBJDIR/bin/i$CONF
+ rm -f $ROOT/$OBJDIR/bin/i$CONF.sq
+
+<../port/portmkfile
+
+../init/$INIT.dis: ../init/$INIT.b
+ cd ../init; mk $INIT.dis
+
+%.$O: ../mpc/%.c
+ $CC $CFLAGS -I. -I../mpc ../mpc/$stem.c
+
+%.$O: ../mpc/%.s
+ $AS -I. -I../mpc ../mpc/$stem.s
+
+clock.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
+devether.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
+faultpower.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
+main.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
+trap.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
+screen.h:NV: ../mpc/screen.h
+
+devether.$O $ETHERS: ../mpc/etherif.h ../port/netif.h
+
+#$VGAS: screen.h vga.h
+$IP devip.$O: ../ip/ip.h
+
+devboot.$O: devboot.c
+ $CC $CFLAGS devboot.c
+
+devuart.$O: ../mpc/devuart.c
+ $CC $CFLAGS ../mpc/devuart.c
diff --git a/os/fads/mmu.c b/os/fads/mmu.c
new file mode 100644
index 00000000..c9cd758b
--- /dev/null
+++ b/os/fads/mmu.c
@@ -0,0 +1,20 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+
+void
+mmuinit(void)
+{
+ /* the l.s initial TLB settings do all that's required */
+}
+
+int
+segflush(void *a, ulong n)
+{
+ /* flush dcache then invalidate icache */
+ dcflush(a, n);
+ icflush(a, n);
+ return 0;
+}
diff --git a/os/fads/tlb.s b/os/fads/tlb.s
new file mode 100644
index 00000000..68ebf4e7
--- /dev/null
+++ b/os/fads/tlb.s
@@ -0,0 +1,23 @@
+#include "mem.h"
+
+#define MB (1024*1024)
+
+/*
+ * TLB prototype entries, loaded once-for-all at startup,
+ * remaining unchanged thereafter.
+ * Limit the table to at most 8 entries to ensure
+ * it works on the 823 (other 8xx processors allow up to 32 TLB entries).
+ */
+#define TLBE(epn,rpn,twc) WORD $(epn); WORD $(twc); WORD $(rpn)
+
+TEXT tlbtab(SB), $-4
+
+ /* epn, rpn, twc */
+ TLBE(KZERO|PHYSDRAM|TLBVALID, PHYSDRAM|PTEWRITE|PTELPS|PTESH|PTEVALID, PTE8MB|/*PTEWT|*/PTEVALID) /* DRAM, 8M */
+ TLBE(KZERO|PHYSBCSR|TLBVALID, PHYSBCSR|PTEWRITE|PTESH|PTECI|PTEVALID, PTE4K|PTEWT|PTEVALID) /* Board CSR, 4K */
+ TLBE(KZERO|PHYSIMM|TLBVALID, PHYSIMM|PTEWRITE|PTELPS|PTESH|PTECI|PTEVALID, PTE4K|PTEWT|PTEVALID) /* IMMR, 16K */
+ TLBE(KZERO|PHYSFLASH|TLBVALID, PHYSFLASH|PTEWRITE|PTELPS|PTESH|PTECI|PTEVALID, PTE8MB|PTEWT|PTEVALID) /* Flash, 8M */
+ TLBE(KZERO|PHYSSDRAM|TLBVALID, PHYSSDRAM|PTEWRITE|PTELPS|PTESH|PTEVALID, PTE8MB|/*PTEWT|*/PTEVALID) /* SDRAM, 8M */
+ TLBE(KZERO|PHYSPCMCIA|TLBVALID, PHYSPCMCIA|PTEWRITE|PTELPS|PTESH|PTECI|PTEVALID, PTE8MB|PTEWT|PTEG|PTEVALID) /* PCMCIA, 8M */
+TEXT tlbtabe(SB), $-4
+ RETURN