/
assem.S
executable file
·228 lines (167 loc) · 3.37 KB
/
assem.S
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
SECTION .text
global fast_outl
global fast_inl
global fast_clock
global fast_rcvr_spi
global assem_flatbin_boot
global assem_linux_boot
global assem_multi_boot
global assem_core_boot
global assem_cpuid
global assem_gdt_flush
global assem_idt_flush
global assem_linux_gdt
fast_outl:
; push ebp
; mov ebp, esp
; push ecx
; IO address
mov dx, 0xcfc
mov eax, [esp+4]
out dx, eax
; pop ecx
; pop ebp
ret
fast_inl:
; push ebp
; mov ebp, esp
; push ecx
; IO address
mov dx, 0xcfc
in eax, dx
; pop ecx
; pop ebp
ret
fast_clock:
; Raise clock line
mov dx, 0xcfc
mov eax, [esp+4]
or eax, (1 << 11)
out dx, eax
; lower clock line
mov eax, [esp+4]
and eax, ~(1 << 11)
out dx, eax
ret
%macro cycle_clock 0
; Raise the clock line
mov eax, [esp+4]
or eax, (1 << 11)
out dx, eax
; lower clock line
mov eax, [esp+4]
and eax, ~(1 << 11)
out dx, eax
%endmacro
; Sample to ebx
%macro mmdo_sample 0
in eax, dx
shr ax, 13 ; JTAG3
and al, 1
or bl, al
cycle_clock
%endmacro
fast_rcvr_spi:
; Store the IO address
mov dx, 0xcfc
xor ebx, ebx ; zero the ebx
mmdo_sample
shl ebx, 1
mmdo_sample
shl ebx, 1
mmdo_sample
shl ebx, 1
mmdo_sample
shl ebx, 1
mmdo_sample
shl ebx, 1
mmdo_sample
shl ebx, 1
mmdo_sample
shl ebx, 1
mmdo_sample
mov eax, ebx
ret
;#define GPIO_JTAG2 (1 << 11)
;#define GPIO_JTAG3 (1 << 13)
;#define GPIO_JTAG4 (1 << 9)
;#define GPIO_JTAG5 (1 << 12)
assem_flatbin_boot:
; load eax with first argument
mov eax, [esp+4]
jmp eax
ret ; never returns
assem_linux_boot:
mov al, 0x80 ; disable NMI
out 0x70, al
mov eax, 0
mov ebp, eax
mov edi, eax
mov ebx, eax
mov eax, [esp+4]
mov esi, [esp+8];
jmp eax
ret ; never returns
assem_multi_boot:
mov al, 0x80 ; disable NMI
out 0x70, al
mov eax, 0
; PG clearer (bit31) PE set (bit 0) all others underfined
mov eax, cr0
and eax, 0x7fffffff
or al, 1
mov cr0, eax
; set the flags register
lahf
and eax, ~((1>>17) | (1<<9))
sahf
mov ebx, [esp+4]
mov ecx, [esp+8]
mov eax, 0x2BADB002 ; magic
jmp ecx
ret ; never returns
assem_core_boot:
mov al, 0x80 ; disable NMI
out 0x70, al
mov eax, 0
; PG clearer (bit31) PE set (bit 0) all others underfined
mov eax, cr0
and eax, 0x7fffffff
or al, 1
mov cr0, eax
; set the flags register
lahf
and eax, ~((1>>17) | (1<<9))
sahf
mov ecx, [esp+4]
call ecx
ret
; We need a 'standard' GDT to boot Linux, like the one in flash
assem_linux_gdt:
lgdt [0xfffff000] ; Load the original 'ROM-based' pointer
mov ax, 0x18 ; 0x10 is the offset in the GDT to our data segment
mov ds, ax ; Load all data segment selectors
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x10:.flush ; 0x08 is the offset to our code segment: Far jump!
.flush:
ret
; general version of the above function
assem_gdt_flush:
mov eax, [esp+4] ; Get the pointer to the GDT, passed as a parameter.
lgdt [eax] ; Load the new GDT pointer
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
mov ds, ax ; Load all data segment selectors
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:.gflush ; 0x08 is the offset to our code segment: Far jump!
.gflush:
ret
assem_idt_flush:
mov eax, [esp+4] ; Get the pointer to the IDT, passed as a parameter.
lidt [eax] ; Load the IDT pointer.
ret