/* Copyright (C) 2021,2022 fef . All rights reserved. */ #pragma once /** @brief I/O port number for the PIC1 command channel */ #define X86_PORT_PIC1_CMD 0x20 /** @brief I/O port number for the PIC1 data channel */ #define X86_PORT_PIC1_DATA 0x21 /** @brief I/O port number for the keyboard data channel */ #define X86_PORT_KBD_DATA 0x60 /** @brief I/O port number for the keyboard status channel */ #define X86_PORT_KBD_STATUS 0x64 /** @brief I/O port number for the PIC2 command channel */ #define X86_PORT_PIC2_CMD 0xa0 /** @brief I/O port number for the PIC2 data channel */ #define X86_PORT_PIC2_DATA 0xa1 #ifndef _ASM_SOURCE #include #include /** * @brief Read a byte from the I/O bus. * * @param port Port number * @return The byte that was read */ static inline u8 x86_inb(u16 port) { u8 data; __asm__ volatile( " inb %w1, %b0 \n" : "=a"(data) : "Nd"(port) ); return data; } /** * @brief Read a word from the I/O bus. * * @param port Port number * @return The word that was read */ static inline u16 x86_inw(u16 port) { u16 data; __asm__ volatile( " inw %w1, %w0 \n" : "=a"(data) : "Nd"(port) ); return data; } /** * @brief Read a longword from the I/O bus. * * @param port Port number * @return The longword that was read */ static inline u32 x86_inl(u16 port) { u32 data; __asm__ volatile( " inl %w1, %l0 \n" : "=a"(data) : "Nd"(port) ); return data; } /** * @brief Write a byte to the I/O bus. * * @param port Port number * @param data Byte to send through the port */ static inline void x86_outb(u16 port, u8 data) { __asm__ volatile( " outb %b0, %w1 \n" : : "a"(data), "Nd"(port) ); } /** * @brief Write a word to the I/O bus. * * @param port Port number * @param data Word to send through the port */ static inline void x86_outw(u16 port, u16 data) { __asm__ volatile( " outw %w0, %w1 \n" : : "a"(data), "Nd"(port) ); } /** * @brief Write a longword to the I/O bus. * * @param port Port number * @param data Longword to send through the port */ static inline void x86_outl(u16 port, u32 data) { __asm__ volatile( " outl %l0, %w1 \n" : : "a"(data), "Nd"(port) ); } /** @brief Induce a brief CPU delay by writing zero to I/O port `0x80`. */ static inline void x86_io_wait(void) { x86_outb(0x80, 0); } static __always_inline void x86_outb_wait(u16 port, u8 data) { x86_outb(port, data); x86_io_wait(); } static __always_inline void x86_outw_wait(u16 port, u16 data) { x86_outw(port, data); x86_io_wait(); } static __always_inline void x86_outl_wait(u16 port, u32 data) { x86_outl(port, data); x86_io_wait(); } #endif /* not _ASM_SOURCE */