summaryrefslogtreecommitdiff
path: root/cpu/io.s
blob: fe370a509332b45ca493a7ab761cbdadb71a1a6b (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
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
.intel_syntax noprefix
.global outsw
.global outb
.global inb
.global rep_outsw
.global rep_insw
.global flush_tss
.global load_idtr

# ebx, esi, edi, ebp, and esp;
outsw:
        push ebp
	mov ebp, esp
	push esi
	mov dx, [ebp + 4+4]
	mov esi, [ebp + 8+4]
	outsw
	pop esi
	mov esp, ebp
	pop ebp
	ret

outb:
	mov al, [esp + 8]
	mov dx, [esp + 4]
	out dx, al
	ret

inb:
	mov dx, [esp + 4]
	in  al, dx
	ret

rep_outsw:
        push ebp
	mov ebp, esp
	push edi
	mov ecx, [ebp + 4+4]      #ECX is counter for OUTSW
	mov edx, [ebp + 8+4]      #Data port, in and out
	mov edi, [ebp + 12+4]		#Memory area
	rep outsw               #in to [RDI]
	pop edi
	mov esp, ebp
	pop ebp
	ret

rep_insw:
        push ebp
	mov ebp, esp
	push edi
	mov ecx, [ebp + 4+4]      #ECX is counter for INSW
	mov edx, [ebp + 8+4]      #Data port, in and out
	mov edi, [ebp + 12+4]		#Memory area
	rep insw                #in to [RDI]
	pop edi
	mov esp, ebp
	pop ebp
	ret

flush_tss:
	mov ax, 40
	ltr ax
	ret

load_idtr:
	mov edx, [esp + 4]
	lidt [edx]
	ret

test_user_function:
	mov eax, 0x00
	int 0x80
	mov ecx, 0x03
	mov ebx, 0x04
	mov eax, 0x02
	int 0x80
	mov ebx, eax
	mov eax, 0x01
	int 0x80
loop:
	jmp loop
	ret

.global spin_lock
.global spin_unlock
.extern locked

spin_lock:
	mov eax, 1
	xchg eax, ebx
	test eax, eax     
	jnz spin_lock
	ret

spin_unlock:
	xor eax, eax
	xchg eax, ebx
	ret


.global jump_usermode
jump_usermode:
	mov ax, (4 * 8) | 3 # user data segment with RPL 3
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax # sysexit sets SS
 
	# setup wrmsr inputs
	xor edx, edx # not necessary; set to 0
	mov eax, 0x100008 # SS=0x10+0x10=0x20, CS=0x8+0x10=0x18
	mov ecx, 0x174 # MSR specifier: IA32_SYSENTER_CS
	wrmsr # set sysexit segments
 
	# setup sysexit inputs
	mov edx, [esp + 4] # to be loaded into EIP
	mov ecx, [esp + 8] # to be loaded into ESP
	mov esp, ecx
	mov ebp, ecx
	sti
	sysexit