retire the dec alpha port

This commit is contained in:
cinap_lenrek 2016-05-04 16:11:48 +02:00
parent f7703d6971
commit 986886f2b8
147 changed files with 12 additions and 28898 deletions

View file

@ -1,76 +0,0 @@
#ifndef __FLOAT
#define __FLOAT
/* IEEE, default rounding */
#define FLT_ROUNDS 1
#define FLT_RADIX 2
#define FLT_DIG 6
#define FLT_EPSILON 1.19209290e-07
#define FLT_MANT_DIG 24
#define FLT_MAX 3.40282347e+38
#define FLT_MAX_10_EXP 38
#define FLT_MAX_EXP 128
#define FLT_MIN 1.17549435e-38
#define FLT_MIN_10_EXP -37
#define FLT_MIN_EXP -125
#define DBL_DIG 15
#define DBL_EPSILON 2.2204460492503131e-16
#define DBL_MANT_DIG 53
#define DBL_MAX 1.797693134862315708145e+308
#define DBL_MAX_10_EXP 308
#define DBL_MAX_EXP 1024
#define DBL_MIN 2.225073858507201383090233e-308
#define DBL_MIN_10_EXP -307
#define DBL_MIN_EXP -1021
#define LDBL_MANT_DIG DBL_MANT_DIG
#define LDBL_EPSILON DBL_EPSILON
#define LDBL_DIG DBL_DIG
#define LDBL_MIN_EXP DBL_MIN_EXP
#define LDBL_MIN DBL_MIN
#define LDBL_MIN_10_EXP DBL_MIN_10_EXP
#define LDBL_MAX_EXP DBL_MAX_EXP
#define LDBL_MAX DBL_MAX
#define LDBL_MAX_10_EXP DBL_MAX_10_EXP
typedef union FPdbleword FPdbleword;
union FPdbleword
{
double x;
struct { /* little endian */
long lo;
long hi;
};
};
#ifdef _RESEARCH_SOURCE
/* define stuff needed for floating conversion */
#define IEEE_8087 1
#define Sudden_Underflow 1
#endif
#ifdef _PLAN9_SOURCE
#define FPINEX (1<<30)
#define FPOVFL (1<<19)
#define FPUNFL ((1<<29)|(1<<28))
#define FPZDIV (1<<18)
#define FPINVAL (1<<17)
#define FPRNR (2<<26)
#define FPRZ (0<<26)
#define FPRPINF (3<<26)
#define FPRNINF (1<<26)
#define FPRMASK (3<<26)
#define FPPEXT 0
#define FPPSGL 0
#define FPPDBL 0
#define FPPMASK 0
/* FSR */
#define FPAINEX (1<<24)
#define FPAUNFL (1<<23)
#define FPAOVFL (1<<22)
#define FPAZDIV (1<<21)
#define FPAINVAL (1<<20)
#endif
#endif /* __FLOAT */

View file

@ -1,77 +0,0 @@
#ifndef __MATH
#define __MATH
#pragma lib "/$M/lib/ape/libap.a"
/* a HUGE_VAL appropriate for IEEE double-precision */
/* the correct value, 1.797693134862316e+308, causes a ken overflow */
#define HUGE_VAL 1.79769313486231e+308
#ifdef __cplusplus
extern "C" {
#endif
extern double acos(double);
extern double asin(double);
extern double atan(double);
extern double atan2(double, double);
extern double cos(double);
extern double sin(double);
extern double tan(double);
extern double cosh(double);
extern double sinh(double);
extern double tanh(double);
extern double exp(double);
extern double frexp(double, int *);
extern double ldexp(double, int);
extern double log(double);
extern double log10(double);
extern double modf(double, double *);
extern double pow(double, double);
extern double sqrt(double);
extern double ceil(double);
extern double fabs(double);
extern double floor(double);
extern double fmod(double, double);
extern double NaN(void);
extern int isNaN(double);
extern double Inf(int);
extern int isInf(double, int);
#ifdef _RESEARCH_SOURCE
/* does >> treat left operand as unsigned ? */
#define Unsigned_Shifts 1
#define M_E 2.7182818284590452354 /* e */
#define M_LOG2E 1.4426950408889634074 /* log 2e */
#define M_LOG10E 0.43429448190325182765 /* log 10e */
#define M_LN2 0.69314718055994530942 /* log e2 */
#define M_LN10 2.30258509299404568402 /* log e10 */
#define M_PI 3.14159265358979323846 /* pi */
#define M_PI_2 1.57079632679489661923 /* pi/2 */
#define M_PI_4 0.78539816339744830962 /* pi/4 */
#define M_1_PI 0.31830988618379067154 /* 1/pi */
#define M_2_PI 0.63661977236758134308 /* 2/pi */
#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
extern double hypot(double, double);
extern double erf(double);
extern double erfc(double);
extern double j0(double);
extern double y0(double);
extern double j1(double);
extern double y1(double);
extern double jn(int, double);
extern double yn(int, double);
#endif
#ifdef __cplusplus
}
#endif
#define isnan(x) isNaN(x)
#define isinf(x) isInf(x)
#endif /* __MATH */

View file

@ -1,17 +0,0 @@
#ifndef __STDARG
#define __STDARG
typedef char *va_list;
#define va_start(list, start) list = (char *)(&(start)+1)
#define va_end(list)
#define va_arg(list, mode)\
(sizeof(mode)==1?\
((mode*)(list += 4))[-1]:\
sizeof(mode)==2?\
((mode*)(list += 4))[-1]:\
sizeof(mode)>4?\
((mode*)(list = (char*)((long)(list+7) & ~7) + sizeof(mode)))[-1]:\
((mode*)(list += sizeof(mode)))[-1])
#endif /* __STDARG */

View file

@ -1,57 +0,0 @@
#ifndef __UREG_H
#define __UREG_H
#if !defined(_PLAN9_SOURCE)
This header file is an extension to ANSI/POSIX
#endif
struct Ureg
{
/* l.s saves 31 64-bit values: */
unsigned long long type;
unsigned long long a0;
unsigned long long a1;
unsigned long long a2;
unsigned long long r0;
unsigned long long r1;
unsigned long long r2;
unsigned long long r3;
unsigned long long r4;
unsigned long long r5;
unsigned long long r6;
unsigned long long r7;
unsigned long long r8;
unsigned long long r9;
unsigned long long r10;
unsigned long long r11;
unsigned long long r12;
unsigned long long r13;
unsigned long long r14;
unsigned long long r15;
unsigned long long r19;
unsigned long long r20;
unsigned long long r21;
unsigned long long r22;
unsigned long long r23;
unsigned long long r24;
unsigned long long r25;
unsigned long long r26;
unsigned long long r27;
unsigned long long r28;
union {
unsigned long long r30;
unsigned long long usp;
unsigned long long sp;
};
/* OSF/1 PALcode frame: */
unsigned long long status; /* PS */
unsigned long long pc;
unsigned long long r29; /* GP */
unsigned long long r16; /* a0 */
unsigned long long r17; /* a1 */
unsigned long long r18; /* a2 */
};
#endif

View file

@ -1,71 +0,0 @@
#define nil ((void*)0)
typedef unsigned short ushort;
typedef unsigned char uchar;
typedef unsigned long ulong;
typedef unsigned int uint;
typedef signed char schar;
typedef long long vlong;
typedef unsigned long long uvlong;
typedef long intptr;
typedef unsigned long uintptr;
typedef unsigned long usize;
typedef uint Rune;
typedef union FPdbleword FPdbleword;
typedef long jmp_buf[2];
#define JMPBUFSP 0
#define JMPBUFPC 1
#define JMPBUFDPC 0
typedef unsigned int mpdigit; /* for /sys/include/mp.h */
typedef unsigned char u8int;
typedef unsigned short u16int;
typedef unsigned int u32int;
typedef unsigned long long u64int;
/* FCR */
#define FPINEX (1<<30)
#define FPOVFL (1<<19)
#define FPUNFL ((1<<29)|(1<<28))
#define FPZDIV (1<<18)
#define FPINVAL (1<<17)
#define FPRNR (2<<26)
#define FPRZ (0<<26)
#define FPRPINF (3<<26)
#define FPRNINF (1<<26)
#define FPRMASK (3<<26)
#define FPPEXT 0
#define FPPSGL 0
#define FPPDBL 0
#define FPPMASK 0
/* FSR */
#define FPAINEX (1<<24)
#define FPAUNFL (1<<23)
#define FPAOVFL (1<<22)
#define FPAZDIV (1<<21)
#define FPAINVAL (1<<20)
union FPdbleword
{
double x;
struct { /* little endian */
ulong lo;
ulong hi;
};
};
/* stdarg */
typedef char* va_list;
#define va_start(list, start) list =\
(sizeof(start) < 4?\
(char*)((int*)&(start)+1):\
(char*)(&(start)+1))
#define va_end(list)\
USED(list)
#define va_arg(list, mode)\
((sizeof(mode) == 1)?\
((list += 4), (mode*)list)[-4]:\
(sizeof(mode) == 2)?\
((list += 4), (mode*)list)[-2]:\
sizeof(mode)>4?\
((mode*)(list = (char*)((uintptr)(list+7) & ~7) + sizeof(mode)))[-1]:\
((list += sizeof(mode)), (mode*)list)[-1])

View file

@ -1,49 +0,0 @@
struct Ureg
{
/* l.s saves 31 64-bit values: */
uvlong type;
uvlong a0;
uvlong a1;
uvlong a2;
uvlong r0;
uvlong r1;
uvlong r2;
uvlong r3;
uvlong r4;
uvlong r5;
uvlong r6;
uvlong r7;
uvlong r8;
uvlong r9;
uvlong r10;
uvlong r11;
uvlong r12;
uvlong r13;
uvlong r14;
uvlong r15;
uvlong r19;
uvlong r20;
uvlong r21;
uvlong r22;
uvlong r23;
uvlong r24;
uvlong r25;
uvlong r26;
uvlong r27;
uvlong r28;
union {
uvlong r30;
uvlong usp;
uvlong sp;
};
/* OSF/1 PALcode frame: */
uvlong status; /* PS */
uvlong pc;
uvlong r29; /* GP */
uvlong r16; /* a0 */
uvlong r17; /* a1 */
uvlong r18; /* a2 */
};

View file

@ -1,6 +0,0 @@
</sys/src/mkfile.proto
CC=7c
LD=7l
O=7
AS=7a

View file

@ -25,7 +25,7 @@ struct Exec
#define E_MAGIC _MAGIC(0, 20) /* arm */
#define Q_MAGIC _MAGIC(0, 21) /* powerpc */
#define N_MAGIC _MAGIC(0, 22) /* mips 4000 LE */
#define L_MAGIC _MAGIC(0, 23) /* dec alpha */
#define L_MAGIC _MAGIC(0, 23) /* dec alpha (retired) */
#define P_MAGIC _MAGIC(0, 24) /* mips 3000 LE */
#define U_MAGIC _MAGIC(0, 25) /* sparc64 */
#define S_MAGIC _MAGIC(HDR_MAGIC, 26) /* amd64 */

View file

@ -1,205 +0,0 @@
// Alpha support
defn acidinit() // Called after all the init modules are loaded
{
bplist = {};
bpfmt = 'X';
srcpath = {
"./",
"/sys/src/libc/port/",
"/sys/src/libc/9sys/",
"/sys/src/libc/alpha/"
};
srcfiles = {}; // list of loaded files
srctext = {}; // the text of the files
}
defn stk() // trace
{
_stk(*PC, *SP, linkreg(0), 0);
}
defn lstk() // trace with locals
{
_stk(*PC, *SP, linkreg(0), 1);
}
defn gpr() // print general purpose registers
{
print("R0\t", *R0, "\n");
print("R1\t", *R1, " R2\t", *R2, " R3\t", *R3, "\n");
print("R4\t", *R4, " R5\t", *R5, " R6\t", *R6, "\n");
print("R7\t", *R7, " R8\t", *R8, " R9\t", *R9, "\n");
print("R10\t", *R10, " R11\t", *R11, " R12\t", *R12, "\n");
print("R13\t", *R13, " R14\t", *R14, " R15\t", *R15, "\n");
print("R16\t", *R16, " R17\t", *R17, " R18\t", *R18, "\n");
print("R19\t", *R19, " R20\t", *R20, " R21\t", *R21, "\n");
print("R22\t", *R22, " R23\t", *R23, " R24\t", *R24, "\n");
print("R25\t", *R25, " R26\t", *R26, " R27\t", *R27, "\n");
print("R28\t", *R28, " R29\t", *R29, " R30\t", *SP\Y, "\n");
}
defn fpr()
{
print("F0\t", *fmt(F0, 'G'), "\tF1\t", *fmt(F1, 'G'), "\n");
print("F2\t", *fmt(F2, 'G'), "\tF3\t", *fmt(F3, 'G'), "\n");
print("F4\t", *fmt(F4, 'G'), "\tF5\t", *fmt(F5, 'G'), "\n");
print("F6\t", *fmt(F6, 'G'), "\tF7\t", *fmt(F7, 'G'), "\n");
print("F8\t", *fmt(F8, 'G'), "\tF9\t", *fmt(F9, 'G'), "\n");
print("F10\t", *fmt(F10, 'G'), "\tF11\t", *fmt(F11, 'G'), "\n");
print("F12\t", *fmt(F12, 'G'), "\tF13\t", *fmt(F13, 'G'), "\n");
print("F14\t", *fmt(F14, 'G'), "\tF15\t", *fmt(F15, 'G'), "\n");
print("F16\t", *fmt(F16, 'G'), "\tF17\t", *fmt(F17, 'G'), "\n");
print("F18\t", *fmt(F18, 'G'), "\tF19\t", *fmt(F19, 'G'), "\n");
print("F20\t", *fmt(F20, 'G'), "\tF21\t", *fmt(F21, 'G'), "\n");
print("F22\t", *fmt(F22, 'G'), "\tF23\t", *fmt(F23, 'G'), "\n");
print("F24\t", *fmt(F24, 'G'), "\tF25\t", *fmt(F25, 'G'), "\n");
print("F26\t", *fmt(F26, 'G'), "\tF27\t", *fmt(F27, 'G'), "\n");
print("F28\t", *fmt(F28, 'G'), "\tF29\t", *fmt(F29, 'G'), "\n");
print("F30\t", *fmt(F30, 'G'), "\tF31\t", *fmt(F31, 'G'), "\n");
}
defn spr() // print special processor registers
{
local pc, link, cause;
pc = *PC;
print("PC\t", pc, " ", fmt(pc, 'a'), " ");
pfl(pc);
link = *R26;
print("SP\t", *SP, "\tLINK\t", link, " ", fmt(link, 'a'), " ");
pfl(link);
cause = *TYPE;
print("STATUS\t", *STATUS, "\tTYPE\t", cause, " ", reason(cause), "\n");
print("A0\t", *A0, " A1\t", *A1, " A2\t", *A2, "\n");
}
defn regs() // print all registers
{
spr();
gpr();
}
defn pstop(pid)
{
local l, pc;
pc = *PC;
print(pid,": ", reason(*TYPE), "\t");
print(fmt(pc, 'a'), "\t", fmt(pc, 'i'), "\n");
if notes then {
if notes[0] != "sys: breakpoint" then {
print("Notes pending:\n");
l = notes;
while l do {
print("\t", head l, "\n");
l = tail l;
}
}
}
}
sizeofUreg = 296;
aggr Ureg
{
'W' 0 type;
'W' 8 a0;
'W' 16 a1;
'W' 24 a2;
'W' 32 r0;
'W' 40 r1;
'W' 48 r2;
'W' 56 r3;
'W' 64 r4;
'W' 72 r5;
'W' 80 r6;
'W' 88 r7;
'W' 96 r8;
'W' 104 r9;
'W' 112 r10;
'W' 120 r11;
'W' 128 r12;
'W' 136 r13;
'W' 144 r14;
'W' 152 r15;
'W' 160 r19;
'W' 168 r20;
'W' 176 r21;
'W' 184 r22;
'W' 192 r23;
'W' 200 r24;
'W' 208 r25;
'W' 216 r26;
'W' 224 r27;
'W' 232 r28;
{
'W' 240 r30;
'W' 240 usp;
'W' 240 sp;
};
'W' 248 status;
'W' 256 pc;
'W' 264 r29;
'W' 272 r16;
'W' 280 r17;
'W' 288 r18;
};
defn
Ureg(addr) {
complex Ureg addr;
print(" type ", addr.type, "\n");
print(" a0 ", addr.a0, "\n");
print(" a1 ", addr.a1, "\n");
print(" a2 ", addr.a2, "\n");
print(" r0 ", addr.r0, "\n");
print(" r1 ", addr.r1, "\n");
print(" r2 ", addr.r2, "\n");
print(" r3 ", addr.r3, "\n");
print(" r4 ", addr.r4, "\n");
print(" r5 ", addr.r5, "\n");
print(" r6 ", addr.r6, "\n");
print(" r7 ", addr.r7, "\n");
print(" r8 ", addr.r8, "\n");
print(" r9 ", addr.r9, "\n");
print(" r10 ", addr.r10, "\n");
print(" r11 ", addr.r11, "\n");
print(" r12 ", addr.r12, "\n");
print(" r13 ", addr.r13, "\n");
print(" r14 ", addr.r14, "\n");
print(" r15 ", addr.r15, "\n");
print(" r19 ", addr.r19, "\n");
print(" r20 ", addr.r20, "\n");
print(" r21 ", addr.r21, "\n");
print(" r22 ", addr.r22, "\n");
print(" r23 ", addr.r23, "\n");
print(" r24 ", addr.r24, "\n");
print(" r25 ", addr.r25, "\n");
print(" r26 ", addr.r26, "\n");
print(" r27 ", addr.r27, "\n");
print(" r28 ", addr.r28, "\n");
print("_12_ {\n");
_12_(addr+240);
print("}\n");
print(" status ", addr.status, "\n");
print(" pc ", addr.pc, "\n");
print(" r29 ", addr.r29, "\n");
print(" r16 ", addr.r16, "\n");
print(" r17 ", addr.r17, "\n");
print(" r18 ", addr.r18, "\n");
};
defn linkreg(addr)
{
complex Ureg addr;
return addr.r26\X;
}
print("/sys/lib/acid/alpha");

View file

@ -434,10 +434,6 @@ if (map()[2]) != {} then { // map has more than two elements -> active proc
if (objtype == "mips" || objtype == "mips2") then {
kdir = "ch";
}
if objtype == "alpha" then {
map({"*data", KZERO, 0xffffffff, KZERO});
kdir = "alpha";
}
needacid("proc");
needacid("chan");
needacid("segment");

View file

@ -160,8 +160,6 @@ defn UPCSPRET() {
return { code(*(*PC-4) & 0xffff), code(*SP+4), code(*R1) };
if objtype == "arm" then
return { code(*(*PC-4) & 0xffff), code(*SP+4), code(*R0) }; // untested
if objtype == "alpha" then
return { code(*(*PC-4) & 0xffff), code(*SP+4), code(*R0) }; // untested
}
defn trapoffset() {
@ -171,7 +169,6 @@ defn trapoffset() {
if objtype == "mips" then return 8;
if objtype == "mips2" then return 8;
if objtype == "arm" then return 8; // untested
if objtype == "alpha" then return 8; // untested
}
defn trapreason() {
@ -181,7 +178,6 @@ defn trapreason() {
if objtype == "mips" then return reason(*CAUSE);
if objtype == "mips2" then return reason(*CAUSE);
if objtype == "arm" then return "unknown trap"; // untested
if objtype == "alpha" then return reason(cause); // untested
}

View file

@ -14,7 +14,7 @@ defn labsp(l)
defn labstk(l)
{
_stk(labpc(l), labsp(l), 0, 0);
_stk(labpc(l), labsp(l), 0, 1);
}
defn lablstk(l)
@ -250,7 +250,7 @@ defn threadstks(P){
ign = stkignore;
stkignore = {
"^/sys/src/libthread/",
"^/sys/src/libc/(386|arm|alpha|sparc|power|mips)/"
"^/sys/src/libc/(386|arm|sparc|power|mips)/"
};
setproc(P.pid);
Tq = (Tqueue)P.threads;
@ -315,7 +315,7 @@ defn threadstk(T){
setproc(P.pid);
if T.state == Running then{
stk();
lstk();
} else {
labstk(T.sched);
}

View file

@ -116,11 +116,11 @@ defn trumpfninfo() {
}
defn trumpretval() {
if objtype=="386" then
if objtype=="386" || objtype=="amd64" then
return *AX;
if objtype=="mips" then
return *R1;
if objtype=="power" || objtype=="alpha" then
if objtype=="power" || objtype=="arm" then
return *R0;
}

View file

@ -160,7 +160,7 @@ defn addressof(pattern) {
// translate to ape system calls if we have an ape binary
if _addressof("_EXITS") != 0 then
pattern = trussapecalls[match(pattern, trusscalls)];
if regexp("(seek|_SEEK)", pattern) && (objtype=="amd64" || objtype == "power64" || objtype == "alpha") then
if regexp("(seek|_SEEK)", pattern) && (objtype=="amd64" || objtype == "power64") then
pattern = "_" + pattern;
return _addressof(pattern);
}

View file

@ -1,62 +0,0 @@
dev
root
cons
arch
pnp pci
env
pipe
proc
mnt
srv
dup
# rtc
ssl
cap
kprof
# loopback
ether netif
ip arp chandial inferno ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum
draw screen vga vgax
mouse mouse
vga
sd
floppy dma
audio dma
uart
link
ether2114x pci
ethermedium
misc
arch164
sdata pci sdscsi
# sd53c8xx pci sdscsi
uarti8250
vgargb524 =cur
vgas3 +cur
vgas3 +cur vgasavage
vgatvp3026 =cur
ip
tcp
udp
ipifc
icmp
icmp6
port
int cpuserver = 0;
bootdir
/$objtype/bin/paqfs
/$objtype/bin/auth/factotum
bootfs.paq
boot

View file

@ -1,56 +0,0 @@
dev
root
cons
arch
pnp pci
env
pipe
proc
mnt
srv
dup
# rtc
ssl
cap
kprof
# loopback
ether netif
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum inferno
sd
floppy dma
audio dma
uart
link
ether2114x pci
ethermedium
loopbackmedium
misc
arch164
sdata pci sdscsi
# sd53c8xx pci sdscsi
uarti8250
ip
tcp
udp
ipifc
icmp
icmp6
gre
ipmux
port
int cpuserver = 1;
bootdir
/$objtype/bin/paqfs
/$objtype/bin/auth/factotum
bootfs.paq
boot

View file

@ -1,363 +0,0 @@
/*
* EB164 and similar
* CPU: 21164
* Core Logic: 21172 CIA or 21174 PYXIS
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
static ulong *core;
static ulong *wind;
static ulong windsave[16];
static ulong coresave[1];
ulong iobase0;
ulong iobase1;
#define iobase(p) (iobase0+(p))
static int
ident(void)
{
return 0; /* bug! */
}
static uvlong* sgmap;
static void
sginit(void)
{
ulong pa;
uvlong *pte;
sgmap = xspanalloc(BY2PG, BY2PG, 0);
memset(sgmap, 0, BY2PG);
/*
* Prepare scatter-gather map for 0-8MB.
*/
pte = sgmap;
for(pa = 0; pa < 8*1024*1024; pa += BY2PG)
*pte++ = ((pa>>PGSHIFT)<<1)|1;
/*
* Set up a map for ISA DMA accesses to physical memory.
* Addresses presented by an ISA device between ISAWINDOW
* and ISAWINDOW+8MB will be translated to between 0 and
* 0+8MB of physical memory.
*/
wind[0x400/4] = ISAWINDOW|2|1; /* window base */
wind[0x440/4] = 0x00700000; /* window mask */
wind[0x480/4] = PADDR(sgmap)>>2; /* <33:10> of sg map */
wind[0x100/4] = 3; /* invalidate tlb cache */
}
static void *
kmapio(ulong space, ulong offset, int size)
{
return kmapv(((uvlong)space<<32LL)|offset, size);
}
static void
coreinit(void)
{
int i;
core = kmapio(0x87, 0x40000000, 0x10000);
wind = kmapio(0x87, 0x60000000, 0x1000);
iobase0 = (ulong)kmapio(0x89, 0, 0x20000);
/* hae_io = core[0x440/4];
iobase1 = (ulong)kmapio(0x89, hae_io, 0x10000); */
/* save critical parts of hardware memory mapping */
for (i = 4; i < 8; i++) {
windsave[4*(i-4)+0] = wind[(i*0x100+0x00)/4];
windsave[4*(i-4)+1] = wind[(i*0x100+0x40)/4];
windsave[4*(i-4)+2] = wind[(i*0x100+0x80)/4];
}
coresave[0] = core[0x140/4];
/* disable windows */
wind[0x400/4] = 0;
wind[0x500/4] = 0;
wind[0x600/4] = 0;
wind[0x700/4] = 0;
sginit();
/*
* Set up a map for PCI DMA accesses to physical memory.
* Addresses presented by a PCI device between PCIWINDOW
* and PCIWINDOW+1GB will be translated to between 0 and
* 0+1GB of physical memory.
*/
wind[0x500/4] = PCIWINDOW|1;
wind[0x540/4] = 0x3ff00000;
wind[0x580/4] = 0;
/* clear error state */
core[0x8200/4] = 0x7ff;
/* set config: byte/word enable, no monster window, etc. */
core[0x140/4] = 0x21;
/* turn off mcheck on master abort. now we can probe PCI space. */
core[0x8280/4] &= ~(1<<7);
/* set up interrupts. */
i8259init();
cserve(52, 4); /* enable SIO interrupt */
}
void
ciaerror(void)
{
print("cia error 0x%luX\n", core[0x8200/4]);
}
static void
corehello(void)
{
print("cpu%d: CIA revision %ld; cnfg %lux cntrl %lux\n",
0, /* BUG */
core[0x80/4] & 0x7f, core[0x140/4], core[0x100/4]);
print("cpu%d: HAE_IO %lux\n", 0, core[0x440/4]);
print("\n");
}
static void
coredetach(void)
{
int i;
for (i = 4; i < 8; i++) {
wind[(i*0x100+0x00)/4] = windsave[4*(i-4)+0];
wind[(i*0x100+0x40)/4] = windsave[4*(i-4)+1];
wind[(i*0x100+0x80)/4] = windsave[4*(i-4)+2];
}
core[0x140/4] = coresave[0];
/* for (i = 0; i < 4; i++)
if (i != 4)
cserve(53, i); /* disable interrupts */
}
static Lock pcicfgl;
static ulong pcimap[256];
static void*
pcicfg2117x(int tbdf, int rno)
{
int space, bus;
ulong base;
bus = BUSBNO(tbdf);
lock(&pcicfgl);
base = pcimap[bus];
if (base == 0) {
if(bus)
space = 0x8B;
else
space = 0x8A;
pcimap[bus] = base = (ulong)kmapio(space, MKBUS(0, bus, 0, 0), (1<<16));
}
unlock(&pcicfgl);
return (void*)(base + BUSDF(tbdf) + rno);
}
static void*
pcimem2117x(int addr, int len)
{
return kmapio(0x88, addr, len);
}
static int
intrenable164(Vctl *v)
{
int vec, irq;
irq = v->irq;
if(irq > MaxIrqPIC) {
print("intrenable: irq %d out of range\n", v->irq);
return -1;
}
if(BUSTYPE(v->tbdf) == BusPCI) {
vec = irq+VectorPCI;
cserve(52, irq);
}
else {
vec = irq+VectorPIC;
if(i8259enable(irq, v->tbdf, v) == -1)
return -1;
}
return vec;
}
/*
* I have a function pointer in PCArch for every one of these, because on
* some Alphas we have to use sparse mode, but on others we can use
* MOVB et al. Additionally, the PC164 documentation threatened us
* with the lie that the SIO is in region B, but everything else in region A.
* This turned out not to be the case. Given the cost of this solution, it
* may be better just to use sparse mode for I/O space on all platforms.
*/
int
inb2117x(int port)
{
mb();
return *(uchar*)(iobase(port));
}
ushort
ins2117x(int port)
{
mb();
return *(ushort*)(iobase(port));
}
ulong
inl2117x(int port)
{
mb();
return *(ulong*)(iobase(port));
}
void
outb2117x(int port, int val)
{
mb();
*(uchar*)(iobase(port)) = val;
mb();
}
void
outs2117x(int port, ushort val)
{
mb();
*(ushort*)(iobase(port)) = val;
mb();
}
void
outl2117x(int port, ulong val)
{
mb();
*(ulong*)(iobase(port)) = val;
mb();
}
void
insb2117x(int port, void *buf, int len)
{
int i;
uchar *p, *q;
p = (uchar*)iobase(port);
q = buf;
for(i = 0; i < len; i++){
mb();
*q++ = *p;
}
}
void
inss2117x(int port, void *buf, int len)
{
int i;
ushort *p, *q;
p = (ushort*)iobase(port);
q = buf;
for(i = 0; i < len; i++){
mb();
*q++ = *p;
}
}
void
insl2117x(int port, void *buf, int len)
{
int i;
ulong *p, *q;
p = (ulong*)iobase(port);
q = buf;
for(i = 0; i < len; i++){
mb();
*q++ = *p;
}
}
void
outsb2117x(int port, void *buf, int len)
{
int i;
uchar *p, *q;
p = (uchar*)iobase(port);
q = buf;
for(i = 0; i < len; i++){
mb();
*p = *q++;
}
}
void
outss2117x(int port, void *buf, int len)
{
int i;
ushort *p, *q;
p = (ushort*)iobase(port);
q = buf;
for(i = 0; i < len; i++){
mb();
*p = *q++;
}
}
void
outsl2117x(int port, void *buf, int len)
{
int i;
ulong *p, *q;
p = (ulong*)iobase(port);
q = buf;
for(i = 0; i < len; i++){
mb();
*p = *q++;
}
}
PCArch arch164 = {
"EB164",
ident,
coreinit,
corehello,
coredetach,
pcicfg2117x,
pcimem2117x,
intrenable164,
nil,
nil,
inb2117x,
ins2117x,
inl2117x,
outb2117x,
outs2117x,
outl2117x,
insb2117x,
inss2117x,
insl2117x,
outsb2117x,
outss2117x,
outsl2117x,
};

View file

@ -1,16 +0,0 @@
enum
{
Bufsize = 16*1024, /* 92 ms each */
Nbuf = 16, /* 1.5 seconds total */
Dma = 5,
IrqAUDIO = 5,
SBswab = 0,
};
#define seteisadma(a, b) dmainit(a, Bufsize);
#define CACHELINESZ 128
#define UNCACHED(type, v) (type*)((ulong)(v))
#define dcflush(a, b)
#define Int0vec
#define setvec(v, f, a) intrenable(v, f, a, BUSUNKNOWN, "audio")

View file

@ -1,71 +0,0 @@
typedef struct Hwrpb Hwrpb;
typedef struct Hwcpu Hwcpu;
typedef struct Hwdsr Hwdsr;
struct Hwrpb
{
uvlong phys;
uvlong sign;
uvlong rev;
uvlong size;
uvlong cpu0;
uvlong by2pg;
uvlong pabits;
uvlong maxasn;
char ssn[16];
uvlong systype;
uvlong sysvar;
uvlong sysrev;
uvlong ifreq;
uvlong cfreq;
uvlong vptb;
uvlong resv;
uvlong tbhint;
uvlong ncpu;
uvlong cpulen;
uvlong cpuoff;
uvlong nctb;
uvlong ctblen;
uvlong ctboff;
uvlong ccrboff;
uvlong memoff;
uvlong confoff;
uvlong fruoff;
uvlong termsaveva;
uvlong termsavex;
uvlong termrestva;
uvlong termrestx;
uvlong termresetva;
uvlong termresetx;
uvlong sysresv;
uvlong hardresv;
uvlong csum;
uvlong rxrdymsk;
uvlong txrdymsk;
uvlong dsroff; /* rev 6 or higher */
};
extern Hwrpb* hwrpb;
struct Hwcpu
{
uvlong hwpcb[16];
uvlong state;
uvlong palmainlen;
uvlong palscratchlen;
uvlong palmainpa;
uvlong palscratchpa;
uvlong palrev;
uvlong cputype;
uvlong cpuvar;
uvlong cpurev;
uvlong serial[2];
/* more crap ... */
};
struct Hwdsr
{
vlong smm;
uvlong lurtoff;
uvlong sysnameoff;
};

View file

@ -1,113 +0,0 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "io.h"
enum {
Width = 160,
Height = 25,
Attr = 0x4f, /* white on blue */
};
static ulong cgabase;
#define CGASCREENBASE ((uchar*)cgabase)
static int cgapos;
static int screeninitdone;
static Lock cgascreenlock;
static uchar
cgaregr(int index)
{
outb(0x3D4, index);
return inb(0x3D4+1) & 0xFF;
}
static void
cgaregw(int index, int data)
{
outb(0x3D4, index);
outb(0x3D4+1, data);
}
static void
movecursor(void)
{
cgaregw(0x0E, (cgapos/2>>8) & 0xFF);
cgaregw(0x0F, cgapos/2 & 0xFF);
CGASCREENBASE[cgapos+1] = Attr;
}
static void
cgascreenputc(int c)
{
int i;
if(c == '\n'){
cgapos = cgapos/Width;
cgapos = (cgapos+1)*Width;
}
else if(c == '\t'){
i = 8 - ((cgapos/2)&7);
while(i-->0)
cgascreenputc(' ');
}
else if(c == '\b'){
if(cgapos >= 2)
cgapos -= 2;
cgascreenputc(' ');
cgapos -= 2;
}
else{
CGASCREENBASE[cgapos++] = c;
CGASCREENBASE[cgapos++] = Attr;
}
if(cgapos >= Width*Height){
memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
for (i = Width*(Height-1); i < Width*Height;) {
CGASCREENBASE[i++] = 0x20;
CGASCREENBASE[i++] = Attr;
}
cgapos = Width*(Height-1);
}
movecursor();
}
void
screeninit(void)
{
cgabase = (ulong)arch->pcimem(0xB8000, 0x8000);
cgapos = cgaregr(0x0E)<<8;
cgapos |= cgaregr(0x0F);
cgapos *= 2;
screeninitdone = 1;
}
static void
cgascreenputs(char* s, int n)
{
if(!screeninitdone)
return;
if(!islo()){
/*
* Don't deadlock trying to
* print in an interrupt.
*/
if(!canlock(&cgascreenlock))
return;
}
else
lock(&cgascreenlock);
while(n-- > 0)
cgascreenputc(*s++);
unlock(&cgascreenlock);
}
void (*screenputs)(char*, int) = cgascreenputs;

View file

@ -1,112 +0,0 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "axp.h"
#include "ureg.h"
void
clockinit(void)
{
}
uvlong
cycletimer(void)
{
ulong pcc;
vlong delta;
pcc = rpcc(nil) & 0xFFFFFFFF;
if(m->cpuhz == 0){
/*
* pcclast is needed to detect wraparound of
* the cycle timer which is only 32-bits.
* m->cpuhz is set from the info passed from
* the firmware.
* This could be in clockinit if can
* guarantee no wraparound between then and now.
*
* All the clock stuff needs work.
*/
m->cpuhz = hwrpb->cfreq;
m->pcclast = pcc;
}
delta = pcc - m->pcclast;
if(delta < 0)
delta += 0x100000000LL;
m->pcclast = pcc;
m->fastclock += delta;
return MACHP(0)->fastclock;
}
uvlong
fastticks(uvlong* hz)
{
uvlong ticks;
int x;
x = splhi();
ticks = cycletimer();
splx(x);
if(hz)
*hz = m->cpuhz;
return ticks;
}
ulong
µs(void)
{
return fastticks2us(cycletimer());
}
/*
* performance measurement ticks. must be low overhead.
* doesn't have to count over a second.
*/
ulong
perfticks(void)
{
return rpcc(nil);
}
void
timerset(Tval)
{
}
void
microdelay(int us)
{
uvlong eot;
eot = fastticks(nil) + (m->cpuhz/1000000)*us;
while(fastticks(nil) < eot)
;
}
void
delay(int millisecs)
{
microdelay(millisecs*1000);
}
void
clock(Ureg *ureg)
{
static int count;
cycletimer();
/* HZ == 100, timer == 1024Hz. error < 1ms */
count += 100;
if (count < 1024)
return;
count -= 1024;
timerintr(ureg, 0);
}

View file

@ -1,27 +0,0 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
int
havetimer(void)
{
return 0;
}
void
timeradd(Timer *)
{
}
void
timerdel(Timer *)
{
}
void
clockintrsched(void)
{
}

View file

@ -1,265 +0,0 @@
typedef struct Conf Conf;
typedef struct Confmem Confmem;
typedef struct FPsave FPsave;
typedef struct ISAConf ISAConf;
typedef struct Label Label;
typedef struct Lock Lock;
typedef struct Mach Mach;
typedef struct Notsave Notsave;
typedef struct Page Page;
typedef struct PCArch PCArch;
typedef struct PCB PCB;
typedef struct Pcidev Pcidev;
typedef struct PMMU PMMU;
typedef struct Proc Proc;
typedef struct Sys Sys;
typedef struct Ureg Ureg;
typedef struct Vctl Vctl;
typedef vlong Tval;
#define MAXSYSARG 6 /* for mount(fd, mpt, flag, arg, srv) */
/*
* parameters for sysproc.c
*/
#define AOUT_MAGIC L_MAGIC
/*
* machine dependent definitions used by ../port/dat.h
*/
struct Lock
{
ulong key; /* semaphore (non-zero = locked) */
ulong sr;
ulong pc;
Proc *p;
Mach *m;
ulong pid;
ushort isilock;
};
struct Label
{
ulong sp;
ulong pc;
};
/*
* Proc.fpstate
*/
enum
{
/* floating point states */
FPinit,
FPactive,
FPinactive,
/* bit or'd with the state */
FPillegal= 0x100,
};
struct FPsave
{
long fpreg[2*32];
long dummy; /* lower bits of FPCR, useless */
long fpstatus;
};
struct Confmem
{
ulong base;
ulong npage;
ulong kbase;
ulong klimit;
};
struct Conf
{
ulong nmach; /* processors */
ulong nproc; /* processes */
Confmem mem[2];
ulong npage; /* total physical pages of memory */
ulong upages; /* user page pool */
ulong nimage; /* number of page cache image headers */
ulong nswap; /* number of swap pages */
int nswppo; /* max # of pageouts per segment pass */
ulong copymode; /* 0 is copy on write, 1 is copy on reference */
int monitor; /* has display? */
ulong ialloc; /* bytes available for interrupt time allocation */
ulong pipeqsize; /* size in bytes of pipe queues */
};
/*
* mmu goo in the Proc structure
*/
struct PMMU
{
Page *mmutop; /* 1st level table */
Page *mmulvl2; /* 2nd level table */
Page *mmufree; /* unused page table pages */
Page *mmuused; /* used page table pages, except for mmustk */
};
/*
* things saved in the Proc structure during a notify
*/
struct Notsave
{
ulong UNUSED;
};
#include "../port/portdat.h"
/*
* machine dependent definitions not used by ../port/dat.h
*/
/*
* Fake kmap
*/
typedef void KMap;
#define VA(k) ((ulong)(k))
#define kmap(p) (KMap*)((p)->pa|KZERO)
#define kunmap(k)
/*
* Process Control Block, used by PALcode
*/
struct PCB {
uvlong ksp;
uvlong usp;
uvlong ptbr;
ulong asn;
ulong pcc;
uvlong unique;
ulong fen;
ulong dummy;
uvlong rsrv1;
uvlong rsrv2;
};
struct Mach
{
/* OFFSETS OF THE FOLLOWING KNOWN BY l.s */
int machno; /* physical id of processor */
ulong splpc; /* pc that called splhi() */
Proc *proc; /* current process on this processor */
/* ordering from here on irrelevant */
ulong ticks; /* of the clock since boot time */
Label sched; /* scheduler wakeup */
Lock alarmlock; /* access to alarm list */
void *alarm; /* alarms bound to this clock */
int inclockintr;
Proc* readied; /* for runproc */
ulong schedticks; /* next forced context switch */
vlong cpuhz; /* hwrpb->cfreq */
uvlong cyclefreq; /* Frequency of user readable cycle counter */
ulong pcclast;
uvlong fastclock;
Perf perf; /* performance counters */
int tlbfault; /* only used by devproc; no access to tlb */
int tlbpurge; /* ... */
int pfault;
int cs;
int syscall;
int load;
int intr;
int flushmmu; /* make current proc flush it's mmu state */
int ilockdepth;
ulong spuriousintr;
int lastintr;
PCB;
/* MUST BE LAST */
int stack[1];
};
struct
{
Lock;
char machs[MAXMACH];
int exiting;
}active;
/*
* Implementation-dependant functions (outside of Alpha architecture proper).
* Called PCArch because that's what mkdevc calls it (for the PC).
*/
struct PCArch
{
char* id;
int (*ident)(void);
void (*coreinit)(void); /* set up core logic, PCI mappings etc */
void (*corehello)(void); /* identify core logic to user */
void (*coredetach)(void); /* restore core logic before return to console */
void *(*pcicfg)(int, int); /* map and point to PCI cfg space */
void *(*pcimem)(int, int); /* map and point to PCI memory space */
int (*intrenable)(Vctl*);
int (*intrvecno)(int);
int (*intrdisable)(int);
int (*_inb)(int);
ushort (*_ins)(int);
ulong (*_inl)(int);
void (*_outb)(int, int);
void (*_outs)(int, ushort);
void (*_outl)(int, ulong);
void (*_insb)(int, void*, int);
void (*_inss)(int, void*, int);
void (*_insl)(int, void*, int);
void (*_outsb)(int, void*, int);
void (*_outss)(int, void*, int);
void (*_outsl)(int, void*, int);
};
/*
* a parsed plan9.ini line
*/
#define NISAOPT 8
struct ISAConf {
char *type;
ulong port;
int irq;
ulong dma;
ulong mem;
ulong size;
ulong freq;
int nopt;
char *opt[NISAOPT];
};
extern PCArch *arch;
#define MACHP(n) ((Mach *)((int)&mach0+n*BY2PG))
extern Mach mach0;
extern register Mach *m;
extern register Proc *up;
/*
* hardware info about a device
*/
typedef struct {
ulong port;
int size;
} Devport;
struct DevConf
{
ulong intnum; /* interrupt number */
char *type; /* card type, malloced */
int nports; /* Number of ports */
Devport *ports; /* The ports themselves */
};
extern FPsave initfp;

View file

@ -1,533 +0,0 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "../port/error.h"
#include "axp.h"
typedef struct IOMap IOMap;
struct IOMap
{
IOMap *next;
char tag[13];
ulong start;
ulong end;
};
static struct
{
Lock;
IOMap *m;
IOMap *free;
IOMap maps[32]; // some initial free maps
QLock ql; // lock for reading map
} iomap;
enum {
Qdir = 0,
Qioalloc = 1,
Qiob,
Qiow,
Qiol,
Qbase,
Qmax = 16,
};
typedef long Rdwrfn(Chan*, void*, long, vlong);
static Rdwrfn *readfn[Qmax];
static Rdwrfn *writefn[Qmax];
static Dirtab archdir[] = {
".", { Qdir, 0, QTDIR }, 0, 0555,
"ioalloc", { Qioalloc, 0 }, 0, 0444,
"iob", { Qiob, 0 }, 0, 0660,
"iow", { Qiow, 0 }, 0, 0660,
"iol", { Qiol, 0 }, 0, 0660,
};
Lock archwlock; /* the lock is only for changing archdir */
int narchdir = Qbase;
int (*_pcmspecial)(char *, ISAConf *);
void (*_pcmspecialclose)(int);
/*
* Add a file to the #P listing. Once added, you can't delete it.
* You can't add a file with the same name as one already there,
* and you get a pointer to the Dirtab entry so you can do things
* like change the Qid version. Changing the Qid path is disallowed.
*/
Dirtab*
addarchfile(char *name, int perm, Rdwrfn *rdfn, Rdwrfn *wrfn)
{
int i;
Dirtab d;
Dirtab *dp;
memset(&d, 0, sizeof d);
strcpy(d.name, name);
d.perm = perm;
lock(&archwlock);
if(narchdir >= Qmax){
unlock(&archwlock);
return nil;
}
for(i=0; i<narchdir; i++)
if(strcmp(archdir[i].name, name) == 0){
unlock(&archwlock);
return nil;
}
d.qid.path = narchdir;
archdir[narchdir] = d;
readfn[narchdir] = rdfn;
writefn[narchdir] = wrfn;
dp = &archdir[narchdir++];
unlock(&archwlock);
return dp;
}
void
ioinit(void)
{
int i;
for(i = 0; i < nelem(iomap.maps)-1; i++)
iomap.maps[i].next = &iomap.maps[i+1];
iomap.maps[i].next = nil;
iomap.free = iomap.maps;
// a dummy entry at 2^17
ioalloc(0x20000, 1, 0, "dummy");
}
//
// alloc some io port space and remember who it was
// alloced to. if port < 0, find a free region.
//
int
ioalloc(int port, int size, int align, char *tag)
{
IOMap *m, **l;
int i;
lock(&iomap);
if(port < 0){
// find a free port above 0x400 and below 0x1000
port = 0x400;
for(l = &iomap.m; *l; l = &(*l)->next){
m = *l;
i = m->start - port;
if(i > size)
break;
if(align > 0)
port = ((port+align-1)/align)*align;
else
port = m->end;
}
if(*l == nil){
unlock(&iomap);
return -1;
}
} else {
// see if the space clashes with previously allocated ports
for(l = &iomap.m; *l; l = &(*l)->next){
m = *l;
if(m->end <= port)
continue;
if(m->start >= port+size)
break;
unlock(&iomap);
return -1;
}
}
m = iomap.free;
if(m == nil){
print("ioalloc: out of maps");
unlock(&iomap);
return port;
}
iomap.free = m->next;
m->next = *l;
m->start = port;
m->end = port + size;
strncpy(m->tag, tag, sizeof(m->tag));
m->tag[sizeof(m->tag)-1] = 0;
*l = m;
archdir[0].qid.vers++;
unlock(&iomap);
return m->start;
}
void
iofree(int port)
{
IOMap *m, **l;
lock(&iomap);
for(l = &iomap.m; *l; l = &(*l)->next){
if((*l)->start == port){
m = *l;
*l = m->next;
m->next = iomap.free;
iomap.free = m;
break;
}
if((*l)->start > port)
break;
}
archdir[0].qid.vers++;
unlock(&iomap);
}
int
iounused(int start, int end)
{
IOMap *m;
for(m = iomap.m; m; m = m->next){
if(start >= m->start && start < m->end
|| start <= m->start && end > m->start)
return 0;
}
return 1;
}
static void
checkport(int start, int end)
{
/* standard vga regs are OK */
if(start >= 0x2b0 && end <= 0x2df+1)
return;
if(start >= 0x3c0 && end <= 0x3da+1)
return;
if(iounused(start, end))
return;
error(Eperm);
}
static Chan*
archattach(char* spec)
{
return devattach('P', spec);
}
Walkqid*
archwalk(Chan* c, Chan *nc, char** name, int nname)
{
return devwalk(c, nc, name, nname, archdir, narchdir, devgen);
}
static int
archstat(Chan* c, uchar* dp, int n)
{
return devstat(c, dp, n, archdir, narchdir, devgen);
}
static Chan*
archopen(Chan* c, int omode)
{
return devopen(c, omode, archdir, nelem(archdir), devgen);
}
static void
archclose(Chan*)
{
}
enum
{
Linelen= 31,
};
static long
archread(Chan *c, void *a, long n, vlong offset)
{
char buf[Linelen+1], *p;
int port;
ushort *sp;
ulong *lp;
IOMap *m;
Rdwrfn *fn;
switch((ulong)c->qid.path){
case Qdir:
return devdirread(c, a, n, archdir, nelem(archdir), devgen);
case Qiob:
port = offset;
checkport(offset, offset+n);
for(p = a; port < offset+n; port++)
*p++ = inb(port);
return n;
case Qiow:
if((n & 0x01) || (offset & 0x01))
error(Ebadarg);
checkport(offset, offset+n+1);
n /= 2;
sp = a;
for(port = offset; port < offset+n; port += 2)
*sp++ = ins(port);
return n*2;
case Qiol:
if((n & 0x03) || (offset & 0x03))
error(Ebadarg);
checkport(offset, offset+n+3);
n /= 4;
lp = a;
for(port = offset; port < offset+n; port += 4)
*lp++ = inl(port);
return n*4;
case Qioalloc:
break;
default:
if(c->qid.path < narchdir && (fn = readfn[c->qid.path]))
return fn(c, a, n, offset);
error(Eperm);
break;
}
offset = offset/Linelen;
n = n/Linelen;
p = a;
lock(&iomap);
for(m = iomap.m; n > 0 && m != nil; m = m->next){
if(offset-- > 0)
continue;
if(strcmp(m->tag, "dummy") == 0)
break;
sprint(buf, "%8lux %8lux %-12.12s\n", m->start, m->end-1, m->tag);
memmove(p, buf, Linelen);
p += Linelen;
n--;
}
unlock(&iomap);
return p - (char*)a;
}
static long
archwrite(Chan *c, void *a, long n, vlong offset)
{
char *p;
int port;
ushort *sp;
ulong *lp;
Rdwrfn *fn;
switch((ulong)c->qid.path){
case Qiob:
p = a;
checkport(offset, offset+n);
for(port = offset; port < offset+n; port++)
outb(port, *p++);
return n;
case Qiow:
if((n & 01) || (offset & 01))
error(Ebadarg);
checkport(offset, offset+n+1);
n /= 2;
sp = a;
for(port = offset; port < offset+n; port += 2)
outs(port, *sp++);
return n*2;
case Qiol:
if((n & 0x03) || (offset & 0x03))
error(Ebadarg);
checkport(offset, offset+n+3);
n /= 4;
lp = a;
for(port = offset; port < offset+n; port += 4)
outl(port, *lp++);
return n*4;
default:
if(c->qid.path < narchdir && (fn = writefn[c->qid.path]))
return fn(c, a, n, offset);
error(Eperm);
break;
}
return 0;
}
Dev archdevtab = {
'P',
"arch",
devreset,
devinit,
devshutdown,
archattach,
archwalk,
archstat,
archopen,
devcreate,
archclose,
archread,
devbread,
archwrite,
devbwrite,
devremove,
devwstat,
};
PCArch* arch;
extern PCArch* knownarch[];
PCArch archgeneric = {
"generic", /* id */
0, /* ident */
0, /* coreinit */
0, /* coredetach */
};
static char *sysnames[] =
{
[1] "Alpha Demo. Unit",
[2] "DEC 4000; Cobra",
[3] "DEC 7000; Ruby",
[4] "DEC 3000/500; Flamingo family (TC)",
[6] "DEC 2000/300; Jensen (EISA/ISA)",
[7] "DEC 3000/300; Pelican (TC)",
[8] "Avalon A12; Avalon Multicomputer",
[9] "DEC 2100/A500; Sable",
[10] "DEC APXVME/64; AXPvme (VME?)",
[11] "DEC AXPPCI/33; NoName (PCI/ISA)",
[12] "DEC 21000; TurboLaser (PCI/EISA)",
[13] "DEC 2100/A50; Avanti (PCI/ISA)",
[14] "DEC MUSTANG; Mustang",
[15] "DEC KN20AA; kn20aa (PCI/EISA)",
[17] "DEC 1000; Mikasa (PCI/ISA?)",
[19] "EB66; EB66 (PCI/ISA?)", // DEC?
[20] "EB64P; EB64+ (PCI/ISA?)", // DEC?
[21] "Alphabook1; Alphabook",
[22] "DEC 4100; Rawhide (PCI/EISA)",
[23] "DEC EV45/PBP; Lego",
[24] "DEC 2100A/A500; Lynx",
[26] "DEC AlphaPC 164", // only supported one: "EB164 (PCI/ISA)"
[27] "DEC 1000A; Noritake",
[28] "DEC AlphaVME/224; Cortex",
[30] "DEC 550; Miata (PCI/ISA)",
[32] "DEC EV56/PBP; Takara",
[33] "DEC AlphaVME/320; Yukon (VME?)",
[34] "DEC 6600; MonetGoldrush",
// 200 and up is Alpha Processor Inc. machines
// [201] "API UP1000; Nautilus",
};
static char *cpunames[] =
{
[1] "EV3",
[2] "EV4: 21064",
[3] "Simulation",
[4] "LCA4: 2106[68]",
[5] "EV5: 21164",
[6] "EV45: 21064A",
[7] "21164A", /* only supported one: EV56 */
[8] "EV6: 21264",
[9] "PCA256: 21164PC",
};
void
cpuidprint(void)
{
int i, maj, min;
Hwcpu *cpu;
Hwdsr *dsr;
char *s;
print("\n");
if (hwrpb->rev >= 6) {
dsr = (Hwdsr*)((ulong)hwrpb + hwrpb->dsroff);
s = (char*)dsr + dsr->sysnameoff + 8;
print("%s\n", s);
}
else {
s = "<unknown>";
if (hwrpb->systype < nelem(sysnames))
s = sysnames[hwrpb->systype];
print("%s (%llux, %llux, %llux)\n", s, hwrpb->systype, hwrpb->sysvar, hwrpb->sysrev);
}
for (i = 0; i < hwrpb->ncpu; i++) {
cpu = (Hwcpu*) ((ulong)hwrpb + hwrpb->cpuoff + i*hwrpb->cpulen);
s = "<unknown>";
maj = (ulong)cpu->cputype;
min = (ulong)(cpu->cputype>>32);
if (maj < nelem(cpunames))
s = cpunames[maj];
print("cpu%d: %s-%d (%d.%d, %llux, %llux)\n",
i, s, min, maj, min, cpu->cpuvar, cpu->cpurev);
}
print("\n");
}
static long
cputyperead(Chan*, void *a, long n, vlong offset)
{
char str[32], *cputype;
ulong mhz, maj;
Hwcpu *cpu;
mhz = (m->cpuhz+999999)/1000000;
cpu = (Hwcpu*) ((ulong)hwrpb + hwrpb->cpuoff); /* NB CPU 0 */
cputype = "unknown";
maj = (ulong)cpu->cputype;
if (maj < nelem(cpunames))
cputype = cpunames[maj];
snprint(str, sizeof(str), "%s %lud\n", cputype, mhz);
return readstr(offset, a, n, str);
}
void
archinit(void)
{
PCArch **p;
arch = 0;
for(p = knownarch; *p; p++){
if((*p)->ident && (*p)->ident() == 0){
arch = *p;
break;
}
}
if(arch == 0)
arch = &archgeneric;
addarchfile("cputype", 0444, cputyperead, nil);
}
int
pcmspecial(char *idstr, ISAConf *isa)
{
return (_pcmspecial != nil)? _pcmspecial(idstr, isa): -1;
}
void
pcmspecialclose(int a)
{
if (_pcmspecialclose != nil)
_pcmspecialclose(a);
}

View file

@ -1,407 +0,0 @@
/*
* VGA controller
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "../port/error.h"
#define Image IMAGE
#include <draw.h>
#include <memdraw.h>
#include <cursor.h>
#include "screen.h"
extern uchar *vgabios;
enum {
Qdir,
Qvgactl,
Qvgabios,
};
static Dirtab vgadir[] = {
".", { Qdir, 0, QTDIR }, 0, 0550,
"vgactl", { Qvgactl, 0 }, 0, 0660,
"vgabios", { Qvgabios, 0 }, 0x10000, 0440,
};
static void
vgareset(void)
{
/* reserve the 'standard' vga registers */
if(ioalloc(0x2b0, 0x2df-0x2b0+1, 0, "vga") < 0)
panic("vga ports already allocated");
if(ioalloc(0x3c0, 0x3da-0x3c0+1, 0, "vga") < 0)
panic("vga ports already allocated");
conf.monitor = 1;
}
static Chan*
vgaattach(char* spec)
{
if(*spec && strcmp(spec, "0"))
error(Eio);
return devattach('v', spec);
}
Walkqid*
vgawalk(Chan* c, Chan *nc, char** name, int nname)
{
return devwalk(c, nc, name, nname, vgadir, nelem(vgadir), devgen);
}
static int
vgastat(Chan* c, uchar* dp, int n)
{
return devstat(c, dp, n, vgadir, nelem(vgadir), devgen);
}
static Chan*
vgaopen(Chan* c, int omode)
{
return devopen(c, omode, vgadir, nelem(vgadir), devgen);
}
static void
vgaclose(Chan*)
{
}
static void
checkport(int start, int end)
{
/* standard vga regs are OK */
if(start >= 0x2b0 && end <= 0x2df+1)
return;
if(start >= 0x3c0 && end <= 0x3da+1)
return;
if(iounused(start, end))
return;
error(Eperm);
}
static long
vgaread(Chan* c, void* a, long n, vlong off)
{
int len;
char *p, *s;
VGAscr *scr;
ulong offset = off;
char chbuf[30];
switch((ulong)c->qid.path){
case Qdir:
return devdirread(c, a, n, vgadir, nelem(vgadir), devgen);
case Qvgactl:
scr = &vgascreen[0];
p = malloc(READSTR);
if(waserror()){
free(p);
nexterror();
}
len = 0;
if(scr->dev)
s = scr->dev->name;
else
s = "cga";
len += snprint(p+len, READSTR-len, "type %s\n", s);
if(scr->gscreen) {
len += snprint(p+len, READSTR-len, "size %dx%dx%d %s\n",
scr->gscreen->r.max.x, scr->gscreen->r.max.y,
scr->gscreen->depth, chantostr(chbuf, scr->gscreen->chan));
if(Dx(scr->gscreen->r) != Dx(physgscreenr)
|| Dy(scr->gscreen->r) != Dy(physgscreenr))
len += snprint(p+len, READSTR-len, "actualsize %dx%d\n",
physgscreenr.max.x, physgscreenr.max.y);
}
len += snprint(p+len, READSTR-len, "blanktime %lud\n", blanktime);
len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->paddr);
n = readstr(offset, a, n, p);
poperror();
free(p);
return n;
case Qvgabios:
if(vgabios == nil)
error(Egreg);
if(offset&0x80000000)
offset &= ~0x800E0000;
if(offset+n > 0x10000)
n = 0x10000-offset;
if(n < 0)
return 0;
memmove(a, vgabios+offset, n);
return n;
default:
error(Egreg);
break;
}
return 0;
}
static char Ebusy[] = "vga already configured";
static void
vgactl(char* a)
{
int align, i, n, size, x, y, z;
char *chanstr, *field[6], *p;
ulong chan;
VGAscr *scr;
extern VGAdev *vgadev[];
extern VGAcur *vgacur[];
Rectangle r;
n = tokenize(a, field, nelem(field));
if(n < 1)
error(Ebadarg);
scr = &vgascreen[0];
if(strcmp(field[0], "hwgc") == 0){
if(n < 2)
error(Ebadarg);
if(strcmp(field[1], "off") == 0){
lock(&cursor);
if(scr->cur){
if(scr->cur->disable)
scr->cur->disable(scr);
scr->cur = nil;
}
unlock(&cursor);
return;
}
for(i = 0; vgacur[i]; i++){
if(strcmp(field[1], vgacur[i]->name))
continue;
lock(&cursor);
if(scr->cur && scr->cur->disable)
scr->cur->disable(scr);
scr->cur = vgacur[i];
if(scr->cur->enable)
scr->cur->enable(scr);
unlock(&cursor);
return;
}
}
else if(strcmp(field[0], "type") == 0){
if(n < 2)
error(Ebadarg);
for(i = 0; vgadev[i]; i++){
if(strcmp(field[1], vgadev[i]->name))
continue;
if(scr->dev && scr->dev->disable)
scr->dev->disable(scr);
scr->dev = vgadev[i];
if(scr->dev->enable)
scr->dev->enable(scr);
return;
}
}
else if(strcmp(field[0], "size") == 0){
if(n < 3)
error(Ebadarg);
if(drawhasclients())
error(Ebusy);
x = strtoul(field[1], &p, 0);
if(x == 0 || x > 2048)
error(Ebadarg);
if(*p)
p++;
y = strtoul(p, &p, 0);
if(y == 0 || y > 2048)
error(Ebadarg);
if(*p)
p++;
z = strtoul(p, &p, 0);
chanstr = field[2];
if((chan = strtochan(chanstr)) == 0)
error("bad channel");
if(chantodepth(chan) != z)
error("depth, channel do not match");
cursoroff(1);
deletescreenimage();
if(screensize(x, y, z, chan))
error(Egreg);
vgascreenwin(scr);
cursoron(1);
return;
}
else if(strcmp(field[0], "actualsize") == 0){
if(scr->gscreen == nil)
error("set the screen size first");
if(n < 2)
error(Ebadarg);
x = strtoul(field[1], &p, 0);
if(x == 0 || x > 2048)
error(Ebadarg);
if(*p)
p++;
y = strtoul(p, nil, 0);
if(y == 0 || y > 2048)
error(Ebadarg);
if(x > scr->gscreen->r.max.x || y > scr->gscreen->r.max.y)
error("physical screen bigger than virtual");
r = Rect(0,0,x,y);
if(!eqrect(r, scr->gscreen->r)){
if(scr->cur == nil || scr->cur->doespanning == 0)
error("virtual screen not supported");
}
physgscreenr = r;
return;
}
else if(strcmp(field[0], "palettedepth") == 0){
if(n < 2)
error(Ebadarg);
x = strtoul(field[1], &p, 0);
if(x != 8 && x != 6)
error(Ebadarg);
scr->palettedepth = x;
return;
}
else if(strcmp(field[0], "drawinit") == 0){
if(scr && scr->dev && scr->dev->drawinit)
scr->dev->drawinit(scr);
return;
}
else if(strcmp(field[0], "linear") == 0){
if(n < 2)
error(Ebadarg);
size = strtoul(field[1], 0, 0);
if(n < 3)
align = 0;
else
align = strtoul(field[2], 0, 0);
if(screenaperture(size, align))
error("not enough free address space");
return;
}
/* else if(strcmp(field[0], "memset") == 0){
if(n < 4)
error(Ebadarg);
memset((void*)strtoul(field[1], 0, 0), atoi(field[2]), atoi(field[3]));
return;
}
*/
else if(strcmp(field[0], "blank") == 0){
if(n < 1)
error(Ebadarg);
drawblankscreen(1);
return;
}
else if(strcmp(field[0], "blanktime") == 0){
if(n < 2)
error(Ebadarg);
blanktime = strtoul(field[1], 0, 0);
return;
}
else if(strcmp(field[0], "hwaccel") == 0){
if(n < 2)
error(Ebadarg);
if(strcmp(field[1], "on") == 0)
hwaccel = 1;
else if(strcmp(field[1], "off") == 0)
hwaccel = 0;
return;
}
else if(strcmp(field[0], "hwblank") == 0){
if(n < 2)
error(Ebadarg);
if(strcmp(field[1], "on") == 0)
hwblank = 1;
else if(strcmp(field[1], "off") == 0)
hwblank = 0;
return;
}
error(Ebadarg);
}
static long
vgawrite(Chan* c, void* a, long n, vlong off)
{
char *p;
ulong offset = off;
switch((ulong)c->qid.path){
case Qdir:
error(Eperm);
case Qvgactl:
if(offset || n >= READSTR)
error(Ebadarg);
p = malloc(READSTR);
if(waserror()){
free(p);
nexterror();
}
memmove(p, a, n);
p[n] = 0;
vgactl(p);
poperror();
free(p);
return n;
default:
error(Egreg);
break;
}
return 0;
}
Dev vgadevtab = {
'v',
"vga",
vgareset,
devinit,
devshutdown,
vgaattach,
vgawalk,
vgastat,
vgaopen,
devcreate,
vgaclose,
vgaread,
devbread,
vgawrite,
devbwrite,
devremove,
devwstat,
};

View file

@ -1,331 +0,0 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
typedef struct DMAport DMAport;
typedef struct DMA DMA;
typedef struct DMAxfer DMAxfer;
/*
* state of a dma transfer
*/
struct DMAxfer
{
ulong bpa; /* bounce buffer physical address */
void* bva; /* bounce buffer virtual address */
int blen; /* bounce buffer length */
void* va; /* virtual address destination/src */
long len; /* bytes to be transferred */
int isread;
};
/*
* the dma controllers. the first half of this structure specifies
* the I/O ports used by the DMA controllers.
*/
struct DMAport
{
uchar addr[4]; /* current address (4 channels) */
uchar count[4]; /* current count (4 channels) */
uchar page[4]; /* page registers (4 channels) */
uchar cmd; /* command status register */
uchar req; /* request registers */
uchar sbm; /* single bit mask register */
uchar mode; /* mode register */
uchar cbp; /* clear byte pointer */
uchar mc; /* master clear */
uchar cmask; /* clear mask register */
uchar wam; /* write all mask register bit */
};
struct DMA
{
DMAport;
int shift;
Lock;
DMAxfer x[4];
};
DMA dma[2] = {
{ 0x00, 0x02, 0x04, 0x06,
0x01, 0x03, 0x05, 0x07,
0x87, 0x83, 0x81, 0x82,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0 },
{ 0xc0, 0xc4, 0xc8, 0xcc,
0xc2, 0xc6, 0xca, 0xce,
0x8f, 0x8b, 0x89, 0x8a,
0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
1 },
};
extern int i8237dma;
static void* i8237bva[2];
static int i8237used;
/*
* DMA must be in the first 16MB. This gets called early by the
* initialisation routines of any devices which require DMA to ensure
* the allocated bounce buffers are below the 16MB limit.
*/
void
_i8237alloc(void)
{
void* bva;
if(i8237dma <= 0)
return;
if(i8237dma > 2)
i8237dma = 2;
bva = xspanalloc(64*1024*i8237dma, BY2PG, 64*1024);
if(bva == nil || PADDR(bva)+64*1024*i8237dma > 16*MB){
/*
* This will panic with the current
* implementation of xspanalloc().
if(bva != nil)
xfree(bva);
*/
return;
}
i8237bva[0] = bva;
if(i8237dma == 2)
i8237bva[1] = ((uchar*)i8237bva[0])+64*1024;
}
static void
dmastatus(DMA *dp, int chan, char c)
{
int a, l, s;
ilock(dp);
outb(dp->cbp, 0);
a = inb(dp->addr[chan]);
a |= inb(dp->addr[chan])<<8;
a |= inb(dp->page[chan])<<16;
a |= inb(0x400|dp->page[chan])<<24;
outb(dp->cbp, 0);
l = inb(dp->count[chan]);
l |= inb(dp->count[chan])<<8;
s = inb(dp->cmd);
iunlock(dp);
print("%c: addr %uX len %uX stat %uX\n", c, a, l, s);
}
int
dmainit(int chan, int maxtransfer)
{
DMA *dp;
DMAxfer *xp;
static int once;
if(once == 0){
if(ioalloc(0x00, 0x10, 0, "dma") < 0
|| ioalloc(0x80, 0x10, 0, "dma") < 0
|| ioalloc(0xd0, 0x10, 0, "dma") < 0)
panic("dmainit");
outb(dma[0].mc, 0);
outb(dma[1].mc, 0);
outb(dma[0].cmask, 0);
outb(dma[1].cmask, 0);
outb(dma[1].mode, 0xC0);
once = 1;
}
if(maxtransfer > 64*1024)
maxtransfer = 64*1024;
dp = &dma[(chan>>2)&1];
chan = chan & 3;
xp = &dp->x[chan];
if(xp->bva != nil){
if(xp->blen < maxtransfer)
return 1;
return 0;
}
//dmastatus(dp, chan, 'I');
if(i8237used >= i8237dma || i8237bva[i8237used] == nil){
print("no i8237 DMA bounce buffer < 16MB\n");
return 1;
}
xp->bva = i8237bva[i8237used++];
xp->bpa = PADDR(xp->bva);
xp->blen = maxtransfer;
xp->len = 0;
xp->isread = 0;
return 0;
}
void
xdmastatus(int chan)
{
DMA *dp;
dp = &dma[(chan>>2)&1];
chan = chan & 3;
dmastatus(dp, chan, 'X');
}
/*
* setup a dma transfer. if the destination is not in kernel
* memory, allocate a page for the transfer.
*
* we assume BIOS has set up the command register before we
* are booted.
*
* return the updated transfer length (we can't transfer across 64k
* boundaries)
*/
long
dmasetup(int chan, void *va, long len, int isread)
{
DMA *dp;
ulong pa;
uchar mode;
DMAxfer *xp;
dp = &dma[(chan>>2)&1];
chan = chan & 3;
xp = &dp->x[chan];
//print("va%lux+", va);
#define tryPCI
#ifndef PCIWADDR
#define PCIWADDR(va) PADDR(va)
#endif /* PCIWADDR */
#ifdef notdef
/*
* if this isn't kernel memory or crossing 64k boundary or above 16 meg
* use the bounce buffer.
*/
pa = PADDR(va);
if((((ulong)va)&0xF0000000) != KZERO
|| (pa&0xFFFF0000) != ((pa+len)&0xFFFF0000)
|| pa >= 16*MB) {
if(xp->bva == nil)
return -1;
if(len > xp->blen)
len = xp->blen;
if(!isread)
memmove(xp->bva, va, len);
xp->va = va;
xp->len = len;
xp->isread = isread;
pa = xp->bpa;
}
else
xp->len = 0;
#endif /* notdef */
#ifdef tryISA
pa = ISAWADDR(va);
#endif /* tryISA */
#ifdef tryPCI
pa = PCIWADDR(va);
if((((ulong)va)&0xF0000000) != KZERO){
if(xp->bva == nil)
return -1;
if(len > xp->blen)
len = xp->blen;
if(!isread)
memmove(xp->bva, va, len);
xp->va = va;
xp->len = len;
xp->isread = isread;
pa = PCIWADDR(xp->bva);
}
else
xp->len = 0;
#endif /* tryPCI */
/*
* this setup must be atomic
*/
mode = (isread ? 0x44 : 0x48) | chan;
ilock(dp);
outb(dp->cbp, 0); /* set count & address to their first byte */
outb(dp->mode, mode); /* single mode dma (give CPU a chance at mem) */
outb(dp->addr[chan], pa>>dp->shift); /* set address */
outb(dp->addr[chan], pa>>(8+dp->shift));
outb(dp->page[chan], pa>>16);
#ifdef tryPCI
outb(0x400|dp->page[chan], pa>>24);
#endif /* tryPCI */
outb(dp->cbp, 0); /* set count & address to their first byte */
outb(dp->count[chan], (len>>dp->shift)-1); /* set count */
outb(dp->count[chan], ((len>>dp->shift)-1)>>8);
outb(dp->sbm, chan); /* enable the channel */
iunlock(dp);
//dmastatus(dp, chan, 'S');
return len;
}
int
dmadone(int chan)
{
DMA *dp;
dp = &dma[(chan>>2)&1];
chan = chan & 3;
return inb(dp->cmd) & (1<<chan);
}
/*
* this must be called after a dma has been completed.
*
* if a page has been allocated for the dma,
* copy the data into the actual destination
* and free the page.
*/
void
dmaend(int chan)
{
DMA *dp;
DMAxfer *xp;
dp = &dma[(chan>>2)&1];
chan = chan & 3;
//dmastatus(dp, chan, 'E');
/*
* disable the channel
*/
ilock(dp);
outb(dp->sbm, 4|chan);
iunlock(dp);
xp = &dp->x[chan];
if(xp->len == 0 || !xp->isread)
return;
/*
* copy out of temporary page
*/
memmove(xp->va, xp->bva, xp->len);
xp->len = 0;
}
/*
int
dmacount(int chan)
{
int retval;
DMA *dp;
dp = &dma[(chan>>2)&1];
outb(dp->cbp, 0);
retval = inb(dp->count[chan]);
retval |= inb(dp->count[chan]) << 8;
return((retval<<dp->shift)+1);
}
*/

View file

@ -1,41 +0,0 @@
enum {
MaxEther = 24,
Ntypes = 8,
};
typedef struct Ether Ether;
struct Ether {
ISAConf; /* hardware info */
int ctlrno;
int tbdf; /* type+busno+devno+funcno */
int minmtu;
int maxmtu;
uchar ea[Eaddrlen];
void (*attach)(Ether*); /* filled in by reset routine */
void (*detach)(Ether*); /* NEW, from ../pc */
void (*transmit)(Ether*);
void (*interrupt)(Ureg*, void*);
long (*ifstat)(Ether*, void*, long, ulong);
long (*ctl)(Ether*, void*, long); /* custom ctl messages */
/* START NEW, from ../pc */
void (*power)(Ether*, int); /* power on/off */
void (*shutdown)(Ether*); /* shutdown hardware before reboot */
/* END NEW */
void *ctlr;
Queue* oq;
Netif;
};
extern Block* etheriq(Ether*, Block*, int);
extern void addethercard(char*, int(*)(Ether*));
extern ulong ethercrc(uchar*, int);
extern int parseether(uchar*, char*);
#define NEXT(x, l) (((x)+1)%(l))
#define PREV(x, l) (((x) == 0) ? (l)-1: (x)-1)
#define HOWMANY(x, y) (((x)+((y)-1))/(y))
#define ROUNDUP(x, y) (HOWMANY((x), (y))*(y))

View file

@ -1,62 +0,0 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "ureg.h"
#include "../port/error.h"
/*
* find out fault address and type of access.
* Call common fault handler.
*/
void
faultalpha(Ureg *ur)
{
ulong addr, cause;
int read, user;
char buf[ERRMAX];
uvlong x;
x = ur->a0&0xffffffff80000000LL;
if (x != 0LL && x != 0xffffffff80000000LL)
iprint("faultalpha bad addr %llux pc %llux\n", ur->a0, ur->pc);
addr = (ulong)ur->a0;
cause = (ulong)ur->a2;
addr &= ~(BY2PG-1);
read = (cause !=1);
user = (ulong)ur->status&UMODE;
/* print("fault %s pc=0x%lux addr=0x%lux 0x%lux\n",
read? (cause != 0) ? "ifetch" : "read" : "write", (ulong)ur->pc, addr, (ulong)ur->a1); /**/
if(fault(addr, read) == 0)
return;
if(user){
sprint(buf, "sys: trap: fault %s addr=0x%lux",
read? (cause != 0) ? "ifetch" : "read" : "write", (ulong)ur->a0);
postnote(up, 1, buf, NDebug);
return;
}
iprint("kernel %s vaddr=0x%lux\n", read? (cause != 0) ? "ifetch" : "read" : "write", (ulong)ur->a0);
if(0)
mmudump();
dumpregs(ur);
_dumpstack(ur);
exit(1);
}
/*
* called in sysfile.c
*/
void
evenaddr(ulong addr)
{
if(addr & 3){
postnote(up, 1, "sys: odd address", NDebug);
error(Ebadarg);
}
}

View file

@ -1,66 +0,0 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
/*
* SMC FDC37C93x Plug and Play Compatible Ultra I/O Controller.
*/
enum { /* I/O Ports */
Config = 0x370, /* could also be 0x3F0 */
Index = 0,
Data = 1,
};
static int fddregs[] = {
0x30,
0x60, 0x61,
0x70,
0x74,
0xF0,
0xF1,
0xF2,
0xF4,
0xF5,
0,
};
#define OUTB(p, d) outb(p, d); microdelay(10);
void
fdc37c93xdump(void)
{
int config, i, x;
config = Config;
OUTB(config, 0x55);
OUTB(config, 0x55);
OUTB(config+Index, 0x20);
x = inb(config+Data);
print("fdc37c93x: Device ID 0x%2.2uX\n", x);
OUTB(config+Index, 0x22);
x = inb(config+Data);
print("fdc37c93x: Power/Control 0x%2.2uX\n", x);
OUTB(config+Index, 0x07);
OUTB(config+Data, 0);
for(i = 0; fddregs[i]; i++){
OUTB(config+Index, fddregs[i]);
x = inb(config+Data);
print("FDD%2.2uX: 0x%2.2uX\n", fddregs[i], x);
}
OUTB(config+Index, 0x70);
OUTB(config+Data, 0x06);
OUTB(config+Index, 0x74);
OUTB(config+Data, 0x02);
OUTB(config+Index, 0x30);
OUTB(config+Data, 0x01);
OUTB(config, 0xAA);
}

View file

@ -1,181 +0,0 @@
typedef struct FController FController;
typedef struct FDrive FDrive;
typedef struct FType FType;
static void floppyintr(Ureg*);
static int floppyon(FDrive*);
static void floppyoff(FDrive*);
static void floppysetdef(FDrive*);
/*
* a floppy drive
*/
struct FDrive
{
FType *t; /* floppy type */
int dt; /* drive type */
int dev;
ulong lasttouched; /* time last touched */
int cyl; /* current arm position */
int confused; /* needs to be recalibrated */
int vers;
int maxtries; /* max read attempts before Eio */
int tcyl; /* target cylinder */
int thead; /* target head */
int tsec; /* target sector */
long len; /* size of xfer */
uchar *cache; /* track cache */
int ccyl;
int chead;
Rendez r; /* waiting here for motor to spin up */
};
/*
* controller for 4 floppys
*/
struct FController
{
QLock; /* exclusive access to the contoller */
int ndrive;
FDrive *d; /* the floppy drives */
FDrive *selected;
int rate; /* current rate selected */
uchar cmd[14]; /* command */
int ncmd; /* # command bytes */
uchar stat[14]; /* command status */
int nstat; /* # status bytes */
int confused; /* controler needs to be reset */
Rendez r; /* wait here for command termination */
int motor; /* bit mask of spinning disks */
Rendez kr; /* for motor watcher */
};
/*
* floppy types (all MFM encoding)
*/
struct FType
{
char *name;
int dt; /* compatible drive type */
int bytes; /* bytes/sector */
int sectors; /* sectors/track */
int heads; /* number of heads */
int steps; /* steps per cylinder */
int tracks; /* tracks/disk */
int gpl; /* intersector gap length for read/write */
int fgpl; /* intersector gap length for format */
int rate; /* rate code */
/*
* these depend on previous entries and are set filled in
* by floppyinit
*/
int bcode; /* coded version of bytes for the controller */
long cap; /* drive capacity in bytes */
long tsize; /* track size in bytes */
};
/* bits in the registers */
enum
{
/* status registers a & b */
Psra= 0x3f0,
Psrb= 0x3f1,
/* digital output register */
Pdor= 0x3f2,
Fintena= 0x8, /* enable floppy interrupt */
Fena= 0x4, /* 0 == reset controller */
/* main status register */
Pmsr= 0x3f4,
Fready= 0x80, /* ready to be touched */
Ffrom= 0x40, /* data from controller */
Ffloppybusy= 0x10, /* operation not over */
/* data register */
Pfdata= 0x3f5,
Frecal= 0x07, /* recalibrate cmd */
Fseek= 0x0f, /* seek cmd */
Fsense= 0x08, /* sense cmd */
Fread= 0x66, /* read cmd */
Freadid= 0x4a, /* read track id */
Fspec= 0x03, /* set hold times */
Fwrite= 0x45, /* write cmd */
Fformat= 0x4d, /* format cmd */
Fmulti= 0x80, /* or'd with Fread or Fwrite for multi-head */
Fdumpreg= 0x0e, /* dump internal registers */
/* digital input register */
Pdir= 0x3F7, /* disk changed port (read only) */
Pdsr= 0x3F7, /* data rate select port (write only) */
Fchange= 0x80, /* disk has changed */
/* status 0 byte */
Drivemask= 3<<0,
Seekend= 1<<5,
Codemask= (3<<6)|(3<<3),
Cmdexec= 1<<6,
/* status 1 byte */
Overrun= 0x10,
};
static void
pcfloppyintr(Ureg *ur, void *a)
{
USED(a);
floppyintr(ur);
}
void
floppysetup0(FController *fl)
{
fl->ndrive = 0;
if(ioalloc(Psra, 6, 0, "floppy") < 0)
return;
if(ioalloc(Pdir, 1, 0, "floppy") < 0){
iofree(Psra);
return;
}
fl->ndrive = 1;
}
void
floppysetup1(FController *fl)
{
if(fl->ndrive > 0){
fl->d[0].dt = 4;
floppysetdef(&fl->d[0]);
}
if(fl->ndrive > 1){
fl->d[1].dt = 4;
floppysetdef(&fl->d[1]);
}
intrenable(IrqFLOPPY, pcfloppyintr, fl, BUSUNKNOWN, "floppy");
}
/*
* eject disk
*/
void
floppyeject(FDrive *dp)
{
floppyon(dp);
dp->vers++;
floppyoff(dp);
}
int
floppyexec(char *a, long b, int c)
{
USED(a, b, c);
return b;
}

View file

@ -1,128 +0,0 @@
#include "../port/portfns.h"
Dirtab* addarchfile(char*, int, long(*)(Chan*,void*,long,vlong), long(*)(Chan*,void*,long,vlong));
void archinit(void);
void arginit(void);
void arith(void);
ulong cankaddr(ulong);
void clock(Ureg*);
void clockinit(void);
void clockintrsched(void);
#define coherence mb
int cistrcmp(char*, char*);
int cistrncmp(char*, char*, int);
int cmpswap(long*, long, long);
void cpuidprint(void);
void cserve(ulong, ulong);
#define cycles(x) do{}while(0)
void timeradd(Timer *);
void timerdel(Timer *);
int dmacount(int);
int dmadone(int);
void dmaend(int);
int dmainit(int, int);
long dmasetup(int, void*, long, int);
void _dumpstack(Ureg *);
void evenaddr(ulong);
void fataltrap(Ureg *, char *);
void fault0(void);
void faultalpha(Ureg*);
ulong fcr31(void);
void firmware(void);
void fpenab(int);
void fptrap(Ureg*);
int getcfields(char*, char**, int, char*);
char *getconf(char*);
int havetimer(void);
int i8042auxcmd(int);
void i8042auxenable(void (*)(int, int));
void i8042reset(void);
void i8250console(void);
void i8250mouse(char*, int(*)(Queue*,int), int);
void i8250setmouseputc(char*, int (*)(Queue*, int));
void i8259init(void);
int i8259enable(int, int, Vctl*);
#define idlehands() /* nothing to do in the runproc */
void icflush(void);
void illegal0(void);
void intr0(void);
void intrenable(int, void (*)(Ureg*, void*), void*, int, char*);
int intrdisable(int, void (*)(Ureg *, void *), void*, int, char*);
int ioalloc(int, int, int, char*);
void iofree(int);
void ioinit(void);
int iounused(int, int);
int irqallocread(char*, long, vlong);
int isaconfig(char*, int, ISAConf*);
#define kexit(a)
#define kmapinval()
void *kmapv(uvlong, int);
int kprint(char*, ...);
void links(void);
void mb(void);
void memholes(void);
ulong meminit(void);
void mmudump(void);
void mmuinit(void);
void mmupark(void);
#define mtrr(a, b, c)
ulong pcibarsize(Pcidev*, int);
int pcicfgr8(Pcidev*, int);
int pcicfgr16(Pcidev*, int);
int pcicfgr32(Pcidev*, int);
void pcicfgw8(Pcidev*, int, int);
void pcicfgw16(Pcidev*, int, int);
void pcicfgw32(Pcidev*, int, int);
void pciclrbme(Pcidev*);
void pcihinv(Pcidev*);
Pcidev* pcimatch(Pcidev*, int, int);
Pcidev* pcimatchtbdf(int);
void pcireset(void);
void pcisetbme(Pcidev*);
int pcmspecial(char*, ISAConf*);
int (*_pcmspecial)(char *, ISAConf *);
void pcmspecialclose(int);
void (*_pcmspecialclose)(int);
void prflush(void);
void printinit(void);
#define procrestore(p)
void procsave(Proc*);
void procsetup(Proc*);
void procfork(Proc*);
void restfpregs(FPsave*);
uvlong rpcc(uvlong*);
void screeninit(void);
void (*screenputs)(char*, int);
void setpcb(PCB *);
PCB *swpctx(PCB *);
void syscall0(void);
int tas(ulong*);
void tlbflush(int, ulong);
void touser(void*);
void trapinit(void);
void unaligned(void);
ulong upaalloc(int, int);
void upafree(ulong, int);
#define userureg(ur) ((ur)->status & UMODE)
void* vmap(ulong, int);
void wrent(int, void*);
void wrvptptr(uvlong);
void vunmap(void*, int);
#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
#define KADDR(a) ((void*)((ulong)(a)|KZERO))
#define PADDR(a) ((ulong)(a)&~KZERO)
#define inb(p) (arch->_inb)(p)
#define ins(p) (arch->_ins)(p)
#define inl(p) (arch->_inl)(p)
#define outb(p, x) (arch->_outb)((p), (x))
#define outs(p, x) (arch->_outs)((p), (x))
#define outl(p, x) (arch->_outl)((p), (x))
#define insb(p, buf, len) (arch->_insb)((p), (buf), (len))
#define inss(p, buf, len) (arch->_inss)((p), (buf), (len))
#define insl(p, buf, len) (arch->_insl)((p), (buf), (len))
#define outsb(p, buf, len) (arch->_outsb)((p), (buf), (len))
#define outss(p, buf, len) (arch->_outss)((p), (buf), (len))
#define outsl(p, buf, len) (arch->_outsl)((p), (buf), (len))

View file

@ -1,46 +0,0 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "ureg.h"
#include "io.h"
#include "../port/error.h"
char *fpcause[] =
{
"invalid operation",
"division by zero",
"overflow",
"underflow",
"inexact operation",
"integer overflow",
};
char *fpexcname(Ureg*, ulong, char*);
void
fptrap(Ureg *ur)
{
char buf[ERRMAX];
int i;
ulong reason;
ur->pc &= ~2;
reason = (ulong)ur->a0;
for (i = 1; i < 6; i++)
if (reason & (1<<i)) {
sprint(buf, "fp: %s", fpcause[i-1]);
goto found;
}
sprint(buf, "fp: code 0x%lux", reason);
found:
fataltrap(ur, buf);
}
char*
fpexcname(Ureg *ur, ulong fcr31, char *buf)
{
USED(ur, fcr31, buf);
return buf;
}

View file

@ -1,152 +0,0 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
/*
* 8259 interrupt controllers
*/
enum
{
Int0ctl= 0x20, /* control port (ICW1, OCW2, OCW3) */
Int0aux= 0x21, /* everything else (ICW2, ICW3, ICW4, OCW1) */
Int1ctl= 0xA0, /* control port */
Int1aux= 0xA1, /* everything else (ICW2, ICW3, ICW4, OCW1) */
Icw1= 0x10, /* select bit in ctl register */
Ocw2= 0x00,
Ocw3= 0x08,
EOI= 0x20, /* non-specific end of interrupt */
Elcr1= 0x4D0, /* Edge/Level Triggered Register */
Elcr2= 0x4D1,
};
static int int0mask; /* interrupts enabled for first 8259 */
static int int1mask; /* interrupts enabled for second 8259 */
int elcr; /* mask of level-triggered interrupts */
void
i8259init(void)
{
int /*elcr1, */ x;
ioalloc(Int0ctl, 2, 0, "i8259.0");
ioalloc(Int1ctl, 2, 0, "i8259.1");
int0mask = 0xFF;
int1mask = 0xFF;
/*
* Set up the first 8259 interrupt processor.
* Make 8259 interrupts start at CPU vector Int0vec.
* Set the 8259 as master with edge triggered
* input with fully nested interrupts.
*/
outb(Int0ctl, (1<<4)|(0<<3)|(1<<0)); /* ICW1 - master, edge triggered,
ICW4 will be sent */
outb(Int0aux, VectorPIC); /* ICW2 - interrupt vector offset */
outb(Int0aux, 0x04); /* ICW3 - have slave on level 2 */
outb(Int0aux, 0x01); /* ICW4 - 8086 mode, not buffered */
/*
* Set up the second 8259 interrupt processor.
* Make 8259 interrupts start at CPU vector VectorPIC+8.
* Set the 8259 as slave with edge triggered
* input with fully nested interrupts.
*/
outb(Int1ctl, (1<<4)|(0<<3)|(1<<0)); /* ICW1 - master, edge triggered,
ICW4 will be sent */
outb(Int1aux, VectorPIC+8); /* ICW2 - interrupt vector offset */
outb(Int1aux, 0x02); /* ICW3 - I am a slave on level 2 */
outb(Int1aux, 0x01); /* ICW4 - 8086 mode, not buffered */
outb(Int1aux, int1mask);
/*
* pass #2 8259 interrupts to #1
*/
int0mask &= ~0x04;
outb(Int0aux, int0mask);
/*
* Set Ocw3 to return the ISR when ctl read.
* After initialisation status read is set to IRR.
* Read IRR first to possibly deassert an outstanding
* interrupt.
*/
x = inb(Int0ctl); USED(x);
outb(Int0ctl, Ocw3|0x03);
x = inb(Int1ctl); USED(x);
outb(Int1ctl, Ocw3|0x03);
/*
* Check for Edge/Level register.
* This check may not work for all chipsets.
*/
/* elcr1 = inb(Elcr1);
outb(Elcr1, 0);
if(inb(Elcr1) == 0){
outb(Elcr1, 0x20);
if(inb(Elcr1) == 0x20)
elcr = (inb(Elcr2)<<8)|elcr1;
}
outb(Elcr1, elcr1);
if(elcr)
iprint("ELCR: %4.4uX\n", elcr);
/**/
}
int
i8259isr(int v)
{
int isr;
/*
* tell the 8259 that we're done with the
* highest level interrupt (interrupts are still
* off at this point)
*/
isr = 0;
if(v >= VectorPIC && v <= MaxVectorPIC){
isr = inb(Int0ctl);
outb(Int0ctl, EOI);
if(v >= VectorPIC+8){
isr |= inb(Int1ctl)<<8;
outb(Int1ctl, EOI);
}
}
return isr & (1<<(v-VectorPIC));
}
int
i8259enable(int v, int, Vctl* vctl)
{
if(v > MaxIrqPIC){
print("i8259enable: vector %d out of range\n", v);
return -1;
}
/*
* enable corresponding interrupt in 8259
*/
if(v < 8){
int0mask &= ~(1<<v);
outb(Int0aux, int0mask);
}
else{
int1mask &= ~(1<<(v-8));
outb(Int1aux, int1mask);
}
if(elcr & (1<<v))
vctl->eoi = i8259isr;
else
vctl->isr = i8259isr;
vctl->isintr = 1;
return v;
}

View file

@ -1,47 +0,0 @@
#include "/sys/src/libc/9syscall/sys.h"
/*
* we pass in the argument of the exec parameters as 0(FP)
*/
TEXT main(SB),$16
MOVQ $setSB(SB), R29
MOVQ $boot(SB), R0
ADDQ $24, R30, R1 /* get a pointer to 0(FP) */
MOVL R0, 8(R30)
MOVL R1, 12(R30)
JSR exec(SB)
MOVQ $(1<<4), R0
MOVL R0, 8(R30)
MOVQ $RFORK, R0
CALL_PAL $0x83
MOVQ $RFORK, R0
CALL_PAL $0x83
MOVQ $RFORK, R0
CALL_PAL $0x83
again:
ADDL $1, R1
MOVQ $0, R0 /* print r1 */
CALL_PAL $0x83
MOVQ $100000000, R2
foo:
SUBQ $1, R2
BNE R2, foo
MOVQ $1000, R0
MOVL R0, 8(R30)
MOVQ $SLEEP, R0
CALL_PAL $0x83
JMP again
TEXT exec(SB), $0
MOVQ $EXEC, R0
CALL_PAL $0x83
RET
DATA boot+0(SB)/5,$"/boot"
DATA boot+5(SB)/5,$"/boot"
DATA bootv+0(SB)/4,$boot+6(SB)
GLOBL boot+0(SB),$11
GLOBL bootv+0(SB),$8

View file

@ -1,176 +0,0 @@
enum {
IrqCLOCK = 0,
IrqKBD = 1,
IrqUART1 = 3,
IrqUART0 = 4,
IrqPCMCIA = 5,
IrqFLOPPY = 6,
IrqLPT = 7,
IrqIRQ7 = 7,
IrqAUX = 12, /* PS/2 port */
IrqIRQ13 = 13, /* coprocessor on 386 */
IrqATA0 = 14,
IrqATA1 = 15,
MaxIrqPIC = 15,
VectorPIC = 64,
MaxVectorPIC = VectorPIC+MaxIrqPIC,
VectorPCI = 16, /* PCI bus (PLD) */
};
typedef struct Vctl {
Vctl* next; /* handlers on this vector */
char name[KNAMELEN]; /* of driver */
int isintr; /* interrupt or fault/trap */
int irq;
int tbdf;
int (*isr)(int); /* get isr bit for this irq */
int (*eoi)(int); /* eoi */
void (*f)(Ureg*, void*); /* handler to call */
void* a; /* argument to call it with */
} Vctl;
enum {
BusCBUS = 0, /* Corollary CBUS */
BusCBUSII, /* Corollary CBUS II */
BusEISA, /* Extended ISA */
BusFUTURE, /* IEEE Futurebus */
BusINTERN, /* Internal bus */
BusISA, /* Industry Standard Architecture */
BusMBI, /* Multibus I */
BusMBII, /* Multibus II */
BusMCA, /* Micro Channel Architecture */
BusMPI, /* MPI */
BusMPSA, /* MPSA */
BusNUBUS, /* Apple Macintosh NuBus */
BusPCI, /* Peripheral Component Interconnect */
BusPCMCIA, /* PC Memory Card International Association */
BusTC, /* DEC TurboChannel */
BusVL, /* VESA Local bus */
BusVME, /* VMEbus */
BusXPRESS, /* Express System Bus */
};
#define MKBUS(t,b,d,f) (((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8))
#define BUSFNO(tbdf) (((tbdf)>>8)&0x07)
#define BUSDNO(tbdf) (((tbdf)>>11)&0x1F)
#define BUSBNO(tbdf) (((tbdf)>>16)&0xFF)
#define BUSTYPE(tbdf) ((tbdf)>>24)
#define BUSDF(tbdf) ((tbdf)&0x000FF00)
#define BUSBDF(tbdf) ((tbdf)&0x0FFFF00)
#define BUSUNKNOWN (-1)
enum {
MaxEISA = 16,
EISAconfig = 0xC80,
};
/*
* PCI support code.
*/
enum { /* type 0 and type 1 pre-defined header */
PciVID = 0x00, /* vendor ID */
PciDID = 0x02, /* device ID */
PciPCR = 0x04, /* command */
PciPSR = 0x06, /* status */
PciRID = 0x08, /* revision ID */
PciCCRp = 0x09, /* programming interface class code */
PciCCRu = 0x0A, /* sub-class code */
PciCCRb = 0x0B, /* base class code */
PciCLS = 0x0C, /* cache line size */
PciLTR = 0x0D, /* latency timer */
PciHDT = 0x0E, /* header type */
PciBST = 0x0F, /* BIST */
PciBAR0 = 0x10, /* base address */
PciBAR1 = 0x14,
PciROM = 0x30,
PciINTL = 0x3C, /* interrupt line */
PciINTP = 0x3D, /* interrupt pin */
};
enum { /* type 0 pre-defined header */
PciCIS = 0x28, /* cardbus CIS pointer */
PciSVID = 0x2C, /* subsystem vendor ID */
PciSID = 0x2E, /* subsystem ID */
PciEBAR0 = 0x30, /* xpansion ROM base address */
PciMGNT = 0x3E, /* burst period length */
PciMLT = 0x3F, /* maximum latency between bursts */
};
enum { /* type 1 pre-defined header */
PciPBN = 0x18, /* primary bus number */
PciSBN = 0x19, /* secondary bus number */
PciUBN = 0x1A, /* subordinate bus number */
PciSLTR = 0x1B, /* secondary latency timer */
PciIBR = 0x1C, /* I/O base */
PciILR = 0x1D, /* I/O limit */
PciSPSR = 0x1E, /* secondary status */
PciMBR = 0x20, /* memory base */
PciMLR = 0x22, /* memory limit */
PciPMBR = 0x24, /* prefetchable memory base */
PciPMLR = 0x26, /* prefetchable memory limit */
PciPUBR = 0x28, /* prefetchable base upper 32 bits */
PciPULR = 0x2C, /* prefetchable limit upper 32 bits */
PciIUBR = 0x30, /* I/O base upper 16 bits */
PciIULR = 0x32, /* I/O limit upper 16 bits */
PciEBAR1 = 0x28, /* expansion ROM base address */
PciBCR = 0x3E, /* bridge control register */
};
typedef struct Pcidev Pcidev;
typedef struct Pcidev {
int tbdf; /* type+bus+device+function */
ushort vid; /* vendor ID */
ushort did; /* device ID */
ushort pcr;
uchar rid;
uchar ccrp;
uchar ccru;
uchar ccrb;
uchar cls;
uchar ltr;
struct {
ulong bar; /* base address */
int size;
} mem[6];
uchar intl; /* interrupt line */
Pcidev* list;
Pcidev* link; /* next device on this bno */
Pcidev* bridge; /* down a bus */
struct {
ulong bar;
int size;
} ioa, mema;
int pmrb; /* power management register block */
};
#define PCIWINDOW 0x40000000
#define PCIWADDR(va) (PADDR(va)+PCIWINDOW)
#define ISAWINDOW 0x00800000
#define ISAWADDR(va) (PADDR(va)+ISAWINDOW)
/*
* PCMCIA support code.
*/
/*
* Map between ISA memory space and PCMCIA card memory space.
*/
struct PCMmap {
ulong ca; /* card address */
ulong cea; /* card end address */
ulong isa; /* ISA address */
int len; /* length of the ISA area */
int attr; /* attribute memory */
int ref;
};

View file

@ -1,438 +0,0 @@
#include "mem.h"
#include "osf1pal.h"
#define SP R30
#define HI_IPL 6 /* use 7 to disable mchecks */
TEXT _main(SB), $-8
MOVQ $setSB(SB), R29
MOVQ R29, R16
CALL_PAL $PALwrkgp
MOVQ $mach0(SB), R(MACH)
MOVQ $(BY2PG-8)(R(MACH)), R30
MOVQ R31, R(USER)
MOVQ R31, 0(R(MACH))
MOVQ $edata(SB), R1
MOVQ $end(SB), R2
clrbss:
MOVQ R31, (R1)
ADDQ $8, R1
CMPUGT R1, R2, R3
BEQ R3, clrbss
MOVL R0, bootconf(SB) /* passed in from boot loader */
_fpinit:
MOVQ $1, R16
CALL_PAL $PALwrfen
MOVQ initfpcr(SB), R1 /* MOVQ $0x2800800000000000, R1 */
MOVQ R1, (R30)
MOVT (R30), F1
MOVT F1, FPCR
MOVT $0.5, F28
ADDT F28, F28, F29
ADDT F29, F29, F30
MOVT F31, F1
MOVT F31, F2
MOVT F31, F3
MOVT F31, F4
MOVT F31, F5
MOVT F31, F6
MOVT F31, F7
MOVT F31, F8
MOVT F31, F9
MOVT F31, F10
MOVT F31, F11
MOVT F31, F12
MOVT F31, F13
MOVT F31, F14
MOVT F31, F15
MOVT F31, F16
MOVT F31, F17
MOVT F31, F18
MOVT F31, F19
MOVT F31, F20
MOVT F31, F21
MOVT F31, F22
MOVT F31, F23
MOVT F31, F24
MOVT F31, F25
MOVT F31, F26
MOVT F31, F27
JSR main(SB)
MOVQ $_divq(SB), R31 /* touch _divq etc.; doesn't need to execute */
MOVQ $_divl(SB), R31 /* touch _divl etc.; doesn't need to execute */
RET
TEXT setpcb(SB), $-8
MOVQ R30, (R0)
AND $0x7FFFFFFF, R0, R16 /* make address physical */
CALL_PAL $PALswpctx
RET
GLOBL mach0(SB), $(MAXMACH*BY2PG)
GLOBL init_ptbr(SB), $8
TEXT firmware(SB), $-8
CALL_PAL $PALhalt
TEXT xxfirmware(SB), $-8
CALL_PAL $PALhalt
TEXT splhi(SB), $0
MOVL R26, 4(R(MACH)) /* save PC in m->splpc */
MOVQ $HI_IPL, R16
CALL_PAL $PALswpipl
RET
TEXT spllo(SB), $0
MOVQ R31, R16
CALL_PAL $PALswpipl
RET
TEXT splx(SB), $0
MOVL R26, 4(R(MACH)) /* save PC in m->splpc */
TEXT splxpc(SB), $0 /* for iunlock */
MOVQ R0, R16
CALL_PAL $PALswpipl
RET
TEXT spldone(SB), $0
RET
TEXT islo(SB), $0
CALL_PAL $PALrdps
AND $IPL, R0
XOR $HI_IPL, R0
RET
TEXT mb(SB), $-8
MB
RET
TEXT icflush(SB), $-8
CALL_PAL $PALimb
RET
TEXT tlbflush(SB), $-8
MOVQ R0, R16
MOVL 4(FP), R17
CALL_PAL $PALtbi
RET
TEXT swpctx(SB), $-8
MOVQ R0, R16
AND $0x7FFFFFFF, R16 /* make address physical */
CALL_PAL $PALswpctx
RET
TEXT wrent(SB), $-8
MOVQ R0, R17
MOVL 4(FP), R16
CALL_PAL $PALwrent
RET
TEXT wrvptptr(SB), $-8
MOVQ R0, R16
CALL_PAL $PALwrvptptr
RET
TEXT cserve(SB), $-8
MOVQ R0, R16
MOVL 4(FP), R17
CALL_PAL $PALcserve
RET
TEXT setlabel(SB), $-8
MOVL R30, 0(R0)
MOVL R26, 4(R0)
MOVQ $0, R0
RET
TEXT gotolabel(SB), $-8
MOVL 0(R0), R30
MOVL 4(R0), R26
MOVQ $1, R0
RET
TEXT tas(SB), $-8
MOVQ R0, R1 /* l */
tas1:
MOVLL (R1), R0 /* l->key */
BNE R0, tas2
MOVQ $1, R2
MOVLC R2, (R1) /* l->key = 1 */
BEQ R2, tas1 /* write failed, try again? */
tas2:
RET
TEXT cmpswap(SB), $-8
MOVQ R0, R1 /* p */
MOVL old+4(FP), R2
MOVL new+8(FP), R3
MOVLL (R1), R0
CMPEQ R0, R2, R4
BEQ R4, fail /* if R0 != [sic] R2, goto fail */
MOVQ R3, R0
MOVLC R0, (R1)
RET
fail:
MOVL $0, R0
RET
TEXT fpenab(SB), $-8
MOVQ R0, R16
CALL_PAL $PALwrfen
RET
TEXT rpcc(SB), $0
MOVL R0, R1
MOVL $0, R0
WORD $0x6000C000 /* RPCC R0 */
BEQ R1, _ret
MOVQ R0, (R1)
_ret:
RET
/*
* Exception handlers. The stack frame looks like this:
*
* R30+0: (unused) link reg storage (R26) (32 bits)
* R30+4: padding for alignment (32 bits)
* R30+8: trap()'s first arg storage (R0) (32 bits -- type Ureg*)
* R30+12: padding for alignment (32 bits)
* R30+16: first 31 fields of Ureg, saved here (31*64 bits)
* R30+264: other 6 fields of Ureg, saved by PALcode (6*64 bits)
* R30+312: previous value of KSP before trap
*/
TEXT arith(SB), $-8
SUBQ $(4*BY2WD+31*BY2V), R30
MOVQ R0, (4*BY2WD+4*BY2V)(R30)
MOVQ $1, R0
JMP trapcommon
TEXT illegal0(SB), $-8
SUBQ $(4*BY2WD+31*BY2V), R30
MOVQ R0, (4*BY2WD+4*BY2V)(R30)
MOVQ $2, R0
JMP trapcommon
TEXT fault0(SB), $-8
SUBQ $(4*BY2WD+31*BY2V), R30
MOVQ R0, (4*BY2WD+4*BY2V)(R30)
MOVQ $4, R0
JMP trapcommon
TEXT unaligned(SB), $-8
SUBQ $(4*BY2WD+31*BY2V), R30
MOVQ R0, (4*BY2WD+4*BY2V)(R30)
MOVQ $6, R0
JMP trapcommon
TEXT intr0(SB), $-8
SUBQ $(4*BY2WD+31*BY2V), R30
MOVQ R0, (4*BY2WD+4*BY2V)(R30)
MOVQ $3, R0
trapcommon:
MOVQ R0, (4*BY2WD+0*BY2V)(R30)
MOVQ R16, (4*BY2WD+1*BY2V)(R30)
MOVQ R17, (4*BY2WD+2*BY2V)(R30)
MOVQ R18, (4*BY2WD+3*BY2V)(R30)
/* R0 already saved, (4*BY2WD+4*BY2V)(R30) */
MOVQ R1, (4*BY2WD+5*BY2V)(R30)
MOVQ R2, (4*BY2WD+6*BY2V)(R30)
MOVQ R3, (4*BY2WD+7*BY2V)(R30)
MOVQ R4, (4*BY2WD+8*BY2V)(R30)
MOVQ R5, (4*BY2WD+9*BY2V)(R30)
MOVQ R6, (4*BY2WD+10*BY2V)(R30)
MOVQ R7, (4*BY2WD+11*BY2V)(R30)
MOVQ R8, (4*BY2WD+12*BY2V)(R30)
MOVQ R9, (4*BY2WD+13*BY2V)(R30)
MOVQ R10, (4*BY2WD+14*BY2V)(R30)
MOVQ R11, (4*BY2WD+15*BY2V)(R30)
MOVQ R12, (4*BY2WD+16*BY2V)(R30)
MOVQ R13, (4*BY2WD+17*BY2V)(R30)
MOVQ R14, (4*BY2WD+18*BY2V)(R30)
MOVQ R15, (4*BY2WD+19*BY2V)(R30)
MOVQ R19, (4*BY2WD+20*BY2V)(R30)
MOVQ R20, (4*BY2WD+21*BY2V)(R30)
MOVQ R21, (4*BY2WD+22*BY2V)(R30)
MOVQ R22, (4*BY2WD+23*BY2V)(R30)
MOVQ R23, (4*BY2WD+24*BY2V)(R30)
MOVQ R24, (4*BY2WD+25*BY2V)(R30)
MOVQ R25, (4*BY2WD+26*BY2V)(R30)
MOVQ R26, (4*BY2WD+27*BY2V)(R30)
MOVQ R27, (4*BY2WD+28*BY2V)(R30)
MOVQ R28, (4*BY2WD+29*BY2V)(R30)
MOVQ $HI_IPL, R16
CALL_PAL $PALswpipl
CALL_PAL $PALrdusp
MOVQ R0, (4*BY2WD+30*BY2V)(R30) /* save USP */
MOVQ $mach0(SB), R(MACH)
MOVQ $(4*BY2WD)(R30), R0
JSR trap(SB)
trapret:
MOVQ (4*BY2WD+30*BY2V)(R30), R16 /* USP */
CALL_PAL $PALwrusp /* ... */
MOVQ (4*BY2WD+4*BY2V)(R30), R0
MOVQ (4*BY2WD+5*BY2V)(R30), R1
MOVQ (4*BY2WD+6*BY2V)(R30), R2
MOVQ (4*BY2WD+7*BY2V)(R30), R3
MOVQ (4*BY2WD+8*BY2V)(R30), R4
MOVQ (4*BY2WD+9*BY2V)(R30), R5
MOVQ (4*BY2WD+10*BY2V)(R30), R6
MOVQ (4*BY2WD+11*BY2V)(R30), R7
MOVQ (4*BY2WD+12*BY2V)(R30), R8
MOVQ (4*BY2WD+13*BY2V)(R30), R9
MOVQ (4*BY2WD+14*BY2V)(R30), R10
MOVQ (4*BY2WD+15*BY2V)(R30), R11
MOVQ (4*BY2WD+16*BY2V)(R30), R12
MOVQ (4*BY2WD+17*BY2V)(R30), R13
MOVQ (4*BY2WD+18*BY2V)(R30), R14
MOVQ (4*BY2WD+19*BY2V)(R30), R15
MOVQ (4*BY2WD+20*BY2V)(R30), R19
MOVQ (4*BY2WD+21*BY2V)(R30), R20
MOVQ (4*BY2WD+22*BY2V)(R30), R21
MOVQ (4*BY2WD+23*BY2V)(R30), R22
MOVQ (4*BY2WD+24*BY2V)(R30), R23
MOVQ (4*BY2WD+25*BY2V)(R30), R24
MOVQ (4*BY2WD+26*BY2V)(R30), R25
MOVQ (4*BY2WD+27*BY2V)(R30), R26
MOVQ (4*BY2WD+28*BY2V)(R30), R27
MOVQ (4*BY2WD+29*BY2V)(R30), R28
/* USP already restored from (4*BY2WD+30*BY2V)(R30) */
ADDQ $(4*BY2WD+31*BY2V), R30
CALL_PAL $PALrti
TEXT forkret(SB), $0
MOVQ R31, R0 /* Fake out system call return */
JMP systrapret
TEXT syscall0(SB), $-8
SUBQ $(4*BY2WD+31*BY2V), R30
MOVQ R0, (4*BY2WD+4*BY2V)(R30) /* save scallnr in R0 */
MOVQ $HI_IPL, R16
CALL_PAL $PALswpipl
MOVQ $mach0(SB), R(MACH)
CALL_PAL $PALrdusp
MOVQ R0, (4*BY2WD+30*BY2V)(R30) /* save USP */
MOVQ R26, (4*BY2WD+27*BY2V)(R30) /* save last return address */
MOVQ $(4*BY2WD)(R30), R0 /* pass address of Ureg */
JSR syscall(SB)
systrapret:
MOVQ (4*BY2WD+30*BY2V)(R30), R16 /* USP */
CALL_PAL $PALwrusp /* consider doing this in execregs... */
MOVQ (4*BY2WD+27*BY2V)(R30), R26 /* restore last return address */
ADDQ $(4*BY2WD+31*BY2V), R30
CALL_PAL $PALretsys
/*
* Take first processor into user mode
* - argument is stack pointer to user
*/
TEXT touser(SB), $-8
MOVQ R0, R16
CALL_PAL $PALwrusp /* set USP to value passed */
SUBQ $(6*BY2V), R30 /* create frame for retsys */
MOVQ $(UTZERO+32), R26 /* header appears in text */
MOVQ R26, (1*BY2V)(R30) /* PC -- only reg that matters */
CALL_PAL $PALretsys
TEXT rfnote(SB), $0
SUBL $(2*BY2WD), R0, SP
JMP trapret
TEXT savefpregs(SB), $-8
MOVT F0, 0x00(R0)
MOVT F1, 0x08(R0)
MOVT F2, 0x10(R0)
MOVT F3, 0x18(R0)
MOVT F4, 0x20(R0)
MOVT F5, 0x28(R0)
MOVT F6, 0x30(R0)
MOVT F7, 0x38(R0)
MOVT F8, 0x40(R0)
MOVT F9, 0x48(R0)
MOVT F10, 0x50(R0)
MOVT F11, 0x58(R0)
MOVT F12, 0x60(R0)
MOVT F13, 0x68(R0)
MOVT F14, 0x70(R0)
MOVT F15, 0x78(R0)
MOVT F16, 0x80(R0)
MOVT F17, 0x88(R0)
MOVT F18, 0x90(R0)
MOVT F19, 0x98(R0)
MOVT F20, 0xA0(R0)
MOVT F21, 0xA8(R0)
MOVT F22, 0xB0(R0)
MOVT F23, 0xB8(R0)
MOVT F24, 0xC0(R0)
MOVT F25, 0xC8(R0)
MOVT F26, 0xD0(R0)
MOVT F27, 0xD8(R0)
MOVT F28, 0xE0(R0)
MOVT F29, 0xE8(R0)
MOVT F30, 0xF0(R0)
MOVT F31, 0xF8(R0)
MOVT FPCR, F0
MOVT F0, 0x100(R0)
MOVQ $0, R16
CALL_PAL $PALwrfen /* disable */
RET
TEXT restfpregs(SB), $-8
MOVQ $1, R16
CALL_PAL $PALwrfen /* enable */
MOVT 0x100(R0), F0
MOVT F0, FPCR
MOVT 0x00(R0), F0
MOVT 0x08(R0), F1
MOVT 0x10(R0), F2
MOVT 0x18(R0), F3
MOVT 0x20(R0), F4
MOVT 0x28(R0), F5
MOVT 0x30(R0), F6
MOVT 0x38(R0), F7
MOVT 0x40(R0), F8
MOVT 0x48(R0), F9
MOVT 0x50(R0), F10
MOVT 0x58(R0), F11
MOVT 0x60(R0), F12
MOVT 0x68(R0), F13
MOVT 0x70(R0), F14
MOVT 0x78(R0), F15
MOVT 0x80(R0), F16
MOVT 0x88(R0), F17
MOVT 0x90(R0), F18
MOVT 0x98(R0), F19
MOVT 0xA0(R0), F20
MOVT 0xA8(R0), F21
MOVT 0xB0(R0), F22
MOVT 0xB8(R0), F23
MOVT 0xC0(R0), F24
MOVT 0xC8(R0), F25
MOVT 0xD0(R0), F26
MOVT 0xD8(R0), F27
MOVT 0xE0(R0), F28
MOVT 0xE8(R0), F29
MOVT 0xF0(R0), F30
MOVT 0xF8(R0), F31
RET

View file

@ -1,604 +0,0 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "init.h"
#include "pool.h"
#include "/sys/src/boot/alphapc/conf.h"
#include "axp.h"
char argbuf[128]; /* arguments passed to initcode and /boot */
Hwrpb *hwrpb;
Bootconf *bootconf;
Conf conf;
FPsave initfp;
/* setfcr(FPPDBL|FPRNR|FPINVAL|FPZDIV|FPOVFL) */
uvlong initfpcr = (1LL<62)|(1LL<61)|(1LL<60)|(2LL<<58)|(1LL<48);
char bootargs[BOOTARGSLEN];
char *confname[MAXCONF];
char *confval[MAXCONF];
int nconf;
static void
options(void)
{
long i, n;
char *cp, *line[MAXCONF], *p, *q;
cp = bootargs;
strncpy(cp, bootconf->bootargs, BOOTARGSLEN);
cp[BOOTARGSLEN-1] = 0;
/* can't print in this routine, see below in main() */
/*
* 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 == nil)
continue;
*cp++ = '\0';
confname[nconf] = line[i];
confval[nconf] = cp;
nconf++;
}
}
/* debugging only */
static void
dumpopts(void)
{
int i;
print("dumpopts: found /alpha/conf options at %#p\n",
bootconf->bootargs);
for(i = 0; i < nconf; i++)
print("dumpopts: read %s=%s\n", confname[i], confval[i]);
}
extern void (*i8237alloc)(void);
void
main(void)
{
hwrpb = (Hwrpb*)0x10000000;
hwrpb = (Hwrpb*)(KZERO|hwrpb->phys);
arginit();
machinit();
options();
ioinit();
clockinit();
confinit();
archinit();
xinit();
memholes();
if(i8237alloc != nil)
i8237alloc();
mmuinit();
if(arch->coreinit)
arch->coreinit();
trapinit();
screeninit();
printinit();
/* it's now safe to print */
/* dumpopts(); /* DEBUG */
i8250console();
quotefmtinstall();
print("\nPlan 9\n");
cpuidprint();
if(arch->corehello)
arch->corehello();
procinit0();
initseg();
timersinit();
links();
chandevreset();
pageinit();
swapinit();
savefpregs(&initfp);
initfp.fpstatus = 0x68028000;
userinit();
schedinit();
}
/* cpu->state bits */
enum {
Cpubootinprog = 1, /* boot in progress */
Cpucanrestart = 2, /* restart possible */
Cpuavail = 4, /* processor available */
Cpuexists = 8, /* processor present */
Cpuuserhalted = 0x10, /* user halted */
Cpuctxtokay = 0x20, /* context valid */
Cpupalokay = 0x40, /* PALcode valid */
Cpupalmemokay = 0x80, /* PALcode memory valid */
Cpupalloaded = 0x100, /* PALcode loaded */
Cpuhaltmask = 0xff0000, /* halt request mask */
Cpuhaltdflt = 0,
Cpuhaltsaveexit = 0x10000,
Cpuhaltcoldboot = 0x20000,
Cpuhaltwarmboot = 0x30000,
Cpuhaltstayhalted = 0x40000,
Cpumustbezero = 0xffffffffff000000ULL, /* 24:63 -- must be zero */
};
/*
* initialize a processor's mach structure. each processor does this
* for itself.
*/
void
machinit(void)
{
int n;
Hwcpu *cpu;
icflush();
n = m->machno;
memset(m, 0, sizeof(Mach));
m->machno = n;
active.exiting = 0;
active.machs[0] = 1;
cpu = (Hwcpu*) ((ulong)hwrpb + hwrpb->cpuoff + n*hwrpb->cpulen);
cpu->state &= ~Cpubootinprog;
if (0)
cpu->state |= Cpuhaltstayhalted;
}
void
init0(void)
{
int i;
char buf[2*KNAMELEN];
up->nerrlab = 0;
spllo();
/*
* These are o.k. because rootinit is null.
* Then early kproc's will have a root and dot.
*/
up->slash = namec("#/", Atodir, 0, 0);
pathclose(up->slash->path);
up->slash->path = newpath("/");
up->dot = cclone(up->slash);
chandevinit();
if(!waserror()){
snprint(buf, sizeof(buf), "alpha %s alphapc", conffile);
ksetenv("terminal", buf, 0);
ksetenv("cputype", "alpha", 0);
if(cpuserver)
ksetenv("service", "cpu", 0);
else
ksetenv("service", "terminal", 0);
for(i = 0; i < nconf; i++)
if(confname[i]){
if(confname[i][0] != '*')
ksetenv(confname[i], confval[i], 0);
ksetenv(confname[i], confval[i], 1);
}
poperror();
}
kproc("alarm", alarmkproc, 0);
touser((uchar*)(USTKTOP - sizeof(argbuf)));
}
void
userinit(void)
{
Proc *p;
Segment *s;
KMap *k;
char **av;
Page *pg;
p = newproc();
p->pgrp = newpgrp();
p->egrp = smalloc(sizeof(Egrp));
p->egrp->ref = 1;
p->fgrp = dupfgrp(nil);
p->rgrp = newrgrp();
p->procmode = 0640;
kstrdup(&eve, "");
kstrdup(&p->text, "*init*");
kstrdup(&p->user, eve);
procsetup(p);
/*
* Kernel Stack
*/
p->sched.pc = (ulong)init0;
p->sched.sp = (ulong)p->kstack+KSTACK-MAXSYSARG*BY2WD;
/*
* User Stack, pass input arguments to boot process
*/
s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
p->seg[SSEG] = s;
pg = newpage(1, 0, USTKTOP-BY2PG);
segpage(s, pg);
k = kmap(pg);
for(av = (char**)argbuf; *av; av++)
*av += (USTKTOP - sizeof(argbuf)) - (ulong)argbuf;
memmove((uchar*)VA(k) + BY2PG - sizeof(argbuf), argbuf, sizeof argbuf);
kunmap(k);
/*
* Text
*/
s = newseg(SG_TEXT, UTZERO, 1);
s->flushme++;
p->seg[TSEG] = s;
pg = newpage(1, 0, UTZERO);
pg->txtflush = ~0;
segpage(s, pg);
k = kmap(s->map[0]->pages[0]);
memmove((uchar*)VA(k), initcode, sizeof initcode);
kunmap(k);
ready(p);
}
void
procsetup(Proc *p)
{
p->fpstate = FPinit;
fpenab(0);
}
void
procfork(Proc *)
{
}
void
procsave(Proc *p)
{
if(p->fpstate == FPactive){
if(p->state == Moribund)
fpenab(0);
else
savefpregs(&up->fpsave);
p->fpstate = FPinactive;
}
/*
* Switch to the prototype page tables for this processor.
* While this processor is in the scheduler, the process could run
* on another processor and exit, returning the page tables to
* the free list where they could be reallocated and overwritten.
* When this processor eventually has to get an entry from the
* trashed page tables it will crash.
*/
mmupark();
}
void
setupboot(int halt)
{
int n = 0; // cpu id of primary cpu, not just m->machno
Hwcpu *cpu = (Hwcpu*)((ulong)hwrpb + hwrpb->cpuoff + n*hwrpb->cpulen);
cpu->state &= ~(Cpucanrestart | Cpuhaltmask);
cpu->state |= (halt? Cpuhaltstayhalted: Cpuhaltwarmboot);
}
void
reboot(void *, void *, ulong)
{
}
void
exit(int)
{
cpushutdown();
splhi();
if(arch->coredetach)
arch->coredetach();
setupboot(1); // set up to halt
for (;;)
firmware();
}
void
confinit(void)
{
ulong ktop, kpages;
Bank *b, *eb;
extern void _main(void);
int userpcnt;
char *p;
if(p = getconf("*kernelpercent"))
userpcnt = 100 - strtol(p, 0, 0);
else
userpcnt = 0;
/*
* The console firmware divides memory into 1 or more banks.
* FInd the bank with the kernel in it.
*/
b = bootconf->bank;
eb = b+bootconf->nbank;
ktop = PGROUND((ulong)end);
ktop = PADDR(ktop);
while(b < eb) {
if(b->min < ktop && ktop < b->max)
break;
b++;
}
if(b == eb)
panic("confinit");
/*
* Split the bank of memory into 2 banks to fool the allocator into
* allocating low memory pages from bank 0 for any peripherals
* which only have a 24bit address counter.
*/
conf.mem[0].npage = (8*1024*1024)/BY2PG;
conf.mem[0].base = 0;
conf.mem[1].npage = (b->max-8*1024*1024)/BY2PG;
conf.mem[1].base = 8*1024*1024;
conf.npage = conf.mem[0].npage+conf.mem[1].npage;
conf.upages = (conf.npage*70)/100;
conf.mem[0].npage -= ktop/BY2PG;
conf.mem[0].base += ktop;
conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;
/*
* Fix up the bank we found to be the remnant, below the kernel.
* This, and the other banks, will be passed to xhole() later.
* BUG: conf.upages needs to be adjusted, but how? In practice,
* we only have 1 bank, and the remnant is small.
*/
b->max = (uvlong)_main & ~(BY2PG-1);
conf.nmach = 1;
conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
if(cpuserver)
conf.nproc *= 3;
if(conf.nproc > 2000)
conf.nproc = 2000;
conf.nimage = 200;
conf.nswap = conf.nproc*80;
conf.nswppo = 4096;
conf.copymode = 0; /* copy on write */
if(cpuserver) {
if(userpcnt < 10)
userpcnt = 70;
kpages = conf.npage - (conf.npage*userpcnt)/100;
/*
* Hack for the big boys. Only good while physmem < 4GB.
* Give the kernel a max. of 16MB + enough to allocate the
* page pool.
* This is an overestimate as conf.upages < conf.npages.
* The patch of nimage is a band-aid, scanning the whole
* page list in imagereclaim just takes too long.
*/
if(kpages > (16*MB + conf.npage*sizeof(Page))/BY2PG){
kpages = (16*MB + conf.npage*sizeof(Page))/BY2PG;
conf.nimage = 2000;
kpages += (conf.nproc*KSTACK)/BY2PG;
}
} else {
if(userpcnt < 10) {
if(conf.npage*BY2PG < 16*MB)
userpcnt = 40;
else
userpcnt = 60;
}
kpages = conf.npage - (conf.npage*userpcnt)/100;
/*
* Make sure terminals with low memory get at least
* 4MB on the first Image chunk allocation.
*/
if(conf.npage*BY2PG < 16*MB)
imagmem->minarena = 4*1024*1024;
}
conf.upages = conf.npage - kpages;
conf.ialloc = (kpages/2)*BY2PG;
/*
* Guess how much is taken by the large permanent
* datastructures. Mntcache and Mntrpc are not accounted for.
*/
kpages *= BY2PG;
kpages -= conf.upages*sizeof(Page)
+ conf.nproc*sizeof(Proc)
+ conf.nimage*sizeof(Image)
+ conf.nswap
+ conf.nswppo*sizeof(Page*);
mainmem->maxsize = kpages;
if(!cpuserver){
/*
* give terminals lots of image memory, too; the dynamic
* allocation will balance the load properly, hopefully.
* be careful with 32-bit overflow.
*/
imagmem->maxsize = kpages;
}
// conf.monitor = 1; /* BUG */
}
void
memholes(void)
{
Bank *b, *eb;
b = bootconf->bank;
eb = b+bootconf->nbank;
while(b < eb) {
if(b->min < (1LL<<32) && b->max < (1LL<<32))
xhole(b->min, b->max-b->min);
b++;
}
}
char *sp;
char *
pusharg(char *p)
{
int n;
n = strlen(p)+1;
sp -= n;
memmove(sp, p, n);
return sp;
}
void
arginit(void)
{
char **av;
av = (char**)argbuf;
sp = argbuf + sizeof(argbuf);
*av++ = pusharg("boot");
*av = 0;
}
char *
getconf(char *name)
{
int n;
for(n = 0; n < nconf; n++)
if(cistrcmp(confname[n], name) == 0) {
return confval[n];
}
return 0;
}
int
isaconfig(char *class, int ctlrno, ISAConf *isa)
{
char cc[32], *p;
int i, n;
snprint(cc, sizeof cc, "%s%d", class, ctlrno);
for(n = 0; n < nconf; n++){
if(cistrcmp(confname[n], cc) != 0)
continue;
isa->nopt = tokenize(confval[n], 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, "dma=", 4) == 0)
isa->dma = 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);
}
return 1;
}
return 0;
}
int
cistrcmp(char *a, char *b)
{
int ac, bc;
for(;;){
ac = *a++;
bc = *b++;
if(ac >= 'A' && ac <= 'Z')
ac = 'a' + (ac - 'A');
if(bc >= 'A' && bc <= 'Z')
bc = 'a' + (bc - 'A');
ac -= bc;
if(ac)
return ac;
if(bc == 0)
break;
}
return 0;
}
int
cistrncmp(char *a, char *b, int n)
{
unsigned ac, bc;
while(n > 0){
ac = *a++;
bc = *b++;
n--;
if(ac >= 'A' && ac <= 'Z')
ac = 'a' + (ac - 'A');
if(bc >= 'A' && bc <= 'Z')
bc = 'a' + (bc - 'A');
ac -= bc;
if(ac)
return ac;
if(bc == 0)
break;
}
return 0;
}
int
getcfields(char* lp, char** fields, int n, char* sep)
{
int i;
for(i = 0; lp && *lp && i < n; i++){
while(*lp && strchr(sep, *lp) != 0)
*lp++ = 0;
if(*lp == 0)
break;
fields[i] = lp;
while(*lp && strchr(sep, *lp) == 0){
if(*lp == '\\' && *(lp+1) == '\n')
*lp++ = ' ';
lp++;
}
}
return i;
}

View file

@ -1,87 +0,0 @@
/*
* 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 vlong */
#define BY2PG 8192 /* bytes per page */
#define WD2PG (BY2PG/BY2WD) /* words per page */
#define PGSHIFT 13 /* log(BY2PG) */
#define ROUND(s, sz) (((s)+((sz)-1))&~((sz)-1))
#define PGROUND(s) ROUND(s, BY2PG)
#define BLOCKALIGN 8
#define BY2PTE 8 /* bytes per pte entry */
#define PTE2PG (BY2PG/BY2PTE) /* pte entries per page */
#define MAXMACH 1 /* max # cpus system can run */
#define KSTACK 4096 /* Size of kernel stack */
/*
* Time
*/
#define HZ 100 /* clock frequency */
#define MS2HZ (1000/HZ)
#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
/*
* Magic registers
*/
#define MACH 15 /* R15 is m-> */
#define USER 14 /* R14 is up-> */
/*
* Fundamental addresses
*/
/* XXX MACHADDR, MACHP(n) */
/*
* MMU
*
* A PTE is 64 bits, but a ulong is 32! Hence we encode
* the PTEs specially for fault.c, and decode them in putmmu().
* This means that we can only map the first 2G of physical
* space via putmmu() - ie only physical memory, not devices.
*/
#define PTEVALID 0x3301
#define PTEKVALID 0x1101
#define PTEASM 0x0010
#define PTEGH(s) ((s)<<5)
#define PTEWRITE 0
#define PTERONLY 0x4
#define PTEUNCACHED 0
#define PPN(n) (((n)>>PGSHIFT)<<14)
#define FIXPTE(x) ((((uvlong)(x)>>14)<<32)|((x) & 0x3fff))
#define PTEPFN(pa) (((uvlong)(pa)>>PGSHIFT)<<32)
#define NCOLOR 1
#define getpgcolor(a) 0
#define PTEMAPMEM (1024*1024)
#define PTEPERTAB (PTEMAPMEM/BY2PG)
#define SEGMAPSIZE 512
#define SSEGMAPSIZE 16
/*
* Address spaces
*/
#define UZERO 0 /* base of user address space */
#define UTZERO (UZERO+BY2PG) /* first address in user text */
#define KZERO 0x80000000 /* base of kernel address space */
#define KTZERO (KZERO+0x400000) /* first address in kernel text */
#define USTKTOP KZERO /* byte just beyond user stack */
#define USTKSIZE (4*1024*1024) /* size of user stack */
/*
* Processor Status (as returned by rdps)
*/
#define UMODE 0x8
#define IPL 0x7
#define isphys(x) (((ulong)x&KZERO)!=0)

View file

@ -1,197 +0,0 @@
#define QUAD 8
#define ALIGN 64
#define BLOCK 64
TEXT memmove(SB), $0
MOVL from+4(FP), R7
MOVL n+8(FP), R10
MOVQ R0, R6
CMPUGE R7, R0, R5
BNE R5, _forward
MOVQ R6, R8 /* end to address */
ADDL R10, R6, R6 /* to+n */
ADDL R10, R7, R7 /* from+n */
CMPUGE $ALIGN, R10, R1 /* need at least ALIGN bytes */
BNE R1, _b1tail
_balign:
AND $(ALIGN-1), R6, R1
BEQ R1, _baligned
MOVBU -1(R7), R2
ADDL $-1, R6, R6
MOVB R2, (R6)
ADDL $-1, R7, R7
JMP _balign
_baligned:
AND $(QUAD-1), R7, R1 /* is the source quad-aligned */
BNE R1, _bunaligned
ADDL $(BLOCK-1), R8, R9
_bblock:
CMPUGE R9, R6, R1
BNE R1, _b8tail
MOVQ -64(R7), R22
MOVQ -56(R7), R23
MOVQ -48(R7), R24
MOVQ -40(R7), R25
MOVQ -32(R7), R2
MOVQ -24(R7), R3
MOVQ -16(R7), R4
MOVQ -8(R7), R5
SUBL $64, R6, R6
SUBL $64, R7, R7
MOVQ R22, (R6)
MOVQ R23, 8(R6)
MOVQ R24, 16(R6)
MOVQ R25, 24(R6)
MOVQ R2, 32(R6)
MOVQ R3, 40(R6)
MOVQ R4, 48(R6)
MOVQ R5, 56(R6)
JMP _bblock
_b8tail:
ADDL $(QUAD-1), R8, R9
_b8block:
CMPUGE R9, R6, R1
BNE R1, _b1tail
MOVQ -8(R7), R2
SUBL $8, R6
MOVQ R2, (R6)
SUBL $8, R7
JMP _b8block
_b1tail:
CMPUGE R8, R6, R1
BNE R1, _ret
MOVBU -1(R7), R2
SUBL $1, R6, R6
MOVB R2, (R6)
SUBL $1, R7, R7
JMP _b1tail
_ret:
RET
_bunaligned:
ADDL $(16-1), R8, R9
_bu8block:
CMPUGE R9, R6, R1
BNE R1, _b1tail
MOVQU -16(R7), R4
MOVQU -8(R7), R3
MOVQU (R7), R2
SUBL $16, R6
EXTQH R7, R2, R2
EXTQL R7, R3, R5
OR R5, R2, R11
EXTQH R7, R3, R3
EXTQL R7, R4, R4
OR R3, R4, R13
MOVQ R11, 8(R6)
MOVQ R13, (R6)
SUBL $16, R7
JMP _bu8block
_forward:
ADDL R10, R6, R8 /* end to address */
CMPUGE $ALIGN, R10, R1 /* need at least ALIGN bytes */
BNE R1, _f1tail
_falign:
AND $(ALIGN-1), R6, R1
BEQ R1, _faligned
MOVBU (R7), R2
ADDL $1, R6, R6
ADDL $1, R7, R7
MOVB R2, -1(R6)
JMP _falign
_faligned:
AND $(QUAD-1), R7, R1 /* is the source quad-aligned */
BNE R1, _funaligned
SUBL $(BLOCK-1), R8, R9
_fblock:
CMPUGT R9, R6, R1
BEQ R1, _f8tail
MOVQ (R7), R2
MOVQ 8(R7), R3
MOVQ 16(R7), R4
MOVQ 24(R7), R5
MOVQ 32(R7), R22
MOVQ 40(R7), R23
MOVQ 48(R7), R24
MOVQ 56(R7), R25
ADDL $64, R6, R6
ADDL $64, R7, R7
MOVQ R2, -64(R6)
MOVQ R3, -56(R6)
MOVQ R4, -48(R6)
MOVQ R5, -40(R6)
MOVQ R22, -32(R6)
MOVQ R23, -24(R6)
MOVQ R24, -16(R6)
MOVQ R25, -8(R6)
JMP _fblock
_f8tail:
SUBL $(QUAD-1), R8, R9
_f8block:
CMPUGT R9, R6, R1
BEQ R1, _f1tail
MOVQ (R7), R2
ADDL $8, R6
ADDL $8, R7
MOVQ R2, -8(R6)
JMP _f8block
_f1tail:
CMPUGT R8, R6, R1
BEQ R1, _fret
MOVBU (R7), R2
ADDL $1, R6, R6
ADDL $1, R7, R7
MOVB R2, -1(R6)
JMP _f1tail
_fret:
RET
_funaligned:
SUBL $(16-1), R8, R9
_fu8block:
CMPUGT R9, R6, R1
BEQ R1, _f1tail
MOVQU (R7), R2
MOVQU 8(R7), R3
MOVQU 16(R7), R4
EXTQL R7, R2, R2
EXTQH R7, R3, R5
OR R5, R2, R11
EXTQL R7, R3, R3
MOVQ R11, (R6)
EXTQH R7, R4, R4
OR R3, R4, R11
MOVQ R11, 8(R6)
ADDL $16, R6
ADDL $16, R7
JMP _fu8block

View file

@ -1,61 +0,0 @@
TEXT memset(SB), $0
MOVL R0, R6
MOVBU data+4(FP), R2
MOVL n+8(FP), R10
ADDL R10, R0, R8
CMPUGE $8, R10, R1 /* need at least 8 bytes */
BNE R1, _1loop
SLLQ $8, R2, R1 /* replicate the byte */
OR R1, R2
SLLQ $16, R2, R1
OR R1, R2
SLLQ $32, R2, R1
OR R1, R2
_align:
AND $(8-1), R6, R1
BEQ R1, _aligned
MOVB R2, (R6)
ADDL $1, R6, R6
JMP _align
_aligned:
SUBL $(64-1), R8, R9 /* end pointer minus slop */
_64loop:
CMPUGT R9, R6, R1
BEQ R1, _8tail
MOVQ R2, (R6)
MOVQ R2, 8(R6)
MOVQ R2, 16(R6)
MOVQ R2, 24(R6)
MOVQ R2, 32(R6)
MOVQ R2, 40(R6)
MOVQ R2, 48(R6)
MOVQ R2, 56(R6)
ADDL $64, R6, R6
JMP _64loop
_8tail:
SUBL $(8-1), R8, R9
_8loop:
CMPUGT R9, R6, R1
BEQ R1, _1loop
MOVQ R2, (R6)
ADDL $8, R6
JMP _8loop
_1loop:
CMPUGT R8, R6, R1
BEQ R1, _ret
MOVB R2, (R6)
ADDL $1, R6
JMP _1loop
_ret:
RET

View file

@ -1,106 +0,0 @@
CONF=apc
CONFLIST=apc apccpu
objtype=alpha
</$objtype/mkfile
p=9
DEVS=`{rc ../port/mkdevlist $CONF}
PORT=\
alarm.$O\
alloc.$O\
allocb.$O\
auth.$O\
cache.$O\
chan.$O\
dev.$O\
fault.$O\
log.$O\
edf.$O\
mul64fract.$O\
page.$O\
parse.$O\
pgrp.$O\
portclock.$O\
print.$O\
proc.$O\
qio.$O\
qlock.$O\
rdb.$O\
rebootcmd.$O\
segment.$O\
swap.$O\
sysfile.$O\
sysproc.$O\
taslock.$O\
tod.$O\
xalloc.$O\
random.$O\
OBJ=\
l.$O\
cga.$O\
clock.$O\
faultalpha.$O\
fdc37c93x.$O\
fptrap.$O\
i8259.$O\
main.$O\
mmu.$O\
trap.$O\
$CONF.root.$O\
$CONF.rootc.$O\
$DEVS\
$PORT\
LIB=\
/$objtype/lib/libmemlayer.a\
/$objtype/lib/libmemdraw.a\
/$objtype/lib/libdraw.a\
/$objtype/lib/libip.a\
/$objtype/lib/libc.a\
/$objtype/lib/libsec.a\
ETHER=`{echo devether.c ether*.c | sed 's/\.c/.'$O'/g'}
VGA=`{echo devvga.c screen.c vga*.c | sed 's/\.c/.'$O'/g'}
SDEV=`{echo devsd.c sd*.c | sed 's/\.c/.'$O'/g'}
loadaddr = 0x80400020
$p$CONF: $CONF.c $OBJ $LIB
$CC $CFLAGS '-DKERNDATE='`{date -n} $CONF.c
$LD -o $target -H3 -R8 -T$loadaddr -l $OBJ $CONF.$O $LIB
size $target
install:V: $p$CONF
cp $p$CONF /$objtype/$p$CONF
<../boot/bootmkfile
<../port/portmkfile
<|../port/mkbootrules $CONF
<../pc/pcmkfile
init.h: initcode /sys/src/libc/9syscall/sys.h
$AS initcode
$LD -l -s -R8 -o init.out initcode.$O -lc
{echo 'uchar initcode[]={'
xd -r -1x init.out |
sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
echo '};'} > init.h
clock.$O: /$objtype/include/ureg.h axp.h
devarch.$O: axp.h
faultalpha.$O: /$objtype/include/ureg.h
fptrap.$O: /$objtype/include/ureg.h
l.$O: osf1pal.h
main.$O: /$objtype/include/ureg.h errstr.h init.h
mmu.$O: /sys/src/boot/alphapc/conf.h
sd53c8xx.$O: /$objtype/include/ureg.h ../port/sd.h sd53c8xx.i
trap.$O: /$objtype/include/ureg.h ../port/error.h ../port/systab.h
sd53c8xx.i: ../pc/sd53c8xx.n
aux/na $prereq > $target
acid:V:
$CC -a -w -I. ../port/qio.c>acid

View file

@ -1,299 +0,0 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "/sys/src/boot/alphapc/conf.h"
static uvlong origlvl1; /* physical address */
static uvlong klvl2; /* physical, as created by boot loader */
static uchar *nextio; /* next virtual address to be allocated by kmapv */
extern Bootconf *bootconf;
#define LVL2OFF(v) ((((long)(v))>>(2*PGSHIFT-3))&(PTE2PG-1))
#define LVL3OFF(v) ((((long)(v))>>(PGSHIFT))&(PTE2PG-1))
static void
setptb(ulong pa)
{
m->ptbr = (uvlong)pa>>PGSHIFT;
swpctx(m);
}
void
mmuinit(void)
{
uvlong *plvl2;
/* set PCB to new one in mach structure before stomping on old one */
m->usp = 0;
m->fen = 1;
m->ptbr = bootconf->pcb->ptbr;
origlvl1 = (m->ptbr << PGSHIFT);
setpcb(m);
plvl2 = (uvlong*) (KZERO|origlvl1|(BY2PG-8));
klvl2 = (*plvl2 >> 32)<<PGSHIFT;
nextio = (uchar*) (KZERO|bootconf->maxphys);
}
static void
mmuptefree(Proc* proc)
{
uvlong *lvl2;
Page **last, *page;
if(proc->mmutop && proc->mmuused){
lvl2 = (uvlong*)proc->mmulvl2->va;
last = &proc->mmuused;
for(page = *last; page; page = page->next){
lvl2[page->daddr] = 0;
last = &page->next;
}
*last = proc->mmufree;
proc->mmufree = proc->mmuused;
proc->mmuused = 0;
}
}
void
mmuswitch(Proc *proc)
{
if(proc->newtlb){
mmuptefree(proc);
proc->newtlb = 0;
}
/* tell processor about new page table and flush cached entries */
if(proc->mmutop == 0)
setptb(origlvl1);
else
setptb(proc->mmutop->pa);
tlbflush(-1, 0);
icflush();
}
/* point to protoype page map */
void
mmupark(void)
{
setptb(origlvl1);
icflush();
}
/*
* give all page table pages back to the free pool. This is called in sched()
* with palloc locked.
*/
void
mmurelease(Proc *proc)
{
Page *page, *next;
mmupark();
mmuptefree(proc);
proc->mmuused = 0;
if(proc->mmutop) {
proc->mmutop->next = proc->mmufree;
proc->mmufree = proc->mmutop;
proc->mmutop = 0;
}
if(proc->mmulvl2) {
proc->mmulvl2->next = proc->mmufree;
proc->mmufree = proc->mmulvl2;
proc->mmulvl2 = 0;
}
for(page = proc->mmufree; page; page = next){
next = page->next;
if(--page->ref)
panic("mmurelease: page->ref %d\n", page->ref);
pagechainhead(page);
}
if(proc->mmufree)
pagechaindone();
proc->mmufree = 0;
}
void
mmunewtop(void)
{
Page *top, *lvl2;
uvlong *ppte;
top = newpage(1, 0, 0);
top->va = VA(kmap(top));
lvl2 = newpage(1, 0, 0);
lvl2->va = VA(kmap(lvl2));
ppte = (uvlong *)top->va;
ppte[0] = PTEPFN(lvl2->pa) | PTEKVALID;
ppte[PTE2PG-2] = PTEPFN(top->pa) | PTEKVALID;
ppte[PTE2PG-1] = PTEPFN(klvl2) | PTEKVALID;
up->mmutop = top;
up->mmulvl2 = lvl2;
setptb(top->pa);
tlbflush(-1, 0);
icflush();
}
void
putmmu(uintptr va, uintptr pa, Page *pg)
{
int lvl2off;
uvlong *lvl2, *pt;
int s;
if(up->mmutop == 0)
mmunewtop();
lvl2 = (uvlong*)up->mmulvl2->va;
lvl2off = LVL2OFF(va);
/*
* if bottom level page table missing, allocate one
* and point the top level page at it.
*/
s = splhi();
if(lvl2[lvl2off] == 0){
if(up->mmufree == 0){
spllo();
pg = newpage(1, 0, 0);
pg->va = VA(kmap(pg));
splhi();
} else {
pg = up->mmufree;
up->mmufree = pg->next;
memset((void*)pg->va, 0, BY2PG);
}
lvl2[lvl2off] = PTEPFN(pg->pa) | PTEVALID;
pg->daddr = lvl2off;
pg->next = up->mmuused;
up->mmuused = pg;
}
/*
* put in new mmu entry
*/
pt = (uvlong*)(((lvl2[lvl2off] >> 32)<<PGSHIFT)|KZERO);
pt[LVL3OFF(va)] = FIXPTE(pa);
/* flush cached mmu entries */
tlbflush(3, va);
icflush();
splx(s);
}
void *
kmapv(uvlong pa, int size)
{
void *va, *new;
int lvl2off, i, npage, offset;
uvlong *lvl2, *pt;
offset = pa&(BY2PG-1);
npage = ((size+offset+BY2PG-1)>>PGSHIFT);
va = nextio+offset;
lvl2 = (uvlong*)(KZERO|klvl2);
for (i = 0; i < npage; i++) {
lvl2off = LVL2OFF(nextio);
if (lvl2[lvl2off] == 0) {
new = xspanalloc(BY2PG, BY2PG, 0);
memset(new, 0, BY2PG);
lvl2[lvl2off] = PTEPFN(PADDR(new)) | PTEKVALID | PTEASM;
}
pt = (uvlong*)(((lvl2[lvl2off] >> 32)<<PGSHIFT)|KZERO);
pt[LVL3OFF(nextio)] = PTEPFN(pa) | PTEKVALID | PTEASM;
nextio += BY2PG;
pa += BY2PG;
}
return va;
}
void
flushmmu(void)
{
int s;
s = splhi();
up->newtlb = 1;
mmuswitch(up);
splx(s);
}
void*
vmap(ulong pa, int size)
{
void *va;
/*
* Viability hack. Only for PCI framebuffers.
*/
if(pa == 0)
return 0;
va = kmapv(((uvlong)0x88<<32LL)|pa, size);
if(va == nil)
return 0;
return (void*)va;
}
void
vunmap(void*, int)
{
print("vunmap: virtual mapping not freed\n");
}
void
mmudump(void)
{
Page *top, *lvl2;
iprint("ptbr %lux up %#p\n", (ulong)m->ptbr, up);
if(up) {
top = up->mmutop;
if(top != nil)
iprint("top %lux top[N-1] %llux\n", top->va, ((uvlong *)top->va)[PTE2PG-1]);
lvl2 = up->mmulvl2;
if(lvl2 != nil)
iprint("lvl2 %lux\n", lvl2->va);
}
}
ulong
upaalloc(int, int)
{
return 0;
}
void
upafree(ulong, int)
{
}
void
checkmmu(uintptr, uintptr)
{
}
void
countpagerefs(ulong*, int)
{
}
/*
* Return the number of bytes that can be accessed via KADDR(pa).
* If pa is not a valid argument to KADDR, return 0.
*/
ulong
cankaddr(ulong pa)
{
ulong kzero;
kzero = -KZERO;
if(pa >= kzero)
return 0;
return kzero - pa;
}

View file

@ -1,78 +0,0 @@
/*
* OSF/1 PALcode instructions, in numerical order.
* Values are from Digital EBSDK and FreeBSD/Alpha.
*/
/* Privilaged PAL functions */
#define PALhalt 0x00 /* required per Alpha architecture */
#define PALcflush 0x01
#define PALdraina 0x02 /* required per Alpha architecture */
/*
* ... 0x03 to 0x08 ?
*/
#define PALcserve 0x09
#define PALswppal 0x0a
/*
* ... 0x0b to 0x0c ?
*/
#define PALwripir 0x0d
/*
* ... 0x0e to 0x0f ?
*/
#define PALrdmces 0x10
#define PALwrmces 0x11
/*
* ... 0x12 to 0x2a ?
*/
#define PALwrfen 0x2b
/* 0x2c OSF/1 ? */
#define PALwrvptptr 0x2d
/*
* ... 0x2e to 0x2f ?
*/
#define PALswpctx 0x30
#define PALwrval 0x31
#define PALrdval 0x32
#define PALtbi 0x33
#define PALwrent 0x34
#define PALswpipl 0x35
#define PALrdps 0x36
#define PALwrkgp 0x37
#define PALwrusp 0x38
#define PALwrperfmon 0x39
#define PALrdusp 0x3a
/* 0x3b OSF/1 ? */
#define PALwhami 0x3c
#define PALretsys 0x3d
#define PALwtint 0x3e
#define PALrti 0x3f
/* Unprivileged PAL functions */
#define PALbpt 0x80
#define PALbugchk 0x81
#define PALcallsys 0x83
#define PALimb 0x86 /* required per Alpha architecture */
/*
* ... 0x89 to 0x91 ?
*/
#define PALurti 0x92
/*
* ... 0x93 to 0x9d ?
*/
#define PALrdunique 0x9e
#define PALwrunique 0x9f
/*
* ... 0xa0 to 0xa9 ?
*/
#define PALgentrap 0xaa
/*
* ... 0xab to 0xac ?
*/
#define PALdbgstop 0xad
#define PALclrfen 0xae
/*
* ... 0xaf to 0xbd ?
*/
#define PALnphalt 0xbe
#define PALcopypal 0xbf

View file

@ -1,412 +0,0 @@
/*
* PCI support code.
* To do:
* initialise bridge mappings if the PCI BIOS didn't.
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "../port/error.h"
enum {
MaxFNO = 7,
MaxUBN = 255,
};
enum
{ /* command register */
IOen = (1<<0),
MEMen = (1<<1),
MASen = (1<<2),
MemWrInv = (1<<4),
PErrEn = (1<<6),
SErrEn = (1<<8),
};
static Lock pcicfglock;
static Lock pcicfginitlock;
static int pcicfgmode = -1;
static int pcimaxdno;
static Pcidev* pciroot;
static Pcidev* pcilist;
static Pcidev* pcitail;
static int pcicfgrw32(int, int, int, int);
uchar *vgabios;
static int
pciscan(int bno, Pcidev** list)
{
ulong v;
Pcidev *p, *head, *tail;
int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn;
maxubn = bno;
head = nil;
tail = nil;
for(dno = 0; dno <= pcimaxdno; dno++){
maxfno = 0;
for(fno = 0; fno <= maxfno; fno++){
/*
* For this possible device, form the
* bus+device+function triplet needed to address it
* and try to read the vendor and device ID.
* If successful, allocate a device struct and
* start to fill it in with some useful information
* from the device's configuration space.
*/
tbdf = MKBUS(BusPCI, bno, dno, fno);
l = pcicfgrw32(tbdf, PciVID, 0, 1);
if(l == 0xFFFFFFFF || l == 0)
continue;
/* optional safety checks:
if(l == pcicfgrw32(tbdf, PciPCR, 0, 1))
continue;
if(l != pcicfgrw32(tbdf, PciVID, 0, 1))
continue;
if(l == pcicfgrw32(tbdf, PciPCR, 0, 1))
continue;
*/
p = malloc(sizeof(*p));
p->tbdf = tbdf;
p->vid = l;
p->did = l>>16;
if(pcilist != nil)
pcitail->list = p;
else
pcilist = p;
pcitail = p;
p->rid = pcicfgr8(p, PciRID);
p->ccrp = pcicfgr8(p, PciCCRp);
p->ccru = pcicfgr8(p, PciCCRu);
p->ccrb = pcicfgr8(p, PciCCRb);
p->pcr = pcicfgr32(p, PciPCR);
p->intl = pcicfgr8(p, PciINTL);
/*
* If the device is a multi-function device adjust the
* loop count so all possible functions are checked.
*/
hdt = pcicfgr8(p, PciHDT);
if(hdt & 0x80)
maxfno = MaxFNO;
/*
* If appropriate, read the base address registers
* and work out the sizes.
*/
switch(p->ccrb){
case 0x03: /* display controller */
if(vgabios == nil) {
v = pcicfgr32(p, PciROM);
pcicfgw32(p, PciROM, v|1); /* enable decode */
vgabios = kmapv(((uvlong)0x88<<32LL)|(v&~0xffff), 0x10000);
// print("VGA BIOS %lux -> %lux\n", v, vgabios);
}
/* fall through */
case 0x01: /* mass storage controller */
case 0x02: /* network controller */
case 0x04: /* multimedia device */
case 0x07: /* simple communication controllers */
case 0x08: /* base system peripherals */
case 0x09: /* input devices */
case 0x0A: /* docking stations */
case 0x0B: /* processors */
case 0x0C: /* serial bus controllers */
if((hdt & 0x7F) != 0)
break;
rno = PciBAR0 - 4;
for(i = 0; i < nelem(p->mem); i++){
rno += 4;
p->mem[i].bar = pcicfgr32(p, rno);
pcicfgw32(p, rno, -1);
v = pcicfgr32(p, rno);
pcicfgw32(p, rno, p->mem[i].bar);
p->mem[i].size = -(v & ~0xF);
}
break;
case 0x00:
case 0x05: /* memory controller */
case 0x06: /* bridge device */
default:
break;
}
if(head != nil)
tail->link = p;
else
head = p;
tail = p;
}
}
*list = head;
for(p = head; p != nil; p = p->link){
/*
* Find PCI-PCI bridges and recursively descend the tree.
*/
if(p->ccrb != 0x06 || p->ccru != 0x04)
continue;
/*
* If the secondary or subordinate bus number is not initialised
* try to do what the PCI BIOS should have done and fill in the
* numbers as the tree is descended. On the way down the subordinate
* bus number is set to the maximum as it's not known how many
* buses are behind this one; the final value is set on the way
* back up.
*/
sbn = pcicfgr8(p, PciSBN);
ubn = pcicfgr8(p, PciUBN);
if(sbn == 0 || ubn == 0){
sbn = maxubn+1;
/*
* Make sure memory, I/O and master enables are off,
* set the primary, secondary and subordinate bus numbers
* and clear the secondary status before attempting to
* scan the secondary bus.
*
* Initialisation of the bridge should be done here.
*/
pcicfgw32(p, PciPCR, 0xFFFF0000);
l = (MaxUBN<<16)|(sbn<<8)|bno;
pcicfgw32(p, PciPBN, l);
pcicfgw16(p, PciSPSR, 0xFFFF);
maxubn = pciscan(sbn, &p->bridge);
l = (maxubn<<16)|(sbn<<8)|bno;
pcicfgw32(p, PciPBN, l);
}
else{
maxubn = ubn;
pciscan(sbn, &p->bridge);
}
}
return maxubn;
}
static void
pcicfginit(void)
{
char *p;
lock(&pcicfginitlock);
if(pcicfgmode == -1){
pcicfgmode = 0;
pcimaxdno = 15; /* was 20; what is correct value??? */
if(p = getconf("*pcimaxdno"))
pcimaxdno = strtoul(p, 0, 0);
pciscan(0, &pciroot);
}
unlock(&pcicfginitlock);
}
static int
pcicfgrw8(int tbdf, int rno, int data, int read)
{
int x;
uchar *p;
if(pcicfgmode == -1)
pcicfginit();
x = -1;
if(BUSDNO(tbdf) > pcimaxdno)
return x;
p = (uchar*)arch->pcicfg(tbdf, rno);
if(read)
x = *p;
else
*p = data;
return x;
}
int
pcicfgr8(Pcidev* pcidev, int rno)
{
return pcicfgrw8(pcidev->tbdf, rno, 0, 1);
}
void
pcicfgw8(Pcidev* pcidev, int rno, int data)
{
pcicfgrw8(pcidev->tbdf, rno, data, 0);
}
static int
pcicfgrw16(int tbdf, int rno, int data, int read)
{
int x;
ushort *p;
if(pcicfgmode == -1)
pcicfginit();
x = -1;
if(BUSDNO(tbdf) > pcimaxdno)
return x;
p = (ushort*)arch->pcicfg(tbdf, rno);
if(read)
x = *p;
else
*p = data;
return x;
}
int
pcicfgr16(Pcidev* pcidev, int rno)
{
return pcicfgrw16(pcidev->tbdf, rno, 0, 1);
}
void
pcicfgw16(Pcidev* pcidev, int rno, int data)
{
pcicfgrw16(pcidev->tbdf, rno, data, 0);
}
static int
pcicfgrw32(int tbdf, int rno, int data, int read)
{
int x;
ulong *p;
if(pcicfgmode == -1)
pcicfginit();
x = -1;
if(BUSDNO(tbdf) > pcimaxdno)
return x;
p = (ulong*)arch->pcicfg(tbdf, rno);
if(read)
x = *p;
else
*p = data;
return x;
}
int
pcicfgr32(Pcidev* pcidev, int rno)
{
return pcicfgrw32(pcidev->tbdf, rno, 0, 1);
}
void
pcicfgw32(Pcidev* pcidev, int rno, int data)
{
pcicfgrw32(pcidev->tbdf, rno, data, 0);
}
Pcidev*
pcimatch(Pcidev* prev, int vid, int did)
{
if(pcicfgmode == -1)
pcicfginit();
if(prev == nil)
prev = pcilist;
else
prev = prev->list;
while(prev != nil) {
if((vid == 0 || prev->vid == vid)
&& (did == 0 || prev->did == did))
break;
prev = prev->list;
}
return prev;
}
Pcidev*
pcimatchtbdf(int tbdf)
{
Pcidev *pcidev;
if(pcicfgmode == -1)
pcicfginit();
for(pcidev = pcilist; pcidev != nil; pcidev = pcidev->list) {
if(pcidev->tbdf == tbdf)
break;
}
return pcidev;
}
void
pcihinv(Pcidev* p)
{
int i;
Pcidev *t;
if(pcicfgmode == -1)
pcicfginit();
if(p == nil) {
p = pciroot;
print("bus dev type vid did intl memory\n");
}
for(t = p; t != nil; t = t->link) {
print("%d %2d/%d %.2ux %.2ux %.2ux %.4ux %.4ux %2d ",
BUSBNO(t->tbdf), BUSDNO(t->tbdf), BUSFNO(t->tbdf),
t->ccrb, t->ccru, t->ccrp, t->vid, t->did, t->intl);
for(i = 0; i < nelem(p->mem); i++) {
if(t->mem[i].size == 0)
continue;
print("%d:%.8lux %d ", i,
t->mem[i].bar, t->mem[i].size);
}
print("\n");
}
while(p != nil) {
if(p->bridge != nil)
pcihinv(p->bridge);
p = p->link;
}
}
void
pcireset(void)
{
Pcidev *p;
int pcr;
if(pcicfgmode == -1)
pcicfginit();
for(p = pcilist; p != nil; p = p->list){
pcr = pcicfgr16(p, PciPSR);
pcicfgw16(p, PciPSR, pcr & ~0x04);
}
}
void
pcisetbme(Pcidev* p)
{
int pcr;
pcr = pcicfgr16(p, PciPCR);
pcr |= MASen;
pcicfgw16(p, PciPCR, pcr);
}
void
pciclrbme(Pcidev* p)
{
int pcr;
pcr = pcicfgr16(p, PciPCR);
pcr &= ~MASen;
pcicfgw16(p, PciPCR, pcr);
}

View file

@ -1,172 +0,0 @@
typedef struct Cursor Cursor;
typedef struct Cursorinfo Cursorinfo;
struct Cursorinfo {
Cursor;
Lock;
};
/* devmouse.c */
extern void mousetrack(int, int, int, int);
extern void absmousetrack(int, int, int, int);
extern Point mousexy(void);
extern void mouseaccelerate(int);
extern int m3mouseputc(Queue*, int);
extern int m5mouseputc(Queue*, int);
extern int mouseputc(Queue*, int);
extern Cursorinfo cursor;
extern Cursor arrow;
/*
* Generic VGA registers.
*/
enum {
MiscW = 0x03C2, /* Miscellaneous Output (W) */
MiscR = 0x03CC, /* Miscellaneous Output (R) */
Status0 = 0x03C2, /* Input status 0 (R) */
Status1 = 0x03DA, /* Input Status 1 (R) */
FeatureR = 0x03CA, /* Feature Control (R) */
FeatureW = 0x03DA, /* Feature Control (W) */
Seqx = 0x03C4, /* Sequencer Index, Data at Seqx+1 */
Crtx = 0x03D4, /* CRT Controller Index, Data at Crtx+1 */
Grx = 0x03CE, /* Graphics Controller Index, Data at Grx+1 */
Attrx = 0x03C0, /* Attribute Controller Index and Data */
PaddrW = 0x03C8, /* Palette Address Register, write */
Pdata = 0x03C9, /* Palette Data Register */
Pixmask = 0x03C6, /* Pixel Mask Register */
PaddrR = 0x03C7, /* Palette Address Register, read */
Pstatus = 0x03C7, /* DAC Status (RO) */
Pcolours = 256, /* Palette */
Pred = 0,
Pgreen = 1,
Pblue = 2,
Pblack = 0x00,
Pwhite = 0xFF,
};
#define VGAMEM() PADDR(arch->pcimem(0xA0000, 1<<16))
#define vgai(port) inb(port)
#define vgao(port, data) outb(port, data)
extern int vgaxi(long, uchar);
extern int vgaxo(long, uchar, uchar);
/*
*/
typedef struct VGAdev VGAdev;
typedef struct VGAcur VGAcur;
typedef struct VGAscr VGAscr;
struct VGAdev {
char* name;
void (*enable)(VGAscr*);
void (*disable)(VGAscr*);
void (*page)(VGAscr*, int);
void (*linear)(VGAscr*, int, int);
void (*drawinit)(VGAscr*);
int (*fill)(VGAscr*, Rectangle, ulong);
void (*flush)(VGAscr*, Rectangle);
};
struct VGAcur {
char* name;
void (*enable)(VGAscr*);
void (*disable)(VGAscr*);
void (*load)(VGAscr*, Cursor*);
int (*move)(VGAscr*, Point);
int doespanning;
};
/*
*/
struct VGAscr {
Lock devlock;
VGAdev* dev;
Pcidev* pci;
VGAcur* cur;
ulong storage;
Cursor;
int useflush;
ulong paddr; /* frame buffer */
void* vaddr;
int apsize;
ulong io; /* device specific registers */
ulong *mmio;
ulong colormap[Pcolours][3];
int palettedepth;
Memimage* gscreen;
Memdata* gscreendata;
Memsubfont* memdefont;
int (*fill)(VGAscr*, Rectangle, ulong);
int (*scroll)(VGAscr*, Rectangle, Rectangle);
void (*blank)(VGAscr*, int);
ulong id; /* internal identifier for driver use */
};
extern VGAscr vgascreen[];
enum {
Backgnd = 0, /* black */
};
/* mouse.c */
extern void mousectl(Cmdbuf*);
/* screen.c */
extern int hwaccel; /* use hw acceleration; default on */
extern int hwblank; /* use hw blanking; default on */
extern void addvgaseg(char*, ulong, ulong);
extern uchar* attachscreen(Rectangle*, ulong*, int*, int*, int*);
extern void flushmemscreen(Rectangle);
extern int cursoron(int);
extern void cursoroff(int);
extern void setcursor(Cursor*);
extern int screensize(int, int, int, ulong);
extern int screenaperture(int, int);
extern Rectangle physgscreenr; /* actual monitor size */
extern void blankscreen(int);
extern VGAcur swcursor;
extern void swcursorinit(void);
extern void swcursorhide(void);
extern void swcursoravoid(Rectangle);
extern void swcursorunhide(void);
/* devdraw.c */
extern void deletescreenimage(void);
extern int drawhasclients(void);
extern ulong blanktime;
extern QLock drawlock;
/* vga.c */
extern void vgascreenwin(VGAscr*);
extern void vgaimageinit(ulong);
extern void vgalinearpciid(VGAscr*, int, int);
extern void vgalinearpci(VGAscr*);
extern void vgalinearaddr(VGAscr*, ulong, int);
extern void drawblankscreen(int);
extern void vgablank(VGAscr*, int);
extern Lock vgascreenlock;
#define ishwimage(i) (vgascreen[0].gscreendata && (i)->data->bdata == vgascreen[0].gscreendata->bdata)

File diff suppressed because it is too large Load diff

View file

@ -1,18 +0,0 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
/*
* 82378ZB Saturn-I/O (SIO) PCI-to-ISA Bus Bridge.
*/
static Pcidev* siodev;
void
siodump(void)
{
if(siodev == nil && (siodev = pcimatch(nil, 0x8086, 0x0484)) == nil)
return;
}

View file

@ -1,902 +0,0 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "ureg.h"
#include "io.h"
#include "../port/error.h"
void noted(Ureg*, Ureg**, ulong);
void rfnote(Ureg**);
void kernfault(Ureg*, int);
void illegal(Ureg *);
void fen(Ureg *);
char *regname[]={
"type", "a0", "a1",
"a2", "R0", "R1",
"R2", "R3", "R4",
"R5", "R6", "R7",
"R8", "R9", "R10",
"R11", "R12", "R13",
"R14", "R15", "R19",
"R20", "R21", "R22",
"R23", "R24", "R25",
"R26", "R27", "R28",
"R30", "status", "PC",
"R29", "R16", "R17",
"R18",
};
static Lock vctllock;
static Vctl *vctl[256];
void
intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf, char *name)
{
int vno;
Vctl *v;
if(f == nil){
print("intrenable: nil handler for %d, tbdf 0x%uX for %s\n",
irq, tbdf, name);
return;
}
v = xalloc(sizeof(Vctl));
v->isintr = 1;
v->irq = irq;
v->tbdf = tbdf;
v->f = f;
v->a = a;
strncpy(v->name, name, KNAMELEN-1);
v->name[KNAMELEN-1] = 0;
ilock(&vctllock);
vno = arch->intrenable(v);
if(vno == -1){
iunlock(&vctllock);
print("intrenable: couldn't enable irq %d, tbdf 0x%uX for %s\n",
irq, tbdf, v->name);
xfree(v);
return;
}
if(vctl[vno]){
if(vctl[vno]->isr != v->isr || vctl[vno]->eoi != v->eoi)
panic("intrenable: handler: %s %s %#p %#p %#p %#p",
vctl[vno]->name, v->name,
vctl[vno]->isr, v->isr, vctl[vno]->eoi, v->eoi);
v->next = vctl[vno];
}
vctl[vno] = v;
iunlock(&vctllock);
}
int
intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name)
{
Vctl **pv, *v;
int vno;
/*
* For now, none of this will work with the APIC code,
* there is no mapping between irq and vector as the IRQ
* is pretty meaningless.
*/
if(arch->intrvecno == nil)
return -1;
vno = arch->intrvecno(irq);
ilock(&vctllock);
for(pv = &vctl[vno]; *pv != nil; pv = &((*pv)->next)){
if((*pv)->irq != irq)
continue;
if((*pv)->tbdf != tbdf)
continue;
if((*pv)->f != f)
continue;
if((*pv)->a != a)
continue;
if(strcmp((*pv)->name, name) != 0)
continue;
break;
}
assert(*pv != nil);
v = *pv;
*pv = (*pv)->next; /* Link out the entry */
if (vctl[vno] == nil && arch->intrdisable != nil)
arch->intrdisable(irq);
iunlock(&vctllock);
xfree(v);
return 0;
}
int
irqallocread(char *buf, long n, vlong offset)
{
int vno;
Vctl *v;
long oldn;
char str[11+1+KNAMELEN+1], *p;
int m;
if(n < 0 || offset < 0)
error(Ebadarg);
oldn = n;
for(vno=0; vno<nelem(vctl); vno++){
for(v=vctl[vno]; v; v=v->next){
m = snprint(str, sizeof str, "%11d %11d %.*s\n", vno, v->irq, KNAMELEN, v->name);
if(m <= offset) /* if do not want this, skip entry */
offset -= m;
else{
/* skip offset bytes */
m -= offset;
p = str+offset;
offset = 0;
/* write at most max(n,m) bytes */
if(m > n)
m = n;
memmove(buf, p, m);
n -= m;
buf += m;
if(n == 0)
return oldn;
}
}
}
return oldn - n;
}
typedef struct Mcheck Mcheck;
struct Mcheck
{
ulong len;
ulong inprogress;
ulong procoff;
ulong sysoff;
ulong code;
};
static char *
smcheck(ulong code)
{
switch (code) {
case 0x80: return "tag parity error";
case 0x82: return "tag control parity error";
case 0x84: return "generic hard error";
case 0x86: return "correctable ECC error";
case 0x88: return "uncorrectable ECC error";
case 0x8a: return "OS-specific PAL bugcheck";
case 0x90: return "callsys in kernel mode";
case 0x96: return "i-cache read retryable error";
case 0x98: return "processor detected hard error";
case 0x203: return "system detected uncorrectable ECC error";
case 0x205: return "parity error detected by CIA";
case 0x207: return "non-existent memory error";
case 0x209: return "PCI SERR detected";
case 0x20b: return "PCI data parity error detected";
case 0x20d: return "PCI address parity error detected";
case 0x20f: return "PCI master abort error";
case 0x211: return "PCI target abort error";
case 0x213: return "scatter/gather PTE invalid error";
case 0x215: return "flash ROM write error";
case 0x217: return "IOA timeout detected";
case 0x219: return "IOCHK#, EISA add-in board parity or other catastrophic error";
case 0x21b: return "EISA fail-safe timer timeout";
case 0x21d: return "EISA bus time-out";
case 0x21f: return "EISA software generated NMI";
case 0x221: return "unexpected ev5 IRQ[3] interrupt";
default: return "unknown mcheck";
}
}
void
mcheck(Ureg *ur, void *x)
{
Mcheck *m;
uvlong *data;
int i, col;
m = x;
data = x;
iprint("panic: Machine Check @%#p: %s (%lux) len %lud\n",
m, smcheck(m->code), m->code, m->len);
iprint("proc offset %lux sys offset %lux\n", m->procoff, m->sysoff);
for (i = 0, col = 0; i < m->len/8; i++) {
iprint("%.3x: %.16llux%s", 8*i, data[i], (col == 2) ? "\n" : " ");
if (col++ == 2)
col = 0;
}
if(col != 2)
print("\n");
print("\n");
dumpregs(ur);
prflush();
firmware();
}
void
intr(Ureg *ur)
{
int i, vno;
Vctl *ctl, *v;
Mach *mach;
vno = (ulong)ur->a1>>4;
vno -= 0x80;
if(vno < nelem(vctl) && (ctl = vctl[vno])){
if(ctl->isintr){
m->intr++;
if(vno >= VectorPIC && vno <= MaxVectorPIC)
m->lastintr = vno-VectorPIC;
}
if(ctl->isr)
ctl->isr(vno);
for(v = ctl; v != nil; v = v->next) {
if(v->f)
v->f(ur, v->a);
}
if(ctl->eoi)
ctl->eoi(vno);
if(ctl->isintr && up)
preempted();
}
else if(vno >= VectorPIC && vno <= MaxVectorPIC){
/*
* An unknown interrupt.
* Check for a default IRQ7. This can happen when
* the IRQ input goes away before the acknowledge.
* In this case, a 'default IRQ7' is generated, but
* the corresponding bit in the ISR isn't set.
* In fact, just ignore all such interrupts.
*/
iprint("cpu%d: spurious interrupt %d, last %d",
m->machno, vno-VectorPIC, m->lastintr);
for(i = 0; i < MAXMACH; i++){
if(active.machs[i] == 0)
continue;
mach = MACHP(i);
if(m->machno == mach->machno)
continue;
iprint(": cpu%d: last %d", mach->machno, mach->lastintr);
}
iprint("\n");
m->spuriousintr++;
return;
}
else{
dumpregs(ur);
print("unknown intr: %d\n", vno); /* */
}
}
void
trap(Ureg *ur)
{
char buf[ERRMAX];
int clockintr, user, x;
user = ur->status&UMODE;
if(user){
up = m->proc;
up->dbgreg = ur;
}
clockintr = 0;
switch ((int)ur->type) {
case 1: /* arith */
fptrap(ur);
break;
case 2: /* bad instr or FEN */
illegal(ur);
break;
case 3: /* intr */
m->intr++;
switch ((int)ur->a0) {
case 0: /* interprocessor */
panic("interprocessor intr");
break;
case 1: /* clock */
clockintr = 1;
clock(ur);
break;
case 2: /* machine check */
mcheck(ur, (void*)(KZERO|(ulong)ur->a2));
break;
case 3: /* device */
intr(ur);
break;
case 4: /* perf counter */
panic("perf count");
break;
default:
panic("bad intr");
break;
}
break;
case 4: /* memory fault */
if(up == 0)
kernfault(ur, (ulong)ur->a1);
x = up->insyscall;
up->insyscall = 1;
spllo();
faultalpha(ur);
up->insyscall = x;
break;
case 6: /* alignment fault */
ur->pc -= 4;
sprint(buf, "trap: unaligned addr 0x%lux", (ulong)ur->a0);
fataltrap(ur, buf);
break;
default: /* cannot happen */
panic("bad trap type %d", (int)ur->type);
break;
}
splhi();
/* delaysched set because we held a lock or because our quantum ended */
if(up && up->delaysched && clockintr){
sched();
splhi();
}
if(user){
if(up->procctl || up->nnote)
notify(ur);
kexit(ur);
}
}
void
trapinit(void)
{
splhi();
wrent(0, intr0);
wrent(1, arith);
wrent(2, fault0);
wrent(3, illegal0);
wrent(4, unaligned);
wrent(5, syscall0);
}
void
fataltrap(Ureg *ur, char *reason)
{
char buf[ERRMAX];
if(ur->status&UMODE) {
spllo();
sprint(buf, "sys: %s", reason);
postnote(up, 1, buf, NDebug);
return;
}
print("kernel %s pc=%lux\n", reason, (ulong)ur->pc);
dumpregs(ur);
dumpstack();
if(m->machno == 0)
spllo();
exit(1);
}
void
kernfault(Ureg *ur, int code)
{
Label l;
char *s;
splhi();
if (code == 0)
s = "read";
else if (code == 1)
s = "write";
else
s = "ifetch";
print("panic: kfault %s VA=0x%lux\n", s, (ulong)ur->a0);
print("u=%#p status=0x%lux pc=0x%lux sp=0x%lux\n",
up, (ulong)ur->status, (ulong)ur->pc, (ulong)ur->sp);
dumpregs(ur);
l.sp = ur->sp;
l.pc = ur->pc;
dumpstack();
exit(1);
}
void
dumpregs(Ureg *ur)
{
int i, col;
uvlong *l;
if(up)
print("registers for %s %ld\n", up->text, up->pid);
else
print("registers for kernel\n");
l = &ur->type;
col = 0;
for (i = 0; i < sizeof regname/sizeof(char*); i++, l++) {
print("%-7s%.16llux%s", regname[i], *l, col == 2 ? "\n" : " ");
if (col++ == 2)
col = 0;
}
print("\n");
}
/*
* Fill in enough of Ureg to get a stack trace, and call a function.
* Used by debugging interface rdb.
*/
static void
getpcsp(ulong *pc, ulong *sp)
{
*pc = getcallerpc(&pc);
*sp = (ulong)&pc-8;
}
void
callwithureg(void (*fn)(Ureg*))
{
Ureg ureg;
getpcsp((ulong*)&ureg.pc, (ulong*)&ureg.sp);
ureg.r26 = getcallerpc(&fn);
fn(&ureg);
}
void
_dumpstack(Ureg *ureg)
{
ulong l, sl, el, v, i, instr, op;
extern ulong etext;
l=(ulong)&l;
if(l&4)
l += 4;
if(up == 0){
el = (ulong)m+BY2PG;
sl = el-KSTACK;
}
else{
sl = (ulong)up->kstack;
el = sl + KSTACK;
}
if(l > el || l < sl){
el = (ulong)m+BY2PG;
sl = el-KSTACK;
}
if(l > el || l < sl)
return;
print("ktrace /kernel/path %.8lux %.8lux %.8lux\n", (ulong)ureg->pc, (ulong)ureg->sp, (ulong)ureg->r26);
i = 0;
for(; l<el; l+=8){
v = *(ulong*)l - 4;
if(KTZERO < v && v < (ulong)&etext && (v&3) == 0){
/*
* Check for JSR/BSR
*/
instr = *(ulong*)v;
op = (instr>>26);
if(op == 26 || op == 52){
print("%lux=%lux ", l, v);
i++;
}
}
if(i == 4){
i = 0;
print("\n");
}
}
if(i)
print("\n");
}
void
dumpstack(void)
{
callwithureg(_dumpstack);
}
int
notify(Ureg *ur)
{
int l;
ulong sp;
Note *n;
if(up->procctl)
procctl();
if(up->nnote == 0)
return 0;
if(up->fpstate == FPactive){
savefpregs(&up->fpsave);
up->fpstate = FPinactive;
}
up->fpstate |= FPillegal;
spllo();
qlock(&up->debug);
up->notepending = 0;
n = &up->note[0];
if(strncmp(n->msg, "sys:", 4) == 0) {
l = strlen(n->msg);
if(l > ERRMAX-15) /* " pc=0x12345678\0" */
l = ERRMAX-15;
sprint(n->msg+l, " pc=0x%lux", (ulong)ur->pc);
}
if(n->flag != NUser && (up->notified || up->notify==0)) {
qunlock(&up->debug);
if(n->flag == NDebug)
pprint("suicide: %s\n", n->msg);
pexit(n->msg, n->flag!=NDebug);
}
if(up->notified) {
qunlock(&up->debug);
splhi();
return 0;
}
if(!up->notify) {
qunlock(&up->debug);
pexit(n->msg, n->flag!=NDebug);
}
sp = ur->usp & ~(BY2V-1);
sp -= sizeof(Ureg);
if(!okaddr((uintptr)up->notify, BY2WD, 0)
|| !okaddr(sp-ERRMAX-6*BY2WD, sizeof(Ureg)+ERRMAX-6*BY2WD, 1)) {
qunlock(&up->debug);
pprint("suicide: bad address or sp in notify\n");
pexit("Suicide", 0);
}
memmove((Ureg*)sp, ur, sizeof(Ureg));
*(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */
up->ureg = (void*)sp;
sp -= 2*BY2WD+ERRMAX;
memmove((char*)sp, up->note[0].msg, ERRMAX);
sp -= 4*BY2WD;
*(ulong*)(sp+3*BY2WD) = sp+4*BY2WD; /* arg 2 is string */
ur->r0 = (ulong)up->ureg; /* arg 1 (R0) is ureg* */
*(ulong*)(sp+2*BY2WD) = (ulong)up->ureg; /* arg 1 0(FP) is ureg* */
*(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */
ur->usp = sp;
ur->pc = (ulong)up->notify;
up->notified = 1;
up->nnote--;
memmove(&up->lastnote, &up->note[0], sizeof(Note));
memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
qunlock(&up->debug);
splhi();
return 1;
}
/*
* Check that status is OK to return from note.
*/
int
validstatus(ulong kstatus, ulong ustatus)
{
if((kstatus & 7) != (ustatus & 7))
return 0;
if((ustatus&UMODE) != UMODE)
return 0;
return 1;
}
/*
* Return user to state before notify()
*/
void
noted(Ureg *kur, Ureg **urp, ulong arg0)
{
Ureg *nur;
ulong oureg, sp;
qlock(&up->debug);
if(arg0!=NRSTR && !up->notified) {
qunlock(&up->debug);
pprint("call to noted() when not notified\n");
pexit("Suicide", 0);
}
up->notified = 0;
up->fpstate &= ~FPillegal;
nur = up->ureg;
oureg = (ulong)nur;
if((oureg & (BY2V-1))
|| !okaddr(oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
qunlock(&up->debug);
pprint("bad ureg in noted or call to noted() when not notified\n");
pexit("Suicide", 0);
}
if(!validstatus(kur->status, nur->status)) {
qunlock(&up->debug);
pprint("bad noted ureg status %lux\n", (ulong)nur->status);
pexit("Suicide", 0);
}
memmove(*urp, up->ureg, sizeof(Ureg));
switch(arg0) {
case NCONT:
case NRSTR:
if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){
qunlock(&up->debug);
pprint("suicide: trap in noted\n");
pexit("Suicide", 0);
}
up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD));
qunlock(&up->debug);
splhi();
rfnote(urp);
break;
case NSAVE:
if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){
qunlock(&up->debug);
pprint("suicide: trap in noted\n");
pexit("Suicide", 0);
}
qunlock(&up->debug);
sp = oureg-4*BY2WD-ERRMAX;
splhi();
(*urp)->sp = sp;
((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */
((ulong*)sp)[0] = 0; /* arg 0 is pc */
(*urp)->r0 = oureg; /* arg 1 is ureg* */
rfnote(urp);
break;
default:
up->lastnote.flag = NDebug;
/* fall through */
case NDFLT:
qunlock(&up->debug);
if(up->lastnote.flag == NDebug)
pprint("suicide: %s\n", up->lastnote.msg);
pexit(up->lastnote.msg, up->lastnote.flag!=NDebug);
}
}
#include "../port/systab.h"
long
syscall(Ureg *aur)
{
int i;
char *e;
long ret;
ulong sp;
Ureg *ur;
ulong scallnr;
m->syscall++;
up = m->proc;
up->insyscall = 1;
ur = aur;
up->pc = ur->pc;
up->dbgreg = aur;
ur->type = 5; /* for debugging */
scallnr = ur->r0;
up->scallnr = ur->r0;
spllo();
sp = ur->sp;
up->nerrlab = 0;
ret = -1;
if(!waserror()) {
if(scallnr >= nsyscall || systab[scallnr] == nil){
pprint("bad sys call %d pc %lux\n", up->scallnr, (ulong)ur->pc);
postnote(up, 1, "sys: bad sys call", NDebug);
error(Ebadarg);
}
if(sp & (BY2WD-1)){ /* XXX too weak? */
pprint("odd sp in sys call pc %lux sp %lux\n",
(ulong)ur->pc, (ulong)ur->sp);
postnote(up, 1, "sys: odd stack", NDebug);
error(Ebadarg);
}
if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs)))
validaddr(sp, sizeof(Sargs), 0);
up->s = *((Sargs*)(sp+2*BY2WD));
up->psstate = sysctab[scallnr];
ret = systab[scallnr]((va_list)up->s.args);
poperror();
}else{
/* failure: save the error buffer for errstr */
e = up->syserrstr;
up->syserrstr = up->errstr;
up->errstr = e;
}
if(up->nerrlab){
print("bad errstack [%uld]: %d extra\n", scallnr, up->nerrlab);
for(i = 0; i < NERR; i++)
print("sp=%lux pc=%lux\n",
up->errlab[i].sp, up->errlab[i].pc);
panic("error stack");
}
up->nerrlab = 0;
up->psstate = 0;
up->insyscall = 0;
if(scallnr == NOTED) /* ugly hack */
noted(ur, &aur, *(ulong*)(sp+2*BY2WD)); /* doesn't return */
if(scallnr!=RFORK && (up->procctl || up->nnote)){
ur->r0 = ret; /* load up for noted() */
if(notify(ur))
return ur->r0;
}
return ret;
}
void
forkchild(Proc *p, Ureg *ur)
{
Ureg *cur;
p->sched.sp = (ulong)p->kstack+KSTACK-(4*BY2WD+sizeof(Ureg));
p->sched.pc = (ulong)forkret;
cur = (Ureg*)(p->sched.sp+4*BY2WD);
memmove(cur, ur, sizeof(Ureg));
/* Things from bottom of syscall we never got to execute */
p->psstate = 0;
p->insyscall = 0;
}
static
void
linkproc(void)
{
spllo();
up->kpfun(up->kparg);
pexit("kproc exiting", 0);
}
void
kprocchild(Proc *p, void (*func)(void*), void *arg)
{
p->sched.pc = (ulong)linkproc;
p->sched.sp = (ulong)p->kstack+KSTACK;
p->kpfun = func;
p->kparg = arg;
}
uintptr
execregs(uintptr entry, ulong ssize, ulong nargs)
{
Ureg *ur;
ulong *sp;
sp = (ulong*)(USTKTOP - ssize);
*--sp = nargs;
ur = (Ureg*)up->dbgreg;
ur->usp = (ulong)sp;
ur->pc = entry;
return USTKTOP-BY2WD; /* address of user-level clock */
}
uintptr
userpc(void)
{
Ureg *ur;
ur = (Ureg*)up->dbgreg;
return ur->pc;
}
/* This routine must save the values of registers the user is not permitted to write
* from devproc and then restore the saved values before returning
*/
void
setregisters(Ureg *xp, char *pureg, char *uva, int n)
{
ulong status;
status = xp->status;
memmove(pureg, uva, n);
xp->status = status;
}
/* Give enough context in the ureg to produce a kernel stack for
* a sleeping process
*/
void
setkernur(Ureg *xp, Proc *p)
{
xp->pc = p->sched.pc;
xp->sp = p->sched.sp;
xp->r26 = (ulong)sched;
}
uintptr
dbgpc(Proc *p)
{
Ureg *ur;
ur = p->dbgreg;
if(ur == 0)
return 0;
return ur->pc;
}
void
illegal(Ureg *ur)
{
switch ((int)ur->a0) {
case 0: /* breakpoint */
ur->pc -= 4;
fataltrap(ur, "breakpoint");
break;
case 1: /* bugchk */
fataltrap(ur, "trap: bugchk");
break;
case 2: /* gentrap */
fataltrap(ur, "trap: gentrap");
break;
case 3: /* FEN */
fen(ur);
break;
case 4: /* opDEC */
fataltrap(ur, "trap: illegal instruction");
break;
default:
panic("illegal illegal %d", (int)ur->a0);
break;
}
}
void
fen(Ureg *ur)
{
if(up){
switch(up->fpstate){
case FPinit:
restfpregs(&initfp);
up->fpstate = FPactive;
//print("EI=%lux+", initfp.fpstatus);
return;
case FPinactive:
restfpregs(&up->fpsave);
up->fpstate = FPactive;
//print("EIA=%lux+", up->fpsave.fpstatus);
return;
}
}
fataltrap(ur, "trap: floating enable"); /* should never happen */
}

View file

@ -1,5 +1,4 @@
ARCH=\
alphapc\
bcm\
bitsy\
kw\

View file

@ -1,4 +0,0 @@
TEXT getcallerpc(SB), $-8
MOVL 0(SP), R0
RET

View file

@ -1,57 +0,0 @@
#define EXCB WORD $0x60000400 /* until 7a/7l catch up */
TEXT getfsr(SB), $8
EXCB
MOVT FPCR, F0
EXCB
MOVT F0, tmp-8(SP)
MOVL tmp-4(SP), R1
MOVQ $0x01e00000, R2
AND R2, R1, R0
RET
TEXT setfsr(SB), $8
MOVQ $0x01e00000, R2
EXCB
MOVT FPCR, F0
EXCB
MOVT F0, tmp-8(SP)
MOVL tmp-4(SP), R1
ANDNOT R2, R1, R3
AND R2, R0, R4
OR R3, R4, R5
MOVL R5, tmp-4(SP)
MOVT tmp-8(SP), F0
EXCB
MOVT F0, FPCR
EXCB
RET
TEXT getfcr(SB), $8
EXCB
MOVT FPCR, F0
EXCB
MOVT F0, tmp-8(SP)
MOVL tmp-4(SP), R1
MOVQ $0x700c0000, R2
AND R2, R1, R0
XOR R2, R0
RET
TEXT setfcr(SB), $8
MOVQ $0x700c0000, R2
XOR R2, R0
EXCB
MOVT FPCR, F0
EXCB
MOVT F0, tmp-8(SP)
MOVL tmp-4(SP), R1
ANDNOT R2, R1, R3
AND R2, R0, R4
OR R3, R4, R5
MOVL R5, tmp-4(SP)
MOVT tmp-8(SP), F0
EXCB
MOVT F0, FPCR
EXCB
RET

View file

@ -1,12 +0,0 @@
extern long __SEEK(long long*, int, long long, int);
long long
_SEEK(int fd, long long o, int p)
{
long long l;
if(__SEEK(&l, fd, o, p) < 0)
l = -1;
return l;
}

View file

@ -1,5 +0,0 @@
void
_cycles(unsigned long long *u)
{
*u = 0;
}

View file

@ -1,189 +0,0 @@
/*
* ulong
* _udiv(ulong num, ulong den)
* {
* int i;
* ulong quo;
*
* if(den == 0)
* *(ulong*)-1 = 0;
* quo = num;
* if(quo > 1<<(32-1))
* quo = 1<<(32-1);
* for(i=0; den<quo; i++)
* den <<= 1;
* quo = 0;
* for(; i>=0; i--) {
* quo <<= 1;
* if(num >= den) {
* num -= den;
* quo |= 1;
* }
* den >>= 1;
* }
* return quo::num;
* }
*/
#define NOPROF 1
/*
* calling sequence:
* num: 8(R30)
* den: 12(R30)
* returns
* quo: 8(R30)
* rem: 12(R30)
*/
TEXT _udivmodl(SB), NOPROF, $-8
MOVQ $-1, R11
SLLQ $31, R11 /* (1<<31) in canonical form */
MOVL 8(R30), R23 /* numerator */
MOVL 12(R30), R10 /* denominator */
BNE R10, udm20
MOVQ R31, -1(R31) /* fault -- divide by zero; todo: use gentrap? */
udm20:
MOVQ R23, R12
BGE R12, udm34
MOVQ R11, R12
udm34:
MOVQ R31, R11
udm38:
CMPUGE R10, R12, R24
BNE R24, udm54
SLLL $1, R10
ADDQ $1, R11
JMP udm38
udm54:
MOVQ R31, R12
udm58:
BLT R11, udm8c
SLLL $1, R12
CMPUGE R23, R10, R24
BEQ R24, udm7c
SUBL R10, R23
OR $1, R12
udm7c:
SRLL $1, R10
SUBQ $1, R11
JMP udm58
udm8c:
MOVL R12, 8(R30) /* quotient */
MOVL R23, 12(R30) /* remainder */
RET
/*
* save working registers
* and bring in num/den parameters
*/
TEXT _unsargl(SB), NOPROF, $-8
MOVQ R10, 24(R30)
MOVQ R11, 32(R30)
MOVQ R12, 40(R30)
MOVQ R23, 48(R30)
MOVQ R24, 56(R30)
MOVL R27, 8(R30)
MOVL 72(R30), R27
MOVL R27, 12(R30)
RET
/*
* save working registers
* and bring in absolute value
* of num/den parameters
*/
TEXT _absargl(SB), NOPROF, $-8
MOVQ R10, 24(R30)
MOVQ R11, 32(R30)
MOVQ R12, 40(R30)
MOVQ R23, 48(R30)
MOVQ R24, 56(R30)
MOVL R27, 64(R30)
BGE R27, ab1
SUBL R27, R31, R27
ab1:
MOVL R27, 8(R30) /* numerator */
MOVL 72(R30), R27
BGE R27, ab2
SUBL R27, R31, R27
ab2:
MOVL R27, 12(R30) /* denominator */
RET
/*
* restore registers and
* return to original caller
* answer is in R27
*/
TEXT _retargl(SB), NOPROF, $-8
MOVQ 24(R30), R10
MOVQ 32(R30), R11
MOVQ 40(R30), R12
MOVQ 48(R30), R23
MOVQ 56(R30), R24
MOVL 0(R30), R26
ADDQ $64, R30
RET /* back to main sequence */
TEXT _divl(SB), NOPROF, $-8
SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
MOVL R26, 0(R30)
JSR _absargl(SB)
JSR _udivmodl(SB)
MOVL 8(R30), R27
MOVL 64(R30), R10 /* clean up the sign */
MOVL 72(R30), R11
XOR R11, R10
BGE R10, div1
SUBL R27, R31, R27
div1:
JSR _retargl(SB)
RET /* not executed */
TEXT _divlu(SB), NOPROF, $-8
SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
MOVL R26, 0(R30)
JSR _unsargl(SB)
JSR _udivmodl(SB)
MOVL 8(R30), R27
JSR _retargl(SB)
RET /* not executed */
TEXT _modl(SB), NOPROF, $-8
SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
MOVL R26, 0(R30)
JSR _absargl(SB)
JSR _udivmodl(SB)
MOVL 12(R30), R27
MOVL 64(R30), R10 /* clean up the sign */
BGE R10, div2
SUBL R27, R31, R27
div2:
JSR _retargl(SB)
RET /* not executed */
TEXT _modlu(SB), NOPROF, $-8
SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
MOVL R26, 0(R30)
JSR _unsargl(SB)
JSR _udivmodl(SB)
MOVL 12(R30), R27
JSR _retargl(SB)
RET /* not executed */

View file

@ -1,191 +0,0 @@
/*
* uvlong
* _udiv(uvlong num, uvlong den)
* {
* int i;
* uvlong quo;
*
* if(den == 0)
* *(ulong*)-1 = 0;
* quo = num;
* if(quo > 1<<(64-1))
* quo = 1<<(64-1);
* for(i=0; den<quo; i++)
* den <<= 1;
* quo = 0;
* for(; i>=0; i--) {
* quo <<= 1;
* if(num >= den) {
* num -= den;
* quo |= 1;
* }
* den >>= 1;
* }
* return quo::num;
* }
*/
#define NOPROF 1
/*
* calling sequence:
* num: 8(R30)
* den: 16(R30)
* returns
* quo: 8(R30)
* rem: 16(R30)
*/
TEXT _udivmodq(SB), NOPROF, $-8
MOVQ $1, R11
SLLQ $63, R11
MOVQ 8(R30), R23 /* numerator */
MOVQ 16(R30), R10 /* denominator */
BNE R10, udm20
MOVQ R31, -1(R31) /* fault -- divide by zero; todo: use gentrap? */
udm20:
MOVQ R23, R12
BGE R12, udm34
MOVQ R11, R12
udm34:
MOVQ R31, R11
udm38:
CMPUGE R10, R12, R24
BNE R24, udm54
SLLQ $1, R10
ADDQ $1, R11
JMP udm38
udm54:
MOVQ R31, R12
udm58:
BLT R11, udm8c
SLLQ $1, R12
CMPUGE R23, R10, R24
BEQ R24, udm7c
SUBQ R10, R23
OR $1, R12
udm7c:
SRLQ $1, R10
SUBQ $1, R11
JMP udm58
udm8c:
MOVQ R12, 8(R30) /* quotient */
MOVQ R23, 16(R30) /* remainder */
RET
/*
* save working registers
* and bring in num/den parameters
*/
TEXT _unsargq(SB), NOPROF, $-8
MOVQ R10, 24(R30)
MOVQ R11, 32(R30)
MOVQ R12, 40(R30)
MOVQ R23, 48(R30)
MOVQ R24, 56(R30)
MOVQ R27, 8(R30)
MOVQ 72(R30), R27
MOVQ R27, 16(R30)
MOVQ (R30), R10 /* debug */
RET
/*
* save working registers
* and bring in absolute value
* of num/den parameters
*/
TEXT _absargq(SB), NOPROF, $-8
MOVQ R10, 24(R30)
MOVQ R11, 32(R30)
MOVQ R12, 40(R30)
MOVQ R23, 48(R30)
MOVQ R24, 56(R30)
MOVQ R27, 64(R30)
BGE R27, ab1
SUBQ R27, R31, R27
ab1:
MOVQ R27, 8(R30) /* numerator */
MOVQ 72(R30), R27
BGE R27, ab2
SUBQ R27, R31, R27
ab2:
MOVQ R27, 16(R30) /* denominator */
MOVQ (R30), R10 /* debug */
RET
/*
* restore registers and
* return to original caller
* answer is in R27
*/
TEXT _retargq(SB), NOPROF, $-8
MOVQ 24(R30), R10
MOVQ 32(R30), R11
MOVQ 40(R30), R12
MOVQ 48(R30), R23
MOVQ 56(R30), R24
MOVL 0(R30), R26
ADDQ $64, R30
RET /* back to main sequence */
TEXT _divq(SB), NOPROF, $-8
SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
MOVQ R26, 0(R30)
JSR _absargq(SB)
JSR _udivmodq(SB)
MOVQ 8(R30), R27
MOVQ 64(R30), R10 /* clean up the sign */
MOVQ 72(R30), R11
XOR R11, R10
BGE R10, div1
SUBQ R27, R31, R27
div1:
JSR _retargq(SB)
RET /* not executed */
TEXT _divqu(SB), NOPROF, $-8
SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
MOVQ R26, 0(R30)
JSR _unsargq(SB)
JSR _udivmodq(SB)
MOVQ 8(R30), R27
JSR _retargq(SB)
RET /* not executed */
TEXT _modq(SB), NOPROF, $-8
SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
MOVQ R26, 0(R30)
JSR _absargq(SB)
JSR _udivmodq(SB)
MOVQ 16(R30), R27
MOVQ 64(R30), R10 /* clean up the sign */
BGE R10, div2
SUBQ R27, R31, R27
div2:
JSR _retargq(SB)
RET /* not executed */
TEXT _modqu(SB), NOPROF, $-8
SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
MOVQ R26, 0(R30)
JSR _unsargq(SB)
JSR _udivmodq(SB)
MOVQ 16(R30), R27
JSR _retargq(SB)
RET /* not executed */

View file

@ -1,33 +0,0 @@
TEXT getfsr(SB), $8
TRAPB
MOVT FPCR, F0
TRAPB
MOVT F0, tmp-8(SP)
MOVL tmp-4(SP), R0
RET
TEXT setfsr(SB), $8
SLLQ $32, R0
MOVQ R0, tmp-8(SP)
MOVT tmp-8(SP), F0
TRAPB
MOVT F0, FPCR
TRAPB
RET
TEXT getfcr(SB), $8
TRAPB
MOVT FPCR, F0
TRAPB
MOVT F0, tmp-8(SP)
MOVL tmp-4(SP), R0
RET
TEXT setfcr(SB), $8
SLLQ $32, R0
MOVQ R0, tmp-8(SP)
MOVT tmp-8(SP), F0
TRAPB
MOVT F0, FPCR
TRAPB
RET

View file

@ -1,26 +0,0 @@
#define _LOCK_EXTENSION
#include "../plan9/sys9.h"
#include <lock.h>
int tas(int*);
void
lock(Lock *lk)
{
while(tas(&lk->val))
_SLEEP(0);
}
int
canlock(Lock *lk)
{
if(tas(&lk->val))
return 0;
return 1;
}
void
unlock(Lock *lk)
{
lk->val = 0;
}

View file

@ -1,39 +0,0 @@
#define NPRIVATES 16
GLOBL _tos(SB), $4
GLOBL _errnoloc(SB), $4
GLOBL _plan9err(SB), $4
GLOBL _privates(SB), $4
GLOBL _nprivates(SB), $4
TEXT _main(SB), 1, $(20+4+128+NPRIVATES*4)
MOVQ $setSB(SB), R29
/* _tos = arg */
MOVL R0, _tos(SB)
MOVL $20(R30), R1
MOVL R1, _errnoloc(SB)
ADDL $4, R1
MOVL R1, _plan9err(SB)
ADDL $128, R1
MOVL R1, _privates(SB)
MOVQ $NPRIVATES, R1
MOVL R1, _nprivates(SB)
JSR _envsetup(SB)
/* main(argc, argv, environ); */
MOVL inargc-4(FP), R0
MOVL $inargv+0(FP), R1
MOVL environ(SB), R2
MOVL R0, 8(R30)
MOVL R1, 12(R30)
MOVL R2, 16(R30)
JSR main(SB)
loop:
MOVL R0, 8(R30)
JSR exit(SB)
MOVQ $_divq(SB), R31 /* force loading of divq */
MOVQ $_divl(SB), R31 /* force loading of divl */
JMP loop

View file

@ -1,56 +0,0 @@
#define NPRIVATES 16
GLOBL _tos(SB), $4
GLOBL _errnoloc(SB), $4
GLOBL _plan9err(SB), $4
GLOBL _privates(SB), $4
GLOBL _nprivates(SB), $4
TEXT _mainp(SB), 1, $(20+4+128+NPRIVATES*4)
MOVQ $setSB(SB), R29
/* _tos = arg */
MOVL R0, _tos(SB)
MOVL $20(R30), R1
MOVL R1, _errnoloc(SB)
ADDL $4, R1
MOVL R1, _plan9err(SB)
ADDL $128, R1
MOVL R1, _privates(SB)
MOVQ $NPRIVATES, R1
MOVL R1, _nprivates(SB)
/* _profmain(); */
JSR _profmain(SB)
/* _tos->prof.pp = _tos->prof.next; */
MOVL _tos+0(SB), R1
MOVL 4(R1), R2
MOVL R2, 0(R1)
JSR _envsetup(SB)
/* main(argc, argv, environ); */
MOVL inargc-4(FP), R0
MOVL $inargv+0(FP), R1
MOVL environ(SB), R2
MOVL R0, 8(R30)
MOVL R1, 12(R30)
MOVL R2, 16(R30)
JSR main(SB)
loop:
MOVL R0, 8(R30)
JSR exit(SB)
MOVQ $_divq(SB), R31 /* force loading of divq */
MOVQ $_divl(SB), R31 /* force loading of divl */
MOVQ $_profin(SB), R31 /* force loading of profile */
JMP loop
TEXT _saveret(SB), 1, $0
TEXT _savearg(SB), 1, $0
RET
TEXT _callpc(SB), 1, $0
MOVL argp-8(FP), R0
RET

View file

@ -1,7 +0,0 @@
#include <string.h>
void*
memcpy(void *a1, const void *a2, size_t n)
{
return memmove(a1, a2, n);
}

View file

@ -1,197 +0,0 @@
#define QUAD 8
#define ALIGN 64
#define BLOCK 64
TEXT memmove(SB), $0
MOVL from+4(FP), R7
MOVL n+8(FP), R10
MOVQ R0, R6
CMPUGE R7, R0, R5
BNE R5, _forward
MOVQ R6, R8 /* end to address */
ADDL R10, R6, R6 /* to+n */
ADDL R10, R7, R7 /* from+n */
CMPUGE $ALIGN, R10, R1 /* need at least ALIGN bytes */
BNE R1, _b1tail
_balign:
AND $(ALIGN-1), R6, R1
BEQ R1, _baligned
MOVBU -1(R7), R2
ADDL $-1, R6, R6
MOVB R2, (R6)
ADDL $-1, R7, R7
JMP _balign
_baligned:
AND $(QUAD-1), R7, R1 /* is the source quad-aligned */
BNE R1, _bunaligned
ADDL $(BLOCK-1), R8, R9
_bblock:
CMPUGE R9, R6, R1
BNE R1, _b8tail
MOVQ -64(R7), R22
MOVQ -56(R7), R23
MOVQ -48(R7), R24
MOVQ -40(R7), R25
MOVQ -32(R7), R2
MOVQ -24(R7), R3
MOVQ -16(R7), R4
MOVQ -8(R7), R5
SUBL $64, R6, R6
SUBL $64, R7, R7
MOVQ R22, (R6)
MOVQ R23, 8(R6)
MOVQ R24, 16(R6)
MOVQ R25, 24(R6)
MOVQ R2, 32(R6)
MOVQ R3, 40(R6)
MOVQ R4, 48(R6)
MOVQ R5, 56(R6)
JMP _bblock
_b8tail:
ADDL $(QUAD-1), R8, R9
_b8block:
CMPUGE R9, R6, R1
BNE R1, _b1tail
MOVQ -8(R7), R2
SUBL $8, R6
MOVQ R2, (R6)
SUBL $8, R7
JMP _b8block
_b1tail:
CMPUGE R8, R6, R1
BNE R1, _ret
MOVBU -1(R7), R2
SUBL $1, R6, R6
MOVB R2, (R6)
SUBL $1, R7, R7
JMP _b1tail
_ret:
RET
_bunaligned:
ADDL $(16-1), R8, R9
_bu8block:
CMPUGE R9, R6, R1
BNE R1, _b1tail
MOVQU -16(R7), R4
MOVQU -8(R7), R3
MOVQU (R7), R2
SUBL $16, R6
EXTQH R7, R2, R2
EXTQL R7, R3, R5
OR R5, R2, R11
EXTQH R7, R3, R3
EXTQL R7, R4, R4
OR R3, R4, R13
MOVQ R11, 8(R6)
MOVQ R13, (R6)
SUBL $16, R7
JMP _bu8block
_forward:
ADDL R10, R6, R8 /* end to address */
CMPUGE $ALIGN, R10, R1 /* need at least ALIGN bytes */
BNE R1, _f1tail
_falign:
AND $(ALIGN-1), R6, R1
BEQ R1, _faligned
MOVBU (R7), R2
ADDL $1, R6, R6
ADDL $1, R7, R7
MOVB R2, -1(R6)
JMP _falign
_faligned:
AND $(QUAD-1), R7, R1 /* is the source quad-aligned */
BNE R1, _funaligned
SUBL $(BLOCK-1), R8, R9
_fblock:
CMPUGT R9, R6, R1
BEQ R1, _f8tail
MOVQ (R7), R2
MOVQ 8(R7), R3
MOVQ 16(R7), R4
MOVQ 24(R7), R5
MOVQ 32(R7), R22
MOVQ 40(R7), R23
MOVQ 48(R7), R24
MOVQ 56(R7), R25
ADDL $64, R6, R6
ADDL $64, R7, R7
MOVQ R2, -64(R6)
MOVQ R3, -56(R6)
MOVQ R4, -48(R6)
MOVQ R5, -40(R6)
MOVQ R22, -32(R6)
MOVQ R23, -24(R6)
MOVQ R24, -16(R6)
MOVQ R25, -8(R6)
JMP _fblock
_f8tail:
SUBL $(QUAD-1), R8, R9
_f8block:
CMPUGT R9, R6, R1
BEQ R1, _f1tail
MOVQ (R7), R2
ADDL $8, R6
ADDL $8, R7
MOVQ R2, -8(R6)
JMP _f8block
_f1tail:
CMPUGT R8, R6, R1
BEQ R1, _fret
MOVBU (R7), R2
ADDL $1, R6, R6
ADDL $1, R7, R7
MOVB R2, -1(R6)
JMP _f1tail
_fret:
RET
_funaligned:
SUBL $(16-1), R8, R9
_fu8block:
CMPUGT R9, R6, R1
BEQ R1, _f1tail
MOVQU (R7), R2
MOVQU 8(R7), R3
MOVQU 16(R7), R4
EXTQL R7, R2, R2
EXTQH R7, R3, R5
OR R5, R2, R11
EXTQL R7, R3, R3
MOVQ R11, (R6)
EXTQH R7, R4, R4
OR R3, R4, R11
MOVQ R11, 8(R6)
ADDL $16, R6
ADDL $16, R7
JMP _fu8block

View file

@ -1,61 +0,0 @@
TEXT memset(SB), $0
MOVL R0, R6
MOVBU data+4(FP), R2
MOVL n+8(FP), R10
ADDL R10, R0, R8
CMPUGE $8, R10, R1 /* need at least 8 bytes */
BNE R1, _1loop
SLLQ $8, R2, R1 /* replicate the byte */
OR R1, R2
SLLQ $16, R2, R1
OR R1, R2
SLLQ $32, R2, R1
OR R1, R2
_align:
AND $(8-1), R6, R1
BEQ R1, _aligned
MOVB R2, (R6)
ADDL $1, R6, R6
JMP _align
_aligned:
SUBL $(64-1), R8, R9 /* end pointer minus slop */
_64loop:
CMPUGT R9, R6, R1
BEQ R1, _8tail
MOVQ R2, (R6)
MOVQ R2, 8(R6)
MOVQ R2, 16(R6)
MOVQ R2, 24(R6)
MOVQ R2, 32(R6)
MOVQ R2, 40(R6)
MOVQ R2, 48(R6)
MOVQ R2, 56(R6)
ADDL $64, R6, R6
JMP _64loop
_8tail:
SUBL $(8-1), R8, R9
_8loop:
CMPUGT R9, R6, R1
BEQ R1, _1loop
MOVQ R2, (R6)
ADDL $8, R6
JMP _8loop
_1loop:
CMPUGT R8, R6, R1
BEQ R1, _ret
MOVB R2, (R6)
ADDL $1, R6
JMP _1loop
_ret:
RET

View file

@ -1,23 +0,0 @@
APE=/sys/src/ape
<$APE/config
LIB=/$objtype/lib/ape/libap.a
OFILES=\
_seek.$O\
cycles.$O\
divl.$O\
divq.$O\
getfcr.$O\
lock.$O\
main9.$O\
main9p.$O\
memcpy.$O\
memmove.$O\
memset.$O\
notetramp.$O\
setjmp.$O\
tas.$O\
</sys/src/cmd/mksyslib
CFLAGS=-c -D_POSIX_SOURCE -D_PLAN9_SOURCE

View file

@ -1,72 +0,0 @@
#include "../plan9/lib.h"
#include "../plan9/sys9.h"
#include <signal.h>
#include <setjmp.h>
/* A stack to hold pcs when signals nest */
#define MAXSIGSTACK 20
typedef struct Pcstack Pcstack;
static struct Pcstack {
int sig;
void (*hdlr)(int, char*, Ureg*);
unsigned long restorepc;
Ureg *u;
} pcstack[MAXSIGSTACK];
static int nstack = 0;
static void notecont(Ureg*, char*);
void
_notetramp(int sig, void (*hdlr)(int, char*, Ureg*), Ureg *u)
{
Pcstack *p;
if(nstack >= MAXSIGSTACK)
_NOTED(1); /* nesting too deep; just do system default */
p = &pcstack[nstack];
p->restorepc = u->pc;
p->sig = sig;
p->hdlr = hdlr;
p->u = u;
nstack++;
u->pc = (unsigned long) notecont;
_NOTED(2); /* NSAVE: clear note but hold state */
}
static void
notecont(Ureg *u, char *s)
{
Pcstack *p;
void(*f)(int, char*, Ureg*);
p = &pcstack[nstack-1];
f = p->hdlr;
u->pc = p->restorepc;
nstack--;
(*f)(p->sig, s, u);
_NOTED(3); /* NRSTR */
}
#define JMPBUFPC 1
#define JMPBUFSP 0
extern sigset_t _psigblocked;
void
siglongjmp(sigjmp_buf j, int ret)
{
struct Ureg *u;
if(j[0])
_psigblocked = j[1];
if(nstack == 0 || pcstack[nstack-1].u->sp > j[2+JMPBUFSP])
longjmp(j+2, ret);
u = pcstack[nstack-1].u;
nstack--;
u->r0 = ret;
if(ret == 0)
u->r0 = 1;
u->pc = j[2+JMPBUFPC];
u->sp = j[2+JMPBUFSP];
_NOTED(3); /* NRSTR */
}

View file

@ -1,24 +0,0 @@
TEXT setjmp(SB), 1, $-8
MOVL R30, (R0)
MOVL R26, 4(R0)
MOVQ $0, R0
RET
TEXT sigsetjmp(SB), 1, $-8
MOVL savemask+4(FP), R3
MOVL R3, 0(R0)
MOVL $_psigblocked(SB), R3
MOVL R3, 4(R0)
MOVL R30, 8(R0)
MOVL R26, 12(R0)
MOVQ $0, R0
RET
TEXT longjmp(SB), 1, $-8
MOVL r+4(FP), R3
BNE R3, ok /* ansi: "longjmp(0) => longjmp(1)" */
MOVQ $1, R3 /* bless their pointed heads */
ok: MOVL (R0), R30
MOVL 4(R0), R26
MOVL R3, R0
RET

View file

@ -1,10 +0,0 @@
TEXT tas(SB), $-8
MOVQ R0, R1 /* l */
tas1:
MOVLL (R1), R0 /* l->key */
BNE R0, tas2
MOVQ $1, R2
MOVLC R2, (R1) /* l->key = 1 */
BEQ R2, tas1 /* write failed, try again? */
tas2:
RET

View file

@ -1,15 +0,0 @@
APE=/sys/src/ape
<$APE/config
LIB=/$objtype/lib/ape/libmp.a
HFILES=\
/sys/include/ape/mp.h\
../../../../libmp/port/dat.h
OFILES=\
UPDATE=mkfile\
$HFILES\
</sys/src/cmd/mksyslib

View file

@ -1,15 +0,0 @@
APE=/sys/src/ape
<$APE/config
LIB=/$objtype/lib/ape/libsec.a
OFILES= \
HFILES=/sys/include/ape/libsec.h
UPDATE=mkfile
</sys/src/cmd/mksyslib
%.$O: /sys/src/libsec/$objtype/%.s
$AS $AFLAGS /sys/src/libsec/$objtype/$stem.s

View file

@ -1,556 +0,0 @@
#include "u.h"
#include "lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "ip.h"
uchar broadcast[Eaddrlen] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static ushort tftpport = 5000;
static int Id = 1;
static Netaddr myaddr;
static Netaddr server;
typedef struct {
uchar header[4];
uchar data[Segsize];
} Tftp;
static Tftp tftpb;
int
etherrxpkt(int ctlrno, Etherpkt *pkt, int timo)
{
int n;
for (;;) {
n = devread(ctlrno, (uchar*)pkt, sizeof(*pkt), 0);
if (n >= 0)
return n;
if (timo-- < 0)
return -1;
}
}
int
ethertxpkt(int ctlrno, Etherpkt *pkt, int len, int timo)
{
USED(timo);
return devwrite(ctlrno, (uchar*)pkt, len, 0);
}
static void
hnputs(uchar *ptr, ushort val)
{
ptr[0] = val>>8;
ptr[1] = val;
}
static void
hnputl(uchar *ptr, ulong val)
{
ptr[0] = val>>24;
ptr[1] = val>>16;
ptr[2] = val>>8;
ptr[3] = val;
}
static ulong
nhgetl(uchar *ptr)
{
return ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
}
static ushort
nhgets(uchar *ptr)
{
return ((ptr[0]<<8) | ptr[1]);
}
static short endian = 1;
static char* aendian = (char*)&endian;
#define LITTLE *aendian
static ushort
ptcl_csum(void *a, int len)
{
uchar *addr;
ulong t1, t2;
ulong losum, hisum, mdsum, x;
addr = a;
losum = 0;
hisum = 0;
mdsum = 0;
x = 0;
if((ulong)addr & 1) {
if(len) {
hisum += addr[0];
len--;
addr++;
}
x = 1;
}
while(len >= 16) {
t1 = *(ushort*)(addr+0);
t2 = *(ushort*)(addr+2); mdsum += t1;
t1 = *(ushort*)(addr+4); mdsum += t2;
t2 = *(ushort*)(addr+6); mdsum += t1;
t1 = *(ushort*)(addr+8); mdsum += t2;
t2 = *(ushort*)(addr+10); mdsum += t1;
t1 = *(ushort*)(addr+12); mdsum += t2;
t2 = *(ushort*)(addr+14); mdsum += t1;
mdsum += t2;
len -= 16;
addr += 16;
}
while(len >= 2) {
mdsum += *(ushort*)addr;
len -= 2;
addr += 2;
}
if(x) {
if(len)
losum += addr[0];
if(LITTLE)
losum += mdsum;
else
hisum += mdsum;
} else {
if(len)
hisum += addr[0];
if(LITTLE)
hisum += mdsum;
else
losum += mdsum;
}
losum += hisum >> 8;
losum += (hisum & 0xff) << 8;
while(hisum = losum>>16)
losum = hisum + (losum & 0xffff);
return ~losum;
}
static ushort
ip_csum(uchar *addr)
{
int len;
ulong sum = 0;
len = (addr[0]&0xf)<<2;
while(len > 0) {
sum += addr[0]<<8 | addr[1] ;
len -= 2;
addr += 2;
}
sum = (sum & 0xffff) + (sum >> 16);
sum = (sum & 0xffff) + (sum >> 16);
return (sum^0xffff);
}
static void
udpsend(int ctlrno, Netaddr *a, void *data, int dlen)
{
Udphdr *uh;
Etherhdr *ip;
Etherpkt pkt;
int len, ptcllen;
uh = (Udphdr*)&pkt;
memset(uh, 0, sizeof(Etherpkt));
memmove(uh->udpcksum+sizeof(uh->udpcksum), data, dlen);
/*
* UDP portion
*/
ptcllen = dlen + (UDP_HDRSIZE-UDP_PHDRSIZE);
uh->ttl = 0;
uh->udpproto = IP_UDPPROTO;
uh->frag[0] = 0;
uh->frag[1] = 0;
hnputs(uh->udpplen, ptcllen);
hnputl(uh->udpsrc, myaddr.ip);
hnputs(uh->udpsport, myaddr.port);
hnputl(uh->udpdst, a->ip);
hnputs(uh->udpdport, a->port);
hnputs(uh->udplen, ptcllen);
uh->udpcksum[0] = 0;
uh->udpcksum[1] = 0;
dlen = (dlen+1)&~1;
hnputs(uh->udpcksum, ptcl_csum(&uh->ttl, dlen+UDP_HDRSIZE));
/*
* IP portion
*/
ip = (Etherhdr*)&pkt;
len = UDP_EHSIZE+UDP_HDRSIZE+dlen; /* non-descriptive names */
ip->vihl = IP_VER|IP_HLEN;
ip->tos = 0;
ip->ttl = 255;
hnputs(ip->length, len-ETHER_HDR);
hnputs(ip->id, Id++);
ip->frag[0] = 0;
ip->frag[1] = 0;
ip->cksum[0] = 0;
ip->cksum[1] = 0;
hnputs(ip->cksum, ip_csum(&ip->vihl));
/*
* Ethernet MAC portion
*/
hnputs(ip->type, ET_IP);
memmove(ip->d, a->ea, sizeof(ip->d));
ethertxpkt(ctlrno, &pkt, len, Timeout);
}
static void
nak(int ctlrno, Netaddr *a, int code, char *msg, int report)
{
int n;
char buf[128];
buf[0] = 0;
buf[1] = Tftp_ERROR;
buf[2] = 0;
buf[3] = code;
strcpy(buf+4, msg);
n = strlen(msg) + 4 + 1;
udpsend(ctlrno, a, buf, n);
if(report)
print("\ntftp: error(%d): %s\n", code, msg);
}
static int
udprecv(int ctlrno, Netaddr *a, void *data, int dlen)
{
int n, len;
ushort csm;
Udphdr *h;
ulong addr, timo;
Etherpkt pkt;
static int rxactive;
if(rxactive == 0)
timo = 1000;
else
timo = Timeout;
timo += msec();
while(timo > msec()){
n = etherrxpkt(ctlrno, &pkt, timo-msec());
if(n <= 0)
continue;
h = (Udphdr*)&pkt;
if(nhgets(h->type) != ET_IP)
continue;
if(ip_csum(&h->vihl)) {
print("ip chksum error\n");
continue;
}
if(h->vihl != (IP_VER|IP_HLEN)) {
print("ip bad vers/hlen\n");
continue;
}
if(h->udpproto != IP_UDPPROTO)
continue;
h->ttl = 0;
len = nhgets(h->udplen);
hnputs(h->udpplen, len);
if(nhgets(h->udpcksum)) {
csm = ptcl_csum(&h->ttl, len+UDP_PHDRSIZE);
if(csm != 0) {
print("udp chksum error csum #%4lux len %d\n", csm, n);
break;
}
}
if(a->port != 0 && nhgets(h->udpsport) != a->port)
continue;
if(myaddr.port != 0 && nhgets(h->udpdport) != myaddr.port)
continue;
addr = nhgetl(h->udpsrc);
if(a->ip != Bcastip && addr != a->ip)
continue;
len -= UDP_HDRSIZE-UDP_PHDRSIZE;
if(len > dlen) {
print("udp: packet too big\n");
continue;
}
memmove(data, h->udpcksum+sizeof(h->udpcksum), len);
a->ip = addr;
a->port = nhgets(h->udpsport);
memmove(a->ea, pkt.s, sizeof(a->ea));
rxactive = 1;
return len;
}
return 0;
}
static int tftpblockno;
static int
tftpopen(int ctlrno, Netaddr *a, char *name, Tftp *tftp)
{
int i, len, rlen;
char buf[Segsize+2];
buf[0] = 0;
buf[1] = Tftp_READ;
len = sprint(buf+2, "%s", name) + 2;
len += sprint(buf+len+1, "octet") + 2;
for(i = 0; i < 5; i++){
udpsend(ctlrno, a, buf, len);
a->port = 0;
if((rlen = udprecv(ctlrno, a, tftp, sizeof(Tftp))) < sizeof(tftp->header))
continue;
switch((tftp->header[0]<<8)|tftp->header[1]){
case Tftp_ERROR:
print("tftpopen: error (%d): %s\n",
(tftp->header[2]<<8)|tftp->header[3], tftp->data);
return -1;
case Tftp_DATA:
tftpblockno = 1;
len = (tftp->header[2]<<8)|tftp->header[3];
if(len != tftpblockno){
print("tftpopen: block error: %d\n", len);
nak(ctlrno, a, 1, "block error", 0);
return -1;
}
return rlen-sizeof(tftp->header);
}
}
print("tftpopen: failed to connect to server\n");
return -1;
}
static int
tftpread(int ctlrno, Netaddr *a, Tftp *tftp, int dlen)
{
int blockno, len;
uchar buf[4];
buf[0] = 0;
buf[1] = Tftp_ACK;
buf[2] = tftpblockno>>8;
buf[3] = tftpblockno;
tftpblockno++;
dlen += sizeof(tftp->header);
buggery:
udpsend(ctlrno, a, buf, sizeof(buf));
if((len = udprecv(ctlrno, a, tftp, dlen)) != dlen){
print("tftpread: %d != %d\n", len, dlen);
nak(ctlrno, a, 2, "short read", 0);
}
blockno = (tftp->header[2]<<8)|tftp->header[3];
if(blockno != tftpblockno){
print("tftpread: block error: %d, expected %d\n", blockno, tftpblockno);
if(blockno == tftpblockno-1)
goto buggery;
nak(ctlrno, a, 1, "block error", 0);
return -1;
}
return len-sizeof(tftp->header);
}
// #define BOOT_MAGIC L_MAGIC
#define BOOT_MAGIC 0x0700e0c3
void
getether(char *dev, uchar *ea)
{
int i;
char *p;
p = dev;
for (i = 0; i < 8; i++) {
p = strchr(p, ' ');
if (p == 0)
panic("no ether addr");
p++;
}
for (i = 0; i < 6; i++) {
ea[i] = strtoul(p, &p, 16);
if (*p != (i == 5 ? ' ' : '-'))
panic("bad ether addr");
p++;
}
}
static char inibuf[BOOTARGSLEN];
int
bootp(char *dev)
{
Bootp req, rep;
int i, fd, dlen, segsize, text, data, bss, total;
uchar *addr, *p, ea[6];
char *cp;
ulong entry;
Exec *exec;
char *filename, confname[32];
getether(dev, ea);
fd = devopen(dev);
if (fd < 0)
panic("bootp devopen");
memset(&req, 0, sizeof(req));
req.op = Bootrequest;
req.htype = 1; /* ethernet */
req.hlen = Eaddrlen; /* ethernet */
memmove(req.chaddr, ea, Eaddrlen);
myaddr.ip = 0;
myaddr.port = BPportsrc;
memmove(myaddr.ea, ea, Eaddrlen);
for(i = 0; i < 10; i++) {
server.ip = Bcastip;
server.port = BPportdst;
memmove(server.ea, broadcast, sizeof(server.ea));
udpsend(fd, &server, &req, sizeof(req));
if(udprecv(fd, &server, &rep, sizeof(rep)) <= 0)
continue;
if(memcmp(req.chaddr, rep.chaddr, Eaddrlen))
continue;
if(rep.htype != 1 || rep.hlen != Eaddrlen)
continue;
break;
}
if(i >= 10) {
print("bootp timed out\n");
return -1;
}
sprint(confname, "/alpha/conf/%d.%d.%d.%d",
rep.yiaddr[0],
rep.yiaddr[1],
rep.yiaddr[2],
rep.yiaddr[3]);
if(rep.sname[0] != '\0')
print("%s ", rep.sname);
print("(%d.%d.%d.%d!%d): %s...",
rep.siaddr[0],
rep.siaddr[1],
rep.siaddr[2],
rep.siaddr[3],
server.port,
confname);
myaddr.ip = nhgetl(rep.yiaddr);
myaddr.port = tftpport++;
server.ip = nhgetl(rep.siaddr);
server.port = TFTPport;
if((dlen = tftpopen(fd, &server, confname, &tftpb)) < 0)
return -1;
cp = inibuf;
while(dlen > 0) {
if(cp-inibuf+dlen > BOOTARGSLEN)
panic("conf too large");
memmove(cp, tftpb.data, dlen);
cp += dlen;
if(dlen != Segsize)
break;
if((dlen = tftpread(fd, &server, &tftpb, sizeof(tftpb.data))) < 0)
return -1;
}
*cp = 0;
setconf(inibuf);
filename = "/alpha/9apc";
cp = getconf("bootfile");
if(cp != nil)
filename = cp;
print("%s\n", filename);
myaddr.port = tftpport++;
server.port = TFTPport;
if((dlen = tftpopen(fd, &server, filename, &tftpb)) < 0)
return -1;
exec = (Exec*)(tftpb.data);
if(dlen < sizeof(Exec) || GLLONG(exec->magic) != BOOT_MAGIC){
nak(fd, &server, 0, "bad magic number", 1);
return -1;
}
text = GLLONG(exec->text);
data = GLLONG(exec->data);
bss = GLLONG(exec->bss);
total = text+data+bss;
entry = GLLONG(exec->entry);
if (!validrgn(entry, entry+total))
panic("memory range not available: %lux-%lux\n", entry, entry+total);
print("%d", text);
addr = (uchar*)entry;
p = tftpb.data+sizeof(Exec);
dlen -= sizeof(Exec);
segsize = text;
for(;;){
if(dlen == 0){
if((dlen = tftpread(fd, &server, &tftpb, sizeof(tftpb.data))) < 0)
return -1;
p = tftpb.data;
}
if(segsize <= dlen)
i = segsize;
else
i = dlen;
memmove(addr, p, i);
addr += i;
p += i;
segsize -= i;
dlen -= i;
if(segsize <= 0){
if(data == 0)
break;
print("+%d", data);
segsize = data;
data = 0;
// addr = (uchar*)pground((uvlong)addr);
}
}
nak(fd, &server, 3, "ok", 0); /* tftpclose */
print("+%d=%d\n", bss, total);
print("entry: 0x%lux\n", entry);
kexec(entry);
return 0;
}

View file

@ -1,75 +0,0 @@
#include "u.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "lib.h"
static char *confname[MAXCONF];
static char *confval[MAXCONF];
static int nconf;
static char bootargs[BOOTARGSLEN];
char*
getconf(char *name)
{
int i;
for(i = 0; i < nconf; i++)
if(strcmp(confname[i], name) == 0)
return confval[i];
return 0;
}
void
setconf(char *buf)
{
char *cp, *line[MAXCONF];
int i, n;
/*
* Keep a pristine copy.
* Should change this to pass the parsed strings
* to the booted programme instead of the raw
* string, then it only gets done once.
*/
strcpy(bootargs, buf);
/* print("boot: stashing /alpha/conf boot args at 0x%lux\n",
bootargs); /* DEBUG */
conf.bootargs = bootargs;
n = getcfields(buf, line, MAXCONF, "\n");
for(i = 0; i < n; i++){
if(*line[i] == '#')
continue;
cp = strchr(line[i], '=');
if(cp == nil)
continue;
*cp++ = 0;
if(cp - line[i] >= NAMELEN+1)
*(line[i]+NAMELEN-1) = 0;
confname[nconf] = line[i];
confval[nconf] = cp;
nconf++;
}
}
int
getcfields(char* lp, char** fields, int n, char* sep)
{
int i;
for(i = 0; lp && *lp && i < n; i++){
while(*lp && strchr(sep, *lp) != 0)
*lp++ = 0;
if(*lp == 0)
break;
fields[i] = lp;
while(*lp && strchr(sep, *lp) == 0){
if(*lp == '\\' && *(lp+1) == '\n')
*lp++ = ' ';
lp++;
}
}
return i;
}

View file

@ -1,20 +0,0 @@
typedef struct Bank Bank;
typedef struct Bootconf Bootconf;
struct Bootconf
{
int nbank;
Bank *bank;
PCB *pcb;
uvlong maxphys;
char *bootargs;
};
struct Bank
{
uvlong min;
uvlong max;
};
#define BOOTARGSLEN (4096)
#define MAXCONF 32

View file

@ -1,243 +0,0 @@
#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;
}

View file

@ -1,169 +0,0 @@
typedef struct Hwrpb Hwrpb;
typedef struct Hwcpu Hwcpu;
typedef struct Hwcrb Hwcrb;
typedef struct Hwdsr Hwdsr;
typedef struct Procdesc Procdesc;
typedef struct Memdsc Memdsc;
typedef struct Memclust Memclust;
typedef struct PCB PCB;
struct Hwrpb
{
uvlong phys;
uvlong sign;
uvlong rev;
uvlong size;
uvlong cpu0;
uvlong by2pg;
uvlong pabits;
uvlong maxasn;
char ssn[16];
uvlong systype;
uvlong sysvar;
uvlong sysrev;
uvlong ifreq;
uvlong cfreq;
uvlong vptb;
uvlong resv;
uvlong tbhint;
uvlong ncpu;
uvlong cpulen;
uvlong cpuoff;
uvlong nctb;
uvlong ctblen;
uvlong ctboff;
uvlong crboff;
uvlong memoff;
uvlong confoff;
uvlong fruoff;
uvlong termsaveva;
uvlong termsavex;
uvlong termrestva;
uvlong termrestx;
uvlong termresetva;
uvlong termresetx;
uvlong sysresv;
uvlong hardresv;
uvlong csum;
uvlong rxrdymsk;
uvlong txrdymsk;
uvlong dsroff; /* rev 6 or higher */
};
extern Hwrpb* hwrpb;
struct Hwcpu
{
uvlong hwpcb[16];
uvlong state;
uvlong palmainlen;
uvlong palscratchlen;
uvlong palmainpa;
uvlong palscratchpa;
uvlong palrev;
uvlong cputype;
uvlong cpuvar;
uvlong cpurev;
uvlong serial[2];
/* more crap ... */
};
struct Hwdsr
{
vlong smm;
uvlong lurtoff;
uvlong sysnameoff;
};
struct Hwcrb
{
uvlong dispatchva;
uvlong dispatchpa;
uvlong fixupva;
uvlong fixuppa;
/* more, uninteresting crud */
};
struct Procdesc
{
uvlong bollocks;
uvlong addr;
};
struct Memclust
{
uvlong pfn;
uvlong npages;
uvlong ntest;
uvlong vabitm;
uvlong pabitm;
uvlong csumbitm;
uvlong usage;
};
struct Memdsc
{
uvlong csum;
uvlong opt;
uvlong nclust;
Memclust clust[1];
};
enum
{
PRINTSIZE = 256,
MB = (1024*1024),
};
#define L_MAGIC ((((4*23)+0)*23)+7)
typedef struct Exec Exec;
struct Exec
{
uchar magic[4]; /* magic number */
uchar text[4]; /* size of text segment */
uchar data[4]; /* size of initialized data */
uchar bss[4]; /* size of uninitialized data */
uchar syms[4]; /* size of symbol table */
uchar entry[4]; /* entry point */
uchar spsz[4]; /* size of sp/pc offset table */
uchar pcsz[4]; /* size of pc/line number table */
};
enum {
Eaddrlen = 6,
ETHERMINTU = 60, /* minimum transmit size */
ETHERMAXTU = 1514, /* maximum transmit size */
ETHERHDRSIZE = 14, /* size of an ethernet header */
MaxEther = 2,
};
typedef struct {
uchar d[Eaddrlen];
uchar s[Eaddrlen];
uchar type[2];
uchar data[1500];
uchar crc[4];
} Etherpkt;
/*
* Process Control Block, used by OSF/1 PALcode when we switch to it
*/
struct PCB {
uvlong ksp;
uvlong usp;
uvlong ptbr;
ulong asn;
ulong pcc;
uvlong unique;
ulong fen;
ulong dummy;
uvlong rsrv1;
uvlong rsrv2;
};
#include "conf.h"
extern Bootconf conf;

View file

@ -1,40 +0,0 @@
#include "u.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "lib.h"
uchar pcbpage[64*1024+sizeof(PCB)];
PCB *pcb;
void (*kentry)(Bootconf*);
void
gokernel(void)
{
(*kentry)(&conf);
}
void
kexec(ulong entry)
{
uvlong pcbb, paltype;
pcb = (PCB*)(((ulong)pcbpage+0xffff) & ~0xffff); /* page align, even on 64K page Alphas */
memset(pcb, 0, sizeof(PCB));
pcb->ksp = (uvlong)&entry;
pcb->ptbr = getptbr();
pcb->fen = 1;
conf.pcb = pcb;
pcbb = paddr((uvlong)pcb);
kentry = (void(*)(Bootconf*))entry;
paltype = 2; /* OSF/1 please */
switch (swppal(paltype, (uvlong)gokernel, pcbb, hwrpb->vptb, pcb->ksp)) {
case 1:
panic("unknown PALcode variant");
case 2:
panic("PALcode variant not loaded");
default:
panic("weird return status from swppal");
}
}

View file

@ -1,37 +0,0 @@
uvlong allocate(int);
int bootp(char*);
void consinit(void);
int devopen(char*);
int devclose(int);
int devread(int, uchar*, int, int);
int devwrite(int, uchar*, int, int);
uvlong dispatch(uvlong, uvlong, uvlong, uvlong, uvlong);
void dumpenv(void);
void firmware(void);
uvlong gendispatch(uvlong, uvlong, uvlong, uvlong, uvlong, uvlong);
int getcfields(char*, char**, int, char*);
char* getconf(char*);
char* getenv(char*);
uvlong getptbr(void);
void kexec(ulong);
uvlong ldqp(uvlong);
void meminit(void);
void mmuinit(void);
ulong msec(void);
uvlong rdv(uvlong);
uvlong paddr(uvlong);
void panic(char *, ...);
ulong pcc_cnt(void);
uvlong pground(uvlong);
void putstrn(char *, int);
void setconf(char*);
void stqp(uvlong, uvlong);
int swppal(uvlong, uvlong, uvlong, uvlong, uvlong);
void tlbflush(void);
int validrgn(ulong, ulong);
void wrv(uvlong, uvlong);
#define GSHORT(p) (((p)[1]<<8)|(p)[0])
#define GLONG(p) ((GSHORT(p+2)<<16)|GSHORT(p))
#define GLSHORT(p) (((p)[0]<<8)|(p)[1])
#define GLLONG(p) ((GLSHORT(p)<<16)|GLSHORT(p+2))

View file

@ -1,98 +0,0 @@
typedef struct Udphdr Udphdr;
struct Udphdr
{
uchar d[6]; /* Ethernet destination */
uchar s[6]; /* Ethernet source */
uchar type[2]; /* Ethernet packet type */
uchar vihl; /* Version and header length */
uchar tos; /* Type of service */
uchar length[2]; /* packet length */
uchar id[2]; /* Identification */
uchar frag[2]; /* Fragment information */
/* Udp pseudo ip really starts here */
uchar ttl;
uchar udpproto; /* Protocol */
uchar udpplen[2]; /* Header plus data length */
uchar udpsrc[4]; /* Ip source */
uchar udpdst[4]; /* Ip destination */
uchar udpsport[2]; /* Source port */
uchar udpdport[2]; /* Destination port */
uchar udplen[2]; /* data length */
uchar udpcksum[2]; /* Checksum */
};
typedef struct Etherhdr Etherhdr;
struct Etherhdr
{
uchar d[6];
uchar s[6];
uchar type[2];
/* Now we have the ip fields */
uchar vihl; /* Version and header length */
uchar tos; /* Type of service */
uchar length[2]; /* packet length */
uchar id[2]; /* Identification */
uchar frag[2]; /* Fragment information */
uchar ttl; /* Time to live */
uchar proto; /* Protocol */
uchar cksum[2]; /* Header checksum */
uchar src[4]; /* Ip source */
uchar dst[4]; /* Ip destination */
};
enum
{
IP_VER = 0x40,
IP_HLEN = 0x05,
UDP_EHSIZE = 22,
UDP_PHDRSIZE = 12,
UDP_HDRSIZE = 20,
ETHER_HDR = 14,
IP_UDPPROTO = 17,
ET_IP = 0x800,
Bcastip = 0xffffffff,
BPportsrc = 68,
BPportdst = 67,
TFTPport = 69,
Timeout = 5000, /* milliseconds */
Bootrequest = 1,
Bootreply = 2,
Tftp_READ = 1,
Tftp_WRITE = 2,
Tftp_DATA = 3,
Tftp_ACK = 4,
Tftp_ERROR = 5,
Segsize = 512,
TFTPSZ = Segsize+10,
};
typedef struct Bootp Bootp;
struct Bootp
{
uchar op; /* opcode */
uchar htype; /* hardware type */
uchar hlen; /* hardware address len */
uchar hops; /* hops */
uchar xid[4]; /* a random number */
uchar secs[2]; /* elapsed snce client started booting */
uchar pad[2];
uchar ciaddr[4]; /* client IP address (client tells server) */
uchar yiaddr[4]; /* client IP address (server tells client) */
uchar siaddr[4]; /* server IP address */
uchar giaddr[4]; /* gateway IP address */
uchar chaddr[16]; /* client hardware address */
char sname[64]; /* server host name (optional) */
char file[128]; /* boot file name */
char vend[128]; /* vendor-specific goo */
};
typedef struct Netaddr Netaddr;
struct Netaddr
{
ulong ip;
ushort port;
char ea[Eaddrlen];
};

View file

@ -1,101 +0,0 @@
#include "mem.h"
#include "vmspal.h"
#define SP R30
TEXT _main(SB), $-8
MOVQ $setSB(SB), R29
MOVQ $edata(SB), R1
MOVQ $end(SB), R2
loop2:
MOVQ R31, (R1)
ADDQ $8, R1
CMPUGT R1, R2, R3
BEQ R3, loop2
JSR main(SB)
TEXT firmware(SB), $-8
CALL_PAL $PALhalt
MOVQ $_divq(SB), R31 /* touch _divq etc.; doesn't need to execute */
MOVQ $_divl(SB), R31 /* touch _divl etc.; doesn't need to execute */
RET
TEXT mb(SB), $-8
MB
RET
TEXT icflush(SB), $-8
CALL_PAL $PALimb
RET
TEXT tlbflush(SB), $-8
CALL_PAL $PALmtpr_tbia
RET
TEXT gendispatch(SB), $-8
MOVQ 8(FP), R16
MOVQ 16(FP), R17
MOVQ 24(FP), R18
MOVQ 32(FP), R19
MOVQ 40(FP), R20
MOVQ R26, R1
JSR (R0)
MOVQ R1, R26
RET /* 7a bug: should be RET (R1) */
TEXT rdv(SB), $-8
MOVQ (R0), R0
RET
TEXT wrv(SB), $-8
MOVQ 8(FP), R1
MOVQ R1, (R0)
RET
TEXT ipl(SB), $-8
CALL_PAL $PALmfpr_ipl
RET
TEXT mces(SB), $-8
CALL_PAL $PALmfpr_mces
RET
TEXT setipl(SB), $-8
MOVQ R0, R16
CALL_PAL $PALmtpr_ipl
RET
TEXT setmces(SB), $-8
MOVQ R0, R16
CALL_PAL $PALmtpr_mces
RET
TEXT ldqp(SB), $-8
MOVQ R0, R16
CALL_PAL $PALldqp
RET
TEXT stqp(SB), $-8
MOVQ R0, R16
MOVQ 8(FP), R17
CALL_PAL $PALstqp
RET
TEXT getptbr(SB), $-8
CALL_PAL $PALmfpr_ptbr
RET
TEXT swppal(SB), $-8
MOVQ R0, R16 /* which PALcode */
MOVQ 8(FP), R17 /* new PC */
MOVQ 16(FP), R18 /* PCBB (physical) */
MOVQ 24(FP), R19 /* VPTB */
MOVQ 32(FP), R20 /* new KSP */
CALL_PAL $PALswppal
RET
TEXT pcc_cnt(SB), $-8
MOVQ PCC, R1
MOVL R1, R0
RET

View file

@ -1,134 +0,0 @@
/*
* functions (possibly) linked in, complete, from libc.
*/
/*
* mem routines
*/
extern void *memccpy(void*, void*, int, long);
extern void *memset(void*, int, long);
extern int memcmp(void*, void*, long);
extern void *memmove(void*, void*, long);
extern void *memchr(void*, int, long);
/*
* string routines
*/
extern char *strcat(char*, char*);
extern char *strchr(char*, char);
extern int strcmp(char*, char*);
extern char *strcpy(char*, char*);
extern char *strncat(char*, char*, long);
extern char *strncpy(char*, char*, long);
extern int strncmp(char*, char*, long);
extern long strlen(char*);
extern int atoi(char*);
enum
{
UTFmax = 3, /* maximum bytes per rune */
Runesync = 0x80, /* cannot represent part of a UTF sequence */
Runeself = 0x80, /* rune and UTF sequences are the same (<) */
Runeerror = 0x80, /* decoding error in UTF */
};
/*
* rune routines
*/
extern int runetochar(char*, Rune*);
extern int chartorune(Rune*, char*);
extern char* utfrune(char*, long);
extern int utflen(char*);
extern int abs(int);
/*
* print routines
*/
typedef
struct
{
char* out; /* pointer to next output */
char* eout; /* pointer to end */
int f1;
int f2;
int f3;
int chr;
} Fconv;
extern void strconv(char*, Fconv*);
extern int numbconv(va_list*, Fconv*);
extern char *doprint(char*, char*, char*, va_list);
extern int fmtinstall(int, int (*)(va_list*, Fconv*));
extern int sprint(char*, char*, ...);
extern int snprint(char*, int, char*, ...);
extern int print(char*, ...);
/*
* one-of-a-kind
*/
extern long strtol(char*, char**, int);
extern ulong strtoul(char*, char**, int);
extern vlong strtovl(char*, char**, int);
extern char etext[];
extern char edata[];
extern char end[];
/*
* Syscall data structures
*/
#define MORDER 0x0003 /* mask for bits defining order of mounting */
#define MREPL 0x0000 /* mount replaces object */
#define MBEFORE 0x0001 /* mount goes before others in union directory */
#define MAFTER 0x0002 /* mount goes after others in union directory */
#define MCREATE 0x0004 /* permit creation in mounted directory */
#define MRECOV 0x0008 /* perform recovery if mount channel is lost */
#define MCACHE 0x0010 /* cache some data */
#define MMASK 0x001F /* all bits on */
#define OREAD 0 /* open for read */
#define OWRITE 1 /* write */
#define ORDWR 2 /* read and write */
#define OEXEC 3 /* execute, == read but check execute permission */
#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */
#define OCEXEC 32 /* or'ed in, close on exec */
#define ORCLOSE 64 /* or'ed in, remove on close */
#define NCONT 0 /* continue after note */
#define NDFLT 1 /* terminate after note */
#define NSAVE 2 /* clear note but hold state */
#define NRSTR 3 /* restore saved state */
typedef struct Qid Qid;
typedef struct Dir Dir;
typedef struct Waitmsg Waitmsg;
#define ERRLEN 64
#define DIRLEN 116
#define NAMELEN 28
struct Qid
{
ulong path;
ulong vers;
};
struct Dir
{
char name[NAMELEN];
char uid[NAMELEN];
char gid[NAMELEN];
Qid qid;
ulong mode;
long atime;
long mtime;
Length;
short type;
short dev;
};
struct Waitmsg
{
char pid[12]; /* of loved one */
char time[3*12]; /* of loved one and descendants */
char msg[ERRLEN];
};

View file

@ -1,25 +0,0 @@
#include "u.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "lib.h"
Bootconf conf;
void
main(void)
{
char *dev;
consinit();
meminit();
mmuinit();
dev = getenv("booted_dev");
if (dev == 0)
panic("get dev name");
if (strncmp(dev, "BOOTP", 5) == 0)
bootp(dev);
else
print("boot device %s not supported\n", dev);
}

View file

@ -1,15 +0,0 @@
/*
* Memory and machine-specific definitions. Used in C and assembler.
*/
#define BI2BY 8 /* bits per byte */
#define BI2WD 32 /* bits per word */
#define BY2WD 4 /* bytes per word */
#define BY2V 8 /* bytes per vlong */
#define KZERO 0x80000000
#define PTEVALID 0xff01
#define PTEKVALID 0x1101
#define PTEASM 0x0010
#define PTEGH(s) ((s)<<5)

View file

@ -1,108 +0,0 @@
#include "u.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "lib.h"
static int debug;
enum {
Maxbank = 2,
};
Bank bank[Maxbank];
int nbank;
void
meminit(void)
{
Memdsc *mem;
Memclust *c;
int i;
uvlong npage, p0, p1;
extern ulong _main[], edata[];
mem = (Memdsc*)((ulong)hwrpb + hwrpb->memoff);
if (debug)
print("\nnumber of clusters: %lld\n", mem->nclust);
npage = 0;
conf.maxphys = 0;
for (i = 0; i < mem->nclust; i++) {
c = &mem->clust[i];
p0 = c->pfn*hwrpb->by2pg;
p1 = (c->pfn+c->npages)*hwrpb->by2pg;
if (debug) {
print("clust%d: %llux-%llux, tested %llud/%llud vabitm %llux usage %llux\n",
i, p0, p1, c->ntest, c->npages, c->vabitm, c->usage);
if (c->vabitm)
print("\tfirst 64 pages: %llux\n", *(uvlong*)c->vabitm);
}
npage += c->npages;
if (p1 > conf.maxphys)
conf.maxphys = p1;
switch ((ulong)c->usage&3) {
case 0:
if (nbank >= Maxbank) {
print("increase Maxbank; lost %lldMB\n", c->npages*hwrpb->by2pg/MB);
break;
}
bank[nbank].min = p0;
bank[nbank].max = p1;
nbank++;
break;
case 2:
print("nvram skipped\n");
break;
}
}
if (debug)
print("\n");
print("Memory size: %lludMB\n", npage*hwrpb->by2pg/MB);
print("\n");
/* kernel virtual space = 2G. leave room for kmapio */
if (conf.maxphys > 1024*MB) {
print("meminit: too much physical memory; only first gigabyte mapped\n\n");
conf.maxphys = 1024*MB;
}
conf.nbank = nbank;
conf.bank = bank;
}
int
validrgn(ulong min, ulong max)
{
int i;
min &= ~KZERO;
max &= ~KZERO;
for (i = 0; i < nbank; i++)
if (bank[i].min <= min && max <= bank[i].max)
return 1;
return 0;
}
uvlong
allocate(int pages)
{
uvlong top, len;
int from, i;
top = 0;
len = pages*hwrpb->by2pg;
from = -1;
for (i = 0; i < nbank; i++)
if (bank[i].max - bank[i].min >= len && bank[i].max > top) {
top = bank[i].max;
from = i;
}
if (from < 0)
return 0;
bank[from].max -= len;
conf.bank[from].max = bank[from].max;
for (i = 0; i < len>>3; i++)
stqp(bank[from].max+8*i, 0);
return bank[from].max;
}

View file

@ -1,42 +0,0 @@
objtype=alpha
</$objtype/mkfile
TARGET=bootalphapc
OBJ=\
l.$O\
main.$O\
conf.$O\
cons.$O\
exec.$O\
bootp.$O\
memory.$O\
mmu.$O\
print.$O\
HFILES=\
u.h\
mem.h\
conf.h\
dat.h\
fns.h\
lib.h\
ip.h\
loadaddr = 0x20000020
$TARGET: $OBJ
$LD -o $target -l -R8 -H3 -T$loadaddr $prereq -lc
install:V: $TARGET
cp $TARGET /$objtype
clean nuke:V:
rm -f *.$O $TARGET
%.$O: %.s
$AS $stem.s
%.$O: %.c
$CC $CFLAGS $stem.c
%.$O: $HFILES

View file

@ -1,111 +0,0 @@
#include "u.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "lib.h"
static int debug;
static uvlong by2pg; /* hwrpb->by2pg */
static uvlong pte2pg; /* by2pg/8 */
static uvlong pgmask; /* by2pg-1 */
static uvlong ptemask; /* pte2pg-1 */
static uvlong pgshift; /* log2(by2pg) */
static uvlong pteshift; /* log2(pte2pg) = pgshift - 3 */
#define L1(va) (((uvlong)(va)>>3*pteshift+3) & (pte2pg-1))
#define L2(va) (((uvlong)(va)>>2*pteshift+3) & (pte2pg-1))
#define L3(va) (((uvlong)(va)>>pgshift) & (pte2pg-1))
#define OFF(va) (((uvlong)(va)) & (by2pg-1))
#define V1(l1) (((vlong)l1<<(64-pteshift)) >> 64-(3*pteshift+3))
#define V2(l2) (((uvlong)l2<<(64-pteshift)) >> 64-(2*pteshift+3))
#define V3(l3) (((uvlong)l3<<(64-pteshift)) >> 64-pgshift)
#define VA(l1, l2, l3, off) (V1(l1) | V2(l2) | V3(l3) | (off))
static int
log2(uvlong x)
{
int i;
if ((x & (x-1)) == 0)
for (i = 0; i < 64; i++)
if (x & (1<<i))
return i;
panic("log2: %llux", x);
return -1;
}
void
mmuinit(void)
{
int i;
uvlong npage, nlvl2, nlvl3;
uvlong l1p, l2p, lvl2, lvl3;
extern ulong _main[], edata[];
/* map entire physical memory at KZERO */
by2pg = hwrpb->by2pg;
pte2pg = (by2pg >> 3);
pgmask = by2pg-1;
ptemask = pte2pg-1;
pgshift = log2(by2pg);
pteshift = pgshift-3;
l1p = (1LL<<3*pteshift+3)|(1LL<<2*pteshift+3)|(1LL<<pgshift);
if (rdv(l1p+8*(pte2pg-1)) != 0 || rdv(l1p+8*(pte2pg-2)) != 0)
panic("KZERO lvl1 already mapped");
npage = (conf.maxphys+pgmask)>>pgshift;
nlvl3 = (npage+ptemask)>>pteshift;
nlvl2 = (nlvl3+ptemask)>>pteshift;
if (nlvl2 > 1)
panic("meminit: nlvl2"); /* cannot happen, due to virtual space limitation */
if (debug)
print("nlvl1 %llud nlvl2 %llud nlvl3 %llud npage %llud\n", 1LL, nlvl2, nlvl3, npage);
lvl2 = allocate(nlvl2+nlvl3);
lvl3 = lvl2 + nlvl2*by2pg;
wrv(l1p+8*(pte2pg-2), rdv(l1p+8)|PTEASM);
wrv(l1p+8*(pte2pg-1), (lvl2<<(32-pgshift)) | PTEKVALID | PTEASM);
l2p = (1LL<<3*pteshift+3)|(1LL<<2*pteshift+3)|((vlong)KZERO >> 2*pteshift)&((1LL<<2*pteshift+3)-1);
for (i = 0; i < nlvl3; i++)
stqp(lvl2+(l2p&(by2pg-1))+8*i, ((lvl3+i*by2pg)<<(32-pgshift)) | PTEKVALID | PTEASM);
for (i = 0; i < npage; i++)
stqp(lvl3+8*i, ((uvlong)i<<32) | PTEKVALID | PTEASM);
tlbflush();
if (debug)
print("\n");
}
uvlong
paddr(uvlong va)
{
uvlong ptbr, x, pte;
ptbr = getptbr();
pte = ldqp((ptbr<<pgshift)+8*L1(va));
if ((pte&PTEKVALID) != PTEKVALID)
return 0;
x = ((pte>>32)<<pgshift);
pte = ldqp(x+8*L2(va));
if ((pte&PTEKVALID) != PTEKVALID)
return 0;
x = ((pte>>32)<<pgshift);
pte = ldqp(x+8*L3(va));
if ((pte&PTEKVALID) != PTEKVALID)
return 0;
x = ((pte>>32)<<pgshift);
return x;
}
uvlong
pground(uvlong x)
{
return (x+pgmask) & ~pgmask;
}

View file

@ -1,575 +0,0 @@
#include "u.h"
#include "lib.h"
enum
{
SIZE = 1024,
IDIGIT = 30,
MAXCONV = 40,
FDIGIT = 30,
FDEFLT = 6,
NONE = -1000,
MAXFMT = 512,
FPLUS = 1<<0,
FMINUS = 1<<1,
FSHARP = 1<<2,
FLONG = 1<<3,
FSHORT = 1<<4,
FUNSIGN = 1<<5,
FVLONG = 1<<6,
};
int printcol;
static int convcount;
static char fmtindex[MAXFMT];
static int noconv(va_list*, Fconv*);
static int flags(va_list*, Fconv*);
static int cconv(va_list*, Fconv*);
static int sconv(va_list*, Fconv*);
static int percent(va_list*, Fconv*);
int numbconv(va_list*, Fconv*);
static
int (*fmtconv[MAXCONV])(va_list*, Fconv*) =
{
noconv
};
static
void
initfmt(void)
{
int cc;
cc = 0;
fmtconv[cc] = noconv;
cc++;
fmtconv[cc] = flags;
fmtindex['+'] = cc;
fmtindex['-'] = cc;
fmtindex['#'] = cc;
fmtindex['h'] = cc;
fmtindex['l'] = cc;
fmtindex['u'] = cc;
cc++;
fmtconv[cc] = numbconv;
fmtindex['d'] = cc;
fmtindex['o'] = cc;
fmtindex['x'] = cc;
fmtindex['X'] = cc;
cc++;
fmtconv[cc] = cconv;
fmtindex['c'] = cc;
fmtindex['C'] = cc;
cc++;
fmtconv[cc] = sconv;
fmtindex['s'] = cc;
fmtindex['S'] = cc;
cc++;
fmtconv[cc] = percent;
fmtindex['%'] = cc;
cc++;
convcount = cc;
}
int
fmtinstall(int c, int (*f)(va_list*, Fconv*))
{
if(convcount == 0)
initfmt();
if(c < 0 || c >= MAXFMT)
return -1;
if(convcount >= MAXCONV)
return -1;
fmtconv[convcount] = f;
fmtindex[c] = convcount;
convcount++;
return 0;
}
char*
doprint(char *s, char *es, char *fmt, va_list argp)
{
int n, c;
Rune rune;
Fconv local;
local.out = s;
local.eout = es-UTFmax-1;
loop:
c = *fmt & 0xff;
if(c >= Runeself) {
n = chartorune(&rune, fmt);
fmt += n;
c = rune;
} else
fmt++;
switch(c) {
case 0:
*local.out = 0;
return local.out;
default:
printcol++;
goto common;
case '\n':
printcol = 0;
goto common;
case '\t':
printcol = (printcol+8) & ~7;
goto common;
common:
if(local.out < local.eout)
if(c >= Runeself) {
rune = c;
n = runetochar(local.out, &rune);
local.out += n;
} else
*local.out++ = c;
goto loop;
case '%':
break;
}
local.f1 = NONE;
local.f2 = NONE;
local.f3 = 0;
/*
* read one of the following
* 1. number, => f1, f2 in order.
* 2. '*' same as number (from args)
* 3. '.' ignored (separates numbers)
* 4. flag => f3
* 5. verb and terminate
*/
l0:
c = *fmt & 0xff;
if(c >= Runeself) {
n = chartorune(&rune, fmt);
fmt += n;
c = rune;
} else
fmt++;
l1:
if(c == 0) {
fmt--;
goto loop;
}
if(c == '.') {
if(local.f1 == NONE)
local.f1 = 0;
local.f2 = 0;
goto l0;
}
if((c >= '1' && c <= '9') ||
(c == '0' && local.f1 != NONE)) { /* '0' is a digit for f2 */
n = 0;
while(c >= '0' && c <= '9') {
n = n*10 + c-'0';
c = *fmt++;
}
if(local.f1 == NONE)
local.f1 = n;
else
local.f2 = n;
goto l1;
}
if(c == '*') {
n = va_arg(argp, int);
if(local.f1 == NONE)
local.f1 = n;
else
local.f2 = n;
goto l0;
}
n = 0;
if(c >= 0 && c < MAXFMT)
n = fmtindex[c];
local.chr = c;
n = (*fmtconv[n])(&argp, &local);
if(n < 0) {
local.f3 |= -n;
goto l0;
}
goto loop;
}
int
numbconv(va_list *arg, Fconv *fp)
{
char s[IDIGIT];
int i, f, n, b, ucase;
short h;
long v;
vlong vl;
SET(v);
SET(vl);
ucase = 0;
b = fp->chr;
switch(fp->chr) {
case 'u':
fp->f3 |= FUNSIGN;
case 'd':
b = 10;
break;
case 'o':
b = 8;
break;
case 'X':
ucase = 1;
case 'x':
b = 16;
break;
}
f = 0;
switch(fp->f3 & (FVLONG|FLONG|FSHORT|FUNSIGN)) {
case FVLONG|FLONG:
vl = va_arg(*arg, vlong);
break;
case FUNSIGN|FVLONG|FLONG:
vl = va_arg(*arg, uvlong);
break;
case FLONG:
v = va_arg(*arg, long);
break;
case FUNSIGN|FLONG:
v = va_arg(*arg, ulong);
break;
case FSHORT:
h = va_arg(*arg, int);
v = h;
break;
case FUNSIGN|FSHORT:
h = va_arg(*arg, int);
v = (ushort)h;
break;
default:
v = va_arg(*arg, int);
break;
case FUNSIGN:
v = va_arg(*arg, unsigned);
break;
}
if(fp->f3 & FVLONG) {
if(!(fp->f3 & FUNSIGN) && vl < 0) {
vl = -vl;
f = 1;
}
} else {
if(!(fp->f3 & FUNSIGN) && v < 0) {
v = -v;
f = 1;
}
}
s[IDIGIT-1] = 0;
for(i = IDIGIT-2;; i--) {
if(fp->f3 & FVLONG)
n = (uvlong)vl % b;
else
n = (ulong)v % b;
n += '0';
if(n > '9') {
n += 'a' - ('9'+1);
if(ucase)
n += 'A'-'a';
}
s[i] = n;
if(i < 2)
break;
if(fp->f3 & FVLONG)
vl = (uvlong)vl / b;
else
v = (ulong)v / b;
if(fp->f2 != NONE && i >= IDIGIT-fp->f2)
continue;
if(fp->f3 & FVLONG) {
if(vl <= 0)
break;
continue;
}
if(v <= 0)
break;
}
if(fp->f3 & FSHARP) {
if(b == 8 && s[i] != '0')
s[--i] = '0';
if(b == 16) {
if(ucase)
s[--i] = 'X';
else
s[--i] = 'x';
s[--i] = '0';
}
}
if(f)
s[--i] = '-';
fp->f2 = NONE;
strconv(s+i, fp);
return 0;
}
void
Strconv(Rune *s, Fconv *fp)
{
int n, c, i;
Rune rune;
if(fp->f3 & FMINUS)
fp->f1 = -fp->f1;
n = 0;
if(fp->f1 != NONE && fp->f1 >= 0) {
for(; s[n]; n++)
;
while(n < fp->f1) {
if(fp->out < fp->eout)
*fp->out++ = ' ';
printcol++;
n++;
}
}
for(;;) {
c = *s++;
if(c == 0)
break;
n++;
if(fp->f2 == NONE || fp->f2 > 0) {
if(fp->out < fp->eout)
if(c >= Runeself) {
rune = c;
i = runetochar(fp->out, &rune);
fp->out += i;
} else
*fp->out++ = c;
if(fp->f2 != NONE)
fp->f2--;
switch(c) {
default:
printcol++;
break;
case '\n':
printcol = 0;
break;
case '\t':
printcol = (printcol+8) & ~7;
break;
}
}
}
if(fp->f1 != NONE && fp->f1 < 0) {
fp->f1 = -fp->f1;
while(n < fp->f1) {
if(fp->out < fp->eout)
*fp->out++ = ' ';
printcol++;
n++;
}
}
}
void
strconv(char *s, Fconv *fp)
{
int n, c, i;
Rune rune;
if(fp->f3 & FMINUS)
fp->f1 = -fp->f1;
n = 0;
if(fp->f1 != NONE && fp->f1 >= 0) {
n = utflen(s);
while(n < fp->f1) {
if(fp->out < fp->eout)
*fp->out++ = ' ';
printcol++;
n++;
}
}
for(;;) {
c = *s & 0xff;
if(c >= Runeself) {
i = chartorune(&rune, s);
s += i;
c = rune;
} else
s++;
if(c == 0)
break;
n++;
if(fp->f2 == NONE || fp->f2 > 0) {
if(fp->out < fp->eout)
if(c >= Runeself) {
rune = c;
i = runetochar(fp->out, &rune);
fp->out += i;
} else
*fp->out++ = c;
if(fp->f2 != NONE)
fp->f2--;
switch(c) {
default:
printcol++;
break;
case '\n':
printcol = 0;
break;
case '\t':
printcol = (printcol+8) & ~7;
break;
}
}
}
if(fp->f1 != NONE && fp->f1 < 0) {
fp->f1 = -fp->f1;
while(n < fp->f1) {
if(fp->out < fp->eout)
*fp->out++ = ' ';
printcol++;
n++;
}
}
}
static
int
noconv(va_list *arg, Fconv *fp)
{
int n;
char s[10];
if(convcount == 0) {
initfmt();
n = 0;
if(fp->chr >= 0 && fp->chr < MAXFMT)
n = fmtindex[fp->chr];
return (*fmtconv[n])(arg, fp);
}
s[0] = '*';
s[1] = fp->chr;
s[2] = '*';
s[3] = 0;
fp->f1 = 0;
fp->f2 = NONE;
fp->f3 = 0;
strconv(s, fp);
return 0;
}
static
int
cconv(va_list *arg, Fconv *fp)
{
char s[10];
Rune rune;
rune = va_arg(*arg, int);
if(fp->chr == 'c')
rune &= 0xff;
s[runetochar(s, &rune)] = 0;
fp->f2 = NONE;
strconv(s, fp);
return 0;
}
static
int
sconv(va_list *arg, Fconv *fp)
{
char *s;
Rune *r;
if(fp->chr == 's') {
s = va_arg(*arg, char*);
if(s == 0)
s = "<null>";
strconv(s, fp);
} else {
r = va_arg(*arg, Rune*);
if(r == 0)
r = L"<null>";
Strconv(r, fp);
}
return 0;
}
static
int
percent(va_list *arg, Fconv *fp)
{
USED(arg);
if(fp->out < fp->eout)
*fp->out++ = '%';
printcol++;
return 0;
}
static
int
flags(va_list *arg, Fconv *fp)
{
int f;
USED(arg);
f = 0;
switch(fp->chr) {
case '+':
f = FPLUS;
break;
case '-':
f = FMINUS;
break;
case '#':
f = FSHARP;
break;
case 'h':
f = FSHORT;
break;
case 'l':
f = FLONG;
if(fp->f3 & FLONG)
f = FVLONG;
break;
case 'u':
f = FUNSIGN;
break;
}
return -f;
}

View file

@ -1,28 +0,0 @@
#define nil ((void*)0)
typedef unsigned short ushort;
typedef unsigned char uchar;
typedef signed char schar;
typedef unsigned long ulong;
typedef unsigned int uint;
typedef long long vlong;
typedef unsigned long long uvlong;
typedef union Length Length;
typedef ushort Rune;
union Length
{
vlong length;
};
/* stdarg */
typedef char* va_list;
#define va_start(list, start) list = (char*)(&(start)+1)
#define va_end(list)
#define va_arg(list, mode)\
(sizeof(mode)==1?\
((mode*)(list += 4))[-1]:\
sizeof(mode)==2?\
((mode*)(list += 4))[-1]:\
sizeof(mode)>4?\
((mode*)(list = (char*)((long)(list+7) & ~7) + sizeof(mode)))[-1]:\
((mode*)(list += sizeof(mode)))[-1])

View file

@ -1,105 +0,0 @@
/*
* VMS PALcode instructions, in numerical order.
*/
#define PALhalt 0x00 /* required per Alpha architecture */
#define PALcflush 0x01
#define PALdraina 0x02 /* required per Alpha architecture */
#define PALldqp 0x03
#define PALstqp 0x04
#define PALswpctx 0x05
#define PALmfpr_asn 0x06
#define PALmtpr_asten 0x07
#define PALmtpr_astsr 0x08
#define PALcserve 0x09
#define PALswppal 0x0a
#define PALmfpr_fen 0x0b
#define PALmtpr_fen 0x0c
#define PALmtpr_ipir 0x0d
#define PALmfpr_ipl 0x0e
#define PALmtpr_ipl 0x0f
#define PALmfpr_mces 0x10
#define PALmtpr_mces 0x11
#define PALmfpr_pcbb 0x12
#define PALmfpr_prbr 0x13
#define PALmtpr_prbr 0x14
#define PALmfpr_ptbr 0x15
#define PALmfpr_scbb 0x16
#define PALmtpr_scbb 0x17
#define PALmtpr_sirr 0x18
#define PALmfpr_sisr 0x19
#define PALmfpr_tbchk 0x1a
#define PALmtpr_tbia 0x1b
#define PALmtpr_tbiap 0x1c
#define PALmtpr_tbis 0x1d
#define PALmfpr_esp 0x1e
#define PALmtpr_esp 0x1f
#define PALmfpr_ssp 0x20
#define PALmtpr_ssp 0x21
#define PALmfpr_usp 0x22
#define PALmtpr_usp 0x23
#define PALmtpr_tbisd 0x24
#define PALmtpr_tbisi 0x25
#define PALmfpr_asten 0x26
#define PALmfpr_astsr 0x27
/* where is instruction 0x28 ? */
#define PALmfpr_vptb 0x29
#define PALmtpr_vptb 0x2a
#define PALmtpr_perfmon 0x2b
/* where is instruction 0x2c ? */
/* where is instruction 0x2d ? */
#define PALmtpr_datfx 0x2e
/*
* ... 0x2f to 0x3e ??
*/
#define PALmfpr_whami 0x3f
/*
* ... 0x40 to 0x7f ??
*/
#define PALbpt 0x80
#define PALbugchk 0x81
#define PALchime 0x82
#define PALchmk 0x83
#define PALchms 0x84
#define PALchmu 0x85
#define PALimb 0x86 /* required per Alpha architecture */
#define PALinsqhil 0x87
#define PALinsqtil 0x88
#define PALinsqhiq 0x89
#define PALinsqtiq 0x8a
#define PALinsquel 0x8b
#define PALinsqueq 0x8c
#define PALinsqueld 0x8d /* INSQUEL/D */
#define PALinsqueqd 0x8e /* INSQUEQ/D */
#define PALprober 0x8f
#define PALprobew 0x90
#define PALrd_ps 0x91
#define PALrei 0x92
#define PALremqhil 0x93
#define PALremqtil 0x94
#define PALremqhiq 0x95
#define PALremqtiq 0x96
#define PALremquel 0x97
#define PALremqueq 0x98
#define PALremqueld 0x99 /* REMQUEL/D */
#define PALremqueqd 0x9a /* REMQUEQ/D */
#define PALswasten 0x9b
#define PALwr_ps_sw 0x9c
#define PALrscc 0x9d
#define PALread_unq 0x9e
#define PALwrite_unq 0x9f
#define PALamovrr 0xa0
#define PALamovrm 0xa1
#define PALinsqhilr 0xa2
#define PALinsqtilr 0xa3
#define PALinsqhiqr 0xa4
#define PALinsqtiqr 0xa5
#define PALremqhilr 0xa6
#define PALremqtilr 0xa7
#define PALremqhiqr 0xa8
#define PALremqtiqr 0xa9
#define PALgentrap 0xaa

View file

@ -1,7 +1,8 @@
ARCH=\
alphapc\
bitsy\
efi\
pc\
zynq\
all:V:
for(i in $ARCH)@{

View file

@ -1,208 +0,0 @@
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "../7c/7.out.h"
#ifndef EXTERN
#define EXTERN extern
#endif
#define MAXALIGN 7
typedef struct Sym Sym;
typedef struct Ref Ref;
typedef struct Gen Gen;
typedef struct Io Io;
typedef struct Hist Hist;
#define FPCHIP 1
#define NSYMB 500
#define BUFSIZ 8192
#define HISTSZ 20
#define NINCLUDE 10
#define NHUNK 10000
#define EOF (-1)
#define IGN (-2)
#define GETC() ((--fi.c < 0)? filbuf(): *fi.p++ & 0xff)
#define NHASH 503
#define STRINGSZ 200
#define NMACRO 10
#define ALLOC(lhs, type)\
while(nhunk < sizeof(type))\
gethunk();\
lhs = (type*)hunk;\
nhunk -= sizeof(type);\
hunk += sizeof(type);
#define ALLOCN(lhs, len, n)\
if(lhs+len != hunk || nhunk < n) {\
while(nhunk <= len)\
gethunk();\
memmove(hunk, lhs, len);\
lhs = hunk;\
hunk += len;\
nhunk -= len;\
}\
hunk += n;\
nhunk -= n;
struct Sym
{
Sym* link;
Ref* ref;
char* macro;
vlong value;
long dummy_pad;
ushort type;
char *name;
char sym;
};
#define S ((Sym*)0)
struct Ref
{
int class;
};
struct
{
char* p;
int c;
} fi;
struct Io
{
Io* link;
char b[BUFSIZ];
char* p;
short c;
short f;
};
#define I ((Io*)0)
struct
{
Sym* sym;
short type;
} h[NSYM];
struct Gen
{
Sym* sym;
vlong offset;
long dummy_pad;
short type;
short reg;
short name;
double dval;
char sval[8];
};
struct Hist
{
Hist* link;
char* name;
long line;
vlong offset;
};
#define H ((Hist*)0)
enum
{
CLAST,
CMACARG,
CMACRO,
CPREPROC,
};
char debug[256];
Sym* hash[NHASH];
char* Dlist[30];
int nDlist;
Hist* ehist;
int newflag;
Hist* hist;
char* hunk;
char* include[NINCLUDE];
Io* iofree;
Io* ionext;
Io* iostack;
long lineno;
int nerrors;
long nhunk;
int ninclude;
Gen nullgen;
char* outfile;
int pass;
char* pathname;
vlong pc;
int peekc;
int sym;
char symb[NSYMB];
int thechar;
char* thestring;
long thunk;
Biobuf obuf;
void errorexit(void);
void pushio(void);
void newio(void);
void newfile(char*, int);
Sym* slookup(char*);
Sym* lookup(void);
void syminit(Sym*);
long yylex(void);
int getc(void);
int getnsc(void);
void unget(int);
int escchar(int);
void cinit(void);
void pinit(char*);
void cclean(void);
int isreg(Gen*);
void outcode(int, Gen*, int, Gen*);
void zname(char*, int, int);
void zaddr(Gen*, int);
void ieeedtod(Ieee*, double);
int filbuf(void);
Sym* getsym(void);
void domacro(void);
void macund(void);
void macdef(void);
void macexpand(Sym*, char*);
void macinc(void);
void maclin(void);
void macprag(void);
void macif(int);
void macend(void);
void outhist(void);
void dodefine(char*);
void prfile(long);
void linehist(char*, int);
void gethunk(void);
void yyerror(char*, ...);
int yyparse(void);
void setinclude(char*);
int assemble(char*);
/*
* system-dependent stuff from ../cc/compat.c
*/
enum /* keep in synch with ../cc/cc.h */
{
Plan9 = 1<<0,
Unix = 1<<1,
Windows = 1<<2,
};
int mywait(int*);
int mycreat(char*, int);
int systemtype(int);
int pathchar(void);
char* mygetwd(char*, int);
int myexec(char*, char*[]);
int mydup(int, int);
int myfork(void);
int mypipe(int*);
void* mysbrk(ulong);

View file

@ -1,537 +0,0 @@
%{
#include "a.h"
%}
%union
{
Sym *sym;
vlong lval;
double dval;
char sval[8];
Gen gen;
}
%left '|'
%left '^'
%left '&'
%left '<' '>'
%left '+' '-'
%left '*' '/' '%'
%token <lval> LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5
%token <lval> LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA
%token <lval> LTYPEB LTYPEC LTYPED LTYPEE LTYPEF
%token <lval> LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK
%token <lval> LCONST LSP LSB LFP LPC LPREG LPCC
%token <lval> LTYPEX LREG LFREG LFPCR LR LP LF
%token <dval> LFCONST
%token <sval> LSCONST
%token <sym> LNAME LLAB LVAR
%type <lval> con expr pointer offset sreg
%type <gen> gen vgen lgen vlgen flgen rel reg freg preg fcreg
%type <gen> imm ximm ireg name oreg imr nireg fgen pcc
%%
prog:
| prog line
line:
LLAB ':'
{
if($1->value != pc)
yyerror("redeclaration of %s", $1->name);
$1->value = pc;
}
line
| LNAME ':'
{
$1->type = LLAB;
$1->value = pc;
}
line
| LNAME '=' expr ';'
{
$1->type = LVAR;
$1->value = $3;
}
| LVAR '=' expr ';'
{
if($1->value != $3)
yyerror("redeclaration of %s", $1->name);
$1->value = $3;
}
| ';'
| inst ';'
| error ';'
inst:
/*
* Integer operates
*/
LTYPE1 imr ',' sreg ',' reg
{
outcode($1, &$2, $4, &$6);
}
| LTYPE1 imr ',' reg
{
outcode($1, &$2, NREG, &$4);
}
/*
* floating-type
*/
| LTYPE2 freg ',' freg
{
outcode($1, &$2, NREG, &$4);
}
| LTYPE3 freg ',' freg
{
outcode($1, &$2, NREG, &$4);
}
| LTYPE3 freg ',' LFREG ',' freg
{
outcode($1, &$2, $4, &$6);
}
/*
* MOVQ
*/
| LTYPE4 vlgen ',' vgen
{
if(!isreg(&$2) && !isreg(&$4))
print("one side must be register\n");
outcode($1, &$2, NREG, &$4);
}
/*
* integer LOAD/STORE, but not MOVQ
*/
| LTYPE5 lgen ',' gen
{
if(!isreg(&$2) && !isreg(&$4))
print("one side must be register\n");
outcode($1, &$2, NREG, &$4);
}
/*
* integer LOAD/STORE (only)
*/
| LTYPE6 oreg ',' reg
{
outcode($1, &$2, NREG, &$4);
}
| LTYPEK reg ',' oreg
{
outcode($1, &$2, NREG, &$4);
}
/*
* floating LOAD/STORE
*/
| LTYPE7 flgen ',' fgen
{
if(!isreg(&$2) && !isreg(&$4))
print("one side must be register\n");
outcode($1, &$2, NREG, &$4);
}
/*
* JMP/JSR/RET
*/
| LTYPE8 comma rel
{
outcode($1, &nullgen, NREG, &$3);
}
| LTYPE8 comma nireg
{
outcode($1, &nullgen, NREG, &$3);
}
| LTYPE8 sreg ',' nireg
{
outcode($1, &nullgen, $2, &$4);
}
| LTYPE9 comma
{
outcode($1, &nullgen, NREG, &nullgen);
}
/*
* integer conditional branches
*/
| LTYPEA gen ',' rel
{
if(!isreg(&$2))
print("left side must be register\n");
outcode($1, &$2, NREG, &$4);
}
/*
* floating conditional branches
*/
| LTYPEB fgen ',' rel
{
if(!isreg(&$2))
print("left side must be register\n");
outcode($1, &$2, NREG, &$4);
}
/*
* TRAPB/MB/REI
*/
| LTYPEC comma
{
outcode($1, &nullgen, NREG, &nullgen);
}
/*
* FETCH/FETCHM
*/
| LTYPED ireg comma
{
outcode($1, &$2, NREG, &nullgen);
}
/*
* Call-pal
*/
| LTYPEE imm
{
outcode($1, &$2, NREG, &nullgen);
}
/*
* TEXT/GLOBL
*/
| LTYPEF name ',' imm
{
outcode($1, &$2, NREG, &$4);
}
| LTYPEF name ',' con ',' imm
{
outcode($1, &$2, $4, &$6);
}
/*
* DATA
*/
| LTYPEG name '/' con ',' ximm
{
outcode($1, &$2, $4, &$6);
}
/*
* word
*/
| LTYPEH comma ximm
{
outcode($1, &nullgen, NREG, &$3);
}
/*
* NOP
*/
| LTYPEI comma
{
outcode($1, &nullgen, NREG, &nullgen);
}
| LTYPEI ',' vgen
{
outcode($1, &nullgen, NREG, &$3);
}
| LTYPEI vgen comma
{
outcode($1, &$2, NREG, &nullgen);
}
comma:
| ','
rel:
con '(' LPC ')'
{
$$ = nullgen;
$$.type = D_BRANCH;
$$.offset = $1 + pc;
}
| LNAME offset
{
$$ = nullgen;
if(pass == 2)
yyerror("undefined label: %s", $1->name);
$$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $2;
}
| LLAB offset
{
$$ = nullgen;
$$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $1->value + $2;
}
vlgen:
lgen
| preg
| pcc
vgen:
gen
| preg
lgen:
gen
| ximm
flgen:
fgen
| ximm
fgen:
gen
| freg
| fcreg
preg:
LPREG
{
$$ = nullgen;
$$.type = D_PREG;
$$.reg = $1;
}
| LP '(' con ')'
{
$$ = nullgen;
$$.type = D_PREG;
$$.reg = $1+$3;
}
fcreg:
LFPCR
{
$$ = nullgen;
$$.type = D_FCREG;
$$.reg = $1;
}
freg:
LFREG
{
$$ = nullgen;
$$.type = D_FREG;
$$.reg = $1;
}
| LF '(' con ')'
{
$$ = nullgen;
$$.type = D_FREG;
$$.reg = $3;
}
pcc:
LPCC
{
$$ = nullgen;
$$.type = D_PCC;
$$.reg = $1;
}
ximm: '$' con
{
$$ = nullgen;
$$.type = D_CONST;
$$.offset = $2;
}
| '$' oreg
{
$$ = $2;
$$.type = D_CONST;
}
| '$' LSCONST
{
$$ = nullgen;
$$.type = D_SCONST;
memcpy($$.sval, $2, sizeof($$.sval));
}
| '$' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = $2;
}
| '$' '-' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = -$3;
}
nireg:
ireg
| name
{
$$ = $1;
if($1.name != D_EXTERN && $1.name != D_STATIC) {
}
}
ireg:
'(' sreg ')'
{
$$ = nullgen;
$$.type = D_OREG;
$$.reg = $2;
$$.offset = 0;
}
gen:
reg
| con
{
$$ = nullgen;
$$.type = D_OREG;
$$.offset = $1;
}
| oreg
oreg:
name
| name '(' sreg ')'
{
$$ = $1;
$$.type = D_OREG;
$$.reg = $3;
}
| '(' sreg ')'
{
$$ = nullgen;
$$.type = D_OREG;
$$.reg = $2;
$$.offset = 0;
}
| con '(' sreg ')'
{
$$ = nullgen;
$$.type = D_OREG;
$$.reg = $3;
$$.offset = $1;
}
imr:
reg
| imm
imm: '$' con
{
$$ = nullgen;
$$.type = D_CONST;
$$.offset = $2;
}
reg:
sreg
{
$$ = nullgen;
$$.type = D_REG;
$$.reg = $1;
}
sreg:
LREG
| LR '(' con ')'
{
if($$ < 0 || $$ >= NREG)
print("register value out of range\n");
$$ = $3;
}
name:
con '(' pointer ')'
{
$$ = nullgen;
$$.type = D_OREG;
$$.name = $3;
$$.sym = S;
$$.offset = $1;
}
| LNAME offset '(' pointer ')'
{
$$ = nullgen;
$$.type = D_OREG;
$$.name = $4;
$$.sym = $1;
$$.offset = $2;
}
| LNAME '<' '>' offset '(' LSB ')'
{
$$ = nullgen;
$$.type = D_OREG;
$$.name = D_STATIC;
$$.sym = $1;
$$.offset = $4;
}
offset:
{
$$ = 0;
}
| '+' con
{
$$ = $2;
}
| '-' con
{
$$ = -$2;
}
pointer:
LSB
| LSP
| LFP
con:
LCONST
| LVAR
{
$$ = $1->value;
}
| '-' con
{
$$ = -$2;
}
| '+' con
{
$$ = $2;
}
| '~' con
{
$$ = ~$2;
}
| '(' expr ')'
{
$$ = $2;
}
expr:
con
| expr '+' expr
{
$$ = $1 + $3;
}
| expr '-' expr
{
$$ = $1 - $3;
}
| expr '*' expr
{
$$ = $1 * $3;
}
| expr '/' expr
{
$$ = $1 / $3;
}
| expr '%' expr
{
$$ = $1 % $3;
}
| expr '<' '<' expr
{
$$ = $1 << $4;
}
| expr '>' '>' expr
{
$$ = $1 >> $4;
}
| expr '&' expr
{
$$ = $1 & $3;
}
| expr '^' expr
{
$$ = $1 ^ $3;
}
| expr '|' expr
{
$$ = $1 | $3;
}

View file

@ -1,694 +0,0 @@
#include <ctype.h>
#define EXTERN
#include "a.h"
#include "y.tab.h"
void
main(int argc, char *argv[])
{
char ofile[100], incfile[20], *p;
int nout, nproc, status, i, c, of;
thechar = '7'; /* of 9 */
thestring = "alpha";
memset(debug, 0, sizeof(debug));
cinit();
outfile = 0;
include[ninclude++] = ".";
ARGBEGIN {
default:
c = ARGC();
if(c >= 0 || c < sizeof(debug))
debug[c] = 1;
break;
case 'o':
outfile = ARGF();
break;
case 'D':
p = ARGF();
if(p)
Dlist[nDlist++] = p;
break;
case 'I':
p = ARGF();
if(p)
include[ninclude++] = p;
break;
} ARGEND
if(*argv == 0) {
print("usage: %ca [-options] file.s\n", thechar);
errorexit();
}
nproc = 3;
if(p = getenv("NPROC"))
nproc = atol(p);
if(argc > 1) {
c = 0;
nout = 0;
for(;;) {
while(nout < nproc && argc > 0) {
i = fork();
if(i < 0) {
i = mywait(&status);
if(i < 0)
errorexit();
if(status)
c++;
nout--;
continue;
}
if(i == 0) {
print("%s:\n", *argv);
goto child;
}
nout++;
argc--;
argv++;
}
i = mywait(&status);
if(i < 0) {
if(c)
errorexit();
exits(0);
}
if(status)
c++;
nout--;
}
}
child:
strecpy(ofile, ofile+sizeof ofile, *argv);
if(p = strrchr(ofile, '/')) {
include[0] = ofile;
*p++ = 0;
} else
p = ofile;
if(outfile == 0) {
outfile = p;
if(p = strrchr(outfile, '.'))
if(p[1] == 's' && p[2] == 0)
p[0] = 0;
p = strrchr(outfile, 0);
p[0] = '.';
p[1] = thechar;
p[2] = 0;
}
if(0) {
strcpy(incfile, "/usr/%include");
p = strrchr(incfile, '%');
if(p)
*p = thechar;
} else {
strcpy(incfile, "/");
strcat(incfile, thestring);
strcat(incfile, "/include");
}
include[ninclude++] = incfile;
if(p = getenv("INCLUDE"))
include[ninclude-1] = p; /* */
of = mycreat(outfile, 0664);
if(of < 0) {
yyerror("%ca: cannot create %s", thechar, outfile);
errorexit();
}
Binit(&obuf, of, OWRITE);
pass = 1;
pinit(*argv);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
if(nerrors) {
cclean();
errorexit();
}
pass = 2;
outhist();
pinit(*argv);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
if(nerrors)
errorexit();
exits(0);
}
struct
{
char *name;
ushort type;
ushort value;
} itab[] =
{
"SP", LSP, D_AUTO,
"SB", LSB, D_EXTERN,
"FP", LFP, D_PARAM,
"PC", LPC, D_BRANCH,
"R", LR, 0,
"R0", LREG, 0,
"R1", LREG, 1,
"R2", LREG, 2,
"R3", LREG, 3,
"R4", LREG, 4,
"R5", LREG, 5,
"R6", LREG, 6,
"R7", LREG, 7,
"R8", LREG, 8,
"R9", LREG, 9,
"R10", LREG, 10,
"R11", LREG, 11,
"R12", LREG, 12,
"R13", LREG, 13,
"R14", LREG, 14,
"R15", LREG, 15,
"R16", LREG, 16,
"R17", LREG, 17,
"R18", LREG, 18,
"R19", LREG, 19,
"R20", LREG, 20,
"R21", LREG, 21,
"R22", LREG, 22,
"R23", LREG, 23,
"R24", LREG, 24,
"R25", LREG, 25,
"R26", LREG, 26,
"R27", LREG, 27,
"R28", LREG, 28,
"R29", LREG, 29,
"R30", LREG, 30,
"R31", LREG, 31,
"P", LP, 0,
"I", LP, 32,
"A", LP, 64,
"IA", LP, 96,
"T", LP, 128,
"IT", LP, 32+128,
"AT", LP, 64+128,
"IAT", LP, 96+128,
"T0", LPREG, 0+128,
"T1", LPREG, 1+128,
"T2", LPREG, 2+128,
"T3", LPREG, 3+128,
"T4", LPREG, 4+128,
"T5", LPREG, 5+128,
"T6", LPREG, 6+128,
"T7", LPREG, 7+128,
"T8", LPREG, 8+128,
"T9", LPREG, 9+128,
"T10", LPREG, 10+128,
"T11", LPREG, 11+128,
"T12", LPREG, 12+128,
"T13", LPREG, 13+128,
"T14", LPREG, 14+128,
"T15", LPREG, 15+128,
"T16", LPREG, 16+128,
"T17", LPREG, 17+128,
"T18", LPREG, 18+128,
"T19", LPREG, 19+128,
"T20", LPREG, 20+128,
"T21", LPREG, 21+128,
"T22", LPREG, 22+128,
"T23", LPREG, 23+128,
"T24", LPREG, 24+128,
"T25", LPREG, 25+128,
"T26", LPREG, 26+128,
"T27", LPREG, 27+128,
"T28", LPREG, 28+128,
"T29", LPREG, 29+128,
"T30", LPREG, 30+128,
"T31", LPREG, 31+128,
"F", LF, 0,
"F0", LFREG, 0,
"F1", LFREG, 1,
"F2", LFREG, 2,
"F3", LFREG, 3,
"F4", LFREG, 4,
"F5", LFREG, 5,
"F6", LFREG, 6,
"F7", LFREG, 7,
"F8", LFREG, 8,
"F9", LFREG, 9,
"F10", LFREG, 10,
"F11", LFREG, 11,
"F12", LFREG, 12,
"F13", LFREG, 13,
"F14", LFREG, 14,
"F15", LFREG, 15,
"F16", LFREG, 16,
"F17", LFREG, 17,
"F18", LFREG, 18,
"F19", LFREG, 19,
"F20", LFREG, 20,
"F21", LFREG, 21,
"F22", LFREG, 22,
"F23", LFREG, 23,
"F24", LFREG, 24,
"F25", LFREG, 25,
"F26", LFREG, 26,
"F27", LFREG, 27,
"F28", LFREG, 28,
"F29", LFREG, 29,
"F30", LFREG, 30,
"F31", LFREG, 31,
"FPCR", LFPCR, 0,
"PCC", LPCC, 0,
/* 1: integer operates */
"ADDQ", LTYPE1, AADDQ,
"ADDL", LTYPE1, AADDL,
"SUBL", LTYPE1, ASUBL,
"SUBQ", LTYPE1, ASUBQ,
"CMPEQ", LTYPE1, ACMPEQ,
"CMPGT", LTYPE1, ACMPGT,
"CMPGE", LTYPE1, ACMPGE,
"CMPUGT", LTYPE1, ACMPUGT,
"CMPUGE", LTYPE1, ACMPUGE,
"CMPBLE", LTYPE1, ACMPBLE,
"AND", LTYPE1, AAND,
"ANDNOT", LTYPE1, AANDNOT,
"OR", LTYPE1, AOR,
"ORNOT", LTYPE1, AORNOT,
"XOR", LTYPE1, AXOR,
"XORNOT", LTYPE1, AXORNOT,
"CMOVEQ", LTYPE1, ACMOVEQ,
"CMOVNE", LTYPE1, ACMOVNE,
"CMOVLT", LTYPE1, ACMOVLT,
"CMOVGE", LTYPE1, ACMOVGE,
"CMOVLE", LTYPE1, ACMOVLE,
"CMOVGT", LTYPE1, ACMOVGT,
"CMOVLBS", LTYPE1, ACMOVLBS,
"CMOVLBC", LTYPE1, ACMOVLBC,
"MULL", LTYPE1, AMULL,
"MULQ", LTYPE1, AMULQ,
"UMULH", LTYPE1, AUMULH,
"DIVQ", LTYPE1, ADIVQ,
"MODQ", LTYPE1, AMODQ,
"DIVQU", LTYPE1, ADIVQU,
"MODQU", LTYPE1, AMODQU,
"DIVL", LTYPE1, ADIVL,
"MODL", LTYPE1, AMODL,
"DIVLU", LTYPE1, ADIVLU,
"MODLU", LTYPE1, AMODLU,
"SLLQ", LTYPE1, ASLLQ,
"SRLQ", LTYPE1, ASRLQ,
"SRAQ", LTYPE1, ASRAQ,
"SLLL", LTYPE1, ASLLL,
"SRLL", LTYPE1, ASRLL,
"SRAL", LTYPE1, ASRAL,
"EXTBL", LTYPE1, AEXTBL,
"EXTWL", LTYPE1, AEXTWL,
"EXTLL", LTYPE1, AEXTLL,
"EXTQL", LTYPE1, AEXTQL,
"EXTWH", LTYPE1, AEXTWH,
"EXTLH", LTYPE1, AEXTLH,
"EXTQH", LTYPE1, AEXTQH,
"INSBL", LTYPE1, AINSBL,
"INSWL", LTYPE1, AINSWL,
"INSLL", LTYPE1, AINSLL,
"INSQL", LTYPE1, AINSQL,
"INSWH", LTYPE1, AINSWH,
"INSLH", LTYPE1, AINSLH,
"INSQH", LTYPE1, AINSQH,
"MSKBL", LTYPE1, AMSKBL,
"MSKWL", LTYPE1, AMSKWL,
"MSKLL", LTYPE1, AMSKLL,
"MSKQL", LTYPE1, AMSKQL,
"MSKWH", LTYPE1, AMSKWH,
"MSKLH", LTYPE1, AMSKLH,
"MSKQH", LTYPE1, AMSKQH,
"ZAP", LTYPE1, AZAP,
"ZAPNOT", LTYPE1, AZAPNOT,
/* 2: floating operates with 2 operands */
"CVTQS", LTYPE2, ACVTQS,
"CVTQT", LTYPE2, ACVTQT,
"CVTTS", LTYPE2, ACVTTS,
"CVTTQ", LTYPE2, ACVTTQ,
"CVTLQ", LTYPE2, ACVTLQ,
"CVTQL", LTYPE2, ACVTQL,
/* 3: floating operates with 2 or 3 operands */
"CPYS", LTYPE3, ACPYS,
"CPYSN", LTYPE3, ACPYSN,
"CPYSE", LTYPE3, ACPYSE,
"ADDS", LTYPE3, AADDS,
"ADDT", LTYPE3, AADDT,
"CMPTEQ", LTYPE3, ACMPTEQ,
"CMPTGT", LTYPE3, ACMPTGT,
"CMPTGE", LTYPE3, ACMPTGE,
"CMPTUN", LTYPE3, ACMPTUN,
"DIVS", LTYPE3, ADIVS,
"DIVT", LTYPE3, ADIVT,
"MULS", LTYPE3, AMULS,
"MULT", LTYPE3, AMULT,
"SUBS", LTYPE3, ASUBS,
"SUBT", LTYPE3, ASUBT,
"FCMOVEQ", LTYPE3, AFCMOVEQ,
"FCMOVNE", LTYPE3, AFCMOVNE,
"FCMOVLT", LTYPE3, AFCMOVLT,
"FCMOVGE", LTYPE3, AFCMOVGE,
"FCMOVLE", LTYPE3, AFCMOVLE,
"FCMOVGT", LTYPE3, AFCMOVGT,
/* 4: integer load/store and reg->reg (incl special regs) */
"MOVQ", LTYPE4, AMOVQ,
/* 5: integer load/store and reg->reg */
"MOVL", LTYPE5, AMOVL,
"MOVQU", LTYPE5, AMOVQU,
"MOVB", LTYPE5, AMOVB,
"MOVBU", LTYPE5, AMOVBU,
"MOVW", LTYPE5, AMOVW,
"MOVWU", LTYPE5, AMOVWU,
"MOVLP", LTYPE5, AMOVLP,
"MOVQP", LTYPE5, AMOVQP,
/* 6: integer load/store (only) */
"MOVA", LTYPE6, AMOVA,
"MOVAH", LTYPE6, AMOVAH,
"MOVLL", LTYPE6, AMOVLL,
"MOVQL", LTYPE6, AMOVQL,
"MOVLC", LTYPEK, AMOVLC,
"MOVQC", LTYPEK, AMOVQC,
/* 7: floating load/store and reg->reg */
"MOVS", LTYPE7, AMOVS,
"MOVT", LTYPE7, AMOVT,
/* 8,9: jumps */
"JMP", LTYPE8, AJMP,
"JSR", LTYPE8, AJSR,
"RET", LTYPE9, ARET,
/* A: integer conditional branches */
"BEQ", LTYPEA, ABEQ,
"BNE", LTYPEA, ABNE,
"BLT", LTYPEA, ABLT,
"BGE", LTYPEA, ABGE,
"BLE", LTYPEA, ABLE,
"BGT", LTYPEA, ABGT,
"BLBC", LTYPEA, ABLBC,
"BLBS", LTYPEA, ABLBS,
/* B: floating conditional branches */
"FBEQ", LTYPEB, AFBEQ,
"FBNE", LTYPEB, AFBNE,
"FBLT", LTYPEB, AFBLT,
"FBGE", LTYPEB, AFBGE,
"FBLE", LTYPEB, AFBLE,
"FBGT", LTYPEB, AFBGT,
/* C-J: miscellaneous */
"TRAPB", LTYPEC, ATRAPB,
"MB", LTYPEC, AMB,
"REI", LTYPEC, AREI,
"END", LTYPEC, AEND,
"FETCH", LTYPED, AFETCH,
"FETCHM", LTYPED, AFETCHM,
"CALL_PAL", LTYPEE, ACALL_PAL,
"TEXT", LTYPEF, ATEXT,
"GLOBL", LTYPEF, AGLOBL,
"DATA", LTYPEG, ADATA,
"WORD", LTYPEH, AWORD,
"NOP", LTYPEI, ANOP,
0
};
void
cinit(void)
{
Sym *s;
int i;
nullgen.sym = S;
nullgen.offset = 0;
nullgen.type = D_NONE;
nullgen.name = D_NONE;
nullgen.reg = NREG;
if(FPCHIP)
nullgen.dval = 0;
for(i=0; i<sizeof(nullgen.sval); i++)
nullgen.sval[i] = 0;
nerrors = 0;
iostack = I;
iofree = I;
peekc = IGN;
nhunk = 0;
for(i=0; i<NHASH; i++)
hash[i] = S;
for(i=0; itab[i].name; i++) {
s = slookup(itab[i].name);
s->type = itab[i].type;
s->value = itab[i].value;
}
ALLOCN(pathname, 0, 100);
if(getwd(pathname, 99) == 0) {
ALLOCN(pathname, 100, 900);
if(getwd(pathname, 999) == 0)
strcpy(pathname, "/???");
}
}
void
syminit(Sym *s)
{
s->type = LNAME;
s->value = 0;
}
int
isreg(Gen *g)
{
USED(g);
return 1;
}
void
cclean(void)
{
outcode(AEND, &nullgen, NREG, &nullgen);
Bflush(&obuf);
}
void
zname(char *n, int t, int s)
{
Bputc(&obuf, ANAME);
Bputc(&obuf, t); /* type */
Bputc(&obuf, s); /* sym */
while(*n) {
Bputc(&obuf, *n);
n++;
}
Bputc(&obuf, 0);
}
void
zaddr(Gen *a, int s)
{
vlong l;
int i;
char *n;
Ieee e;
Bputc(&obuf, a->type);
Bputc(&obuf, a->reg);
Bputc(&obuf, s);
Bputc(&obuf, a->name);
switch(a->type) {
default:
print("unknown type %d\n", a->type);
exits("arg");
case D_NONE:
case D_REG:
case D_FREG:
case D_PREG:
case D_FCREG:
case D_PCC:
break;
case D_OREG:
case D_CONST:
case D_BRANCH:
l = a->offset;
Bputc(&obuf, l);
Bputc(&obuf, l>>8);
Bputc(&obuf, l>>16);
Bputc(&obuf, l>>24);
Bputc(&obuf, l>>32);
Bputc(&obuf, l>>40);
Bputc(&obuf, l>>48);
Bputc(&obuf, l>>56);
break;
case D_SCONST:
n = a->sval;
for(i=0; i<NSNAME; i++) {
Bputc(&obuf, *n);
n++;
}
break;
case D_FCONST:
ieeedtod(&e, a->dval);
Bputc(&obuf, e.l);
Bputc(&obuf, e.l>>8);
Bputc(&obuf, e.l>>16);
Bputc(&obuf, e.l>>24);
Bputc(&obuf, e.h);
Bputc(&obuf, e.h>>8);
Bputc(&obuf, e.h>>16);
Bputc(&obuf, e.h>>24);
break;
}
}
void
outcode(int a, Gen *g1, int reg, Gen *g2)
{
int sf, st, t;
Sym *s;
if(pass == 1)
goto out;
jackpot:
sf = 0;
s = g1->sym;
while(s != S) {
sf = s->sym;
if(sf < 0 || sf >= NSYM)
sf = 0;
t = g1->name;
if(h[sf].type == t)
if(h[sf].sym == s)
break;
zname(s->name, t, sym);
s->sym = sym;
h[sym].sym = s;
h[sym].type = t;
sf = sym;
sym++;
if(sym >= NSYM)
sym = 1;
break;
}
st = 0;
s = g2->sym;
while(s != S) {
st = s->sym;
if(st < 0 || st >= NSYM)
st = 0;
t = g2->name;
if(h[st].type == t)
if(h[st].sym == s)
break;
zname(s->name, t, sym);
s->sym = sym;
h[sym].sym = s;
h[sym].type = t;
st = sym;
sym++;
if(sym >= NSYM)
sym = 1;
if(st == sf)
goto jackpot;
break;
}
Bputc(&obuf, a);
Bputc(&obuf, reg);
Bputc(&obuf, lineno);
Bputc(&obuf, lineno>>8);
Bputc(&obuf, lineno>>16);
Bputc(&obuf, lineno>>24);
zaddr(g1, sf);
zaddr(g2, st);
out:
if(a != AGLOBL && a != ADATA)
pc++;
}
void
outhist(void)
{
Gen g;
Hist *h;
char *p, *q, *op;
int n;
g = nullgen;
for(h = hist; h != H; h = h->link) {
p = h->name;
op = 0;
if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') {
op = p;
p = pathname;
}
while(p) {
q = strchr(p, '/');
if(q) {
n = q-p;
if(n == 0)
n = 1; /* leading "/" */
q++;
} else {
n = strlen(p);
q = 0;
}
if(n) {
Bputc(&obuf, ANAME);
Bputc(&obuf, D_FILE); /* type */
Bputc(&obuf, 1); /* sym */
Bputc(&obuf, '<');
Bwrite(&obuf, p, n);
Bputc(&obuf, 0);
}
p = q;
if(p == 0 && op) {
p = op;
op = 0;
}
}
g.offset = h->offset;
Bputc(&obuf, AHISTORY);
Bputc(&obuf, 0);
Bputc(&obuf, h->line);
Bputc(&obuf, h->line>>8);
Bputc(&obuf, h->line>>16);
Bputc(&obuf, h->line>>24);
zaddr(&nullgen, 0);
zaddr(&g, 0);
}
}
#include "../cc/lexbody"
#include "../cc/macbody"
#include "../cc/compat"

View file

@ -1,19 +0,0 @@
</$objtype/mkfile
TARG=7a
OFILES=\
y.tab.$O\
lex.$O\
HFILES=\
../7c/7.out.h\
y.tab.h\
a.h\
YFILES=a.y\
BIN=/$objtype/bin
< /sys/src/cmd/mkone
YFLAGS=-D1 -d
lex.$O: ../cc/macbody ../cc/lexbody

View file

@ -1,265 +0,0 @@
#define NSNAME 8
#define NSYM 50
#define NREG 32
#define NOPROF (1<<0)
#define DUPOK (1<<1)
enum
{
REGRET = 0, /* return register and first temp, grows++ */
REGARG = 0, /* first arg passed in */
REGEXT = 15, /* first external register, grows-- */
REGLINK = 26, /* subroutine linkage */
REGTMP = 27, /* used by the loader */
REGTMP2 = 28, /* used by the loader */
REGSB = 29, /* static pointer */
REGSP = 30, /* stack pointer */
REGZERO = 31, /* always zero */
FREGRET = 0,
FREGEXT = 27, /* first external register */
FREGHALF = 28, /* double */
FREGONE = 29, /* double */
FREGTWO = 30, /* double */
FREGZERO = 31, /* both float and double */
};
enum as
{
AXXX,
AGOK,
ATEXT,
ADATA,
AGLOBL,
AHISTORY,
ANAME,
AWORD,
ANOP,
AMOVL,
AMOVLU,
AMOVQ,
AMOVQU,
AMOVS,
AMOVT,
AMOVB,
AMOVBU,
AMOVW,
AMOVWU,
AMOVA,
AMOVAH,
AMOVLL,
AMOVQL,
AMOVLC,
AMOVQC,
AMOVQP,
AMOVLP,
AADDL,
AADDLV,
AADDQ,
AADDQV,
AS4ADDL,
AS4ADDQ,
AS8ADDL,
AS8ADDQ,
AS4SUBL,
AS4SUBQ,
AS8SUBL,
AS8SUBQ,
ASUBL,
ASUBLV,
ASUBQ,
ASUBQV,
ACMPEQ,
ACMPGT,
ACMPGE,
ACMPUGT,
ACMPUGE,
ACMPBLE,
AAND,
AANDNOT,
AOR,
AORNOT,
AXOR,
AXORNOT,
ACMOVEQ,
ACMOVNE,
ACMOVLT,
ACMOVGE,
ACMOVLE,
ACMOVGT,
ACMOVLBC,
ACMOVLBS,
AMULL,
AMULQ,
AMULLV,
AMULQV,
AUMULH,
ADIVQ,
AMODQ,
ADIVQU,
AMODQU,
ADIVL,
AMODL,
ADIVLU,
AMODLU,
ASLLQ,
ASRLQ,
ASRAQ,
ASLLL,
ASRLL,
ASRAL,
AEXTBL,
AEXTWL,
AEXTLL,
AEXTQL,
AEXTWH,
AEXTLH,
AEXTQH,
AINSBL,
AINSWL,
AINSLL,
AINSQL,
AINSWH,
AINSLH,
AINSQH,
AMSKBL,
AMSKWL,
AMSKLL,
AMSKQL,
AMSKWH,
AMSKLH,
AMSKQH,
AZAP,
AZAPNOT,
AJMP,
AJSR,
ARET,
ABR,
ABSR,
ABEQ,
ABNE,
ABLT,
ABGE,
ABLE,
ABGT,
ABLBC,
ABLBS,
AFBEQ,
AFBNE,
AFBLT,
AFBGE,
AFBLE,
AFBGT,
ATRAPB,
AMB,
AFETCH,
AFETCHM,
ARPCC,
ACPYS,
ACPYSN,
ACPYSE,
ACVTLQ,
ACVTQL,
AFCMOVEQ,
AFCMOVNE,
AFCMOVLT,
AFCMOVGE,
AFCMOVLE,
AFCMOVGT,
AADDS,
AADDT,
ACMPTEQ,
ACMPTGT,
ACMPTGE,
ACMPTUN,
ACVTQS,
ACVTQT,
ACVTTS,
ACVTTQ,
ADIVS,
ADIVT,
AMULS,
AMULT,
ASUBS,
ASUBT,
ACALL_PAL,
AREI,
AEND,
ADYNT,
AINIT,
ASIGNAME,
ALAST,
};
/* type/name */
enum
{
D_GOK = 0,
D_NONE,
/* name */
D_EXTERN,
D_STATIC,
D_AUTO,
D_PARAM,
/* type */
D_BRANCH,
D_OREG,
D_CONST,
D_FCONST,
D_SCONST,
D_REG,
D_FREG,
D_FCREG,
D_PREG,
D_PCC,
D_FILE,
D_FILE1,
};
/*
* this is the ranlib header
*/
#define SYMDEF "__.SYMDEF"
/*
* this is the simulated IEEE floating point
*/
typedef struct ieee Ieee;
struct ieee
{
long l; /* contains ls-man 0xffffffff */
long h; /* contains sign 0x80000000
exp 0x7ff00000
ms-man 0x000fffff */
};

File diff suppressed because it is too large Load diff

View file

@ -1,165 +0,0 @@
char* anames[] =
{
"XXX",
"GOK",
"TEXT",
"DATA",
"GLOBL",
"HISTORY",
"NAME",
"WORD",
"NOP",
"MOVL",
"MOVLU",
"MOVQ",
"MOVQU",
"MOVS",
"MOVT",
"MOVB",
"MOVBU",
"MOVW",
"MOVWU",
"MOVA",
"MOVAH",
"MOVLL",
"MOVQL",
"MOVLC",
"MOVQC",
"MOVQP",
"MOVLP",
"ADDL",
"ADDLV",
"ADDQ",
"ADDQV",
"S4ADDL",
"S4ADDQ",
"S8ADDL",
"S8ADDQ",
"S4SUBL",
"S4SUBQ",
"S8SUBL",
"S8SUBQ",
"SUBL",
"SUBLV",
"SUBQ",
"SUBQV",
"CMPEQ",
"CMPGT",
"CMPGE",
"CMPUGT",
"CMPUGE",
"CMPBLE",
"AND",
"ANDNOT",
"OR",
"ORNOT",
"XOR",
"XORNOT",
"CMOVEQ",
"CMOVNE",
"CMOVLT",
"CMOVGE",
"CMOVLE",
"CMOVGT",
"CMOVLBC",
"CMOVLBS",
"MULL",
"MULQ",
"MULLV",
"MULQV",
"UMULH",
"DIVQ",
"MODQ",
"DIVQU",
"MODQU",
"DIVL",
"MODL",
"DIVLU",
"MODLU",
"SLLQ",
"SRLQ",
"SRAQ",
"SLLL",
"SRLL",
"SRAL",
"EXTBL",
"EXTWL",
"EXTLL",
"EXTQL",
"EXTWH",
"EXTLH",
"EXTQH",
"INSBL",
"INSWL",
"INSLL",
"INSQL",
"INSWH",
"INSLH",
"INSQH",
"MSKBL",
"MSKWL",
"MSKLL",
"MSKQL",
"MSKWH",
"MSKLH",
"MSKQH",
"ZAP",
"ZAPNOT",
"JMP",
"JSR",
"RET",
"BR",
"BSR",
"BEQ",
"BNE",
"BLT",
"BGE",
"BLE",
"BGT",
"BLBC",
"BLBS",
"FBEQ",
"FBNE",
"FBLT",
"FBGE",
"FBLE",
"FBGT",
"TRAPB",
"MB",
"FETCH",
"FETCHM",
"RPCC",
"CPYS",
"CPYSN",
"CPYSE",
"CVTLQ",
"CVTQL",
"FCMOVEQ",
"FCMOVNE",
"FCMOVLT",
"FCMOVGE",
"FCMOVLE",
"FCMOVGT",
"ADDS",
"ADDT",
"CMPTEQ",
"CMPTGT",
"CMPTGE",
"CMPTUN",
"CVTQS",
"CVTQT",
"CVTTS",
"CVTTQ",
"DIVS",
"DIVT",
"MULS",
"MULT",
"SUBS",
"SUBT",
"CALL_PAL",
"REI",
"END",
"DYNT",
"INIT",
"LAST",
};

View file

@ -1,343 +0,0 @@
#include "../cc/cc.h"
#include "../7c/7.out.h"
/*
* 7c/alpha
* DEC Alpha
*/
#define SZ_CHAR 1
#define SZ_SHORT 2
#define SZ_INT 4
#define SZ_LONG 4
#define SZ_IND 4
#define SZ_FLOAT 4
#define SZ_VLONG 8
#define SZ_DOUBLE 8
#define FNX 100
typedef struct Adr Adr;
typedef struct Prog Prog;
typedef struct Case Case;
typedef struct C1 C1;
typedef struct Multab Multab;
typedef struct Hintab Hintab;
typedef struct Bits Bits;
typedef struct Var Var;
typedef struct Reg Reg;
typedef struct Rgn Rgn;
struct Adr
{
union
{
vlong offset;
double dval;
char sval[NSNAME];
Ieee ieee;
};
Sym* sym;
char type;
char reg;
char name;
char etype;
};
#define A ((Adr*)0)
#define INDEXED 9
struct Prog
{
Adr from;
Adr to;
Prog* link;
long lineno;
uchar as;
char reg;
};
#define P ((Prog*)0)
struct Case
{
Case* link;
vlong val;
long label;
char def;
char isv;
};
#define C ((Case*)0)
struct C1
{
vlong val;
long label;
};
struct Multab
{
long val;
char code[20];
};
struct Hintab
{
ushort val;
char hint[10];
};
struct Var
{
vlong offset;
Sym* sym;
char name;
char etype;
};
struct Reg
{
long pc;
long rpo; /* reverse post ordering */
Bits set;
Bits use1;
Bits use2;
Bits refbehind;
Bits refahead;
Bits calbehind;
Bits calahead;
Bits regdiff;
Bits act;
long regu;
long loop; /* could be shorter */
union
{
Reg* log5;
long active;
};
Reg* p1;
Reg* p2;
Reg* p2link;
Reg* s1;
Reg* s2;
Reg* link;
Prog* prog;
};
#define R ((Reg*)0)
#define NRGN 600
struct Rgn
{
Reg* enter;
short cost;
short varno;
short regno;
};
EXTERN long breakpc;
EXTERN long nbreak;
EXTERN Case* cases;
EXTERN Node constnode;
EXTERN Node fconstnode;
EXTERN long continpc;
EXTERN long curarg;
EXTERN long cursafe;
EXTERN Prog* firstp;
EXTERN Prog* lastp;
EXTERN long maxargsafe;
EXTERN int mnstring;
EXTERN Multab multab[20];
EXTERN int hintabsize;
EXTERN Node* nodrat;
EXTERN Node* nodret;
EXTERN Node* nodsafe;
EXTERN long nrathole;
EXTERN long nstring;
EXTERN Prog* p;
EXTERN long pc;
EXTERN Node regnode;
EXTERN char string[NSNAME];
EXTERN Sym* symrathole;
EXTERN Node znode;
EXTERN Prog zprog;
EXTERN char reg[NREG+NREG];
EXTERN long exregoffset;
EXTERN long exfregoffset;
#define BLOAD(r) band(bnot(r->refbehind), r->refahead)
#define BSTORE(r) band(bnot(r->calbehind), r->calahead)
#define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z])
#define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z])
#define bset(a,n) ((a).b[(n)/32]&(1L<<(n)%32))
#define CLOAD 4
#define CREF 5
#define CINF 1000
#define LOOP 3
EXTERN Rgn region[NRGN];
EXTERN Rgn* rgp;
EXTERN int nregion;
EXTERN int nvar;
EXTERN Bits externs;
EXTERN Bits params;
EXTERN Bits consts;
EXTERN Bits addrs;
EXTERN Bits zbits;
EXTERN long regbits;
EXTERN long exregbits;
EXTERN int change;
EXTERN int suppress;
EXTERN Reg* firstr;
EXTERN Reg* lastr;
EXTERN Reg zreg;
EXTERN Reg* freer;
EXTERN Var var[NVAR];
EXTERN long* idom;
EXTERN Reg** rpo2r;
EXTERN long maxnr;
extern char* anames[];
extern Hintab hintab[];
/*
* sgen.c
*/
void codgen(Node*, Node*);
void gen(Node*);
void usedset(Node*, int);
void noretval(int);
void xcom(Node*);
int bcomplex(Node*, Node*);
/*
* cgen.c
*/
void cgen(Node*, Node*);
void reglcgen(Node*, Node*, Node*);
void lcgen(Node*, Node*);
void bcgen(Node*, int);
void boolgen(Node*, int, Node*);
void sugen(Node*, Node*, long);
void layout(Node*, Node*, int, int, Node*);
/*
* txt.c
*/
void ginit(void);
void gclean(void);
void nextpc(void);
void gargs(Node*, Node*, Node*);
void garg1(Node*, Node*, Node*, int, Node**);
Node* nodconst(long);
Node* nod32const(vlong);
Node* nodfconst(double);
void nodreg(Node*, Node*, int);
void regret(Node*, Node*);
void regalloc(Node*, Node*, Node*);
void regfree(Node*);
void regialloc(Node*, Node*, Node*);
void regsalloc(Node*, Node*);
void regaalloc1(Node*, Node*);
void regaalloc(Node*, Node*);
void regind(Node*, Node*);
void gprep(Node*, Node*);
void raddr(Node*, Prog*);
void naddr(Node*, Adr*);
void gmove(Node*, Node*);
void gins(int a, Node*, Node*);
void gopcode(int, Node*, Node*, Node*);
int samaddr(Node*, Node*);
void gbranch(int);
void patch(Prog*, long);
int bconst(Node*);
int sconst(Node*);
int bval(vlong);
int sval(long);
void gpseudo(int, Sym*, Node*);
/*
* swt.c
*/
int swcmp(void*, void*);
void doswit(Node*);
void swit1(C1*, int, long, Node*);
void swit2(C1*, int, long, Node*, Node*);
void casf(void);
void bitload(Node*, Node*, Node*, Node*, Node*);
void bitstore(Node*, Node*, Node*, Node*, Node*);
long outstring(char*, long);
int vlog(Node*);
int mulcon(Node*, Node*);
Multab* mulcon0(long);
void nullwarn(Node*, Node*);
void sextern(Sym*, Node*, long, long);
void gextern(Sym*, Node*, long, long);
void outcode(void);
void ieeedtod(Ieee*, double);
/*
* list
*/
void listinit(void);
int Pconv(Fmt*);
int Aconv(Fmt*);
int Dconv(Fmt*);
int Sconv(Fmt*);
int Nconv(Fmt*);
int Bconv(Fmt*);
/*
* reg.c
*/
Reg* rega(void);
int rcmp(void*, void*);
void regopt(Prog*);
void addmove(Reg*, int, int, int);
Bits mkvar(Adr*, int);
void prop(Reg*, Bits, Bits);
void loopit(Reg*, long);
void synch(Reg*, Bits);
ulong allreg(ulong, Rgn*);
void paint1(Reg*, int);
ulong paint2(Reg*, int);
void paint3(Reg*, int, long, int);
void addreg(Adr*, int);
/*
* peep.c
*/
void peep(void);
void excise(Reg*);
Reg* uniqp(Reg*);
Reg* uniqs(Reg*);
int regtyp(Adr*);
int regzer(Adr*);
int anyvar(Adr*);
int subprop(Reg*);
int copyprop(Reg*);
int copy1(Adr*, Adr*, Reg*, int);
int copyu(Prog*, Adr*, Adr*);
int copyas(Adr*, Adr*);
int copyau(Adr*, Adr*);
int copyau1(Prog*, Adr*);
int copysub(Adr*, Adr*, Adr*, int);
int copysub1(Prog*, Adr*, Adr*, int);
long RtoB(int);
long FtoB(int);
int BtoR(long);
int BtoF(long);
#pragma varargck type "A" int
#pragma varargck type "B" Bits
#pragma varargck type "D" Adr*
#pragma varargck type "N" Adr*
#pragma varargck type "P" Prog*
#pragma varargck type "S" char*

View file

@ -1,231 +0,0 @@
#define EXTERN
#include "gc.h"
void
listinit(void)
{
fmtinstall('A', Aconv);
fmtinstall('P', Pconv);
fmtinstall('S', Sconv);
fmtinstall('N', Nconv);
fmtinstall('B', Bconv);
fmtinstall('D', Dconv);
}
int
Bconv(Fmt *fp)
{
char str[STRINGSZ], ss[STRINGSZ], *s;
Bits bits;
int i;
memset(str, 0, sizeof str);
bits = va_arg(fp->args, Bits);
while(bany(&bits)) {
i = bnum(bits);
if(str[0])
strncat(str, " ", sizeof str - 1);
if(var[i].sym == S) {
snprint(ss, sizeof ss, "$%lld", var[i].offset);
s = ss;
} else
s = var[i].sym->name;
strncat(str, s, sizeof str - 1);
bits.b[i/32] &= ~(1L << (i%32));
}
return fmtstrcpy(fp, str);
}
int
Pconv(Fmt *fp)
{
char str[STRINGSZ];
Prog *p;
int a;
p = va_arg(fp->args, Prog*);
a = p->as;
if(a == ADATA)
snprint(str, sizeof str, " %A %D/%d,%D", a, &p->from, p->reg, &p->to);
else
if(p->as == ATEXT)
snprint(str, sizeof str, " %A %D,%d,%D", a, &p->from, p->reg, &p->to);
else
if(p->reg == NREG)
snprint(str, sizeof str, " %A %D,%D", a, &p->from, &p->to);
else
if(p->from.type != D_FREG)
snprint(str, sizeof str, " %A %D,R%d,%D", a, &p->from, p->reg, &p->to);
else
snprint(str, sizeof str, " %A %D,F%d,%D", a, &p->from, p->reg, &p->to);
return fmtstrcpy(fp, str);
}
int
Aconv(Fmt *fp)
{
char *s;
int a;
a = va_arg(fp->args, int);
s = "???";
if(a >= AXXX && a < ALAST)
s = anames[a];
return fmtstrcpy(fp, s);
}
int
Dconv(Fmt *fp)
{
char str[STRINGSZ];
Adr *a;
a = va_arg(fp->args, Adr*);
switch(a->type) {
default:
snprint(str, sizeof str, "GOK-type(%d)", a->type);
break;
case D_NONE:
str[0] = 0;
if(a->name != D_NONE || a->reg != NREG || a->sym != S)
snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
break;
case D_CONST:
if(a->reg != NREG)
snprint(str, sizeof str, "$%N(R%d)", a, a->reg);
else
snprint(str, sizeof str, "$%N", a);
break;
case D_OREG:
if(a->reg != NREG)
snprint(str, sizeof str, "%N(R%d)", a, a->reg);
else
snprint(str, sizeof str, "%N", a);
break;
case D_REG:
snprint(str, sizeof str, "R%d", a->reg);
if(a->name != D_NONE || a->sym != S)
snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
break;
case D_FREG:
snprint(str, sizeof str, "F%d", a->reg);
if(a->name != D_NONE || a->sym != S)
snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
break;
case D_FCREG:
snprint(str, sizeof str, "FPCR");
if(a->reg != 0 || a->name != D_NONE || a->sym != S)
snprint(str, sizeof str, "%N(FPCR%d)(REG)", a, a->reg);
break;
case D_BRANCH:
snprint(str, sizeof str, "%lld(PC)", a->offset-pc);
break;
case D_FCONST:
snprint(str, sizeof str, "$%.17e", a->dval);
break;
case D_SCONST:
snprint(str, sizeof str, "$\"%S\"", a->sval);
break;
}
return fmtstrcpy(fp, str);
}
int
Sconv(Fmt *fp)
{
int i, c;
char str[STRINGSZ], *p, *a;
a = va_arg(fp->args, char*);
p = str;
for(i=0; i<NSNAME; i++) {
c = a[i] & 0xff;
if(c >= 'a' && c <= 'z' ||
c >= 'A' && c <= 'Z' ||
c >= '0' && c <= '9' ||
c == ' ' || c == '%') {
*p++ = c;
continue;
}
*p++ = '\\';
switch(c) {
case 0:
*p++ = 'z';
continue;
case '\\':
case '"':
*p++ = c;
continue;
case '\n':
*p++ = 'n';
continue;
case '\t':
*p++ = 't';
continue;
case '\r':
*p++ = 'r';
continue;
case '\f':
*p++ = 'f';
continue;
}
*p++ = (c>>6) + '0';
*p++ = ((c>>3) & 7) + '0';
*p++ = (c & 7) + '0';
}
*p = 0;
return fmtstrcpy(fp, str);
}
int
Nconv(Fmt *fp)
{
char str[STRINGSZ];
Adr *a;
Sym *s;
a = va_arg(fp->args, Adr*);
s = a->sym;
if(s == S) {
snprint(str, sizeof str, "%lld", a->offset);
goto out;
}
switch(a->name) {
default:
snprint(str, sizeof str, "GOK-name(%d)", a->name);
break;
case D_NONE:
snprint(str, sizeof str, "%lld", a->offset);
break;
case D_EXTERN:
snprint(str, sizeof str, "%s+%lld(SB)", s->name, a->offset);
break;
case D_STATIC:
snprint(str, sizeof str, "%s<>+%lld(SB)", s->name, a->offset);
break;
case D_AUTO:
snprint(str, sizeof str, "%s-%lld(SP)", s->name, -a->offset);
break;
case D_PARAM:
snprint(str, sizeof str, "%s+%lld(FP)", s->name, a->offset);
break;
}
out:
return fmtstrcpy(fp, str);
}

View file

@ -1,9 +0,0 @@
#include "gc.h"
int
machcap(Node *n)
{
if(n == Z) /* test */
return 1;
return 0;
}

View file

@ -1,15 +0,0 @@
ed - ../7c/7.out.h <<'!'
v/^ A/d
,s/^ A/ "/
g/ .*$/s///
,s/,*$/",/
1i
char* anames[] =
{
.
$a
};
.
w enam.c
Q
!

View file

@ -1,39 +0,0 @@
</$objtype/mkfile
TARG=7c
OFILES=\
cgen.$O\
enam.$O\
list.$O\
machcap.$O\
peep.$O\
pgen.$O\
pswt.$O\
reg.$O\
sgen.$O\
swt.$O\
txt.$O\
mul.$O\
HFILES=\
gc.h\
7.out.h\
../cc/cc.h\
LIB=../cc/cc.a$O
BIN=/$objtype/bin
</sys/src/cmd/mkone
$LIB:
cd ../cc
mk install
mk clean
%.$O: ../cc/%.c
$CC $CFLAGS ../cc/$stem.c
t:V: $O.out
$O.out -S t
$LD -o t.out t.$O
t.out

View file

@ -1,608 +0,0 @@
#include "gc.h"
/*
* code sequences for multiply by constant.
* [a-l][0-3]
* lsl $(A-'a'),r0,r1
* [+][0-7]
* add r0,r1,r2
* [-][0-7]
* sub r0,r1,r2
*/
static int multabp;
static long mulval;
static char* mulcp;
static long valmax;
static int shmax;
static int docode(char *hp, char *cp, int r0, int r1);
static int gen1(int len);
static int gen2(int len, long r1);
static int gen3(int len, long r0, long r1, int flag);
enum
{
SR1 = 1<<0, /* r1 has been shifted */
SR0 = 1<<1, /* r0 has been shifted */
UR1 = 1<<2, /* r1 has not been used */
UR0 = 1<<3, /* r0 has not been used */
};
Multab*
mulcon0(long v)
{
int a1, a2, g;
Multab *m, *m1;
char hint[10];
if(v < 0)
v = -v;
/*
* look in cache
*/
m = multab;
for(g=0; g<nelem(multab); g++) {
if(m->val == v) {
if(m->code[0] == 0)
return 0;
return m;
}
m++;
}
/*
* select a spot in cache to overwrite
*/
multabp++;
if(multabp < 0 || multabp >= nelem(multab))
multabp = 0;
m = multab+multabp;
m->val = v;
mulval = v;
/*
* look in execption hint table
*/
a1 = 0;
a2 = hintabsize;
for(;;) {
if(a1 >= a2)
goto no;
g = (a2 + a1)/2;
if(v < hintab[g].val) {
a2 = g;
continue;
}
if(v > hintab[g].val) {
a1 = g+1;
continue;
}
break;
}
if(docode(hintab[g].hint, m->code, 1, 0))
return m;
print("multiply table failure %ld\n", v);
m->code[0] = 0;
return 0;
no:
/*
* try to search
*/
hint[0] = 0;
for(g=1; g<=6; g++) {
if(g >= 6 && v >= 65535)
break;
mulcp = hint+g;
*mulcp = 0;
if(gen1(g)) {
if(docode(hint, m->code, 1, 0))
return m;
print("multiply table failure %ld\n", v);
break;
}
}
/*
* try a recur followed by a shift
*/
g = 0;
while(!(v & 1)) {
g++;
v >>= 1;
}
if(g) {
m1 = mulcon0(v);
if(m1) {
strcpy(m->code, m1->code);
sprint(strchr(m->code, 0), "%c0", g+'a');
return m;
}
}
m->code[0] = 0;
return 0;
}
static int
docode(char *hp, char *cp, int r0, int r1)
{
int c, i;
c = *hp++;
*cp = c;
cp += 2;
switch(c) {
default:
c -= 'a';
if(c < 1 || c >= 30)
break;
for(i=0; i<4; i++) {
switch(i) {
case 0:
if(docode(hp, cp, r0<<c, r1))
goto out;
break;
case 1:
if(docode(hp, cp, r1<<c, r1))
goto out;
break;
case 2:
if(docode(hp, cp, r0, r0<<c))
goto out;
break;
case 3:
if(docode(hp, cp, r0, r1<<c))
goto out;
break;
}
}
break;
case '+':
for(i=0; i<8; i++) {
cp[-1] = i+'0';
switch(i) {
case 1:
if(docode(hp, cp, r0+r1, r1))
goto out;
break;
case 5:
if(docode(hp, cp, r0, r0+r1))
goto out;
break;
}
}
break;
case '-':
for(i=0; i<8; i++) {
cp[-1] = i+'0';
switch(i) {
case 1:
if(docode(hp, cp, r0-r1, r1))
goto out;
break;
case 2:
if(docode(hp, cp, r1-r0, r1))
goto out;
break;
case 5:
if(docode(hp, cp, r0, r0-r1))
goto out;
break;
case 6:
if(docode(hp, cp, r0, r1-r0))
goto out;
break;
}
}
break;
case 0:
if(r0 == mulval)
return 1;
}
return 0;
out:
cp[-1] = i+'0';
return 1;
}
static int
gen1(int len)
{
int i;
for(shmax=1; shmax<30; shmax++) {
valmax = 1<<shmax;
if(valmax >= mulval)
break;
}
if(mulval == 1)
return 1;
len--;
for(i=1; i<=shmax; i++)
if(gen2(len, 1<<i)) {
*--mulcp = 'a'+i;
return 1;
}
return 0;
}
static int
gen2(int len, long r1)
{
int i;
if(len <= 0) {
if(r1 == mulval)
return 1;
return 0;
}
len--;
if(len == 0)
goto calcr0;
if(gen3(len, r1, r1+1, UR1)) {
i = '+';
goto out;
}
if(gen3(len, r1-1, r1, UR0)) {
i = '-';
goto out;
}
if(gen3(len, 1, r1+1, UR1)) {
i = '+';
goto out;
}
if(gen3(len, 1, r1-1, UR1)) {
i = '-';
goto out;
}
return 0;
calcr0:
if(mulval == r1+1) {
i = '+';
goto out;
}
if(mulval == r1-1) {
i = '-';
goto out;
}
return 0;
out:
*--mulcp = i;
return 1;
}
static int
gen3(int len, long r0, long r1, int flag)
{
int i, f1, f2;
long x;
if(r0 <= 0 ||
r0 >= r1 ||
r1 > valmax)
return 0;
len--;
if(len == 0)
goto calcr0;
if(!(flag & UR1)) {
f1 = UR1|SR1;
for(i=1; i<=shmax; i++) {
x = r0<<i;
if(x > valmax)
break;
if(gen3(len, r0, x, f1)) {
i += 'a';
goto out;
}
}
}
if(!(flag & UR0)) {
f1 = UR1|SR1;
for(i=1; i<=shmax; i++) {
x = r1<<i;
if(x > valmax)
break;
if(gen3(len, r1, x, f1)) {
i += 'a';
goto out;
}
}
}
if(!(flag & SR1)) {
f1 = UR1|SR1|(flag&UR0);
for(i=1; i<=shmax; i++) {
x = r1<<i;
if(x > valmax)
break;
if(gen3(len, r0, x, f1)) {
i += 'a';
goto out;
}
}
}
if(!(flag & SR0)) {
f1 = UR0|SR0|(flag&(SR1|UR1));
f2 = UR1|SR1;
if(flag & UR1)
f2 |= UR0;
if(flag & SR1)
f2 |= SR0;
for(i=1; i<=shmax; i++) {
x = r0<<i;
if(x > valmax)
break;
if(x > r1) {
if(gen3(len, r1, x, f2)) {
i += 'a';
goto out;
}
} else
if(gen3(len, x, r1, f1)) {
i += 'a';
goto out;
}
}
}
x = r1+r0;
if(gen3(len, r0, x, UR1)) {
i = '+';
goto out;
}
if(gen3(len, r1, x, UR1)) {
i = '+';
goto out;
}
x = r1-r0;
if(gen3(len, x, r1, UR0)) {
i = '-';
goto out;
}
if(x > r0) {
if(gen3(len, r0, x, UR1)) {
i = '-';
goto out;
}
} else
if(gen3(len, x, r0, UR0)) {
i = '-';
goto out;
}
return 0;
calcr0:
f1 = flag & (UR0|UR1);
if(f1 == UR1) {
for(i=1; i<=shmax; i++) {
x = r1<<i;
if(x >= mulval) {
if(x == mulval) {
i += 'a';
goto out;
}
break;
}
}
}
if(mulval == r1+r0) {
i = '+';
goto out;
}
if(mulval == r1-r0) {
i = '-';
goto out;
}
return 0;
out:
*--mulcp = i;
return 1;
}
/*
* hint table has numbers that
* the search algorithm fails on.
* <1000:
* all numbers
* <5000:
* ÷ by 5
* <10000:
* ÷ by 50
* <65536:
* ÷ by 250
*/
Hintab hintab[] =
{
683, "b++d+e+",
687, "b+e++e-",
691, "b++d+e+",
731, "b++d+e+",
811, "b++d+i+",
821, "b++e+e+",
843, "b+d++e+",
851, "b+f-+e-",
853, "b++e+e+",
877, "c++++g-",
933, "b+c++g-",
981, "c-+e-d+",
1375, "b+c+b+h-",
1675, "d+b++h+",
2425, "c++f-e+",
2675, "c+d++f-",
2750, "b+d-b+h-",
2775, "c-+g-e-",
3125, "b++e+g+",
3275, "b+c+g+e+",
3350, "c++++i+",
3475, "c-+e-f-",
3525, "c-+d+g-",
3625, "c-+e-j+",
3675, "b+d+d+e+",
3725, "b+d-+h+",
3925, "b+d+f-d-",
4275, "b+g++e+",
4325, "b+h-+d+",
4425, "b+b+g-j-",
4525, "b+d-d+f+",
4675, "c++d-g+",
4775, "b+d+b+g-",
4825, "c+c-+i-",
4850, "c++++i-",
4925, "b++e-g-",
4975, "c+f++e-",
5500, "b+g-c+d+",
6700, "d+b++i+",
9700, "d++++j-",
11000, "b+f-c-h-",
11750, "b+d+g+j-",
12500, "b+c+e-k+",
13250, "b+d+e-f+",
13750, "b+h-c-d+",
14250, "b+g-c+e-",
14500, "c+f+j-d-",
14750, "d-g--f+",
16750, "b+e-d-n+",
17750, "c+h-b+e+",
18250, "d+b+h-d+",
18750, "b+g-++f+",
19250, "b+e+b+h+",
19750, "b++h--f-",
20250, "b+e-l-c+",
20750, "c++bi+e-",
21250, "b+i+l+c+",
22000, "b+e+d-g-",
22250, "b+d-h+k-",
22750, "b+d-e-g+",
23250, "b+c+h+e-",
23500, "b+g-c-g-",
23750, "b+g-b+h-",
24250, "c++g+m-",
24750, "b+e+e+j-",
25000, "b++dh+g+",
25250, "b+e+d-g-",
25750, "b+e+b+j+",
26250, "b+h+c+e+",
26500, "b+h+c+g+",
26750, "b+d+e+g-",
27250, "b+e+e+f+",
27500, "c-i-c-d+",
27750, "b+bd++j+",
28250, "d-d-++i-",
28500, "c+c-h-e-",
29000, "b+g-d-f+",
29500, "c+h+++e-",
29750, "b+g+f-c+",
30250, "b+f-g-c+",
33500, "c-f-d-n+",
33750, "b+d-b+j-",
34250, "c+e+++i+",
35250, "e+b+d+k+",
35500, "c+e+d-g-",
35750, "c+i-++e+",
36250, "b+bh-d+e+",
36500, "c+c-h-e-",
36750, "d+e--i+",
37250, "b+g+g+b+",
37500, "b+h-b+f+",
37750, "c+be++j-",
38500, "b+e+b+i+",
38750, "d+i-b+d+",
39250, "b+g-l-+d+",
39500, "b+g-c+g-",
39750, "b+bh-c+f-",
40250, "b+bf+d+g-",
40500, "b+g-c+g+",
40750, "c+b+i-e+",
41250, "d++bf+h+",
41500, "b+j+c+d-",
41750, "c+f+b+h-",
42500, "c+h++g+",
42750, "b+g+d-f-",
43250, "b+l-e+d-",
43750, "c+bd+h+f-",
44000, "b+f+g-d-",
44250, "b+d-g--f+",
44500, "c+e+c+h+",
44750, "b+e+d-h-",
45250, "b++g+j-g+",
45500, "c+d+e-g+",
45750, "b+d-h-e-",
46250, "c+bd++j+",
46500, "b+d-c-j-",
46750, "e-e-b+g-",
47000, "b+c+d-j-",
47250, "b+e+e-g-",
47500, "b+g-c-h-",
47750, "b+f-c+h-",
48250, "d--h+n-",
48500, "b+c-g+m-",
48750, "b+e+e-g+",
49500, "c-f+e+j-",
49750, "c+c+g++f-",
50000, "b+e+e+k+",
50250, "b++i++g+",
50500, "c+g+f-i+",
50750, "b+e+d+k-",
51500, "b+i+c-f+",
51750, "b+bd+g-e-",
52250, "b+d+g-j+",
52500, "c+c+f+g+",
52750, "b+c+e+i+",
53000, "b+i+c+g+",
53500, "c+g+g-n+",
53750, "b+j+d-c+",
54250, "b+d-g-j-",
54500, "c-f+e+f+",
54750, "b+f-+c+g+",
55000, "b+g-d-g-",
55250, "b+e+e+g+",
55500, "b+cd++j+",
55750, "b+bh-d-f-",
56250, "c+d-b+j-",
56500, "c+d+c+i+",
56750, "b+e+d++h-",
57000, "b+d+g-f+",
57250, "b+f-m+d-",
57750, "b+i+c+e-",
58000, "b+e+d+h+",
58250, "c+b+g+g+",
58750, "d-e-j--e+",
59000, "d-i-+e+",
59250, "e--h-m+",
59500, "c+c-h+f-",
59750, "b+bh-e+i-",
60250, "b+bh-e-e-",
60500, "c+c-g-g-",
60750, "b+e-l-e-",
61250, "b+g-g-c+",
61750, "b+g-c+g+",
62250, "f--+c-i-",
62750, "e+f--+g+",
64750, "b+f+d+p-",
};
int hintabsize = nelem(hintab);

Some files were not shown because too many files have changed in this diff Show more