Subject: [RFC] Patch to clean up/straighten out i386 GDT entries
To: None <tech-kern@netbsd.org>
From: Rafal Boni <rafal@mediaone.net>
List: port-i386
Date: 01/19/2002 23:04:02
Folks:
	Trying to get an SMP kernel running on my newly-smp devel. box, I
	found that I once again tripped over PR port-i386/11299.  In order
	to fix it, I needed to add an entry a GDT entry to map the extended
	bios data area (see the PR for details)... However, the entries in
	the GDT are getting to be a bit of a mess (for example, not allowing
	you to use APM & COMPAT_MACH at the same time).

	
	Appended is a proposed patch for the trunk I'd like to check in to 
	clean up some of this, as well as setting aside the magick GDT entry
	to map the extended bios data area (it needs to be a the 8th entry 
	to map to the correct selector).  Also attached is a patch to the 
	SMP branch, which I submit for Bill's consideration (I actually did
	the work in the smp branch first and then back-ported to the trunk, 
	FWIW).

	Note that I've merged the GCPU_SEL from the smp branch into the 
	trunk as it let me fill a hole in the table and still keep the
	related segments (eg, for APM, PNPBIOS, ...) numerically consecutive.

	I'd like to check this in, but as the x86 port is not really my 
	area, I thought I'd solicit for comments here first... Note that
	this change requires arch/i386/bioscall/biostramp.inc to also be
	rebuild with the new header and checked in (as it depends on 
	GBIOSCODE_SEL & GBIOSDATA_SEL); I'm not providing that patch here
	as biostramp.inc is just a hex dump of the trampoline code and the
	diff isn't very interesting).  Obviously, I'd check in the updated
	bios trampoline code along with this change if it's deemed OK.

Thanks,
--rafal

	For the trunk:

Index: segments.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/include/segments.h,v
retrieving revision 1.32
diff -u -r1.32 segments.h
--- segments.h	2001/07/14 02:02:45	1.32
+++ segments.h	2002/01/20 03:21:26
@@ -213,7 +213,19 @@
 #define	NRSVIDT	32		/* reserved entries for cpu exceptions */
 
 /*
- * Entries in the Global Descriptor Table (GDT)
+ * Entries in the Global Descriptor Table (GDT).
+ *
+ * NB: If you change GBIOSCODE/GBIOSDATA, you *must* rebuild arch/i386/
+ * bioscall/biostramp.inc, as that relies on GBIOSCODE/GBIOSDATA and a
+ * normal kernel build does not rebuild it (it's merely included whole-
+ * sale from i386/bioscall.s)
+ * 
+ * Also, note that the GEXTBIOSDATA_SEL selector is special, as it maps 
+ * to the value 0x0040 (when created as a KPL global selector).  Some 
+ * Some BIOSes reference the extended BIOS data area at segment 0040 in 
+ * a non-relocatable fashion (even when in protected mode); mapping the
+ * zero page via the GEXTBIOSDATA_SEL allows these buggy BIOSes to continue
+ * to work under NetBSD.
  */
 #define	GNULL_SEL	0	/* Null descriptor */
 #define	GCODE_SEL	1	/* Kernel code descriptor */
@@ -221,20 +233,19 @@
 #define	GLDT_SEL	3	/* Default LDT descriptor */
 #define	GUCODE_SEL	4	/* User code descriptor */
 #define	GUDATA_SEL	5	/* User data descriptor */
-#define	GAPM32CODE_SEL	6
-#ifndef COMPAT_MACH
-#define	GAPM16CODE_SEL	7
-#else
+#define GCPU_SEL	6	/* per-CPU segment */
 #define	GMACHCALLS_SEL	7	/* Darwin (mach trap) system call gate */
-#endif
-#define	GAPMDATA_SEL	8
-#define	GBIOSCODE_SEL	9
-#define	GBIOSDATA_SEL	10
-#define GPNPBIOSCODE_SEL 11
-#define GPNPBIOSDATA_SEL 12
-#define GPNPBIOSSCRATCH_SEL 13
-#define GPNPBIOSTRAMP_SEL 14
-#define	NGDT		15
+#define GEXTBIOSDATA_SEL 8	/* magic to catch BIOS refs to EBDA */
+#define	GAPM32CODE_SEL	9	/* 3 APM segments must be consecutive */
+#define	GAPM16CODE_SEL	10	/* and in the specified order: code32 */
+#define	GAPMDATA_SEL	11	/* code16 and then data per APM spec */
+#define	GBIOSCODE_SEL	12
+#define	GBIOSDATA_SEL	13
+#define GPNPBIOSCODE_SEL 14
+#define GPNPBIOSDATA_SEL 15
+#define GPNPBIOSSCRATCH_SEL 16
+#define GPNPBIOSTRAMP_SEL 17
+#define	NGDT		18
 
 /*
  * Entries in the Local Descriptor Table (LDT)

	For the sommerfeld_i386_mp_1 branch:

Index: segments.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/include/segments.h,v
retrieving revision 1.30.2.4
diff -u -r1.30.2.4 segments.h
--- segments.h	2001/12/29 23:31:08	1.30.2.4
+++ segments.h	2002/01/20 03:23:36
@@ -221,7 +221,19 @@
 #define	NRSVIDT	32		/* reserved entries for cpu exceptions */
 
 /*
- * Entries in the Global Descriptor Table (GDT)
+ * Entries in the Global Descriptor Table (GDT).
+ *
+ * NB: If you change GBIOSCODE/GBIOSDATA, you *must* rebuild arch/i386/
+ * bioscall/biostramp.inc, as that relies on GBIOSCODE/GBIOSDATA and a
+ * normal kernel build does not rebuild it (it's merely included whole-
+ * sale from i386/bioscall.s)
+ * 
+ * Also, note that the GEXTBIOSDATA_SEL selector is special, as it maps 
+ * to the value 0x0040 (when created as a KPL global selector).  Some 
+ * Some BIOSes reference the extended BIOS data area at segment 0040 in 
+ * a non-relocatable fashion (even when in protected mode); mapping the
+ * zero page via the GEXTBIOSDATA_SEL allows these buggy BIOSes to continue
+ * to work under NetBSD.
  */
 #define	GNULL_SEL	0	/* Null descriptor */
 #define	GCODE_SEL	1	/* Kernel code descriptor */
@@ -229,21 +241,19 @@
 #define	GLDT_SEL	3	/* Default LDT descriptor */
 #define	GUCODE_SEL	4	/* User code descriptor */
 #define	GUDATA_SEL	5	/* User data descriptor */
-#define	GAPM32CODE_SEL	6
-#ifndef COMPAT_MACH
-#define	GAPM16CODE_SEL	7
-#else
+#define GCPU_SEL	6	/* per-CPU segment */
 #define	GMACHCALLS_SEL	7	/* Darwin (mach trap) system call gate */
-#endif
-#define	GAPMDATA_SEL	8
-#define	GBIOSCODE_SEL	9
-#define	GBIOSDATA_SEL	10
-#define GPNPBIOSCODE_SEL 11
-#define GPNPBIOSDATA_SEL 12
-#define GPNPBIOSSCRATCH_SEL 13
-#define GPNPBIOSTRAMP_SEL 14
-#define GCPU_SEL	15	/* per-CPU segment */
-#define	NGDT		16
+#define GEXTBIOSDATA_SEL 8	/* magic to catch BIOS refs to EBDA */
+#define	GAPM32CODE_SEL	9	/* 3 APM segments must be consecutive */
+#define	GAPM16CODE_SEL	10	/* and in the specified order: code32 */
+#define	GAPMDATA_SEL	11	/* code16 and then data per APM spec */
+#define	GBIOSCODE_SEL	12
+#define	GBIOSDATA_SEL	13
+#define GPNPBIOSCODE_SEL 14
+#define GPNPBIOSDATA_SEL 15
+#define GPNPBIOSSCRATCH_SEL 16
+#define GPNPBIOSTRAMP_SEL 17
+#define	NGDT		18
 
 /*
  * Entries in the Local Descriptor Table (LDT)
----
Rafal Boni                                                   rafal@mediaone.net