On Sun, 23 Apr 2000, Kevin D. Kissell wrote:
> >i am trying to build "pileup" which is a "SoundBlaster" morse trainer.
> >As it directly accesses hardware it seems to include some files which
> >aehm - dont seem to work for userspace :)
> >
> >Does someone have an idea what goes wrong here ?
>
> Sure. The "IN" and "OUT" macros used to simulate x86
> I/O instructions operating on ISA I/O space use
> mips_io_port_base as the base address for the
> memory-mapped I/O access to "non memory-mapped I/O"
> (in the PC sense) addresses. Since MIPS platforms don't
> always have the same address space layout as a standard PC,
> mips_io_port_base is not a constant, but a variable declared
> in arch/mips/kernel/setup.c and initialized (if a non-zero value
> is required) in the platform setup code.
>
> So arguably, what you need to do to make those macros
> work in user mode, is to have some kind of library module
> that you can link into the application that contains a declaration
> of mips_io_port_base, initialized to the correct value for
> your platform.
This is similar like on other platforms, like e.g. PPC.
I think the best solution is to provide the value of mips_io_port_base through
some /proc interface, so userspace knows where ISA I/O space is located.
Of course this is best coordinated across the different architectures where
this problem occurs (e.g. PPC).
> >[...]
> >make CFLAGS="-O2 -g -Wall -D_REENTRANT"
> >make[1]: Entering directory `/home/builder/build/pileup-1.1'
> >gcc -O2 -g -Wall -D_REENTRANT -c AdLib.c
> >gcc -O2 -g -Wall -D_REENTRANT -c pileup.c
> >gcc -O2 -g -Wall -D_REENTRANT -o pileup pileup.o AdLib.o -lm -lpthread
> >pileup.o: In function `stop_thread':
> >/home/builder/build/pileup-1.1/pileup.c:229: undefined reference to `ioperm'
And we don't have ioperm() on architectures that don't have special I/O
instructions.
Just for reference, this is an example of what I use on PPC to access ISA I/O
space (please also look at include/asm-ppc/io.h, which resembles a bit to the
MIPS version).
--- tulip/tulip-diag.c.orig Wed Mar 22 09:30:07 2000
+++ tulip/tulip-diag.c Wed Mar 22 18:18:22 2000
@@ -42,6 +42,7 @@
#include <string.h>
#include <strings.h>
#include <errno.h>
+#include <sys/mman.h>
#include <asm/types.h>
#include <asm/unaligned.h>
@@ -168,6 +169,56 @@
static int scan_proc_pci(int card_num);
static int parse_media_type(const char *capabilities);
static int get_media_index(const char *name);
+
+#ifdef __powerpc__
+unsigned long isa_io_base;
+static int io_fd = -1;
+
+#define REAL_ISA_IO_BASE 0xf8000000 /* for CHRP LongTrail */
+#define REAL_ISA_IO_SIZE 0x01000000
+
+#warning Make sure REAL_ISA_IO_BASE is the correct base address for ISA I/O
space!
+
+static void enable_isa_io(void)
+{
+ if ((io_fd = open("/dev/mem", O_RDWR)) == -1) {
+ perror("open /dev/mem");
+ exit(1);
+ }
+ isa_io_base = (unsigned long)mmap(0, REAL_ISA_IO_SIZE,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ io_fd, REAL_ISA_IO_BASE);
+ if (isa_io_base == (unsigned long)-1) {
+ fprintf(stderr, "mmap 0x%08x: %s", REAL_ISA_IO_BASE, strerror(errno));
+ exit(1);
+ }
+}
+
+static void disable_isa_io(void)
+{
+ if (isa_io_base != (unsigned long)-1) {
+ munmap((caddr_t)isa_io_base, REAL_ISA_IO_SIZE);
+ isa_io_base = (unsigned long)-1;
+ }
+ if (io_fd != -1) {
+ close(io_fd);
+ io_fd = -1;
+ }
+}
+#else
+static void enable_isa_io(void)
+{
+ /* Get access to all of I/O space. */
+ if (iopl(3) < 0) {
+ perror("Network adapter diagnostic: iopl()");
+ fprintf(stderr, "This program must be run as root.\n");
+ exit(1);
+ }
+}
+
+#define disable_isa_io() do { } while (0)
+#endif /* !__powerpc__ */
+
int
main(int argc, char **argv)
@@ -244,12 +295,7 @@
return 3;
}
- /* Get access to all of I/O space. */
- if (iopl(3) < 0) {
- perror("Network adapter diagnostic: iopl()");
- fprintf(stderr, "This program must be run as root.\n");
- return 2;
- }
+ enable_isa_io();
/* Try to read a likely port_base value from /proc/pci. */
if (port_base) {
@@ -270,6 +316,7 @@
" '-e' to show EEPROM contents, -ee for parsed
contents,\n"
" or '-m' or '-mm' to show MII management
registers.\n");
+ disable_isa_io();
return 0;
}
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- Linux/{m68k~Amiga,PPC~CHRP} -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
|