CoolPotOS/boot/io.asm

184 lines
3.9 KiB
NASM
Raw Normal View History

2024-04-09 23:46:56 +08:00
section .data
global io_hlt, io_cli, io_sti, io_stihlt
global io_in8, io_in16, io_in32
global io_out8, io_out16, io_out32
global io_load_eflags, io_store_eflags
global load_gdtr, load_idtr
2024-04-20 02:43:22 +08:00
global tss_flush, gdt_flush, switch_to, copy_page_physical
2024-04-09 23:46:56 +08:00
section .text
2024-04-20 02:43:22 +08:00
[GLOBAL copy_page_physical]
copy_page_physical:
push ebx ; According to __cdecl, we must preserve the contents of EBX.
pushf ; push EFLAGS, so we can pop it and reenable interrupts
; later, if they were enabled anyway.
cli ; Disable interrupts, so we aren't interrupted.
; Load these in BEFORE we disable paging!
mov ebx, [esp+12] ; Source address
mov ecx, [esp+16] ; Destination address
mov edx, cr0 ; Get the control register...
and edx, 0x7fffffff ; and...
mov cr0, edx ; Disable paging.
mov edx, 1024 ; 1024*4bytes = 4096 bytes
.loop:
mov eax, [ebx] ; Get the word at the source address
mov [ecx], eax ; Store it at the dest address
add ebx, 4 ; Source address += sizeof(word)
add ecx, 4 ; Dest address += sizeof(word)
dec edx ; One less word to do
jnz .loop
mov edx, cr0 ; Get the control register again
or edx, 0x80000000 ; and...
mov cr0, edx ; Enable paging.
popf ; Pop EFLAGS back.
pop ebx ; Get the original value of EBX back.
2024-04-14 17:14:26 +08:00
2024-04-09 23:46:56 +08:00
switch_to:
mov eax, [esp+4]
mov [eax+0], esp
mov [eax+4], ebp
mov [eax+8], ebx
mov [eax+12], esi
mov [eax+16], edi
pushf
pop ecx
mov [eax+20], ecx
mov eax, [esp+8]
mov esp, [eax+0]
mov ebp, [eax+4]
mov ebx, [eax+8]
mov esi, [eax+12]
mov edi, [eax+16]
mov eax, [eax+20]
push eax
popf
ret
2024-04-12 22:03:07 +08:00
[global inw]
inw:
xor eax, eax
push dx
mov dx, [esp + 4]
in ax, dx
pop dx
ret
2024-04-09 23:46:56 +08:00
[global read_port]
read_port:
mov edx, [esp + 4]
in al, dx
ret
[global idt_flush]
idt_flush: ; void idt_flush(uint32_t);
mov eax, [esp + 4]
lidt [eax]
ret
[global gdt_flush]
gdt_flush: ; void gdt_flush(uint32_t gdtr);
mov eax, [esp + 4] ; [esp+4]按规定是第一个参数即gdtr
lgdt [eax] ; 加载新gdt指针传入的是地址
mov ax, 0x10 ; 新数据段
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax ; 各数据段全部划给这一数据段
jmp 0x08:.flush ; cs没法mov只能用farjmp/farcall这里用farjmp刷新cs
.flush:
ret ; 刷新完毕,返回
tss_flush:
mov ax, 0x2B
ltr ax
ret
io_hlt: ; void io_hlt(void);
HLT
RET
io_cli: ; void io_cli(void);
CLI
RET
io_sti: ; void io_sti(void);
STI
RET
io_stihlt: ; void io_stihlt(void);
STI
HLT
RET
io_in8: ; int io_in8(int port);
MOV EDX,[ESP+4] ; port
MOV EAX,0
IN AL,DX
RET
io_in16: ; int io_in16(int port);
MOV EDX,[ESP+4] ; port
MOV EAX,0
IN AX,DX
RET
io_in32: ; int io_in32(int port);
MOV EDX,[ESP+4] ; port
IN EAX,DX
RET
2024-04-11 23:32:28 +08:00
io_out8: ; void io_out8(int port, int util);
2024-04-09 23:46:56 +08:00
MOV EDX,[ESP+4] ; port
2024-04-11 23:32:28 +08:00
MOV AL,[ESP+8] ; util
2024-04-09 23:46:56 +08:00
OUT DX,AL
RET
2024-04-11 23:32:28 +08:00
io_out16: ; void io_out16(int port, int util);
2024-04-09 23:46:56 +08:00
MOV EDX,[ESP+4] ; port
2024-04-11 23:32:28 +08:00
MOV EAX,[ESP+8] ; util
2024-04-09 23:46:56 +08:00
OUT DX,AX
RET
2024-04-11 23:32:28 +08:00
io_out32: ; void io_out32(int port, int util);
2024-04-09 23:46:56 +08:00
MOV EDX,[ESP+4] ; port
2024-04-11 23:32:28 +08:00
MOV EAX,[ESP+8] ; util
2024-04-09 23:46:56 +08:00
OUT DX,EAX
RET
io_load_eflags: ; int io_load_eflags(void);
PUSHFD ; PUSH EFLAGS
POP EAX
RET
io_store_eflags: ; void io_store_eflags(int eflags);
MOV EAX,[ESP+4]
PUSH EAX
POPFD ; POP EFLAGS
RET
load_gdtr: ; void load_gdtr(int limit, int addr);
MOV AX,[ESP+4] ; limit
MOV [ESP+6],AX
LGDT [ESP+6]
RET
load_idtr: ; void load_idtr(int limit, int addr);
MOV AX,[ESP+4] ; limit
MOV [ESP+6],AX
LIDT [ESP+6]
RET