You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
2.6 KiB
C

/* Copyright (C) 2021,2022 fef <owo@fef.moe>. 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 <gay/cdefs.h>
#include <gay/types.h>
/**
* @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 */