-
Notifications
You must be signed in to change notification settings - Fork 1
/
Sys.cpp
189 lines (167 loc) · 6.42 KB
/
Sys.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#include "Sys.hpp"
#include "Irq.hpp"
#include "Dma.hpp"
#include "Osc.hpp"
enum {
BMXCON = 0xBF882000,
//BMXERRDIS = 27,
BMXERRIXI = 20,
BMXERRICD = 19,
BMXERRDMA = 18,
BMXERRDS = 17,
BMXERRIS = 16,
BMXWSDRM = 6,
BMXARB_SHIFT = 0, BMXARB_MASK = 7,
BMXDKPBA = 0xBF882010, // Kseg Program (RAM) base address (until User Data RAM)
BMXDUDBA = 0xBF882020, // User Data (RAM) base Address (until User Program RAM)
BMXDUPBA = 0xBF882030, // User Program (RAM) base address (until end of RAM)
//EXECADDR_SHIFT = 16, EXECADDR_MASK = 255,
BMXDRMSZ = 0xBF882040, // Data Ram size
BMXPUPBA = 0xBF882050, // User Program (Flash) base address (until end of PFM)
BMXPFMSZ = 0xBF882060, // Program Flash Memory (PFM) size
BMXBOOTSZ = 0xBF882070, // Boot Flash size
DDPCON = 0xBF80F200,
JTAGEN = 3,
DEVID = 0xBF80F220,
VER_SHIFT = 28, VER_MASK = 15,
ID_SHIFT = 0, ID_MASK = 0xFFFFFFF,
SYSKEY = 0xBF80F230,
MAGIC1 = 0xAA996655,
MAGIC2 = 0x556699AA,
CHECON = 0xBF884000,
PFMWS_SHIFT = 0, PFMWS_MASK = 7,
PREFEN_SHIFT = 4, PREFEN_MASK = 3,
FLASHSPEED = 30000000
};
//syskey lock/unlock
//keep track of unlock count-
//inc unlock_count on lock(), dec unlock_count on unlock()
//unlock done when unlock_count is 0
//lock done when unlock_count is 0
static volatile uint8_t unlock_count;
//=============================================================================
auto Sys::
lock () -> void
{
bool irqstate = Irq::global(); //get STATUS.IE
Irq::global(false);
//unlock_count only accessed with irq off
if(unlock_count) unlock_count--; //dec counter
if(unlock_count == 0) val(SYSKEY, 0); //if 0, lock
//
if(irqstate) Irq::global(true); //restore IE state
}
//=============================================================================
auto Sys::
unlock () -> void
{
bool irqstate = Irq::global(); //get STATUS.IE
Irq::global(false);
bool dmasusp = Dma::all_suspend(); // DMA suspend status
Dma::all_suspend(true); //suspend DMA
//
if(unlock_count == 0){ //first time, unlock
val(SYSKEY, MAGIC1);
val(SYSKEY, MAGIC2);
}
unlock_count++; //inc unlock_count
//
if(not dmasusp) Dma::all_suspend(false); //DMA resume
if(irqstate) Irq::global(true); //restore IE state
}
//provide previous irq/dma status
//=============================================================================
auto Sys::
lock (uint8_t v) -> void
{
lock();
Dma::all_suspend(v & 2); //restore dma
if(v & 1) Irq::global(true); //restore irq
}
//blocking, return irq/dma status for use in next call to lock()
//=============================================================================
auto Sys::
unlock_wait () -> uint8_t
{
bool irqstate = Irq::global(); //get STATUS.IE
Irq::global(false);
bool dmasusp = Dma::all_suspend(); // DMA suspend status
Dma::all_suspend(true); //suspend DMA
//
if(unlock_count == 0){ //first time, unlock
val(SYSKEY, MAGIC1);
val(SYSKEY, MAGIC2);
}
unlock_count++; //inc unlock_count
//
return (dmasusp<<1) bitor irqstate;
}
//cfgcon
//=============================================================================
// auto Sys::
//bus_err (bool tf) -> void
// {
// setbit(BMXCON, 1<<BMXERRDIS, !tf);
// }
//=============================================================================
auto Sys::
bus_mode (BMXARB e) -> void
{
clrbit(BMXCON, BMXARB_MASK<<BMXARB_SHIFT);
setbit(BMXCON, e<<BMXARB_SHIFT);
}
//=============================================================================
auto Sys::
jtag (bool tf) -> void
{
setbit(DDPCON, 1<<JTAGEN, tf);
}
//devid
//=============================================================================
auto Sys::
devid () -> uint32_t
{
return val(DEVID) bitand ID_MASK;
}
//=============================================================================
auto Sys::
ver () -> uint8_t
{
return val(DEVID)>>VER_SHIFT;
}
//=============================================================================
auto Sys::
waitstates (uint32_t clk) -> void
{
uint8_t waitstates = clk / FLASHSPEED;
bool irqstate = Irq::global(); //get STATUS.IE
Irq::global(false);
clrbit(BMXCON, 1 << BMXWSDRM); //Disable RAM wait states
val(CHECON, waitstates << PFMWS_SHIFT);
if(irqstate) Irq::global(true); //restore IE state
}
//=============================================================================
auto Sys::
flash_size () -> uint32_t
{
return val(BMXPFMSZ);
}
//=============================================================================
auto Sys::
pcache (PREFEN p) -> void
{
bool irqstate = Irq::global(); //get STATUS.IE
Irq::global(false);
clrbit(CHECON, PREFEN_MASK << PREFEN_SHIFT);
setbit(CHECON, p << PREFEN_SHIFT);
kseg0_cache_enable(ON);
if(irqstate) Irq::global(true); //restore IE state
}
//=============================================================================
auto Sys::
kseg0_cache_enable (KSEG0_CACHE m) -> void
{
uint32_t tmp = __builtin_mfc0(16, 0) ;
tmp = (tmp & (~7)) | m;
__builtin_mtc0(16, 0, tmp);
}