Subversion Repositories HelenOS

Rev

Rev 2927 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
913 decky 1
#
2071 jermar 2
# Copyright (c) 2006 Martin Decky
913 decky 3
# All rights reserved.
4
#
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions
7
# are met:
8
#
9
# - Redistributions of source code must retain the above copyright
10
#   notice, this list of conditions and the following disclaimer.
11
# - Redistributions in binary form must reproduce the above copyright
12
#   notice, this list of conditions and the following disclaimer in the
13
#   documentation and/or other materials provided with the distribution.
14
# - The name of the author may not be used to endorse or promote products
15
#   derived from this software without specific prior written permission.
16
#
17
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
#
28
 
1058 decky 29
#include "asm.h"
913 decky 30
#include "regname.h"
31
 
4341 svoboda 32
.macro SMC_COHERENCY addr
33
	dcbst 0, \addr
34
	sync
35
	icbi 0, \addr
36
	sync
37
	isync
38
.endm
39
 
40
.macro FLUSH_DCACHE addr
41
	dcbst 0, \addr
42
	sync
43
	isync
44
.endm
45
 
46
.macro TLB_FLUSH reg
47
	tlbie \reg
48
	addi \reg, \reg, 0x1000
49
.endm
50
 
913 decky 51
.text
52
 
1058 decky 53
.global halt
1075 decky 54
.global memcpy
913 decky 55
.global jump_to_kernel
56
 
1058 decky 57
halt:
58
	b halt
913 decky 59
 
1075 decky 60
memcpy:
61
	srwi. r7, r5, 3
62
	addi r6, r3, -4
63
	addi r4, r4, -4
64
	beq	2f
65
 
66
	andi. r0, r6, 3
67
	mtctr r7
68
	bne 5f
69
 
70
	1:
71
 
72
	lwz r7, 4(r4)
73
	lwzu r8, 8(r4)
74
	stw r7, 4(r6)
75
	stwu r8, 8(r6)
76
	bdnz 1b
77
 
78
	andi. r5, r5, 7
79
 
80
	2:
81
 
82
	cmplwi 0, r5, 4
83
	blt 3f
84
 
85
	lwzu r0, 4(r4)
86
	addi r5, r5, -4
87
	stwu r0, 4(r6)
88
 
89
	3:
90
 
91
	cmpwi 0, r5, 0
92
	beqlr
93
	mtctr r5
94
	addi r4, r4, 3
95
	addi r6, r6, 3
96
 
97
	4:
98
 
99
	lbzu r0, 1(r4)
100
	stbu r0, 1(r6)
101
	bdnz 4b
102
	blr
103
 
104
	5:
105
 
106
	subfic r0, r0, 4
107
	mtctr r0
108
 
109
	6:
110
 
111
	lbz r7, 4(r4)
112
	addi r4, r4, 1
113
	stb r7, 4(r6)
114
	addi r6, r6, 1
115
	bdnz 6b
116
	subf r5, r0, r5
117
	rlwinm. r7, r5, 32-3, 3, 31
118
	beq 2b
119
	mtctr r7
120
	b 1b
121
 
122
 
913 decky 123
jump_to_kernel:
1022 decky 124
 
1131 decky 125
	# r3 = bootinfo (pa)
126
	# r4 = bootinfo_size
127
	# r5 = trans (pa)
1372 decky 128
	# r6 = bytes to copy
129
	# r7 = real_mode (pa)
1478 decky 130
	# r8 = framebuffer (pa)
131
	# r9 = scanline
1022 decky 132
 
1216 decky 133
	# disable interrupts
134
 
135
	mfmsr r31
136
	rlwinm r31, r31, 0, 17, 15
137
	mtmsr r31
138
 
139
	# set real_mode meeting point address
140
 
1372 decky 141
	mtspr srr0, r7
1022 decky 142
 
143
	# jumps to real_mode
144
 
1058 decky 145
	mfmsr r31
146
	lis r30, ~0@h
1478 decky 147
	ori r30, r30, ~(msr_ir | msr_dr | msr_ee)@l
1058 decky 148
	and r31, r31, r30
149
	mtspr srr1, r31
1157 decky 150
 
151
	sync
152
	isync
1022 decky 153
	rfi
154
 
1214 decky 155
.section REALMODE, "ax"
1058 decky 156
.align PAGE_WIDTH
1022 decky 157
.global real_mode
158
 
159
real_mode:
1479 decky 160
 
1058 decky 161
	# copy kernel to proper location
162
	#
1131 decky 163
	# r5 = trans (pa)
1372 decky 164
	# r6 = bytes to copy
1478 decky 165
	# r8 = framebuffer (pa)
166
	# r9 = scanline
1058 decky 167
 
1068 decky 168
	li r31, PAGE_SIZE >> 2
1058 decky 169
	li r30, 0
170
 
171
	page_copy:
172
 
1131 decky 173
		cmpwi r6, 0
1058 decky 174
		beq copy_end
175
 
1068 decky 176
		# copy page
1058 decky 177
 
178
		mtctr r31
1131 decky 179
		lwz r29, 0(r5)
1058 decky 180
 
181
		copy_loop:
182
 
183
			lwz r28, 0(r29)
184
			stw r28, 0(r30)
185
 
4341 svoboda 186
			SMC_COHERENCY r30
187
 
1058 decky 188
			addi r29, r29, 4
189
			addi r30, r30, 4
1131 decky 190
			subi r6, r6, 4
1058 decky 191
 
1131 decky 192
			cmpwi r6, 0
1068 decky 193
			beq copy_end
194
 
1058 decky 195
			bdnz copy_loop
1479 decky 196
 
1131 decky 197
		addi r5, r5, 4
1058 decky 198
		b page_copy
199
 
200
	copy_end:
1068 decky 201
 
1214 decky 202
	# initially fill segment registers
1728 decky 203
 
1071 decky 204
	li r31, 0
1728 decky 205
 
206
	li r29, 8
207
	mtctr r29
1737 decky 208
	li r30, 0                     # ASID 0 (VSIDs 0 .. 7)
4341 svoboda 209
 
1728 decky 210
	seg_fill_uspace:
1022 decky 211
 
1071 decky 212
		mtsrin r30, r31
1728 decky 213
		addi r30, r30, 1
1071 decky 214
		addis r31, r31, 0x1000    # move to next SR
215
 
1728 decky 216
		bdnz seg_fill_uspace
1022 decky 217
 
1728 decky 218
	li r29, 8
219
	mtctr r29
1737 decky 220
	lis r30, 0x4000               # priviledged access only
221
	ori r30, r30, 8               # ASID 0 (VSIDs 8 .. 15)
1728 decky 222
 
223
	seg_fill_kernel:
224
 
225
		mtsrin r30, r31
226
		addi r30, r30, 1
227
		addis r31, r31, 0x1000    # move to next SR
228
 
229
		bdnz seg_fill_kernel
230
 
1068 decky 231
	# invalidate block address translation registers
232
 
1373 decky 233
	li r30, 0
234
 
1068 decky 235
	mtspr ibat0u, r30
236
	mtspr ibat0l, r30
237
 
238
	mtspr ibat1u, r30
239
	mtspr ibat1l, r30
240
 
241
	mtspr ibat2u, r30
242
	mtspr ibat2l, r30
243
 
244
	mtspr ibat3u, r30
245
	mtspr ibat3l, r30
246
 
247
	mtspr dbat0u, r30
248
	mtspr dbat0l, r30
249
 
250
	mtspr dbat1u, r30
251
	mtspr dbat1l, r30
252
 
253
	mtspr dbat2u, r30
254
	mtspr dbat2l, r30
255
 
256
	mtspr dbat3u, r30
257
	mtspr dbat3l, r30
258
 
1738 decky 259
	# create empty Page Hash Table
260
	# on top of memory, size 64 KB
1725 decky 261
 
1738 decky 262
	lwz r31, 0(r3)                # r31 = memory size
1725 decky 263
 
1738 decky 264
	lis r30, 65536@h
265
	ori r30, r30, 65536@l         # r30 = 65536
266
 
267
	subi r29, r30, 1              # r29 = 65535
268
 
269
	sub r31, r31, r30
270
	andc r31, r31, r29            # pht = ALIGN_DOWN(memory_size - 65536, 65536)
271
 
272
	mtsdr1 r31
273
 
274
	li r29, 2
275
	srw r30, r30, r29             # r30 = 16384
1728 decky 276
	li r29, 0
277
 
278
	pht_clear:
279
 
1737 decky 280
		# write zeroes
281
 
1728 decky 282
		stw r29, 0(r31)
4341 svoboda 283
		FLUSH_DCACHE r31
1728 decky 284
 
285
		addi r31, r31, 4
286
		subi r30, r30, 4
287
 
288
		cmpwi r30, 0
289
		beq clear_end
290
 
291
		bdnz pht_clear
292
 
293
	clear_end:
294
 
295
#ifdef CONFIG_BAT
296
 
1737 decky 297
	# create BAT identity mapping
298
 
1738 decky 299
	lwz r31, 0(r3)                # r31 = memory size
1068 decky 300
 
1737 decky 301
	lis r29, 0x0002
302
	cmpw r31, r29
303
	blt no_bat                    # less than 128 KB -> no BAT
1068 decky 304
 
1737 decky 305
	li r29, 18
306
	srw r31, r31, r29             # r31 = total >> 18
307
 
308
	# create Block Length mask by replicating
309
	# the leading logical one 14 times
310
 
311
	li r29, 14
312
	mtctr r31
313
	li r29, 1
314
 
315
	bat_mask:
316
		srw r30, r31, r29         # r30 = mask >> 1
317
		or r31, r31, r30          # mask = mask | r30
318
 
319
		bdnz bat_mask
320
 
321
	andi. r31, r31, 0x07ff        # mask = mask & 0x07ff (BAT can map up to 256 MB)
322
 
323
	li r29, 2
324
	slw r31, r31, r29             # mask = mask << 2
325
	ori r31, r31, 0x0002          # mask = mask | 0x0002 (priviledged access only)
326
 
327
	lis r29, 0x8000
328
	or r29, r29, r31
329
 
1068 decky 330
	lis r30, 0x0000
331
	ori r30, r30, 0x0002
332
 
1737 decky 333
	mtspr ibat0u, r29
1068 decky 334
	mtspr ibat0l, r30
335
 
1737 decky 336
	mtspr dbat0u, r29
1068 decky 337
	mtspr dbat0l, r30
1737 decky 338
 
339
	no_bat:
4341 svoboda 340
 
1728 decky 341
#endif
1068 decky 342
 
4341 svoboda 343
	# flush TLB
1479 decky 344
 
4341 svoboda 345
	li r31, 0
346
	sync
347
 
348
	TLB_FLUSH r31
349
	TLB_FLUSH r31
350
	TLB_FLUSH r31
351
	TLB_FLUSH r31
352
	TLB_FLUSH r31
353
	TLB_FLUSH r31
354
	TLB_FLUSH r31
355
	TLB_FLUSH r31
356
 
357
	TLB_FLUSH r31
358
	TLB_FLUSH r31
359
	TLB_FLUSH r31
360
	TLB_FLUSH r31
361
	TLB_FLUSH r31
362
	TLB_FLUSH r31
363
	TLB_FLUSH r31
364
	TLB_FLUSH r31
365
 
366
	TLB_FLUSH r31
367
	TLB_FLUSH r31
368
	TLB_FLUSH r31
369
	TLB_FLUSH r31
370
	TLB_FLUSH r31
371
	TLB_FLUSH r31
372
	TLB_FLUSH r31
373
	TLB_FLUSH r31
374
 
375
	TLB_FLUSH r31
376
	TLB_FLUSH r31
377
	TLB_FLUSH r31
378
	TLB_FLUSH r31
379
	TLB_FLUSH r31
380
	TLB_FLUSH r31
381
	TLB_FLUSH r31
382
	TLB_FLUSH r31
383
 
384
	TLB_FLUSH r31
385
	TLB_FLUSH r31
386
	TLB_FLUSH r31
387
	TLB_FLUSH r31
388
	TLB_FLUSH r31
389
	TLB_FLUSH r31
390
	TLB_FLUSH r31
391
	TLB_FLUSH r31
392
 
393
	TLB_FLUSH r31
394
	TLB_FLUSH r31
395
	TLB_FLUSH r31
396
	TLB_FLUSH r31
397
	TLB_FLUSH r31
398
	TLB_FLUSH r31
399
	TLB_FLUSH r31
400
	TLB_FLUSH r31
401
 
402
	TLB_FLUSH r31
403
	TLB_FLUSH r31
404
	TLB_FLUSH r31
405
	TLB_FLUSH r31
406
	TLB_FLUSH r31
407
	TLB_FLUSH r31
408
	TLB_FLUSH r31
409
	TLB_FLUSH r31
410
 
411
	TLB_FLUSH r31
412
	TLB_FLUSH r31
413
	TLB_FLUSH r31
414
	TLB_FLUSH r31
415
	TLB_FLUSH r31
416
	TLB_FLUSH r31
417
	TLB_FLUSH r31
418
	TLB_FLUSH r31
419
 
420
	eieio
1381 decky 421
	tlbsync
4341 svoboda 422
	sync
1058 decky 423
 
424
	# start the kernel
1022 decky 425
	#
1728 decky 426
	# pc = KERNEL_START_ADDR
1131 decky 427
	# r3 = bootinfo (pa)
1728 decky 428
	# sprg0 = KA2PA(KERNEL_START_ADDR)
429
	# sprg3 = physical memory size
430
	# sp = 0 (pa)
1022 decky 431
 
1058 decky 432
	lis r31, KERNEL_START_ADDR@ha
433
	addi r31, r31, KERNEL_START_ADDR@l
1022 decky 434
 
1058 decky 435
	mtspr srr0, r31
1022 decky 436
 
1728 decky 437
	subis r31, r31, 0x8000
438
	mtsprg0 r31
439
 
440
	lwz r31, 0(r3)
441
	mtsprg3 r31
442
 
443
	li sp, 0
444
 
1058 decky 445
	mfmsr r31
446
	ori r31, r31, (msr_ir | msr_dr)@l
447
	mtspr srr1, r31
448
 
1146 decky 449
	sync
450
	isync
1022 decky 451
	rfi
1058 decky 452
 
453
.align PAGE_WIDTH
454
.global trans
455
trans:
456
	.space (TRANS_SIZE * TRANS_ITEM_SIZE)