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

libc patches for arm



I've attached below a couple of recent patches that are somewhat important for 
the ARM port.  Since it looks like potato will freeze before libc 2.1.3 is 
released, I'd appreciate it if they could be included in the Debian patchset
for the time being.

Thanks

p.
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.

Index: ioperm.c
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/arm/ioperm.c,v
retrieving revision 1.2
diff -u -p -r1.2 ioperm.c
--- sysdeps/unix/sysv/linux/arm/ioperm.c	1999/04/12 09:02:39	1.2
+++ sysdeps/unix/sysv/linux/arm/ioperm.c	2000/01/02 14:11:18
@@ -27,6 +27,12 @@
    registers tend to be memory mapped these days so this should be no big
    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 <fcntl.h>
 #include <stdio.h>
@@ -39,6 +45,7 @@
 #include <sys/mman.h>
 
 #include <asm/page.h>
+#include <sys/sysctl.h>
 
 #define PATH_ARM_SYSTYPE	"/etc/arm_systype"
 #define PATH_CPUINFO		"/proc/cpuinfo"
@@ -69,16 +76,22 @@ static struct platform {
 #define IO_ADDR(port)	(io.base + ((port) << io.shift))
 
 /*
- * Initialize I/O system.  To determine what I/O system we're dealing
- * with, we first try to read the value of symlink PATH_ARM_SYSTYPE,
- * 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.
+ * Initialize I/O system.  There are several ways to get the information
+ * we need.  Each is tried in turn until one succeeds.
+ *
+ * 1. Sysctl (CTL_BUS, BUS_ISA, ISA_*).  This is the preferred method
+ *    but not all kernels support it.
+ *
+ * 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>".
  *
- * If the value received from PATH_ARM_SYSTYPE 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
@@ -86,6 +99,16 @@ init_iosys (void)
 {
   char systype[256];
   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);
   if (n > 0)
@@ -106,7 +129,7 @@ init_iosys (void)
       FILE * fp;
 
       fp = fopen (PATH_CPUINFO, "r");
-      if (!fp)
+      if (! fp)
 	return -1;
       while ((n = fscanf (fp, "Hardware\t: %256[^\n]\n", systype))
 	     != EOF)
@@ -149,10 +172,7 @@ init_iosys (void)
 int
 _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;
 
   /* this test isn't as silly as it may look like; consider overflows! */
@@ -173,25 +193,16 @@ _ioperm (unsigned long int from, unsigne
 	    return -1;
 
 	  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);
 	  close (fd);
 	  if ((long) io.base == -1)
 	    return -1;
 	}
-      prot = PROT_READ | PROT_WRITE;
     }
-  else
-    {
-      if (!io.base)
-	return 0;	/* never was turned on... */
 
-      /* turnoff access to relevant pages: */
-      prot = PROT_NONE;
-    }
-  addr = (io.base + (from << io.shift)) & PAGE_MASK;
-  len = num << io.shift;
-  return mprotect ((void *) addr, len, prot);
+  return 0;
 }
 
 
1999-12-26  Philip Blundell  <philb@gnu.org>

	* sysdeps/unix/sysv/linux/arm/syscalls.list: Remove vm86.  Set
	argument count for `syscall' to 7.
	* sysdeps/unix/sysv/linux/arm/sysdep.h: Add support for syscalls
	with more than five arguments.
	(DOARGS_5, UNDOARGS_5): Don't corrupt the calling stack frame.

Index: syscalls.list
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/arm/syscalls.list,v
retrieving revision 1.7
diff -u -r1.7 syscalls.list
--- sysdeps/unix/sysv/linux/arm/syscalls.list	1998/12/22 17:25:27	1.7
+++ sysdeps/unix/sysv/linux/arm/syscalls.list	1999/12/26 15:29:56
@@ -11,5 +11,4 @@
 s_setresuid	setresuid setresuid	3	__syscall_setresuid
 s_setreuid	setreuid setreuid	2	__syscall_setreuid
 s_setuid	setuid	setuid		1	__syscall_setuid
-syscall		-	syscall		5	syscall
-vm86		-	vm86		1	__vm86		vm86
+syscall		-	syscall		7	syscall
Index: sysdep.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/arm/sysdep.h,v
retrieving revision 1.11
diff -u -r1.11 sysdep.h
--- sysdeps/unix/sysv/linux/arm/sysdep.h	1999/04/12 09:04:12	1.11
+++ sysdeps/unix/sysv/linux/arm/sysdep.h	1999/12/26 15:29:58
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 93, 95, 96, 97, 98 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 93, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>, August 1995.
    ARM changes by Philip Blundell, <pjb27@cam.ac.uk>, May 1997.
@@ -69,6 +69,8 @@
 	arg 3		r2
 	arg 4		r3
 	arg 5		r4	(this is different from the APCS convention)
+	arg 6		r5
+	arg 7		r6
 
    The compiler is going to form a call by coming here, through PSEUDO, with
    arguments
@@ -78,9 +80,12 @@
    	arg 3		r2
    	arg 4		r3
    	arg 5		[sp]
+	arg 6		[sp+4]
+	arg 7		[sp+8]
 
-   We need to shuffle values between R4 and the stack so that the caller's
-   R4 is not corrupted, and the kernel sees the right argument there.
+   We need to shuffle values between R4..R6 and the stack so that the
+   caller's v1..v3 and stack frame are not corrupted, and the kernel
+   sees the right arguments.
 
 */
 
@@ -95,14 +100,18 @@
 #define DOARGS_2 /* nothing */
 #define DOARGS_3 /* nothing */
 #define DOARGS_4 /* nothing */
-#define DOARGS_5 ldr ip, [sp]; str r4, [sp]; mov r4, ip;
+#define DOARGS_5 str r4, [sp, $-4]!; ldr r4, [sp, $4];
+#define DOARGS_6 mov ip, sp; stmfd sp!, {r4, r5}; ldmia ip, {r4, r5};
+#define DOARGS_7 mov ip, sp; stmfd sp!, {r4, r5, r6}; ldmia ip, {r4, r5, r6};
 
 #define UNDOARGS_0 /* nothing */
 #define UNDOARGS_1 /* nothing */
 #define UNDOARGS_2 /* nothing */
 #define UNDOARGS_3 /* nothing */
 #define UNDOARGS_4 /* nothing */
-#define UNDOARGS_5 ldr r4, [sp];
+#define UNDOARGS_5 ldr r4, [sp, $4]!;
+#define UNDOARGS_6 ldmfd sp!, {r4, r5};
+#define UNDOARGS_7 ldmfd sp!, {r4, r5, r6};
 
 #else /* not __ASSEMBLER__ */
 
@@ -149,6 +158,14 @@
   register int _v1 asm ("v1") = (int) (a5);	\
   LOAD_ARGS_4 (a1, a2, a3, a4)
 #define ASM_ARGS_5	ASM_ARGS_4, "r" (_v1)
+#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)	\
+  register int _v2 asm ("v2") = (int) (a6);	\
+  LOAD_ARGS_5 (a1, a2, a3, a4, a5)
+#define ASM_ARGS_6	ASM_ARGS_5, "r" (_v2)
+#define LOAD_ARGS_7(a1, a2, a3, a4, a5, a6, a7)	\
+  register int _v3 asm ("v3") = (int) (a7);	\
+  LOAD_ARGS_6 (a1, a2, a3, a4, a5, a6)
+#define ASM_ARGS_7	ASM_ARGS_6, "r" (_v3)
 
 #endif	/* __ASSEMBLER__ */
 

Reply to: