summaryrefslogtreecommitdiff
path: root/sys/src/9/pc/rebootcode.s
blob: 0b4a28481a0fb08bedbd85a063cb24c993a5d3b2 (plain)
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
#include "mem.h"

/*
 * Turn off MMU, then memmove the new kernel to its correct location
 * in physical memory.  Then jumps the to start of the kernel.
 */

TEXT	main(SB),$0
	MOVL	p1+0(FP), DI		/* destination */
	MOVL	DI, AX			/* entry point */
	MOVL	p2+4(FP), SI		/* source */
	MOVL	n+8(FP), CX		/* byte count */

/*
 * disable paging
 */
	MOVL	CR0, DX
	ANDL	$~0x80000000, DX		/* ~(PG) */
	MOVL	DX, CR0
	MOVL	$0, DX
	MOVL	DX, CR3

	/* stack below entry point */
	MOVL	AX, SP

	/* park cpu for zero entry point */
	ORL	AX, AX
	JZ	_idle

/*
 * the source and destination may overlap.
 * determine whether to copy forward or backwards
 */
	CMPL	SI, DI
	JGT	_forward
	MOVL	SI, DX
	ADDL	CX, DX
	CMPL	DX, DI
	JGT	_back

_forward:
	CLD
	REP;	MOVSB
	JMP	_startkernel

_back:
	ADDL	CX, DI
	ADDL	CX, SI
	SUBL	$1, DI
	SUBL	$1, SI
	STD
	REP;	MOVSB
	JMP	_startkernel
/*
 * JMP to kernel entry point.  Note the true kernel entry point is
 * the virtual address KZERO|AX, but this must wait until
 * the MMU is enabled by the kernel in l.s
 */
_startkernel:
	ORL	AX, AX		/* NOP: avoid link bug */
	JMP*	AX

_idle:
	HLT
	JMP	_idle