From 40e253d7569396db6a12245fc0b0d204263a2a71 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 30 Nov 2010 21:44:50 +0000 Subject: [PATCH] BeOS and Haiku ports MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The BeOS port uses private syscalls exported by libroot.so to implement the intel access methods. The Haiku port uses ioctls to the /dev/misc/poke device driver (use originally for debugging with /bin/poke) to implement the intel access methods. BeOS has non-standard arch names, so we map them to i386 and powerpc in the configure. Updated README and pcilib.man accordingly. Signed-off-by: François Revol --- README | 2 + lib/configure | 12 ++++- lib/i386-io-beos.h | 59 +++++++++++++++++++++ lib/i386-io-haiku.h | 124 ++++++++++++++++++++++++++++++++++++++++++++ lib/i386-ports.c | 4 ++ pcilib.man | 4 +- 6 files changed, 201 insertions(+), 4 deletions(-) create mode 100644 lib/i386-io-beos.h create mode 100644 lib/i386-io-haiku.h diff --git a/README b/README index d00cb5d..7544cfb 100644 --- a/README +++ b/README @@ -24,6 +24,8 @@ In runs on the following systems: GNU Hurd (direct port access) Windows (direct port access) CYGWIN (direct port access) + BeOS (via syscalls) + Haiku (via /dev/misc/poke) It should be very easy to add support for other systems as well (volunteers wanted; if you want to try that, I'll be very glad to see the patches and diff --git a/lib/configure b/lib/configure index eec225a..4ae20d4 100755 --- a/lib/configure +++ b/lib/configure @@ -30,7 +30,7 @@ if [ -z "$HOST" ] ; then proc=`/usr/sbin/lsdev -C -c processor -S available -F name | head -1` cpu=`/usr/sbin/lsattr -F value -l $proc -a type | sed 's/_.*//'` else - cpu=`uname -m | sed 's/^i.86$/i386/;s/^sun4u$/sparc64/;s/^i86pc$/i386/'` + cpu=`uname -m | sed 's/^i.86$/i386/;s/^sun4u$/sparc64/;s/^i86pc$/i386/;s/^BePC$/i386/;s/^BeMac$/powerpc/;s/^BeBox$/powerpc/'` fi if [ "$sys" = "GNU/kFreeBSD" -o "$sys" = "DragonFly" ] then @@ -124,7 +124,15 @@ case $sys in echo >>$c '#define PCI_HAVE_PM_INTEL_CONF' echo >>$m 'WITH_LIBS+=-lioperm' ;; - *) + beos|haiku) + case $cpu in + i?86|x86_64) echo_n " i386-ports" + echo >>$c '#define PCI_HAVE_PM_INTEL_CONF' + ;; + esac + echo >>$c '#define PCI_HAVE_STDINT_H' + ;; + *) echo " Unfortunately, your OS is not supported by the PCI Library" exit 1 ;; diff --git a/lib/i386-io-beos.h b/lib/i386-io-beos.h new file mode 100644 index 0000000..a107a4e --- /dev/null +++ b/lib/i386-io-beos.h @@ -0,0 +1,59 @@ +/* + * The PCI Library -- Access to i386 I/O ports on BeOS + * + * Copyright (c) 2009 Francois Revol + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +/* those are private syscalls */ +extern int read_isa_io(int pci_bus, void *addr, int size); +extern int write_isa_io(int pci_bus, void *addr, int size, u32 value); + +static int +intel_setup_io(struct pci_access *a UNUSED) +{ + return 1; +} + +static inline int +intel_cleanup_io(struct pci_access *a UNUSED) +{ + return 1; +} + +static inline u8 +inb (u16 port) +{ + return (u8)read_isa_io(0, (void *)(u32)port, sizeof(u8)); +} + +static inline u16 +inw (u16 port) +{ + return (u16)read_isa_io(0, (void *)(u32)port, sizeof(u16)); +} + +static inline u32 +inl (u16 port) +{ + return (u32)read_isa_io(0, (void *)(u32)port, sizeof(u32)); +} + +static inline void +outb (u8 value, u16 port) +{ + write_isa_io(0, (void *)(u32)port, sizeof(value), value); +} + +static inline void +outw (u16 value, u16 port) +{ + write_isa_io(0, (void *)(u32)port, sizeof(value), value); +} + +static inline void +outl (u32 value, u16 port) +{ + write_isa_io(0, (void *)(u32)port, sizeof(value), value); +} diff --git a/lib/i386-io-haiku.h b/lib/i386-io-haiku.h new file mode 100644 index 0000000..2a824f9 --- /dev/null +++ b/lib/i386-io-haiku.h @@ -0,0 +1,124 @@ +/* + * The PCI Library -- Access to i386 I/O ports on Haiku + * + * Copyright (c) 2009 Francois Revol + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#include +#include +#include + +/* from haiku/trunk/headers/private/drivers/poke.h */ + +#define POKE_DEVICE_NAME "poke" +#define POKE_DEVICE_FULLNAME "/dev/misc/poke" +#define POKE_SIGNATURE 'wltp' // "We Like To Poke" + +enum { + POKE_PORT_READ = B_DEVICE_OP_CODES_END + 1, + POKE_PORT_WRITE, + POKE_PORT_INDEXED_READ, + POKE_PORT_INDEXED_WRITE, + POKE_PCI_READ_CONFIG, + POKE_PCI_WRITE_CONFIG, + POKE_GET_NTH_PCI_INFO, + POKE_GET_PHYSICAL_ADDRESS, + POKE_MAP_MEMORY, + POKE_UNMAP_MEMORY +}; + + +typedef struct { + uint32 signature; + uint8 index; + pci_info* info; + status_t status; +} pci_info_args; + + +typedef struct { + uint32 signature; + uint16 port; + uint8 size; // == index for POKE_PORT_INDEXED_* + uint32 value; +} port_io_args; + + +typedef struct { + uint32 signature; + uint8 bus; + uint8 device; + uint8 function; + uint8 size; + uint8 offset; + uint32 value; +} pci_io_args; + + +/* en poke.h*/ + +static int poke_driver_fd; + +static int +intel_setup_io(struct pci_access *a UNUSED) +{ + poke_driver_fd = open(POKE_DEVICE_FULLNAME, O_RDWR); + return (poke_driver_fd < 0) ? 0 : 1; +} + +static inline int +intel_cleanup_io(struct pci_access *a UNUSED) +{ + close(poke_driver_fd); + return 1; +} + +static inline u8 +inb (u16 port) +{ + port_io_args args = { POKE_SIGNATURE, port, sizeof(u8), 0 }; + if (ioctl(poke_driver_fd, POKE_PORT_READ, &args, sizeof(args)) < 0) + return 0; + return (u8)args.value; +} + +static inline u16 +inw (u16 port) +{ + port_io_args args = { POKE_SIGNATURE, port, sizeof(u16), 0 }; + if (ioctl(poke_driver_fd, POKE_PORT_READ, &args, sizeof(args)) < 0) + return 0; + return (u16)args.value; +} + +static inline u32 +inl (u16 port) +{ + port_io_args args = { POKE_SIGNATURE, port, sizeof(u32), 0 }; + if (ioctl(poke_driver_fd, POKE_PORT_READ, &args, sizeof(args)) < 0) + return 0; + return (u32)args.value; +} + +static inline void +outb (u8 value, u16 port) +{ + port_io_args args = { POKE_SIGNATURE, port, sizeof(u8), value }; + ioctl(poke_driver_fd, POKE_PORT_WRITE, &args, sizeof(args)); +} + +static inline void +outw (u16 value, u16 port) +{ + port_io_args args = { POKE_SIGNATURE, port, sizeof(u16), value }; + ioctl(poke_driver_fd, POKE_PORT_WRITE, &args, sizeof(args)); +} + +static inline void +outl (u32 value, u16 port) +{ + port_io_args args = { POKE_SIGNATURE, port, sizeof(u32), value }; + ioctl(poke_driver_fd, POKE_PORT_WRITE, &args, sizeof(args)); +} diff --git a/lib/i386-ports.c b/lib/i386-ports.c index 072fac5..421bbfd 100644 --- a/lib/i386-ports.c +++ b/lib/i386-ports.c @@ -22,6 +22,10 @@ #include "i386-io-windows.h" #elif defined(PCI_OS_CYGWIN) #include "i386-io-cygwin.h" +#elif defined(PCI_OS_HAIKU) +#include "i386-io-haiku.h" +#elif defined(PCI_OS_BEOS) +#include "i386-io-beos.h" #else #error Do not know how to access I/O ports on this OS. #endif diff --git a/pcilib.man b/pcilib.man index 1bcff3d..d9d8a0a 100644 --- a/pcilib.man +++ b/pcilib.man @@ -33,11 +33,11 @@ to all users, the rest only to root. .TP .B intel-conf1 Direct hardware access via Intel configuration mechanism 1. Available on i386 and compatibles -on Linux, Solaris/x86, GNU Hurd and Windows. Requires root privileges. +on Linux, Solaris/x86, GNU Hurd, Windows, BeOS and Haiku. Requires root privileges. .TP .B intel-conf2 Direct hardware access via Intel configuration mechanism 2. Available on i386 and compatibles -on Linux, Solaris/x86, GNU Hurd and Windows. Requires root privileges. Warning: This method +on Linux, Solaris/x86, GNU Hurd, Windows, BeOS and Haiku. Requires root privileges. Warning: This method is able to address only the first 16 devices on any bus and it seems to be very unreliable in many cases. .TP -- 2.39.5