summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/tiny/386/sys.s
blob: 85117147669efe9b2b3f1ad79ff23b7d857221ac (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
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
// Copyright 2010 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Manipulation of segment tables.
//
// Descriptor entry format for system call
// is the native machine format, ugly as it is:
//
//	2-byte limit
//	3-byte base
//	1-byte: 0x80=present, 0x60=dpl<<5, 0x1F=type
//	1-byte: 0x80=limit is *4k, 0x40=32-bit operand size,
//		0x0F=4 more bits of limit
//	1 byte: 8 more bits of base

// Called to set up memory hardware.
// Already running in 32-bit mode thanks to boot block,
// but we need to install our new GDT that we can modify.
TEXT runtime·msetup(SB), 7, $0
	MOVL	runtime·gdtptr(SB), GDTR
	MOVL	$(1*8+0), AX
	MOVW	AX, DS
	MOVW	AX, ES
	MOVW	AX, SS
	MOVW	$0, AX
	MOVW	AX, FS
	MOVW	AX, GS

	// long jmp to cs:mret
	BYTE	$0xEA
	LONG $runtime·mret(SB)
	WORD $(2*8+0)
	
TEXT runtime·mret(SB), 7, $0
	RET

// GDT memory
TEXT runtime·gdt(SB), 7, $0
	// null segment
	LONG	$0
	LONG	$0
	
	// 4GB data segment
	LONG	$0xFFFF
	LONG	$0x00CF9200

	// 4GB code segment
	LONG	$0xFFFF
	LONG	$0x00CF9A00

	// null segment (will be thread-local storage segment)
	LONG	$0
	LONG	$0

// GDT pseudo-descriptor
TEXT runtime·gdtptr(SB), 7, $0
	WORD	$(4*8)
	LONG	$runtime·gdt(SB)

// Called to establish the per-thread segment.
// Write to gdt[3] and reload the gdt register.
// setldt(int entry, int address, int limit)
TEXT runtime·setldt(SB),7,$32
	MOVL	address+4(FP), BX	// aka base
	MOVL	limit+8(FP), CX

	// set up segment descriptor
	LEAL	gdt+(3*8)(SB), AX	// gdt entry #3
	MOVL	$0, 0(AX)
	MOVL	$0, 4(AX)

	MOVW	BX, 2(AX)
	SHRL	$16, BX
	MOVB	BX, 4(AX)
	SHRL	$8, BX
	MOVB	BX, 7(AX)

	MOVW	CX, 0(AX)
	SHRL	$16, CX
	ANDL	$0x0F, CX
	ORL	$0x40, CX		// 32-bit operand size
	MOVB	CX, 6(AX)
	MOVB	$0xF2, 5(AX)	// r/w data descriptor, dpl=3, present

	MOVL	runtime·gdtptr(SB), GDTR

	// Compute segment selector - (entry*8+0)
	MOVL	$(3*8+0), AX
	MOVW	AX, GS
	RET