1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-01 10:06:57 +03:00
2000-01-02  Philip Blundell  <philb@gnu.org>

	* sysdeps/unix/sysv/linux/arm/ioperm.c: Use sysctl by preference
	to obtain port mapping information.  Avoid use of mprotect.
This commit is contained in:
Ulrich Drepper
2000-01-04 23:56:39 +00:00
parent 856275fa78
commit f19f2b3443
3 changed files with 47 additions and 27 deletions

View File

@ -1,3 +1,8 @@
2000-01-02 Philip Blundell <philb@gnu.org>
* sysdeps/unix/sysv/linux/arm/ioperm.c: Use sysctl by preference
to obtain port mapping information. Avoid use of mprotect.
2000-01-04 Ulrich Drepper <drepper@cygnus.com> 2000-01-04 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/sysv/linux/sparc/bits/fcntl.h (O_LARGEFILE): Add * sysdeps/unix/sysv/linux/sparc/bits/fcntl.h (O_LARGEFILE): Add

View File

@ -27,6 +27,12 @@
registers tend to be memory mapped these days so this should be no big registers tend to be memory mapped these days so this should be no big
problem. */ problem. */
/* Once upon a time this file used mprotect to enable and disable
access to particular areas of I/O space. Unfortunately the
mprotect syscall also has the side effect of enabling caching for
the area affected (this is a kernel limitation). So we now just
enable all the ports all of the time. */
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
@ -39,6 +45,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <asm/page.h> #include <asm/page.h>
#include <sys/sysctl.h>
#define PATH_ARM_SYSTYPE "/etc/arm_systype" #define PATH_ARM_SYSTYPE "/etc/arm_systype"
#define PATH_CPUINFO "/proc/cpuinfo" #define PATH_CPUINFO "/proc/cpuinfo"
@ -69,16 +76,22 @@ static struct platform {
#define IO_ADDR(port) (io.base + ((port) << io.shift)) #define IO_ADDR(port) (io.base + ((port) << io.shift))
/* /*
* Initialize I/O system. To determine what I/O system we're dealing * Initialize I/O system. There are several ways to get the information
* with, we first try to read the value of symlink PATH_ARM_SYSTYPE, * we need. Each is tried in turn until one succeeds.
* if that fails, we lookup the "system type" field in /proc/cpuinfo.
* If that fails as well, we give up. Other possible options might be
* to look at the ELF auxiliary vector or to add a special system call
* but there is probably no point.
* *
* If the value received from PATH_ARM_SYSTYPE begins with a number, * 1. Sysctl (CTL_BUS, BUS_ISA, ISA_*). This is the preferred method
* assume this is a previously unsupported system and the values encode, * but not all kernels support it.
* in order, "<io_base>,<port_shift>". *
* 2. Read the value (not the contents) of symlink PATH_ARM_SYSTYPE.
* - If it matches one of the entries in the table above, use the
* corresponding values.
* - If it begins with a number, assume this is a previously
* unsupported system and the values encode, in order,
* "<io_base>,<port_shift>".
*
* 3. Lookup the "system type" field in /proc/cpuinfo. Again, if it
* matches an entry in the platform[] table, use the corresponding
* values.
*/ */
static int static int
@ -86,6 +99,16 @@ init_iosys (void)
{ {
char systype[256]; char systype[256];
int i, n; int i, n;
static int iobase_name[] = { CTL_BUS, BUS_ISA, BUS_ISA_PORT_BASE };
static int ioshift_name[] = { CTL_BUS, BUS_ISA, BUS_ISA_PORT_SHIFT };
size_t len = sizeof(io.base);
if (! sysctl (iobase_name, 3, &io.io_base, &len, NULL, 0)
&& ! sysctl (ioshift_name, 3, &io.shift, &len, NULL, 0))
{
io.initdone = 1;
return 0;
}
n = readlink (PATH_ARM_SYSTYPE, systype, sizeof (systype) - 1); n = readlink (PATH_ARM_SYSTYPE, systype, sizeof (systype) - 1);
if (n > 0) if (n > 0)
@ -149,9 +172,6 @@ init_iosys (void)
int int
_ioperm (unsigned long int from, unsigned long int num, int turn_on) _ioperm (unsigned long int from, unsigned long int num, int turn_on)
{ {
unsigned long int addr, len;
int prot;
if (! io.initdone && init_iosys () < 0) if (! io.initdone && init_iosys () < 0)
return -1; return -1;
@ -173,25 +193,16 @@ _ioperm (unsigned long int from, unsigned long int num, int turn_on)
return -1; return -1;
io.base = io.base =
(unsigned long int) __mmap (0, MAX_PORT << io.shift, PROT_NONE, (unsigned long int) __mmap (0, MAX_PORT << io.shift,
PROT_READ | PROT_WRITE,
MAP_SHARED, fd, io.io_base); MAP_SHARED, fd, io.io_base);
close (fd); close (fd);
if ((long) io.base == -1) if ((long) io.base == -1)
return -1; return -1;
} }
prot = PROT_READ | PROT_WRITE;
} }
else
{
if (!io.base)
return 0; /* never was turned on... */
/* turnoff access to relevant pages: */ return 0;
prot = PROT_NONE;
}
addr = (io.base + (from << io.shift)) & PAGE_MASK;
len = num << io.shift;
return mprotect ((void *) addr, len, prot);
} }

View File

@ -44,8 +44,12 @@
#endif #endif
#ifdef __USE_LARGEFILE64 #ifdef __USE_LARGEFILE64
# if __WORDSIZE == 64
# define O_LARGEFILE 0
# else
# define O_LARGEFILE 0x40000 # define O_LARGEFILE 0x40000
# endif # endif
#endif
/* For now Linux has no synchronisity options for data and read /* For now Linux has no synchronisity options for data and read
operations. We define the symbols here but let them do the same as operations. We define the symbols here but let them do the same as