]> git.lizzy.rs Git - nyax.git/blob - stage3/paging.asm
Force make to use bash (#1)
[nyax.git] / stage3 / paging.asm
1 global page_map, page_region
2 extern print_hex, print_chr, newline, print_dec, print_str
3
4 section .data
5
6 dd 0
7
8 pagebuf_init:
9         .start: dq 0x5000
10         .size: dq 0x2000
11         .used: dq 0
12
13 pagebuf: dq pagebuf_init
14
15 next_page: dq 0
16
17 section .text
18
19 ; allocate new page table buffer
20 alloc:
21         ; rsi = buffer (result)
22         ; rdi = next_page
23         ; r8  = pagebuf
24         ; rbx = upper
25         ; rax = tmp; used_next
26
27         mov r8, [pagebuf] ; *pagebuf
28         mov rsi, [r8]     ; start = pagebuf->start
29
30         mov rbx, [r8+8]   ; size = pagebuf->size
31         add rbx, rsi      ; upper_have = start + size
32
33         ; round *up* to 0x1000 align
34         mov rax, 0xfff
35         add rsi, rax
36         not rax
37         and rsi, rax      ; aligned_start = (start + 0xfff) & (~0xfff)
38
39         mov rax, [r8+16]  ; used = pagebuf->used
40         add rax, 0x1000
41         add rsi, rax      ; upper_need = aligned_start + used + 0x1000
42
43         cmp rsi, rbx      ; if upper_need > upper_have
44         ja .newbuf        ; current region is full, get new
45
46         cmp rsi, r10      ; if upper_need >= next_page
47         jae .oom          ; out of memory (target buffer isn't paged yet)
48
49         mov [r8+16], rax  ; pagebuf->used = used + 0x1000
50
51         ; clear out buffer
52
53         mov rbx, rsi
54         sub rsi, 0x1000
55
56 .clear:
57         sub rbx, 8
58         mov qword[rbx], 0
59         cmp rbx, rsi
60         jne .clear
61
62         ret
63
64 ; select next page buffer
65 .newbuf:
66         cmp r8, pagebuf_init
67         jne .nextbuf
68
69         mov r8, 0x500
70         jmp .trybuf
71
72 .nextbuf:
73         add r8, 24
74
75 .trybuf:
76         cmp qword[r8], 0
77         je .oom       ; last region reached
78
79         mov rax, [r8+16]
80
81         cmp rax, -1
82         je .nextbuf   ; region is reserved
83
84         cmp rax, 0
85         jne .oom      ; region has not been paged yet
86
87         mov [pagebuf], r8
88         jmp alloc
89
90 .oom:
91         push rdi
92
93         mov rdi, .oom_msg
94         call print_str
95
96         pop rdi
97
98         call print_hex
99         call newline
100
101         jmp $
102
103 .oom_msg: db "out of memory for page table", 10, "next_page = ", 0
104
105 ; get/create page tables
106 get_tables:
107 ; level 4
108
109         ; rdi = address         (arg, persist)
110         ; rax = tmp
111         ; rbx = mask
112         ; rcx = bits            (persist)
113         ; rdx = level           (persist)
114         ; r8  = table address
115         ; rsi = next offset     (persist)
116
117         mov cl, 12+9*4
118         mov dl, 4
119
120         mov rsi, 0x1000
121
122 ; level 4
123 .level:
124         dec dl
125         mov r8, rdi
126         mov rbx, -1           ; reset remainder mask
127         shl rbx, cl           ; update remainder mask
128         not rbx               ; negate remainder mask
129         and r8, rbx           ; apply remainder mask
130
131         mov al, 9
132         mul dl
133         add al, 12
134         mov cl, al
135
136         shr r8, cl            ; divide
137         shl r8, 3             ; multiply by 8
138
139         mov rbx, 0xfff        ; 0x1000 alignment
140         not rbx               ; offset mask
141
142         and rsi, rbx          ; apply offset mask
143         add r8, rsi           ; add offset
144         push r8               ; store
145
146         cmp dl, 0
147         je .done
148
149         mov rsi, [r8]         ; next offset
150         cmp rsi, 0
151         jne .level
152
153         call alloc
154         or rsi, 3
155         mov r8, [rsp]
156         mov [r8], rsi
157
158         jmp .level
159
160 .done:
161         pop r11
162         pop r12
163         pop r13
164         pop r14
165
166         ret
167
168 space:
169         mov dil, ' '
170         jmp print_chr
171
172 page_region:
173         mov rdi, [r9]   ; ptr = mmap_entry->ptr
174         mov r10, [next_page]
175
176         push rdi
177
178         mov rax, 1 << 63
179
180         or rdi, rax
181         call print_hex
182         call space
183
184         mov rdi, [r9+8]
185         add rdi, [rsp]
186         or rdi, rax
187
188         call print_hex
189         call newline
190
191         pop rdi
192
193         ; for   usable region (type = 1), set mmap_entry->used =  0
194         ; for reserved region (type = 2), set mmap_entry->used = -1
195         xor rax, rax
196         xor rbx, rbx
197         mov eax, dword[r9+16]
198         cmp rax, 1
199         je .set_used
200         dec rbx
201 .set_used:
202         mov [r9+16], rbx
203
204         mov r10, rdi
205         mov r15, rdi    ; r15 = end of region
206         add r15, [r9+8]
207
208         mov rax, 0xfff
209         not rax
210         and rdi, rax    ; round down to 0x1000 aligned
211
212         cmp rdi, r10
213         jb .get_tables
214
215         mov r10, rdi
216
217 .get_tables:
218         call get_tables ; page tables into r11-r14
219
220         ; start filling L1 map
221 .l1:
222         mov rax, rdi
223         or rax, 3
224         mov [r11], rax
225
226         add rdi, 0x1000
227
228         cmp rdi, r10
229         jb .next
230
231         mov r10, rdi
232
233 .next:
234         cmp rdi, r15    ; if next >= end
235         jae .done
236
237         ; prepare rcx mask for later
238         mov rcx, -1
239         shl rcx, 3
240
241         ; bump L1
242
243         add r11, 8
244         mov rax, r11
245         and rax, 0xfff
246         jnz .l1
247
248         ; bump L2
249
250         add r12, 8
251         mov rax, r12
252         and rax, 0xfff
253         jnz .l2
254
255         ; bump L3
256
257         add r13, 8
258         mov rax, r13
259         and rax, 0xfff
260         jnz .l3
261
262         ; bump L4
263
264         add r14, 8
265         mov rax, r14
266         and rax, 0xfff
267         jnz .l4
268
269         ; machine has more than 256TB of RAM, tell user to fuck off
270         jmp .bruh
271
272 .l4:
273         mov r13, [r14]
274         and r13, rcx
275         jnz .l3
276
277         call alloc
278         mov r13, rsi
279         or rsi, 3
280         mov [r14], rsi
281
282 .l3:
283         mov r12, [r13]
284         and r12, rcx
285         jnz .l2
286
287         call alloc
288         mov r12, rsi
289         or rsi, 3
290         mov [r13], rsi
291
292 .l2:
293         mov r11, [r12]
294         and r11, rcx
295         jnz .l2
296
297         call alloc
298         mov r11, rsi
299         or rsi, 3
300         mov [r12], rsi
301
302         jmp .l1
303
304 .done:
305         mov [next_page], r10
306         ret
307
308 .bruh:
309         mov rdi, .bruh_msg
310         call print_str
311         jmp $
312
313 .bruh_msg: db "bruh why do you have more than 256TB of RAM (you fucking glow)", 10, 0
314
315 ; identity map available memory
316 page_map:
317         mov r9, 0x0500                ; mmap_entry
318 .entry:
319         cmp qword[r9], 0
320         je .done
321         call page_region
322         add r9, 24
323         jmp .entry
324 .done:
325         ret