[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MiNT] [PATCH] PCI-BIOS interface emulation



Hi,

attached you can find a patch which adds interface emulation for the
PCI-BIOS interface, like it's done already for the XHDI and SCSIDRV
interfaces. This allows to control the access to PCI-BIOS functions
for non-root processes. Besides now it will be possible to call the
PCI functions from inside the kernel without worrying of passing
parameters conventions, the _PCI cookie, jump functions table, etc...,
and after exporting these functions to the kentry structure it will be
possible to call them from modules too.

This patch only takes care of the "through cookie way" of accessing
the PCI-BIOS, version 1.13 of the PCI_BIOS specification, it doesn't
take care of the XBIOS way as it's define in the specification version
2.00.

I've added the #define PCI-BIOS to avoid increasing size of kenels for
machines with few memory and surely not support for PCI, I'm thinking
of 68000 and 68030 targets. For now it's only enabled for the ColdFire
target, it could be enabled too for 68060 (Hades and CTPCI) and Milan
targets as testing are done.
Index: sys/KERNELDEFS
===================================================================
RCS file: /mint/freemint/sys/KERNELDEFS,v
retrieving revision 1.58
diff -u -8 -r1.58 KERNELDEFS
--- sys/KERNELDEFS	12 Oct 2013 15:34:12 -0000	1.58
+++ sys/KERNELDEFS	22 Mar 2014 12:04:05 -0000
@@ -3,16 +3,17 @@
 # generic flags
 #
 # -DVERBOSE_BOOT	include extensive messages
 # -DCRYPTO_CODE		include the cryptographic filesystem stuff
 # -DSOFT_UNITABLE	loadable unicode tables
 # -DBUILTIN_SHELL	include the built-in minimal shell
 # -DC_ONLY		replace some assembly function by C compatible one
 # -DWITH_MMU_SUPPORT	include MMU support
+# -DPCI_BIOS		include PCI_BIOS interface emulation
 
 #
 # machine flags
 #
 # -DM68000		build for 68000 (no mmu, no caches)
 # -DM68030		build for 68030
 # -DM68040		build for 68040-060
 # -DM68060		build for 68060
@@ -94,17 +95,17 @@
 MINT = mintdeb.prg
 CPU  = 020-60
 KERNELDEFS = -DDEBUG_INFO -DM68040
 endif
 
 ifeq ($(kernel),col)
 MINT = mintv4e.prg
 CPU  = v4e
-KERNELDEFS = -DM68040 -DNO_FAKE_SUPER -DC_ONLY
+KERNELDEFS = -DM68040 -DNO_FAKE_SUPER -DC_ONLY -DPCI_BIOS
 kernel_nocflags = -DWITH_MMU_SUPPORT
 endif
 
 ifeq ($(kernel),mil)
 MINT = mintmil.prg
 CPU  = 020-60
 KERNELDEFS = -DMILAN -DM68040
 endif
Index: sys/SRCFILES
===================================================================
RCS file: /mint/freemint/sys/SRCFILES,v
retrieving revision 1.27
diff -u -8 -r1.27 SRCFILES
--- sys/SRCFILES	12 Jul 2004 00:52:52 -0000	1.27
+++ sys/SRCFILES	22 Mar 2014 12:04:05 -0000
@@ -50,16 +50,17 @@
 	kernget.c \
 	keyboard.c \
 	kmemory.c \
 	mcount.c \
 	memory.c \
 	mis.c \
 	module.c \
 	nullfs.c \
+	pcibios.c \
 	pipefs.c \
 	proc.c \
 	proc_help.c \
 	proc_wakeup.c \
 	procfs.c \
 	profil.c \
 	ptrace.c \
 	pun.c \
Index: sys/cookie.h
===================================================================
RCS file: /mint/freemint/sys/cookie.h,v
retrieving revision 1.19
diff -u -8 -r1.19 cookie.h
--- sys/cookie.h	19 Mar 2014 17:36:54 -0000	1.19
+++ sys/cookie.h	22 Mar 2014 12:04:05 -0000
@@ -79,16 +79,18 @@
 /* Not that we want to support these below ... */
 # define COOKIE_STiK	0x5354694bL
 # define COOKIE_ICIP	0x49434950L
 # define COOKIE_NF	0x5F5F4E46L
 
 /* hardware cookies */
 # define COOKIE_CT60	0x43543630L
 # define COOKIE_HADES	0x68616465L
+# define COOKIE__PCI	0x5f504349L
+# define COOKIE__CF_	0x5f43465fL /* ColdFire, set by FireTOS and EmuTOS */
 
 /* values of MCH cookie */
 # define ST		0
 # define STE		0x00010000L
 # define STBOOK		0x00010001L
 # define STEIDE		0x00010008L
 # define MEGASTE	0x00010010L
 # define TT		0x00020000L
Index: sys/init.c
===================================================================
RCS file: /mint/freemint/sys/init.c,v
retrieving revision 1.139
diff -u -8 -r1.139 init.c
--- sys/init.c	12 Oct 2013 15:28:46 -0000	1.139
+++ sys/init.c	22 Mar 2014 12:04:05 -0000
@@ -56,16 +56,17 @@
 # include "k_exec.h"		/* sys_pexec */
 # include "k_exit.h"		/* sys_pwaitpid */
 # include "k_fds.h"		/* do_open/do_close */
 # include "keyboard.h"		/* init_keytbl() */
 # include "kmemory.h"		/* kmalloc */
 # include "memory.h"		/* init_mem, get_region, attach_region, restr_screen */
 # include "mis.h"		/* startup_shell */
 # include "module.h"		/* load_all_modules */
+# include "pcibios.h"		/* pcibios_init() */
 # include "proc.h"		/* init_proc, add_q, rm_q */
 # include "signal.h"		/* post_sig */
 # include "syscall_vectors.h"
 # include "time.h"		/* */
 # include "timeout.h"		/* */
 # include "unicode.h"		/* init_unicode() */
 # include "update.h"		/* start_sysupdate */
 # include "util.h"		/* */
@@ -470,16 +471,22 @@
 	DEBUG (("init_xbios() ok!"));
 
 	/* initialize basic keyboard stuff */
 # ifndef NO_AKP_KEYBOARD
 	init_keybd();
 	DEBUG (("init_keybd() ok!"));
 # endif
 
+	/* initalize PCI-BIOS interface */
+#ifdef PCI_BIOS
+	if (pcibios_init())
+		DEBUG (("No PCI-BIOS found"));
+#endif
+
 	/* Disable all CPU caches */
 # ifndef M68000
 	ccw_set(0x00000000L, 0x0000c57fL);
 	DEBUG (("ccw_set() ok!"));
 # endif
 
 	/* initialize interrupt vectors */
 	init_intr ();
Index: sys/pcibios.c
===================================================================
RCS file: sys/pcibios.c
diff -N sys/pcibios.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sys/pcibios.c	22 Mar 2014 12:04:06 -0000
@@ -0,0 +1,424 @@
+/*
+ * Copyright 2014 David Galvez.
+ * Based on SCSIDRV sys_emu implementation by Frank Naumann.
+ *
+ * This file belongs to FreeMiNT. It's not in the original MiNT 1.12
+ * distribution. See the file CHANGES for a detailed log of changes.
+ *
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifdef PCI_BIOS
+# include "pcibios.h"
+# include "global.h"
+
+# include "arch/pcibios_emu.h"
+# include "mint/proc.h"
+# include "libkern/libkern.h"
+
+# include "cookie.h"	/* cookie handling */
+# include "init.h"	/* boot_printf */
+# include "k_prot.h"
+
+# include "proc.h"
+
+static PCIBIOS_MINT pcibios_MiNT = { {
+	0,
+	0,
+	emu_pcibios_Find_pci_device,
+	emu_pcibios_Find_pci_classcode,
+	emu_pcibios_Read_config_byte,
+	emu_pcibios_Read_config_word,
+	emu_pcibios_Read_config_longword,
+	emu_pcibios_Fast_read_config_byte,
+	emu_pcibios_Fast_read_config_word,
+	emu_pcibios_Fast_read_config_longword,
+	emu_pcibios_Write_config_byte,
+	emu_pcibios_Write_config_word,
+	emu_pcibios_Write_config_longword,
+	emu_pcibios_Hook_interrupt,
+	emu_pcibios_Unhook_interrupt,
+	emu_pcibios_Special_cycle,
+	emu_pcibios_Get_routing,
+	emu_pcibios_Set_interrupt,
+	emu_pcibios_Get_resource,
+	emu_pcibios_Get_card_used,
+	emu_pcibios_Set_card_used,
+	emu_pcibios_Read_mem_byte,
+	emu_pcibios_Read_mem_word,
+	emu_pcibios_Read_mem_longword,
+	emu_pcibios_Fast_read_mem_byte,
+	emu_pcibios_Fast_read_mem_word,
+	emu_pcibios_Fast_read_mem_longword,
+	emu_pcibios_Write_mem_byte,
+	emu_pcibios_Write_mem_word,
+	emu_pcibios_Write_mem_longword,
+	emu_pcibios_Read_io_byte,
+	emu_pcibios_Read_io_word,
+	emu_pcibios_Read_io_longword,
+	emu_pcibios_Fast_read_io_byte,
+	emu_pcibios_Fast_read_io_word,
+	emu_pcibios_Fast_read_io_longword,
+	emu_pcibios_Write_io_byte,
+	emu_pcibios_Write_io_word,
+	emu_pcibios_Write_io_longword,
+	emu_pcibios_Get_machine_id,
+	emu_pcibios_Get_pagesize,
+	emu_pcibios_Virt_to_bus,
+	emu_pcibios_Bus_to_virt,
+	emu_pcibios_Virt_to_phys,
+	emu_pcibios_Phys_to_virt,
+} };
+
+
+# ifdef DEBUG_INFO
+# define PCIBIOS_DEBUG(x)	DEBUG (x)
+# else
+# define SCSIDRV_DEBUG(x)
+# endif
+
+
+ushort pcibios_installed = 0;
+
+PCIBIOS *pcibios = NULL;
+void *tab_funcs_pci;
+
+long
+pcibios_init (void)
+{
+	long r;
+	unsigned long t = 0, dummy = 0;
+
+	r = get_toscookie(COOKIE__PCI, &t);
+	pcibios = (PCIBIOS *)t;
+
+	if (!r && pcibios)
+	{
+		pcibios_installed = pcibios->version;
+		/* First function in jump table */
+		tab_funcs_pci = &pcibios->Find_pci_device;
+		pcibios_MiNT.emu_pcibios.version = pcibios_installed;
+		r = set_toscookie (COOKIE__PCI, (long) &(pcibios_MiNT.emu_pcibios));
+	}
+	else
+	{
+		pcibios_installed = 0;
+		pcibios = NULL;
+		return r;
+	}
+
+	/* Some PCI-BIOS functions in FireTOS and CTPCI PCI-BIOS get the
+	 * cookie value every time they're called to calculate the place
+	 * in memory where descriptors are stored, as the cookie value
+	 * is replaced by MiNT the memory addresses calculated are wrong,
+	 * so to avoid this we need to make this hack. Resource and status
+	 * descriptors are store following the PCI-BIOS functions jump table.
+	 */
+	r = get_toscookie(COOKIE__CPU, &t); /* cf68klib in FireTOS emulates 68060 CPU */
+	if (!r && t == 60)
+		if (!get_toscookie(COOKIE__CF_, &dummy) ||	/* Test for FireTOS */
+		     !get_toscookie(COOKIE_CT60, &dummy)) {	/* Test for CT60 (CTPCI) */
+			/* Copy descriptors following the PCI-BIOS structure */
+			memcpy(&(pcibios_MiNT.pci_rsc_desc), pcibios + 1, 
+				PCI_MAX_HANDLE * PCI_MAX_FUNCTION * ((sizeof(PCI_RSC_DESC) *  PCI_MAX_RSC_DESC) + sizeof(PCI_STS_DESC)));
+			r = set_toscookie (COOKIE__PCI, (long) &pcibios_MiNT);
+	}
+
+	return r;
+}
+
+long _cdecl
+sys_pcibios (ushort op,
+	     long a1, long a2, long a3, long a4,
+	     long a5, long a6, long a7)
+{
+	typedef long (*wrap0)();
+	typedef long (*wrap1)(long);
+	typedef long (*wrap2)(long, long);
+	typedef long (*wrap3)(long, long, long);
+
+	/* only superuser can use this interface */
+	if (!suser (get_curproc()->p_cred->ucr))
+		return EPERM;
+
+	if (!pcibios)
+		return ENOSYS;
+
+	switch (op)
+	{
+		/* PCI_BIOS exist */
+		case 0:
+		case 1:
+		{
+			return E_OK;
+		}
+		/* Find_pci_device */
+		case 2:
+		{
+			wrap2 f = (wrap2)Find_pci_device;
+			return (*f)(a1, a2);
+		}
+		/* Find_pci_classcode */
+		case 3:
+		{
+			wrap2 f = (wrap2)Find_pci_classcode;
+			return (*f)(a1, a2);
+		}
+		/* Read_config_byte */
+		case 4:
+		{
+			wrap3 f = (wrap3)Read_config_byte;
+			return (*f)(a1, a2, a3);
+		}
+		/* Read_config_word */
+		case 5:
+		{
+			wrap3 f = (wrap3)Read_config_word;
+			return (*f)(a1, a2, a3);
+		}
+		/* Read_config_longword */
+		case 6:
+		{
+			wrap3 f = (wrap3)Read_config_longword;
+			return (*f)(a1, a2, a3);
+		}
+		/* Fast_read_config_byte */
+		case 7:
+		{
+			wrap2 f = (wrap2)Fast_read_config_byte;
+			return (*f)(a1, a2);
+		}
+		/* Fast_read_config_word */
+		case 8:
+		{
+			wrap2 f = (wrap2)Fast_read_config_word;
+			return (*f)(a1, a2);
+		}
+		/* Fast_read_config_longword */
+		case 9:
+		{
+			wrap2 f = (wrap2)Fast_read_config_longword;
+			return (*f)(a1, a2);
+		}
+		/* Write_config_byte */
+		case 10:
+		{
+			wrap3 f = (wrap3)Write_config_byte;
+			return (*f)(a1, a2, a3);
+		}
+		/* Write_config_word */
+		case 11:
+		{
+			wrap3 f = (wrap3)Write_config_word;
+			return (*f)(a1, a2, a3);
+		}
+		/* Write_config_longword */
+		case 12:
+		{
+			wrap3 f = (wrap3)Write_config_longword;
+			return (*f)(a1, a2, a3);
+		}
+		/* Hook_interrupt */
+		case 13:
+		{
+			wrap3 f = (wrap3)Hook_interrupt;
+			return (*f)(a1, a2, a3);
+		}
+		/* Unhook_interrupt */
+		case 14:
+		{
+			wrap1 f = (wrap1)Unhook_interrupt;
+			return (*f)(a1);
+		}
+		/* Special_cycle */
+		case 15:
+		{
+			wrap2 f = (wrap2)Special_cycle;
+			return (*f)(a1, a2);
+		}
+		/* Get_routing */
+		/* Set_interrupt */
+		case 16:
+		case 17:
+		{
+			return ENOSYS;
+		}
+		/* Get_resource */
+		case 18:
+		{
+			wrap1 f = (wrap1)Get_resource;
+			return (*f)(a1);
+		}
+		/* Get_card_used */
+		case 19:
+		{
+			wrap2 f = (wrap2)Get_card_used;
+			return (*f)(a1, a2);
+		}
+		/* Set_card_used */
+		case 20:
+		{
+			wrap2 f = (wrap2)Set_card_used;
+			return (*f)(a1, a2);
+		}
+		/* Read_mem_byte */
+		case 21:
+		{
+			wrap3 f = (wrap3)Read_mem_byte;
+			return (*f)(a1, a2, a3);
+		}
+		/* Read_mem_word */
+		case 22:
+		{
+			wrap3 f = (wrap3)Read_mem_word;
+			return (*f)(a1, a2, a3);
+		}
+		/* Read_mem_longword */
+		case 23:
+		{
+			wrap3 f = (wrap3)Read_mem_longword;
+			return (*f)(a1, a2, a3);
+		}
+		/* Fast_read_mem_byte */
+		case 24:
+		{
+			wrap2 f = (wrap2)Fast_read_mem_byte;
+			return (*f)(a1, a2);
+		}
+		/* Fast_read_mem_word */
+		case 25:
+		{
+			wrap2 f = (wrap2)Fast_read_mem_word;
+			return (*f)(a1, a2);
+		}
+		/* Fast_read_mem_longword */
+		case 26:
+		{
+			wrap2 f = (wrap2)Fast_read_mem_longword;
+			return (*f)(a1, a2);
+		}
+		/* Write_mem_byte */
+		case 27:
+		{
+			wrap3 f = (wrap3)Write_mem_byte;
+			return (*f)(a1, a2, a3);
+		}
+		/* Write_mem_word */
+		case 28:
+		{
+			wrap3 f = (wrap3)Write_mem_word;
+			return (*f)(a1, a2, a3);
+		}
+		/* Write_mem_longword */
+		case 29:
+		{
+			wrap3 f = (wrap3)Write_mem_longword;
+			return (*f)(a1, a2, a3);
+		}
+		/* Read_io_byte */
+		case 30:
+		{
+			wrap3 f = (wrap3)Read_io_byte;
+			return (*f)(a1, a2, a3);
+		}
+		/* Read_io_word */
+		case 31:
+		{
+			wrap3 f = (wrap3)Read_io_word;
+			return (*f)(a1, a2, a3);
+		}
+		/* Read_io_longword */
+		case 32:
+		{
+			wrap3 f = (wrap3)Read_io_longword;
+			return (*f)(a1, a2, a3);
+		}
+		/* Fast_read_io_byte */
+		case 33:
+		{
+			wrap2 f = (wrap2)Fast_read_io_byte;
+			return (*f)(a1, a2);
+		}
+		/* Fast_read_io_word */
+		case 34:
+		{
+			wrap2 f = (wrap2)Fast_read_io_word;
+			return (*f)(a1, a2);
+		}
+		/* Fast_read_io_longword */
+		case 35:
+		{
+			wrap2 f = (wrap2)Fast_read_io_longword;
+			return (*f)(a1, a2);
+		}
+		/* Write_io_byte */
+		case 36:
+		{
+			wrap3 f = (wrap3)Write_io_byte;
+			return (*f)(a1, a2, a3);
+		}
+		/* Write_io_word */
+		case 37:
+		{
+			wrap3 f = (wrap3)Write_io_word;
+			return (*f)(a1, a2, a3);;
+		}
+		/* Write_io_longword */
+		case 38:
+		{
+			wrap3 f = (wrap3)Write_io_longword;
+			return (*f)(a1, a2, a3);
+		}
+		/* Get_machine_id */
+		case 39:
+		{
+			wrap1 f = (wrap1)Get_machine_id;
+			return (*f)(a1);
+		}
+		/* Get_pagesize */
+		case 40:
+		{
+			wrap0 f = (wrap0)Get_pagesize;
+			return (*f)();
+		}
+		/* Virt_to_bus */
+		case 41:
+		{
+			wrap3 f = (wrap3)Virt_to_bus;
+			return (*f)(a1, a2, a3);
+		}
+		/* Bus_to_virt */
+		case 42:
+		{
+			wrap3 f = (wrap3)Bus_to_virt;
+			return (*f)(a1, a2, a3);
+		}
+		/* Virt_to_phys */
+		case 43:
+		{
+			wrap2 f = (wrap2)Virt_to_phys;
+			return (*f)(a1, a2);
+		}
+		/* Phys_to_virt */
+		case 44:
+		{
+			wrap2 f = (wrap2)Phys_to_virt;
+			return (*f)(a1, a2);
+		}
+	}
+	return EBADARG;
+}
+#endif /* PCI-BIOS */
Index: sys/pcibios.h
===================================================================
RCS file: sys/pcibios.h
diff -N sys/pcibios.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sys/pcibios.h	22 Mar 2014 12:04:06 -0000
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2014 David Galvez.
+ * Based on SCSIDRV sys_emu implementation by Frank Naumann.
+ * Some code chunks taken from FireTOS sources:
+ * Didier Mequignon 2005-2007, e-mail: aniplay@wanadoo.fr
+ *
+ * This file belongs to FreeMiNT. It's not in the original MiNT 1.12
+ * distribution. See the file CHANGES for a detailed log of changes.
+ *
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/* Header only for PCI-BIOS system call emulation.
+ * IMPORTANT: Drivers must use /mint/pcibios.h
+ */
+
+# ifndef _pcibios_h
+# define _pcibios_h
+
+# include "mint/mint.h"
+
+/* forward definitions
+ */
+
+typedef struct pcibios	PCIBIOS;
+
+/* exported data
+ */
+
+extern ushort pcibios_installed;
+
+
+/* exported functions
+ */
+
+long	pcibios_init		(void);
+
+long	_cdecl sys_pcibios	(ushort op,
+				     long a1, long a2, long a3, long a4,
+				     long a5, long a6, long a7);
+
+/* the struct definitions
+ */
+
+typedef struct				/* structure of address conversion */
+{
+	unsigned long adr;			/* calculated address (CPU<->PCI) */
+	unsigned long len;			/* length of memory range */
+} PCI_CONV_ADR;
+
+/* structure of resource descriptor */
+typedef struct				/* structure of resource descriptor */
+{
+	unsigned short next;			/* length of the following structure */
+	unsigned short flags;			/* type of resource and misc. flags */
+	unsigned long start;			/* start-address of resource */
+	unsigned long length;			/* length of resource */
+	unsigned long offset;			/* offset PCI to phys. CPU Address */
+	unsigned long dmaoffset;		/* offset for DMA-transfers */
+	long		error;			/* internal error code */
+} PCI_RSC_DESC;
+
+/* structure of status descriptor */
+typedef struct
+{
+	unsigned long status;		/* Status PCI */
+	unsigned long callback;	/* Address of Callback Routine */
+	unsigned long handler;	/* Address of Interrupt Handlers */
+	unsigned long parameter;	/* Parameter for Interrupt Handler */
+	unsigned long start_IRQ;	/* Routine Start IRQ */
+} PCI_STS_DESC;
+
+/* PCI_BIOS structure */
+
+struct pcibios {
+	unsigned long subjar;
+	unsigned long version;
+	/* Although we declare this functions as standard gcc functions (cdecl),
+	 * they expect paramenters inside registers (fastcall) unsupported by gcc m68k.
+	 * Caller will take care of parameters passing convention.
+	 */
+	long (*Find_pci_device)	(unsigned long id, unsigned short index);
+	long (*Find_pci_classcode)	(unsigned long class, unsigned short index);
+	long (*Read_config_byte)	(long handle, unsigned short reg, unsigned char *address);
+	long (*Read_config_word)	(long handle, unsigned short reg, unsigned short *address);
+	long (*Read_config_longword)	(long handle, unsigned short reg, unsigned long *address);
+	unsigned char (*Fast_read_config_byte)	(long handle, unsigned short reg);
+	unsigned short (*Fast_read_config_word)	(long handle, unsigned short reg);
+	unsigned long (*Fast_read_config_longword)	(long handle, unsigned short reg);
+	long (*Write_config_byte)	(long handle, unsigned short reg, unsigned short val);
+	long (*Write_config_word)	(long handle, unsigned short reg, unsigned short val);
+	long (*Write_config_longword)	(long handle, unsigned short reg, unsigned long val);
+	long (*Hook_interrupt)	(long handle, unsigned long *routine, unsigned long *parameter);
+	long (*Unhook_interrupt)	(long handle);
+	long (*Special_cycle)	(unsigned short bus, unsigned long data);
+	long (*Get_routing)	(long handle);
+	long (*Set_interrupt)	(long handle);
+	long (*Get_resource)	(long handle);
+	long (*Get_card_used)	(long handle, unsigned long *address);
+	long (*Set_card_used)	(long handle, unsigned long *callback);
+	long (*Read_mem_byte)	(long handle, unsigned long offset, unsigned char *address);
+	long (*Read_mem_word)	(long handle, unsigned long offset, unsigned short *address);
+	long (*Read_mem_longword)	(long handle, unsigned long offset, unsigned long *address);
+	unsigned char (*Fast_read_mem_byte)	(long handle, unsigned long offset);
+	unsigned short (*Fast_read_mem_word)	(long handle, unsigned long offset);
+	unsigned long (*Fast_read_mem_longword)	(long handle, unsigned long offset);
+	long (*Write_mem_byte)	(long handle, unsigned long offset, unsigned short val);
+	long (*Write_mem_word)	(long handle, unsigned long offset, unsigned short val);
+	long (*Write_mem_longword)	(long handle, unsigned long offset, unsigned long val);
+	long (*Read_io_byte)	(long handle, unsigned long offset, unsigned char *address);
+	long (*Read_io_word)	(long handle, unsigned long offset, unsigned short *address);
+	long (*Read_io_longword)	(long handle, unsigned long offset, unsigned long *address);
+	unsigned char (*Fast_read_io_byte)	(long handle, unsigned long offset);
+	unsigned short (*Fast_read_io_word)	(long handle, unsigned long offset);
+	unsigned long (*Fast_read_io_longword)	(long handle, unsigned long offset);
+	long (*Write_io_byte)	(long handle, unsigned long offset, unsigned short val);
+	long (*Write_io_word)	(long handle, unsigned long offset, unsigned short val);
+	long (*Write_io_longword)	(long handle, unsigned long offset, unsigned long val);
+	long (*Get_machine_id)	(void);
+	long (*Get_pagesize)	(void);
+	long (*Virt_to_bus)	(long handle, unsigned long address, PCI_CONV_ADR *pointer);
+	long (*Bus_to_virt)	(long handle, unsigned long address, PCI_CONV_ADR *pointer);
+	long (*Virt_to_phys)	(unsigned long address, PCI_CONV_ADR *pointer);
+	long (*Phys_to_virt)	(unsigned long address, PCI_CONV_ADR *pointer);
+	long reserved[2];
+};
+
+typedef struct pcibios_mint {
+	PCIBIOS emu_pcibios;
+	/* Only for FireTOS and CTPCI */
+#define PCI_MAX_HANDLE		5 	/* 4 slots on the CTPCI + host bridge PLX9054 */
+#define PCI_MAX_FUNCTION	4	/* 4 functions per PCI slot */
+#define PCI_MAX_RSC_DESC	6	/* 6 resource descriptors */
+	PCI_RSC_DESC pci_rsc_desc[PCI_MAX_HANDLE][PCI_MAX_FUNCTION][PCI_MAX_RSC_DESC];
+	PCI_STS_DESC pci_sts_desc[PCI_MAX_HANDLE][PCI_MAX_FUNCTION];
+} PCIBIOS_MINT;
+
+
+/* PCI bios calls from _PCI cookie
+ */
+
+long Find_pci_device(unsigned long id, unsigned short index);
+long Find_pci_classcode(unsigned long class, unsigned short index);
+long Read_config_byte(long handle, unsigned short reg, unsigned char *address);
+long Read_config_word(long handle, unsigned short reg, unsigned short *address);
+long Read_config_longword(long handle, unsigned short reg, unsigned long *address);
+unsigned char Fast_read_config_byte(long handle, unsigned short reg);
+unsigned short Fast_read_config_word(long handle, unsigned short reg);
+unsigned long Fast_read_config_longword(long handle, unsigned short reg);
+long Write_config_byte(long handle, unsigned short reg, unsigned short val);
+long Write_config_word(long handle, unsigned short reg, unsigned short val);
+long Write_config_longword(long handle, unsigned short reg, unsigned long val);
+long Hook_interrupt(long handle, unsigned long *routine, unsigned long *parameter);
+long Unhook_interrupt(long handle);
+long Special_cycle(unsigned short bus, unsigned long data);
+long Get_routing(long handle);
+long Set_interrupt(long handle);
+long Get_resource(long handle);
+long Get_card_used(long handle, unsigned long *address);
+long Set_card_used(long handle, unsigned long *callback);
+long Read_mem_byte(long handle, unsigned long offset, unsigned char *address);
+long Read_mem_word(long handle, unsigned long offset, unsigned short *address);
+long Read_mem_longword(long handle, unsigned long offset, unsigned long *address);
+unsigned char Fast_read_mem_byte(long handle, unsigned long offset);
+unsigned short Fast_read_mem_word(long handle, unsigned long offset);
+unsigned long Fast_read_mem_longword(long handle, unsigned long offset);
+long Write_mem_byte(long handle, unsigned long offset, unsigned short val);
+long Write_mem_word(long handle, unsigned long offset, unsigned short val);
+long Write_mem_longword(long handle, unsigned long offset, unsigned long val);
+long Read_io_byte(long handle, unsigned long offset, unsigned char *address);
+long Read_io_word(long handle, unsigned long offset, unsigned short *address);
+long Read_io_longword(long handle, unsigned long offset, unsigned long *address);
+unsigned char Fast_read_io_byte(long handle, unsigned long offset);
+unsigned short Fast_read_io_word(long handle, unsigned long offset);
+unsigned long Fast_read_io_longword(long handle, unsigned long offset);
+long Write_io_byte(long handle, unsigned long offset, unsigned short val);
+long Write_io_word(long handle, unsigned long offset, unsigned short val);
+long Write_io_longword(long handle, unsigned long offset, unsigned long val);
+long Get_machine_id(void);
+long Get_pagesize(void);
+long Virt_to_bus(long handle, unsigned long address, PCI_CONV_ADR *pointer);
+long Bus_to_virt(long handle, unsigned long address, PCI_CONV_ADR *pointer);
+long Virt_to_phys(unsigned long address, PCI_CONV_ADR *pointer);
+long Phys_to_virt(unsigned long address, PCI_CONV_ADR *pointer);
+
+# endif /* _pcibios_h */
Index: sys/sys_emu.c
===================================================================
RCS file: /mint/freemint/sys/sys_emu.c,v
retrieving revision 1.2
diff -u -8 -r1.2 sys_emu.c
--- sys/sys_emu.c	13 Jun 2001 20:21:31 -0000	1.2
+++ sys/sys_emu.c	22 Mar 2014 12:04:06 -0000
@@ -41,16 +41,17 @@
  * todo:
  * 
  */
 
 # include "sys_emu.h"
 
 # include "scsidrv.h"
 # include "xhdi.h"
+# include "pcibios.h"
 
 
 long _cdecl
 sys_emu (ushort which, ushort op,
 		long a1, long a2, long a3, long a4,
 		long a5, long a6, long a7)
 {
 	switch (which)
@@ -67,12 +68,19 @@
 			return sys_xhdi (op, a1, a2, a3, a4, a5, a6, a7);
 		}
 		
 		/* SCSIDRV */
 		case 2:
 		{
 			return sys_scsidrv (op, a1, a2, a3, a4, a5, a6, a7);
 		}
+#ifdef PCI_BIOS
+		/* PCI-BIOS */
+		case 3:
+		{
+			return sys_pcibios (op, a1, a2, a3, a4, a5, a6, a7);
+		}
+#endif /* PCI-BIOS */
 	}
 	
 	return EBADARG;
 }
Index: sys/arch/SRCFILES
===================================================================
RCS file: /mint/freemint/sys/arch/SRCFILES,v
retrieving revision 1.17
diff -u -8 -r1.17 SRCFILES
--- sys/arch/SRCFILES	19 Mar 2007 21:05:48 -0000	1.17
+++ sys/arch/SRCFILES	22 Mar 2014 12:04:06 -0000
@@ -23,15 +23,17 @@
 	aranym_asm.S \
 	context.S \
 	cpu.S \
 	detect.S \
 	intr.S \
 	kernel.S \
 	mmu030.S \
 	mmu040.S \
+	pcibios.S \
+	pcibios_emu.S \
 	scsidrv_emu.S \
 	syscall.S \
 	user_things.S \
 	xhdi_emu.S \
 	v4epatch.S
 
 SRCFILES = $(STARTUP) $(COBJS) $(SOBJS)
Index: sys/arch/pcibios.S
===================================================================
RCS file: sys/arch/pcibios.S
diff -N sys/arch/pcibios.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sys/arch/pcibios.S	22 Mar 2014 12:04:06 -0000
@@ -0,0 +1,428 @@
+/*
+ * Ported to FreeMiNT by David Galvez. 2014.
+ *
+ * Didier Mequignon 2005-2007, e-mail: aniplay@wanadoo.fr
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifdef PCI_BIOS
+	.global _tab_funcs_pci
+	.global _Find_pci_device,_Find_pci_classcode,_Read_config_byte,_Read_config_word,_Read_config_longword
+	.global _Fast_read_config_byte,_Fast_read_config_word,_Fast_read_config_longword,_Write_config_byte,_Write_config_word,_Write_config_longword
+	.global _Hook_interrupt,_Unhook_interrupt,_Special_cycle,_Get_routing,_Set_interrupt
+	.global _Get_resource,_Get_card_used,_Set_card_used,_Read_mem_byte,_Read_mem_word,_Read_mem_longword
+	.global _Fast_read_mem_byte,_Fast_read_mem_word,_Fast_read_mem_longword,_Write_mem_byte,_Write_mem_word,_Write_mem_longword
+	.global _Read_io_byte,_Read_io_word,_Read_io_longword,_Fast_read_io_byte,_Fast_read_io_word,_Fast_read_io_longword
+	.global _Write_io_byte,_Write_io_word,_Write_io_longword,_Get_machine_id
+	.global _Get_pagesize,_Virt_to_bus,_Bus_to_virt,_Virt_to_phys,_Phys_to_virt
+
+_Find_pci_device:
+	move.l 4(SP),D0          // ID
+	move.l 8(SP),D1          // index
+	move.l _tab_funcs_pci,A1
+	move.l (A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Find_pci_classcode:
+	move.l 4(SP),D0          // class
+	move.l 8(SP),D1          // index
+	move.l _tab_funcs_pci,A1
+	move.l 4(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Read_config_byte:
+	movem.l 4(SP),D0-D1/A0   // handle, PCI register, pointer to space for read data
+	move.l _tab_funcs_pci,A1
+	move.l 8(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Read_config_word:
+	movem.l 4(SP),D0-D1/A0   // handle, PCI register, pointer to space for read data
+	move.l _tab_funcs_pci,A1
+	move.l 12(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Read_config_longword:
+	movem.l 4(SP),D0-D1/A0   // handle, PCI register, pointer to space for read data
+	move.l _tab_funcs_pci,A1
+	move.l 16(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Fast_read_config_byte:
+	move.l 4(SP),D0          // handle
+	move.l 8(SP),D1          // PCI register
+	move.l _tab_funcs_pci,A1
+	move.l 20(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Fast_read_config_word:
+	move.l 4(SP),D0          // handle
+	move.l 8(SP),D1          // PCI register
+	move.l _tab_funcs_pci,A1
+	move.l 24(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Fast_read_config_longword:
+	move.l 4(SP),D0          // handle
+	move.l 8(SP),D1          // PCI register
+	move.l _tab_funcs_pci,A1
+	move.l 28(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Write_config_byte:
+	move.l D2,-(SP)
+	movem.l 8(SP),D0-D2      // handle, PCI register, data to write
+	move.l _tab_funcs_pci,A1
+	move.l 32(A1),A1
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Write_config_word:
+	move.l D2,-(SP)
+	movem.l 8(SP),D0-D2      // handle, PCI register, data to write
+	move.l _tab_funcs_pci,A1
+	move.l 36(A1),A1
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Write_config_longword:
+	move.l D2,-(SP)
+	movem.l 8(SP),D0-D2      // handle, PCI register, data to write
+	move.l _tab_funcs_pci,A1
+	move.l 40(A1),A1
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Hook_interrupt:
+	movem.l 4(SP),D0/A0/A1   // handle, pointer to interrupt handler, parameter for interrupt handler
+	move.l A2,-(SP)
+	move.l _tab_funcs_pci,A2
+	move.l 44(A2),A2
+	move.l D2,-(SP)
+	jsr (A2)
+	move.l (SP)+,D2
+	move.l (SP)+,A2
+	rts
+
+_Unhook_interrupt:
+	move.l 4(SP),D0          // handle
+	move.l _tab_funcs_pci,A1
+	move.l 48(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Special_cycle:
+	move.l 4(SP),D0          // bus number
+	move.l 8(SP),D1          // special cycle data
+	move.l _tab_funcs_pci,A1
+	move.l 52(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Get_routing:
+	move.l 4(SP),D0          // handle
+	move.l _tab_funcs_pci,A1
+	move.l 56(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Set_interrupt:
+	move.l 4(SP),D0          // handle
+	move.l 8(SP),D1          // mode
+	move.l _tab_funcs_pci,A1
+	move.l 60(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Get_resource:
+	move.l 4(SP),D0          // handle
+	move.l _tab_funcs_pci,A1
+	move.l 64(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Get_card_used:
+	move.l 4(SP),D0          // handle
+	move.l 8(SP),A0          // address
+	move.l _tab_funcs_pci,A1
+	move.l 68(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Set_card_used:
+	move.l 4(SP),D0          // handle
+	move.l 8(SP),A0          // callback
+	move.l _tab_funcs_pci,A1
+	move.l 72(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Read_mem_byte:
+	movem.l 4(SP),D0-D1/A0    // handle, address to access (in PCI memory address space), pointer to data in memory
+	move.l _tab_funcs_pci,A1
+	move.l 76(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Read_mem_word:
+	movem.l 4(SP),D0-D1/A0    // handle, address to access (in PCI memory address space), pointer to data in memory
+	move.l _tab_funcs_pci,A1
+	move.l 80(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Read_mem_longword:
+	movem.l 4(SP),D0-D1/A0    // handle, address to access (in PCI memory address space), pointer to data in memory
+	move.l _tab_funcs_pci,A1
+	move.l 84(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Fast_read_mem_byte:
+	move.l 8(SP),D1          // address to access (in PCI memory address space)
+	move.l _tab_funcs_pci,A1
+	move.l 88(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Fast_read_mem_word:
+	move.l 8(SP),D1          // address to access (in PCI memory address space)
+	move.l _tab_funcs_pci,A1
+	move.l 92(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Fast_read_mem_longword:
+	move.l 8(SP),D1          // address to access (in PCI memory address space)
+	move.l _tab_funcs_pci,A1
+	move.l 96(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Write_mem_byte:
+	move.l D2,-(SP)
+	movem.l 8(SP),D0-D2      // handle, address to access (in PCI memory address space), data to write
+	move.l _tab_funcs_pci,A1
+	move.l 100(A1),A1
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Write_mem_word:
+	move.l D2,-(SP)
+	movem.l 8(SP),D0-D2      // handle, address to access (in PCI memory address space), data to write
+	move.l _tab_funcs_pci,A1
+	move.l 104(A1),A1
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Write_mem_longword:
+	move.l D2,-(SP)
+	movem.l 8(SP),D0-D2      // handle, address to access (in PCI memory address space), data to write
+	move.l _tab_funcs_pci,A1
+	move.l 108(A1),A1
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Read_io_byte:
+	movem.l 4(SP),D0-D1/A0   // handle, address to access (in PCI I/O address space), pointer to data in memory
+	move.l _tab_funcs_pci,A1
+	move.l 112(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Read_io_word:
+	movem.l 4(SP),D0-D1/A0   // handle, address to access (in PCI I/O address space), pointer to data in memory
+	move.l _tab_funcs_pci,A1
+	move.l 116(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Read_io_longword:
+	movem.l 4(SP),D0-D1/A0   // handle, address to access (in PCI I/O address space), pointer to data in memory
+	move.l _tab_funcs_pci,A1
+	move.l 120(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Fast_read_io_byte:
+	move.l 8(SP),D1          // address to access (in PCI I/O address space)
+	move.l _tab_funcs_pci,A1
+	move.l 124(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Fast_read_io_word:
+	move.l 8(SP),D1          // address to access (in PCI I/O address space)
+	move.l _tab_funcs_pci,A1
+	move.l 128(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Fast_read_io_longword:
+	move.l 8(SP),D1          // address to access (in PCI I/O address space)
+	move.l _tab_funcs_pci,A1
+	move.l 132(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Write_io_byte:
+	move.l D2,-(SP)
+	movem.l 8(SP),D0-D2      // handle, address to access (in PCI I/O address space), data to write
+	move.l _tab_funcs_pci,A1
+	move.l 136(A1),A1
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Write_io_word:
+	move.l D2,-(SP)
+	movem.l 8(SP),D0-D2      // handle, address to access (in PCI I/O address space), data to write
+	move.l _tab_funcs_pci,A1
+	move.l 140(A1),A1
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Write_io_longword:
+	move.l D2,-(SP)
+	movem.l 8(SP),D0-D2      // handle, address to access (in PCI I/O address space), data to write
+	move.l _tab_funcs_pci,A1
+	move.l 144(A1),A1
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Get_machine_id:
+	move.l _tab_funcs_pci,A1
+	move.l 148(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Get_pagesize:
+	move.l _tab_funcs_pci,A1
+	move.l 152(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Virt_to_bus:
+	movem.l 4(SP),D0-D1/A0   // handle, address in virtual CPU space, ptr
+	move.l _tab_funcs_pci,A1
+	move.l 156(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Bus_to_virt:
+	movem.l 4(SP),D0-D1/A0   // handle, PCI bus address, ptr
+	move.l _tab_funcs_pci,A1
+	move.l 160(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Virt_to_phys:
+	move.l 4(SP),D0          // address in virtual CPU space  
+	move.l 8(SP),A0          // ptr
+	move.l _tab_funcs_pci,A1
+	move.l 164(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+
+_Phys_to_virt:
+	move.l 4(SP),D0          // physical CPU address 
+	move.l 8(SP),A0          // ptr
+	move.l _tab_funcs_pci,A1
+	move.l 168(A1),A1
+	move.l D2,-(SP)
+	jsr (A1)
+	move.l (SP)+,D2
+	rts
+#endif /* PCI-BIOS */
Index: sys/arch/pcibios_emu.S
===================================================================
RCS file: sys/arch/pcibios_emu.S
diff -N sys/arch/pcibios_emu.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sys/arch/pcibios_emu.S	22 Mar 2014 12:04:06 -0000
@@ -0,0 +1,343 @@
+/*
+ * Copyright 2014 David Galvez.
+ * Based on SCSIDRV sys_emu implementation by Frank Naumann.
+ *
+ * This file belongs to FreeMiNT. It's not in the original MiNT 1.12
+ * distribution. See the file CHANGES for a detailed log of changes.
+ *
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifdef PCI_BIOS
+	.text
+
+	.global _emu_pcibios_Find_pci_device
+	.global _emu_pcibios_Find_pci_classcode
+	.global _emu_pcibios_Read_config_byte
+	.global _emu_pcibios_Read_config_word
+	.global _emu_pcibios_Read_config_longword
+	.global _emu_pcibios_Fast_read_config_byte
+	.global _emu_pcibios_Fast_read_config_word
+	.global _emu_pcibios_Fast_read_config_longword
+	.global _emu_pcibios_Write_config_byte
+	.global _emu_pcibios_Write_config_word
+	.global _emu_pcibios_Write_config_longword
+	.global _emu_pcibios_Hook_interrupt
+	.global _emu_pcibios_Unhook_interrupt
+	.global _emu_pcibios_Special_cycle
+	.global _emu_pcibios_Get_routing
+	.global _emu_pcibios_Set_interrupt
+	.global _emu_pcibios_Get_resource
+	.global _emu_pcibios_Get_card_used
+	.global _emu_pcibios_Set_card_used
+	.global _emu_pcibios_Read_mem_byte
+	.global _emu_pcibios_Read_mem_word
+	.global _emu_pcibios_Read_mem_longword
+	.global _emu_pcibios_Fast_read_mem_byte
+	.global _emu_pcibios_Fast_read_mem_word
+	.global _emu_pcibios_Fast_read_mem_longword
+	.global _emu_pcibios_Write_mem_byte
+	.global _emu_pcibios_Write_mem_word
+	.global _emu_pcibios_Write_mem_longword
+	.global _emu_pcibios_Read_io_byte
+	.global _emu_pcibios_Read_io_word
+	.global _emu_pcibios_Read_io_longword
+	.global _emu_pcibios_Fast_read_io_byte
+	.global _emu_pcibios_Fast_read_io_word
+	.global _emu_pcibios_Fast_read_io_longword
+	.global _emu_pcibios_Write_io_byte
+	.global _emu_pcibios_Write_io_word
+	.global _emu_pcibios_Write_io_longword
+	.global _emu_pcibios_Get_machine_id
+	.global _emu_pcibios_Get_pagesize
+	.global _emu_pcibios_Virt_to_bus
+	.global _emu_pcibios_Bus_to_virt
+	.global _emu_pcibios_Virt_to_phys
+	.global _emu_pcibios_Phys_to_virt
+
+_emu_pcibios_Find_pci_device:
+	move.l	d3,-(sp)
+	move.l	#2,d3
+	bra	_do_trap_dd
+
+_emu_pcibios_Find_pci_classcode:
+	move.l	d3,-(sp)
+	moveq	#3,d3
+	bra	_do_trap_dd
+
+_emu_pcibios_Read_config_byte:
+	move.l	d3,-(sp)
+	moveq	#4,d3
+	bra	_do_trap_dda
+
+_emu_pcibios_Read_config_word:
+	move.l	d3,-(sp)
+	moveq	#5,d3
+	bra	_do_trap_dda
+
+_emu_pcibios_Read_config_longword:
+	move.l	d3,-(sp)
+	moveq	#6,d3
+	bra	_do_trap_dda
+
+_emu_pcibios_Fast_read_config_byte:
+	move.l	d3,-(sp)
+	moveq	#7,d3
+	bra	_do_trap_dd
+
+_emu_pcibios_Fast_read_config_word:
+	move.l	d3,-(sp)
+	moveq	#8,d3
+	bra	_do_trap_dd
+
+_emu_pcibios_Fast_read_config_longword:
+	move.l	d3,-(sp)
+	moveq	#9,d3
+	bra	_do_trap_dd
+
+_emu_pcibios_Write_config_byte:
+	move.l	d3,-(sp)
+	moveq	#10,d3
+	bra	_do_trap_ddd
+
+_emu_pcibios_Write_config_word:
+	move.l	d3,-(sp)
+	moveq	#11,d3
+	bra	_do_trap_ddd
+
+_emu_pcibios_Write_config_longword:
+	move.l	d3,-(sp)
+	moveq	#12,d3
+	bra	_do_trap_ddd
+
+_emu_pcibios_Hook_interrupt:
+	move.l	d3,-(sp)
+	moveq	#13,d3
+	bra	_do_trap_daa
+
+_emu_pcibios_Unhook_interrupt:
+	move.l	d3,-(sp)
+	moveq	#14,d3
+	bra	_do_trap_d
+
+_emu_pcibios_Special_cycle:
+	move.l	d3,-(sp)
+	moveq	#15,d3
+	bra	_do_trap_dd
+
+_emu_pcibios_Get_routing:
+	move.l	d3,-(sp)
+	moveq	#16,d3
+	bra	_do_trap
+
+_emu_pcibios_Set_interrupt:
+	move.l	d3,-(sp)
+	moveq	#17,d3
+	bra	_do_trap
+
+_emu_pcibios_Get_resource:
+	move.l	d3,-(sp)
+	moveq	#18,d3
+	bra	_do_trap_d
+
+_emu_pcibios_Get_card_used:
+	move.l	d3,-(sp)
+	moveq	#19,d3
+	bra	_do_trap_da
+
+_emu_pcibios_Set_card_used:
+	move.l	d3,-(sp)
+	moveq	#20,d3
+	bra	_do_trap_da
+
+_emu_pcibios_Read_mem_byte:
+	move.l	d3,-(sp)
+	moveq	#21,d3
+	bra	_do_trap_dda
+
+_emu_pcibios_Read_mem_word:
+	move.l	d3,-(sp)
+	moveq	#22,d3
+	bra	_do_trap_dda
+
+_emu_pcibios_Read_mem_longword:
+	move.l	d3,-(sp)
+	moveq	#23,d3
+	bra	_do_trap_dda
+
+_emu_pcibios_Fast_read_mem_byte:
+	move.l	d3,-(sp)
+	moveq	#24,d3
+	bra	_do_trap_dd
+
+_emu_pcibios_Fast_read_mem_word:
+	move.l	d3,-(sp)
+	moveq	#25,d3
+	bra	_do_trap_dd
+
+_emu_pcibios_Fast_read_mem_longword:
+	move.l	d3,-(sp)
+	moveq	#26,d3
+	bra	_do_trap_dd
+
+_emu_pcibios_Write_mem_byte:
+	move.l	d3,-(sp)
+	moveq	#27,d3
+	bra	_do_trap_ddd
+
+_emu_pcibios_Write_mem_word:
+	move.l	d3,-(sp)
+	moveq	#28,d3
+	bra	_do_trap_ddd
+
+_emu_pcibios_Write_mem_longword:
+	move.l	d3,-(sp)
+	moveq	#29,d3
+	bra	_do_trap_ddd
+
+_emu_pcibios_Read_io_byte:
+	move.l	d3,-(sp)
+	moveq	#30,d3
+	bra	_do_trap_dda
+
+_emu_pcibios_Read_io_word:
+	move.l	d3,-(sp)
+	moveq	#31,d3
+	bra	_do_trap_dda
+
+_emu_pcibios_Read_io_longword:
+	move.l	d3,-(sp)
+	moveq	#32,d3
+	bra	_do_trap_dda
+
+_emu_pcibios_Fast_read_io_byte:
+	move.l	d3,-(sp)
+	moveq	#33,d3
+	bra	_do_trap_dd
+
+_emu_pcibios_Fast_read_io_word:
+	move.l	d3,-(sp)
+	moveq	#34,d3
+	bra	_do_trap_dd
+
+_emu_pcibios_Fast_read_io_longword:
+	move.l	d3,-(sp)
+	moveq	#35,d3
+	bra	_do_trap_dd
+
+_emu_pcibios_Write_io_byte:
+	move.l	d3,-(sp)
+	moveq	#36,d3
+	bra	_do_trap_ddd
+
+_emu_pcibios_Write_io_word:
+	move.l	d3,-(sp)
+	moveq	#37,d3
+	bra	_do_trap_ddd
+
+_emu_pcibios_Write_io_longword:
+	move.l	d3,-(sp)
+	moveq	#38,d3
+	bra	_do_trap_ddd
+
+_emu_pcibios_Get_machine_id:
+	move.l	d3,-(sp)
+	moveq	#39,d3
+	bra	_do_trap_d
+
+_emu_pcibios_Get_pagesize:
+	move.l	d3,-(sp)
+	moveq	#40,d3
+	bra	_do_trap
+
+_emu_pcibios_Virt_to_bus:
+	move.l	d3,-(sp)
+	moveq	#41,d3
+	bra	_do_trap_dda
+
+_emu_pcibios_Bus_to_virt:
+	move.l	d3,-(sp)
+	moveq	#42,d3
+	bra	_do_trap_dda
+
+_emu_pcibios_Virt_to_phys:
+	move.l	d3,-(sp)
+	moveq	#43,d3
+	bra	_do_trap_da
+
+_emu_pcibios_Phys_to_virt:
+	move.l	d3,-(sp)
+	moveq	#44,d3
+	bra	_do_trap_da
+
+
+_do_trap:
+	lea	-28(sp),sp	//  ensure that stack space is equal to all
+	bra	_call_sys_emu
+
+_do_trap_d:
+	lea	-24(sp),sp	//  ensure that stack space is equal to all
+				//  arguments of sys_emu
+	move.l	d0,-(sp)
+	bra	_call_sys_emu
+
+_do_trap_dd:
+	lea	-20(sp),sp	//  ensure that stack space is equal to all
+				//  arguments of sys_emu
+	move.l	d1,-(sp)
+	move.l	d0,-(sp)
+	bra	_call_sys_emu
+
+_do_trap_ddd:
+	lea	-16(sp),sp	//  ensure that stack space is equal to all
+				//  arguments of sys_emu
+	move.l	d2,-(sp)
+	move.l	d1,-(sp)
+	move.l	d0,-(sp)
+	bra	_call_sys_emu
+
+_do_trap_da:
+	lea	-20(sp),sp	//  ensure that stack space is equal to all
+				//  arguments of sys_emu
+	move.l	a0,-(sp)
+	move.l	d0,-(sp)
+	bra	_call_sys_emu
+
+_do_trap_dda:
+	lea	-16(sp),sp	//  ensure that stack space is equal to all
+				//  arguments of sys_emu
+	move.l	a0,-(sp)
+	move.l	d1,-(sp)
+	move.l	d0,-(sp)
+	bra	_call_sys_emu
+
+_do_trap_daa:
+	lea	-16(sp),sp	//  ensure that stack space is equal to all
+				//  arguments of sys_emu
+	move.l	a1,-(sp)
+	move.l	a0,-(sp)
+	move.l	d0,-(sp)
+	bra	_call_sys_emu
+
+_call_sys_emu:
+	move.w	d3,-(sp)
+	move.w	#0x0003,-(sp)	//  we want PCI-BIOS EMU
+	move.w	#0x015f,-(sp)	//  system EMU
+	trap	#1		//  do the GEMDOS trap
+	lea	34(sp),sp	//  correct stack
+	move.l	(sp)+,d3
+	rts
+#endif /* PCI-BIOS */
Index: sys/arch/pcibios_emu.h
===================================================================
RCS file: sys/arch/pcibios_emu.h
diff -N sys/arch/pcibios_emu.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sys/arch/pcibios_emu.h	22 Mar 2014 12:04:06 -0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2014 David Galvez.
+ * Based on SCSIDRV sys_emu implementation by Frank Naumann.
+ *
+ * This file belongs to FreeMiNT. It's not in the original MiNT 1.12
+ * distribution. See the file CHANGES for a detailed log of changes.
+ *
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+# ifndef _m68k_pcibios_emu_h
+# define _m68k_pcibios_emu_h
+
+# include "mint/mint.h"
+# include "pcibios.h"
+
+/* Although we declare this functions as standard gcc functions (cdecl),
+ * they expect paramenters inside registers (fastcall), which is unsupported by gcc m68k.
+ * Don't worry caller will take care of parameters passing convention.
+ */
+long emu_pcibios_Find_pci_device	(unsigned long id, unsigned short index);
+long emu_pcibios_Find_pci_classcode	(unsigned long class, unsigned short index);
+long emu_pcibios_Read_config_byte	(long handle, unsigned short reg, unsigned char *address);
+long emu_pcibios_Read_config_word	(long handle, unsigned short reg, unsigned short *address);
+long emu_pcibios_Read_config_longword	(long handle, unsigned short reg, unsigned long *address);
+unsigned char emu_pcibios_Fast_read_config_byte	(long handle, unsigned short reg);
+unsigned short emu_pcibios_Fast_read_config_word	(long handle, unsigned short reg);
+unsigned long emu_pcibios_Fast_read_config_longword	(long handle, unsigned short reg);
+long emu_pcibios_Write_config_byte	(long handle, unsigned short reg, unsigned short val);
+long emu_pcibios_Write_config_word	(long handle, unsigned short reg, unsigned short val);
+long emu_pcibios_Write_config_longword	(long handle, unsigned short reg, unsigned long val);
+long emu_pcibios_Hook_interrupt	(long handle, unsigned long *routine, unsigned long *parameter);
+long emu_pcibios_Unhook_interrupt	(long handle);
+long emu_pcibios_Special_cycle	(unsigned short bus, unsigned long data);
+long emu_pcibios_Get_routing	(long handle);
+long emu_pcibios_Set_interrupt	(long handle);
+long emu_pcibios_Get_resource	(long handle);
+long emu_pcibios_Get_card_used	(long handle, unsigned long *address);
+long emu_pcibios_Set_card_used	(long handle, unsigned long *callback);
+long emu_pcibios_Read_mem_byte	(long handle, unsigned long offset, unsigned char *address);
+long emu_pcibios_Read_mem_word	(long handle, unsigned long offset, unsigned short *address);
+long emu_pcibios_Read_mem_longword	(long handle, unsigned long offset, unsigned long *address);
+unsigned char emu_pcibios_Fast_read_mem_byte	(long handle, unsigned long offset);
+unsigned short emu_pcibios_Fast_read_mem_word	(long handle, unsigned long offset);
+unsigned long emu_pcibios_Fast_read_mem_longword	(long handle, unsigned long offset);
+long emu_pcibios_Write_mem_byte	(long handle, unsigned long offset, unsigned short val);
+long emu_pcibios_Write_mem_word	(long handle, unsigned long offset, unsigned short val);
+long emu_pcibios_Write_mem_longword	(long handle, unsigned long offset, unsigned long val);
+long emu_pcibios_Read_io_byte	(long handle, unsigned long offset, unsigned char *address);
+long emu_pcibios_Read_io_word	(long handle, unsigned long offset, unsigned short *address);
+long emu_pcibios_Read_io_longword	(long handle, unsigned long offset, unsigned long *address);
+unsigned char emu_pcibios_Fast_read_io_byte	(long handle, unsigned long offset);
+unsigned short emu_pcibios_Fast_read_io_word	(long handle, unsigned long offset);
+unsigned long emu_pcibios_Fast_read_io_longword	(long handle, unsigned long offset);
+long emu_pcibios_Write_io_byte	(long handle, unsigned long offset, unsigned short val);
+long emu_pcibios_Write_io_word	(long handle, unsigned long offset, unsigned short val);
+long emu_pcibios_Write_io_longword	(long handle, unsigned long offset, unsigned long val);
+long emu_pcibios_Get_machine_id	(void);
+long emu_pcibios_Get_pagesize	(void);
+long emu_pcibios_Virt_to_bus	(long handle, unsigned long address, PCI_CONV_ADR *pointer);
+long emu_pcibios_Bus_to_virt	(long handle, unsigned long address, PCI_CONV_ADR *pointer);
+long emu_pcibios_Virt_to_phys	(unsigned long address, PCI_CONV_ADR *pointer);
+long emu_pcibios_Phys_to_virt	(unsigned long address, PCI_CONV_ADR *pointer);
+
+# endif /* _m68k_pcibios_emu_h */
Index: sys/mint/pcibios.h
===================================================================
RCS file: sys/mint/pcibios.h
diff -N sys/mint/pcibios.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sys/mint/pcibios.h	22 Mar 2014 12:04:06 -0000
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2014 David Galvez.
+ * Based on SCSIDRV sys_emu implementation by Frank Naumann.
+ * Some code chunks taken from FireTOS sources:
+ * Didier Mequignon 2005-2007, e-mail: aniplay@wanadoo.fr
+ *
+ * This file belongs to FreeMiNT. It's not in the original MiNT 1.12
+ * distribution. See the file CHANGES for a detailed log of changes.
+ *
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+# ifndef _mint_pcibios_h
+# define _mint_pcibios_h
+
+
+/* PCI config registers offsets
+ */
+
+#define PCIIDR			0x00   /* PCI Configuration ID Register       */
+#define PCICSR			0x04   /* PCI Command/Status Register         */
+#define PCICR			0x04   /* PCI Command Register                */
+#define PCISR			0x06   /* PCI Status Register                 */
+#define PCIREV			0x08   /* PCI Revision ID Register            */
+#define PCICCR			0x09   /* PCI Class Code Register             */
+#define PCICLSR			0x0C   /* PCI Cache Line Size Register        */
+#define PCILTR			0x0D   /* PCI Latency Timer Register          */
+#define PCIHTR			0x0E   /* PCI Header Type Register            */
+#define PCIBISTR		0x0F   /* PCI Build-In Self Test Register     */
+#define PCIBAR0			0x10   /* PCI Base Address Register for Memory
+					Accesses to Local, Runtime, and DMA */
+#define PCIBAR1			0x14   /* PCI Base Address Register for I/O
+					Accesses to Local, Runtime, and DMA */
+#define PCIBAR2			0x18   /* PCI Base Address Register for Memory
+					Accesses to Local Address Space 0   */
+#define PCIBAR3			0x1C   /* PCI Base Address Register for Memory
+					Accesses to Local Address Space 1   */ 
+#define PCIBAR4			0x20   /* PCI Base Address Register, reserved */
+#define PCIBAR5			0x24   /* PCI Base Address Register, reserved */
+#define PCICIS			0x28   /* PCI Cardbus CIS Pointer, not support*/
+#define PCISVID			0x2C   /* PCI Subsystem Vendor ID             */
+#define PCISID			0x2E   /* PCI Subsystem ID                    */
+#define PCIERBAR		0x30   /* PCI Expansion ROM Base Register     */
+#define CAP_PTR			0x34   /* New Capability Pointer              */
+#define PCIILR			0x3C   /* PCI Interrupt Line Register         */
+#define PCIIPR			0x3D   /* PCI Interrupt Pin Register          */
+#define PCIMGR			0x3E   /* PCI Min_Gnt Register                */
+#define PCIMLR			0x3F   /* PCI Max_Lat Register                */
+#define PMCAPID			0x40   /* Power Management Capability ID      */
+#define PMNEXT			0x41   /* Power Management Next Capability
+					Pointer                             */
+#define PMC			0x42   /* Power Management Capabilities       */
+#define PMCSR			0x44   /* Power Management Control/Status     */
+#define PMCSR_BSE		0x46   /* PMCSR Bridge Support Extensions     */
+#define PMDATA			0x47   /* Power Management Data               */
+#define HS_CNTL			0x48   /* Hot Swap Control                    */
+#define HS_NEXT			0x49   /* Hot Swap Next Capability Pointer    */
+#define HS_CSR			0x4A   /* Hot Swap Control/Status             */
+#define PVPDCNTL		0x4C   /* PCI Vital Product Data Control      */
+#define PVPD_NEXT		0x4D   /* PCI Vital Product Data Next
+					Capability Pointer                  */
+#define PVPDAD			0x4E   /* PCI Vital Product Data Address      */
+#define PVPDATA			0x50   /* PCI VPD Data                        */
+
+
+/* the struct definitions
+ */
+
+typedef struct				/* structure of resource descriptor    */
+{
+	unsigned short next;			/* length of the following structure   */
+	unsigned short flags;			/* type of resource and misc. flags    */
+	unsigned long start;			/* start-address of resource           */
+	unsigned long length;			/* length of resource                  */
+	unsigned long offset;			/* offset PCI to phys. CPU Address     */
+	unsigned long dmaoffset;		/* offset for DMA-transfers            */
+} PCI_RSC_DESC;
+
+typedef struct				/* structure of address conversion     */
+{
+	unsigned long adr;			/* calculated address (CPU<->PCI)      */
+	unsigned long len;			/* length of memory range              */
+} PCI_CONV_ADR;
+
+
+/* PCI-BIOS Error Codes
+ */
+
+#define PCI_SUCCESSFUL			0  /* everything's fine         */
+#define PCI_FUNC_NOT_SUPPORTED		-2  /* function not supported    */
+#define PCI_BAD_VENDOR_ID		-3  /* wrong Vendor ID           */
+#define PCI_DEVICE_NOT_FOUND		-4  /* PCI-Device not found      */
+#define PCI_BAD_REGISTER_NUMBER		-5  /* wrong register number     */
+#define PCI_SET_FAILED			-6  /* reserved for later use    */
+#define PCI_BUFFER_TOO_SMALL		-7  /* reserved for later use    */
+#define PCI_GENERAL_ERROR		-8  /* general BIOS error code   */
+#define PCI_BAD_HANDLE			-9  /* wrong/unknown PCI-handle  */
+
+
+/* Flags used in Resource-Descriptor
+ */
+
+#define FLG_IO		0x4000         /* Ressource in IO range               */
+#define FLG_ROM		0x2000         /* Expansion ROM */
+#define FLG_LAST	0x8000         /* last ressource                      */
+#define FLG_8BIT	0x0100         /* 8 bit accesses allowed              */
+#define FLG_16BIT	0x0200         /* 16 bit accesses allowed             */
+#define FLG_32BIT	0x0400         /* 32 bit accesses allowed             */
+#define FLG_ENDMASK	0x000F         /* mask for byte ordering              */
+
+
+/* Values used in FLG_ENDMASK for Byte Ordering
+ */
+
+#define ORD_MOTOROLA	0         /* Motorola (big endian)               */
+#define ORD_INTEL_AS	1         /* Intel (little endian), addr.swapped */
+#define ORD_INTEL_LS	2         /* Intel (little endian), lane swapped */
+#define ORD_UNKNOWN	15         /* unknown (BIOS-calls allowed only)   */
+
+
+/* Status Info used in Device-Descriptor
+ */
+
+#define DEVICE_FREE		0         /* Device is not used                  */
+#define DEVICE_USED		1         /* Device is used by another driver    */
+#define DEVICE_CALLBACK		2         /* used, but driver can be cancelled   */
+#define DEVICE_AVAILABLE	3         /* used, not available                 */
+#define NO_DEVICE		-1         /* no device detected                  */
+
+
+/* Callback-Routine
+ */
+
+ #define GET_DRIVER_ID		0        /* CB-Routine 0: Get Driver ID         */
+ #define REMOVE_DRIVER		1        /* CB-Routine 1: Remove Driver         */
+
+long Find_pci_device(unsigned long id, unsigned short index);
+long Find_pci_classcode(unsigned long class, unsigned short index);
+long Read_config_byte(long handle, unsigned short reg, unsigned char *address);
+long Read_config_word(long handle, unsigned short reg, unsigned short *address);
+long Read_config_longword(long handle, unsigned short reg, unsigned long *address);
+unsigned char Fast_read_config_byte(long handle, unsigned short reg);
+unsigned short Fast_read_config_word(long handle, unsigned short reg);
+unsigned long Fast_read_config_longword(long handle, unsigned short reg);
+long Write_config_byte(long handle, unsigned short reg, unsigned short val);
+long Write_config_word(long handle, unsigned short reg, unsigned short val);
+long Write_config_longword(long handle, unsigned short reg, unsigned long val);
+long Hook_interrupt(long handle, unsigned long *routine, unsigned long *parameter);
+long Unhook_interrupt(long handle);
+long Special_cycle(unsigned short bus, unsigned long data);
+long Get_routing(long handle);
+long Set_interrupt(long handle);
+long Get_resource(long handle);
+long Get_card_used(long handle, unsigned long *address);
+long Set_card_used(long handle, unsigned long *callback);
+long Read_mem_byte(long handle, unsigned long offset, unsigned char *address);
+long Read_mem_word(long handle, unsigned long offset, unsigned short *address);
+long Read_mem_longword(long handle, unsigned long offset, unsigned long *address);
+unsigned char Fast_read_mem_byte(long handle, unsigned long offset);
+unsigned short Fast_read_mem_word(long handle, unsigned long offset);
+unsigned long Fast_read_mem_longword(long handle, unsigned long offset);
+long Write_mem_byte(long handle, unsigned long offset, unsigned short val);
+long Write_mem_word(long handle, unsigned long offset, unsigned short val);
+long Write_mem_longword(long handle, unsigned long offset, unsigned long val);
+long Read_io_byte(long handle, unsigned long offset, unsigned char *address);
+long Read_io_word(long handle, unsigned long offset, unsigned short *address);
+long Read_io_longword(long handle, unsigned long offset, unsigned long *address);
+unsigned char Fast_read_io_byte(long handle, unsigned long offset);
+unsigned short Fast_read_io_word(long handle, unsigned long offset);
+unsigned long Fast_read_io_longword(long handle, unsigned long offset);
+long Write_io_byte(long handle, unsigned long offset, unsigned short val);
+long Write_io_word(long handle, unsigned long offset, unsigned short val);
+long Write_io_longword(long handle, unsigned long offset, unsigned long val);
+long Get_machine_id(void);
+long Get_pagesize(void);
+long Virt_to_bus(long handle, unsigned long address, PCI_CONV_ADR *pointer);
+long Bus_to_virt(long handle, unsigned long address, PCI_CONV_ADR *pointer);
+long Virt_to_phys(unsigned long address, PCI_CONV_ADR *pointer);
+long Phys_to_virt(unsigned long address, PCI_CONV_ADR *pointer);
+
+# endif /* _mint_pcibios_h */