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