Current-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[PAE] minor virtual memory i386 code rework
Hi list,
I am currently in the process of adding PAE support within kvm(3). As
such, I am proposing a patch (see attached) to the "review before
commit" process:
- it makes paddr_t a 64 bits entity for i386 userland, whether PAE
support was compiled in, or not (only affects kvm_i386).
- basic rework of PD/PT code, to expose some macros simultaneously for
i386 native and PAE mode.
Depending on the mode they apply to, they are either prefixed with
"I386_" or "PAE_" (suggestions welcomed for better wording). These
macros are required in different parts of pmap, directly or indirectly
(through pl*_i functions). In order to remain "largely" compatible with
the current architecture, I am using ___CONCAT() magic to properly
select the ones that will be used at compilation time.
After the pmap rework from rmind@, I will investigate further on how I
could get more abstraction inside pmap, like providing native and PAE
code simultaneously in kernel, without too much duplication (this will
need paddr_t 64 bits work too, so let's do this gradually).
Opinions on that one? It is required for my kvm(3) prototype change
work, which will be subject of another mail to current-users@ in about 5
min. The libsa change will be committed separately.
--
Jean-Yves Migeon
jeanyves.migeon%free.fr@localhost
Index: sys/arch/i386/include/pte.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/include/pte.h,v
retrieving revision 1.24
diff -u -p -r1.24 pte.h
--- sys/arch/i386/include/pte.h 6 Jul 2010 20:50:34 -0000 1.24
+++ sys/arch/i386/include/pte.h 6 Sep 2010 17:39:03 -0000
@@ -192,50 +192,96 @@ typedef uint32_t pt_entry_t; /* PTE */
#endif
/*
- * now we define various for playing with virtual addresses
+ * now we define various macros for playing with virtual addresses.
+ * As PAE modifies the way virtual addresses are manipulated, certain macros
+ * are prefixed with either 'I386_' (native i386) or 'PAE_' (PAE mode)
+ * depending on the mode to which they apply.
*/
-#ifdef PAE
-#define L1_SHIFT 12
-#define L2_SHIFT 21
-#define L3_SHIFT 30
-#define NBPD_L1 (1ULL << L1_SHIFT) /* # bytes mapped by L1 ent
(4K) */
-#define NBPD_L2 (1ULL << L2_SHIFT) /* # bytes mapped by L2 ent
(2MB) */
-#define NBPD_L3 (1ULL << L3_SHIFT) /* # bytes mapped by L3 ent
(1GB) */
-
-#define L3_MASK 0xc0000000
-#define L2_REALMASK 0x3fe00000
-#define L2_MASK (L2_REALMASK | L3_MASK)
-#define L1_MASK 0x001ff000
-
-#define L3_FRAME (L3_MASK)
-#define L2_FRAME (L3_FRAME | L2_MASK)
-#define L1_FRAME (L2_FRAME|L1_MASK)
+/* First, the native i386 macros */
-#define PG_FRAME 0x000ffffffffff000ULL /* page frame mask */
-#define PG_LGFRAME 0x000fffffffe00000ULL /* large (2MB) page frame
mask */
+#define I386_L1_SHIFT 12
+#define I386_L2_SHIFT 22
-/* macros to get real L2 and L3 index, from our "extended" L2 index */
-#define l2tol3(idx) ((idx) >> (L3_SHIFT - L2_SHIFT))
-#define l2tol2(idx) ((idx) & (L2_REALMASK >> L2_SHIFT))
+/* # bytes mapped by L1 ent (4K) */
+#define I386_NBPD_L1 (1UL << I386_L1_SHIFT)
-#else /* PAE */
+/* # bytes mapped by L2 ent (4MB) */
+#define I386_NBPD_L2 (1UL << I386_L2_SHIFT)
+
+#define I386_L2_MASK 0xffc00000
+#define I386_L1_MASK 0x003ff000
+
+#define I386_L2_FRAME (I386_L2_MASK)
+#define I386_L1_FRAME (I386_L2_FRAME | I386_L1_MASK)
+
+#define I386_PG_FRAME 0xfffff000 /* page frame mask */
+#define I386_PG_LGFRAME 0xffc00000 /* large (4MB) page frame mask
*/
-#define L1_SHIFT 12
-#define L2_SHIFT 22
-#define NBPD_L1 (1UL << L1_SHIFT) /* # bytes mapped by L1 ent
(4K) */
-#define NBPD_L2 (1UL << L2_SHIFT) /* # bytes mapped by L2 ent
(4MB) */
+/* Second, PAE macros */
-#define L2_MASK 0xffc00000
-#define L1_MASK 0x003ff000
+#define PAE_L1_SHIFT 12
+#define PAE_L2_SHIFT 21
+#define PAE_L3_SHIFT 30
-#define L2_FRAME (L2_MASK)
-#define L1_FRAME (L2_FRAME|L1_MASK)
+/* # bytes mapped by L1 ent (4K) */
+#define PAE_NBPD_L1 (1ULL << PAE_L1_SHIFT)
-#define PG_FRAME 0xfffff000 /* page frame mask */
-#define PG_LGFRAME 0xffc00000 /* large (4MB) page frame mask
*/
+/* # bytes mapped by L2 ent (2MB) */
+#define PAE_NBPD_L2 (1ULL << PAE_L2_SHIFT)
+/* # bytes mapped by L3 ent (1GB) */
+#define PAE_NBPD_L3 (1ULL << PAE_L3_SHIFT)
+
+#define PAE_L3_MASK 0xc0000000
+#define PAE_L2_REALMASK 0x3fe00000
+#define PAE_L2_MASK (PAE_L2_REALMASK | PAE_L3_MASK)
+#define PAE_L1_MASK 0x001ff000
+
+#define PAE_L3_FRAME (PAE_L3_MASK)
+#define PAE_L2_FRAME (PAE_L3_FRAME | PAE_L2_MASK)
+#define PAE_L1_FRAME (PAE_L2_FRAME | PAE_L1_MASK)
+
+#define PAE_PG_FRAME 0x000ffffffffff000ULL /* page frame mask */
+#define PAE_PG_LGFRAME 0x000fffffffe00000ULL /* large (2MB) page frame
mask */
+
+/* macros to get real L2 and L3 index, from our "extended" L2 index */
+#define l2tol3(idx) ((idx) >> (PAE_L3_SHIFT - PAE_L2_SHIFT))
+#define l2tol2(idx) ((idx) & (PAE_L2_REALMASK >> PAE_L2_SHIFT))
+
+/*
+ * Use CONCAT dark magic, so that general purpose in-kernel macros
+ * are correctly chosen depending on i386 mode (native, or PAE) used at build
+ * time.
+ */
+
+#include <sys/cdefs.h>
+
+#ifdef PAE
+#define I386_MODE PAE_
+#else /* PAE */
+#define I386_MODE I386_
#endif /* PAE */
+
+#define L1_SHIFT ___CONCAT(I386_MODE,L1_SHIFT)
+#define L2_SHIFT ___CONCAT(I386_MODE,L2_SHIFT)
+#define L3_SHIFT ___CONCAT(I386_MODE,L3_SHIFT)
+
+#define NBPD_L1 ___CONCAT(I386_MODE,NBPD_L1)
+#define NBPD_L2 ___CONCAT(I386_MODE,NBPD_L2)
+#define NBPD_L3 ___CONCAT(I386_MODE,NBPD_L3)
+
+#define L1_MASK ___CONCAT(I386_MODE,L1_MASK)
+#define L2_MASK ___CONCAT(I386_MODE,L2_MASK)
+#define L3_MASK ___CONCAT(I386_MODE,L3_MASK)
+
+#define L1_FRAME ___CONCAT(I386_MODE,L1_FRAME)
+#define L2_FRAME ___CONCAT(I386_MODE,L2_FRAME)
+#define L3_FRAME ___CONCAT(I386_MODE,L3_FRAME)
+
+#define PG_FRAME ___CONCAT(I386_MODE,PG_FRAME)
+#define PG_LGFRAME ___CONCAT(I386_MODE,PG_LGFRAME)
+
/*
* here we define the bits of the PDE/PTE, as described above:
*
@@ -267,7 +313,7 @@ typedef uint32_t pt_entry_t; /* PTE */
#define PG_KW 0x00000002 /* kernel read-write */
#ifdef PAE
-#define PG_NX 0x8000000000000000 /* No-execute */
+#define PG_NX 0x8000000000000000ULL /* No-execute */
#else
#define PG_NX 0 /* dummy */
#endif
Index: sys/arch/i386/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/include/types.h,v
retrieving revision 1.67
diff -u -p -r1.67 types.h
--- sys/arch/i386/include/types.h 11 Dec 2009 05:52:03 -0000 1.67
+++ sys/arch/i386/include/types.h 6 Sep 2010 17:39:03 -0000
@@ -47,27 +47,43 @@ typedef struct label_t {
} label_t;
#endif
-/* NB: This should probably be if defined(_KERNEL) */
#if defined(_NETBSD_SOURCE)
+#if defined(_KERNEL)
+
+/*
+ * XXX JYM for now, in kernel paddr_t can be 32 or 64 bits, depending
+ * on PAE. Revisit when paddr_t becomes 64 bits for !PAE systems.
+ */
#ifdef PAE
typedef unsigned long long paddr_t;
typedef unsigned long long psize_t;
#define PRIxPADDR "llx"
#define PRIxPSIZE "llx"
#define PRIuPSIZE "llu"
-#else
+#else /* PAE */
typedef unsigned long paddr_t;
typedef unsigned long psize_t;
#define PRIxPADDR "lx"
#define PRIxPSIZE "lx"
#define PRIuPSIZE "lu"
#endif /* PAE */
+
+#else /* _KERNEL */
+/* paddr_t is always 64 bits for userland */
+typedef unsigned long long paddr_t;
+typedef unsigned long long psize_t;
+#define PRIxPADDR "llx"
+#define PRIxPSIZE "llx"
+#define PRIuPSIZE "llu"
+
+#endif /* _KERNEL */
+
typedef unsigned long vaddr_t;
typedef unsigned long vsize_t;
#define PRIxVADDR "lx"
#define PRIxVSIZE "lx"
#define PRIuVSIZE "lu"
-#endif
+#endif /* _NETBSD_SOURCE */
typedef int pmc_evid_t;
typedef __uint64_t pmc_ctr_t;
Index: sys/lib/libsa/loadfile_elf32.c
===================================================================
RCS file: /cvsroot/src/sys/lib/libsa/loadfile_elf32.c,v
retrieving revision 1.26
diff -u -p -r1.26 loadfile_elf32.c
--- sys/lib/libsa/loadfile_elf32.c 2 Sep 2010 17:10:14 -0000 1.26
+++ sys/lib/libsa/loadfile_elf32.c 6 Sep 2010 17:39:10 -0000
@@ -263,8 +263,9 @@ ELFNAMEEND(loadfile)(int fd, Elf_Ehdr *e
int i, j;
ssize_t sz;
int first;
- paddr_t minp = ~0, maxp = 0, pos = 0;
- paddr_t offset = marks[MARK_START], shpp, elfp = 0;
+ Elf_Addr shpp;
+ Elf_Addr minp = ~0, maxp = 0, pos = 0, elfp = 0;
+ u_long offset = marks[MARK_START];
ssize_t nr;
struct __packed {
Elf_Nhdr nh;
Home |
Main Index |
Thread Index |
Old Index