| git.druid.rocks | index | druid520 | kaboom | src/ | drivers/ | io.s |
src/drivers/io.s
/*
* raw port i/o primitives. nsc has no inline asm, so every driver that
* touches a port (vga cursor, keyboard, pit, ata, pic) calls through
* here via a plain extern declaration -- same proven pattern as the
* nscc test suite's cross-file extern linking (t12).
*
* sysv abi: arg1 in %rdi, arg2 in %rsi. nsc does not promise the upper
* bits of a register holding a narrower type (u8/u16) are clean, so
* every function here reads only the sub-register width it needs
* (%dil/%di/%sil) rather than trusting the rest of the word.
*/
.section .text
.global outb
.type outb, @function
outb:
movw %di, %dx
movb %sil, %al
outb %al, %dx
ret
.global inb
.type inb, @function
inb:
movw %di, %dx
inb %dx, %al
movzbq %al, %rax
ret
.global outw
.type outw, @function
outw:
movw %di, %dx
movw %si, %ax
outw %ax, %dx
ret
.global inw
.type inw, @function
inw:
movw %di, %dx
inw %dx, %ax
movzwq %ax, %rax
ret
/* classic "delay by writing to an unused port" trick, needed after
* some port i/o sequences on real hardware (pic remap, ata) so the
* device has time to react. harmless under qemu but keep it -- this
* kernel should behave the same under emulation and on the user's
* real hardware. */
.global io_wait
.type io_wait, @function
io_wait:
xorb %al, %al
movw $0x80, %dx
outb %al, %dx
ret
.global halt
.type halt, @function
halt:
hlt
ret
.global cli
.type cli, @function
cli:
cli
ret
.global sti
.type sti, @function
sti:
sti
ret