blob: f887c8b94c511cbd5b1f04ab2ffeabf7c8d80143 [file] [log] [blame] [raw]
/*
* x86 port I/O for UNIX
* Copyright 2015-2024 Rivoreo
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined MSDOS && (defined __i386__ || defined __amd64__ || defined __x86_64__ || defined _X86_ || defined __IA32__ || defined _M_IX86 || defined _M_AMD64)
#include <sys/param.h>
#if defined __FreeBSD__ && !defined __FreeBSD_kernel__
#define __FreeBSD_kernel__
#elif defined __LINUX__ && !defined __linux__
#define __linux__
#endif
#if defined __FreeBSD_kernel__ || defined __linux__
#ifdef __FreeBSD_kernel__
#include <sys/types.h>
#include <sys/ioctl.h>
#include <dev/io/iodev.h>
#include <machine/iodev.h>
#endif
#include <unistd.h>
#include <fcntl.h>
static int port_io_fd = -1;
#endif
void open_port_io_device() {
#if defined __FreeBSD_kernel__ || defined __linux__
if(port_io_fd != -1) return;
port_io_fd = open(
#ifdef __FreeBSD_kernel__
"/dev/io",
#else
"/dev/port",
#endif
O_RDWR
);
#endif
}
unsigned int inp(unsigned int port) {
#if defined __FreeBSD_kernel__ || defined __linux__
//if(port_io_fd == -1) open_port_io_device();
if(port_io_fd != -1) {
#ifdef __FreeBSD_kernel__
struct iodev_pio_req req = { IODEV_PIO_READ, port, 1 };
if(ioctl(port_io_fd, IODEV_PIO, &req) == 0) return req.val;
#elif defined __linux__
unsigned char b;
if(lseek(port_io_fd, port, SEEK_SET) == port && read(port_io_fd, &b, 1) == 1) return b;
#endif
}
#endif
unsigned char value;
#ifdef __GNUC__
__asm__ volatile("inb %w1, %0\n" : "=a"(value) : "d"(port));
#else
__asm in value, port
#endif
return value;
}
unsigned int outp(unsigned int port, unsigned int value) {
#if defined __FreeBSD_kernel__ || defined __linux__
//if(port_io_fd == -1) open_port_io_device();
if(port_io_fd != -1) {
#ifdef __FreeBSD_kernel__
struct iodev_pio_req req = { IODEV_PIO_WRITE, port, 1, value };
if(ioctl(port_io_fd, IODEV_PIO, &req) == 0) return req.val;
#elif defined __linux__
unsigned char b = value;
if(lseek(port_io_fd, port, SEEK_SET) == port && write(port_io_fd, &b, 1) == 1) return b;
#endif
}
#endif
#ifdef __GNUC__
__asm__ volatile("outb %b0, %w1\n" :: "a"(value), "d"(port));
#else
__asm out port, value
#endif
return value & 0xff;
}
#endif