1*5c47fe09SDavid du Colombier /*
2*5c47fe09SDavid du Colombier * from 9front
3*5c47fe09SDavid du Colombier */
4*5c47fe09SDavid du Colombier
5*5c47fe09SDavid du Colombier #include "u.h"
6*5c47fe09SDavid du Colombier #include "../port/lib.h"
7*5c47fe09SDavid du Colombier #include "mem.h"
8*5c47fe09SDavid du Colombier #include "dat.h"
9*5c47fe09SDavid du Colombier #include "fns.h"
10*5c47fe09SDavid du Colombier #include "../port/error.h"
11*5c47fe09SDavid du Colombier #include "ureg.h"
12*5c47fe09SDavid du Colombier
13*5c47fe09SDavid du Colombier /*
14*5c47fe09SDavid du Colombier * GISB arbiter registers
15*5c47fe09SDavid du Colombier */
16*5c47fe09SDavid du Colombier static u32int *regs = (u32int*)(VIRTIO + 0x400000);
17*5c47fe09SDavid du Colombier
18*5c47fe09SDavid du Colombier enum {
19*5c47fe09SDavid du Colombier ArbMasterMask = 0x004/4,
20*5c47fe09SDavid du Colombier ArbTimer = 0x008/4,
21*5c47fe09SDavid du Colombier TimerFreq = 216000000, // 216MHz
22*5c47fe09SDavid du Colombier
23*5c47fe09SDavid du Colombier ArbErrCapClear = 0x7e4/4,
24*5c47fe09SDavid du Colombier ArbErrCapAddrHi = 0x7e8/4,
25*5c47fe09SDavid du Colombier ArbErrCapAddr = 0x7ec/4,
26*5c47fe09SDavid du Colombier ArbErrCapData = 0x7f0/4,
27*5c47fe09SDavid du Colombier ArbErrCapStatus = 0x7f4/4,
28*5c47fe09SDavid du Colombier CapStatusTimeout = 1<<12,
29*5c47fe09SDavid du Colombier CapStatusAbort = 1<<11,
30*5c47fe09SDavid du Colombier CapStatusStrobe = 15<<2,
31*5c47fe09SDavid du Colombier CapStatusWrite = 1<<1,
32*5c47fe09SDavid du Colombier CapStatusValid = 1<<0,
33*5c47fe09SDavid du Colombier ArbErrCapMaster = 0x7f8/4,
34*5c47fe09SDavid du Colombier
35*5c47fe09SDavid du Colombier ArbIntrSts = 0x3000/4,
36*5c47fe09SDavid du Colombier ArbIntrSet = 0x3004/4,
37*5c47fe09SDavid du Colombier ArbIntrClr = 0x3008/4,
38*5c47fe09SDavid du Colombier
39*5c47fe09SDavid du Colombier ArbCpuMaskSet = 0x3010/4,
40*5c47fe09SDavid du Colombier };
41*5c47fe09SDavid du Colombier
42*5c47fe09SDavid du Colombier static int
arberror(Ureg *)43*5c47fe09SDavid du Colombier arberror(Ureg*)
44*5c47fe09SDavid du Colombier {
45*5c47fe09SDavid du Colombier u32int status, intr;
46*5c47fe09SDavid du Colombier u32int master, data;
47*5c47fe09SDavid du Colombier uvlong addr;
48*5c47fe09SDavid du Colombier
49*5c47fe09SDavid du Colombier status = regs[ArbErrCapStatus];
50*5c47fe09SDavid du Colombier if((status & CapStatusValid) == 0)
51*5c47fe09SDavid du Colombier return 0;
52*5c47fe09SDavid du Colombier intr = regs[ArbIntrSts];
53*5c47fe09SDavid du Colombier master = regs[ArbErrCapMaster];
54*5c47fe09SDavid du Colombier addr = regs[ArbErrCapAddr];
55*5c47fe09SDavid du Colombier addr |= (uvlong)regs[ArbErrCapAddrHi]<<32;
56*5c47fe09SDavid du Colombier data = regs[ArbErrCapData];
57*5c47fe09SDavid du Colombier if(intr)
58*5c47fe09SDavid du Colombier regs[ArbIntrClr] = intr;
59*5c47fe09SDavid du Colombier regs[ArbErrCapClear] = CapStatusValid;
60*5c47fe09SDavid du Colombier
61*5c47fe09SDavid du Colombier iprint("cpu%d: GISB arbiter error: %s%s %s bus addr %llux data %.8ux, "
62*5c47fe09SDavid du Colombier "master %.8ux, status %.8ux, intr %.8ux\n",
63*5c47fe09SDavid du Colombier m->machno,
64*5c47fe09SDavid du Colombier (status & CapStatusTimeout) ? "timeout" : "",
65*5c47fe09SDavid du Colombier (status & CapStatusAbort) ? "abort" : "",
66*5c47fe09SDavid du Colombier (status & CapStatusWrite) ? "writing" : "reading",
67*5c47fe09SDavid du Colombier addr, data,
68*5c47fe09SDavid du Colombier master, status, intr);
69*5c47fe09SDavid du Colombier
70*5c47fe09SDavid du Colombier return 1;
71*5c47fe09SDavid du Colombier }
72*5c47fe09SDavid du Colombier
73*5c47fe09SDavid du Colombier static void
arbclock(void)74*5c47fe09SDavid du Colombier arbclock(void)
75*5c47fe09SDavid du Colombier {
76*5c47fe09SDavid du Colombier arberror(nil);
77*5c47fe09SDavid du Colombier }
78*5c47fe09SDavid du Colombier
79*5c47fe09SDavid du Colombier void
gisblink(void)80*5c47fe09SDavid du Colombier gisblink(void)
81*5c47fe09SDavid du Colombier {
82*5c47fe09SDavid du Colombier extern int (*buserror)(Ureg*); // trap.c
83*5c47fe09SDavid du Colombier
84*5c47fe09SDavid du Colombier regs[ArbErrCapClear] = CapStatusValid;
85*5c47fe09SDavid du Colombier regs[ArbIntrClr] = -1;
86*5c47fe09SDavid du Colombier
87*5c47fe09SDavid du Colombier addclock0link(arbclock, 100);
88*5c47fe09SDavid du Colombier
89*5c47fe09SDavid du Colombier //buserror = arberror;
90*5c47fe09SDavid du Colombier }
91