linux-arch.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* x86 setup code rewrite in C
@ 2007-07-10  2:51 H. Peter Anvin
       [not found] ` <2034f71d414def30de582fb59573295cadbdabb4.1184032748.git.hpa@zytor.com>
                   ` (3 more replies)
  0 siblings, 4 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm

This patch set replaces the x86 setup code, which is currently all in
assembly, with a version written in C, using the ".code16gcc" feature
of binutils (which has been present since at least 2001.)

The new code is vastly easier to read, and, I hope, debug.  It should
be noted that I found a fair number of minor bugs while going through
this code, and have attempted to correct them.

In the process of doing so, it introduces several cleanups, in
particular:

- Obsoletes the hd_info field in the boot_params structure; they are
  only ever used for ST-506 (pre-IDE) drives and are pretty much
  guaranteed to be wrong on current BIOSes;
- Unifies the CPU feature bits between i386 and x86-64.  In the
  future, it should be possible to use arch/i386/boot/cpucheck.c to do
  the post-invocation CPU check currently done in
  arch/x86_64/kernel/trampoline.S, although this patch set doesn't
  introduce that change.
- boot_params is now a proper structure.

This code has been tested in -mm since early in the 2.6.22 cycle.

 arch/i386/boot/bootsect.S                     |   98 -
 arch/i386/boot/edd.S                          |  231 --
 arch/i386/boot/setup.S                        | 1075 -------------
 arch/i386/boot/video.S                        | 2043 --------------------------
 arch/i386/kernel/verify_cpu.S                 |   94 -
 arch/x86_64/boot/bootsect.S                   |   98 -
 arch/x86_64/boot/install.sh                   |    2
 arch/x86_64/boot/mtools.conf.in               |   17
 arch/x86_64/boot/setup.S                      |  826 ----------
 arch/x86_64/boot/tools/build.c                |  185 --
 b/Documentation/i386/zero-page.txt            |    1
 b/MAINTAINERS                                 |    4
 b/arch/i386/Kconfig.cpu                       |    6
 b/arch/i386/boot/Makefile                     |   46
 b/arch/i386/boot/a20.c                        |  161 ++
 b/arch/i386/boot/apm.c                        |   97 +
 b/arch/i386/boot/bitops.h                     |   45
 b/arch/i386/boot/boot.h                       |  290 +++
 b/arch/i386/boot/cmdline.c                    |   97 +
 b/arch/i386/boot/code16gcc.h                  |    9
 b/arch/i386/boot/compressed/Makefile          |    7
 b/arch/i386/boot/compressed/head.S            |    6
 b/arch/i386/boot/copy.S                       |  101 +
 b/arch/i386/boot/cpu.c                        |   69
 b/arch/i386/boot/cpucheck.c                   |  267 +++
 b/arch/i386/boot/edd.c                        |  196 ++
 b/arch/i386/boot/header.S                     |  283 +++
 b/arch/i386/boot/main.c                       |  161 ++
 b/arch/i386/boot/mca.c                        |   43
 b/arch/i386/boot/memory.c                     |   99 +
 b/arch/i386/boot/pm.c                         |  170 ++
 b/arch/i386/boot/pmjump.S                     |   54
 b/arch/i386/boot/printf.c                     |  331 ++++
 b/arch/i386/boot/setup.ld                     |   54
 b/arch/i386/boot/string.c                     |   34
 b/arch/i386/boot/tools/build.c                |  160 --
 b/arch/i386/boot/tty.c                        |  112 +
 b/arch/i386/boot/version.c                    |   23
 b/arch/i386/boot/vesa.h                       |   79 +
 b/arch/i386/boot/video-bios.c                 |  125 +
 b/arch/i386/boot/video-vesa.c                 |  284 +++
 b/arch/i386/boot/video-vga.c                  |  260 +++
 b/arch/i386/boot/video.c                      |  456 +++++
 b/arch/i386/boot/video.h                      |  145 +
 b/arch/i386/boot/voyager.c                    |   46
 b/arch/i386/kernel/cpu/Makefile               |    2
 b/arch/i386/kernel/cpu/addon_cpuid_features.c |   50
 b/arch/i386/kernel/cpu/common.c               |    2
 b/arch/i386/kernel/cpu/proc.c                 |   21
 b/arch/i386/kernel/e820.c                     |    2
 b/arch/i386/kernel/setup.c                    |   12
 b/arch/x86_64/Kconfig                         |    4
 b/arch/x86_64/boot/Makefile                   |  136 -
 b/arch/x86_64/boot/compressed/Makefile        |    9
 b/arch/x86_64/boot/compressed/head.S          |    6
 b/arch/x86_64/kernel/Makefile                 |    2
 b/arch/x86_64/kernel/setup.c                  |   21
 b/arch/x86_64/kernel/verify_cpu.S             |   22
 b/drivers/ide/legacy/hd.c                     |   73
 b/include/asm-i386/boot.h                     |    6
 b/include/asm-i386/bootparam.h                |   85 +
 b/include/asm-i386/cpufeature.h               |   26
 b/include/asm-i386/e820.h                     |   14
 b/include/asm-i386/processor.h                |    1
 b/include/asm-i386/required-features.h        |   39
 b/include/asm-i386/setup.h                    |   10
 b/include/asm-x86_64/alternative.h            |   68
 b/include/asm-x86_64/boot.h                   |   16
 b/include/asm-x86_64/bootparam.h              |    1
 b/include/asm-x86_64/cpufeature.h             |  115 -
 b/include/asm-x86_64/e820.h                   |    6
 b/include/asm-x86_64/processor.h              |    3
 b/include/asm-x86_64/required-features.h      |   46
 b/include/asm-x86_64/segment.h                |    8
 b/include/linux/edd.h                         |    4
 b/include/linux/screen_info.h                 |    9
 76 files changed, 4601 insertions(+), 5208 deletions(-)

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [x86 setup 01/33] x86 setup: MAINTAINERS: formally take responsibility for the i386 boot code
       [not found] ` <2034f71d414def30de582fb59573295cadbdabb4.1184032748.git.hpa@zytor.com>
@ 2007-07-10  2:51   ` H. Peter Anvin
       [not found]   ` <de4df4ebeb6ec1bf47d4adf19f6a388035e2bfec.1184032748.git.hpa@zytor.com>
                     ` (31 subsequent siblings)
  32 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Change MAINTAINERS to formally take responsibility for the i386 boot code.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 MAINTAINERS |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index df40a4e..7f92ce2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1750,8 +1750,8 @@ T:	http://www.harbaum.org/till/i2c_tiny_usb
 S:	Maintained
 
 i386 BOOT CODE
-P:	Riley H. Williams
-M:	Riley@Williams.Name
+P:	H. Peter Anvin
+M:	hpa@zytor.com
 L:	Linux-Kernel@vger.kernel.org
 S:	Maintained
 
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 02/33] hd.c: remove BIOS/CMOS queries
       [not found]   ` <de4df4ebeb6ec1bf47d4adf19f6a388035e2bfec.1184032748.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

An ST-506 disk these days is pretty much someone trying to pull ancient
data using an auxilliary controller.  Pulling data from the BIOS or CMOS
is just plain wrong, since it's likely to be the primary OS disk... and
would be user-entered data anyway.  Instead, require the user enters it
on the command line.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 drivers/ide/legacy/hd.c |   73 ++++++++---------------------------------------
 1 files changed, 12 insertions(+), 61 deletions(-)

diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index 45ed035..9d7d8aa 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -718,74 +718,25 @@ static int __init hd_init(void)
 	device_timer.function = hd_times_out;
 	blk_queue_hardsect_size(hd_queue, 512);
 
-#ifdef __i386__
 	if (!NR_HD) {
-		extern struct drive_info drive_info;
-		unsigned char *BIOS = (unsigned char *) &drive_info;
-		unsigned long flags;
-		int cmos_disks;
-
-		for (drive=0 ; drive<2 ; drive++) {
-			hd_info[drive].cyl = *(unsigned short *) BIOS;
-			hd_info[drive].head = *(2+BIOS);
-			hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
-			hd_info[drive].ctl = *(8+BIOS);
-			hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
-			hd_info[drive].sect = *(14+BIOS);
-#ifdef does_not_work_for_everybody_with_scsi_but_helps_ibm_vp
-			if (hd_info[drive].cyl && NR_HD == drive)
-				NR_HD++;
-#endif
-			BIOS += 16;
-		}
-
-	/*
-		We query CMOS about hard disks : it could be that 
-		we have a SCSI/ESDI/etc controller that is BIOS
-		compatible with ST-506, and thus showing up in our
-		BIOS table, but not register compatible, and therefore
-		not present in CMOS.
-
-		Furthermore, we will assume that our ST-506 drives
-		<if any> are the primary drives in the system, and 
-		the ones reflected as drive 1 or 2.
-
-		The first drive is stored in the high nibble of CMOS
-		byte 0x12, the second in the low nibble.  This will be
-		either a 4 bit drive type or 0xf indicating use byte 0x19 
-		for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.
-
-		Needless to say, a non-zero value means we have 
-		an AT controller hard disk for that drive.
-
-		Currently the rtc_lock is a bit academic since this
-		driver is non-modular, but someday... ?         Paul G.
-	*/
-
-		spin_lock_irqsave(&rtc_lock, flags);
-		cmos_disks = CMOS_READ(0x12);
-		spin_unlock_irqrestore(&rtc_lock, flags);
-
-		if (cmos_disks & 0xf0) {
-			if (cmos_disks & 0x0f)
-				NR_HD = 2;
-			else
-				NR_HD = 1;
-		}
-	}
-#endif /* __i386__ */
-#ifdef __arm__
-	if (!NR_HD) {
-		/* We don't know anything about the drive.  This means
+		/*
+		 * We don't know anything about the drive.  This means
 		 * that you *MUST* specify the drive parameters to the
 		 * kernel yourself.
+		 *
+		 * If we were on an i386, we used to read this info from
+		 * the BIOS or CMOS.  This doesn't work all that well,
+		 * since this assumes that this is a primary or secondary
+		 * drive, and if we're using this legacy driver, it's
+		 * probably an auxilliary controller added to recover
+		 * legacy data off an ST-506 drive.  Either way, it's
+		 * definitely safest to have the user explicitly specify
+		 * the information.
 		 */
 		printk("hd: no drives specified - use hd=cyl,head,sectors"
 			" on kernel command line\n");
-	}
-#endif
-	if (!NR_HD)
 		goto out;
+	}
 
 	for (drive=0 ; drive < NR_HD ; drive++) {
 		struct gendisk *disk = alloc_disk(64);
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 03/33] include/asm-i386/boot.h: This is <asm/boot.h>, not <linux/boot.h>
       [not found]   ` <38825725eb2e4aac1dd8e312460c5c239466b39a.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

include/asm-i386/boot.h incorrectly has the multiple include guards
as _LINUX_BOOT_H instead of _ASM_BOOT_H.  Fix.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 include/asm-i386/boot.h |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/asm-i386/boot.h b/include/asm-i386/boot.h
index bd024ab..ed8affb 100644
--- a/include/asm-i386/boot.h
+++ b/include/asm-i386/boot.h
@@ -1,5 +1,5 @@
-#ifndef _LINUX_BOOT_H
-#define _LINUX_BOOT_H
+#ifndef _ASM_BOOT_H
+#define _ASM_BOOT_H
 
 /* Don't touch these, unless you really know what you're doing. */
 #define DEF_INITSEG	0x9000
@@ -17,4 +17,4 @@
 				+ (CONFIG_PHYSICAL_ALIGN - 1)) \
 				& ~(CONFIG_PHYSICAL_ALIGN - 1))
 
-#endif /* _LINUX_BOOT_H */
+#endif /* _ASM_BOOT_H */
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 04/33] Unify the CPU features vectors between i386 and x86-64
       [not found]   ` <62f9b07039d6bef798882977f3c8986fc2d2c6c6.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Unify the handling of the CPU features vectors between i386 and x86-64.
This also adopts the collapsing of features which are required at
compile-time into constant tests from x86-64 to i386.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/kernel/cpu/proc.c            |   15 +++--
 arch/i386/kernel/verify_cpu.S          |   12 ++--
 arch/x86_64/kernel/setup.c             |   13 ++--
 arch/x86_64/kernel/verify_cpu.S        |   22 +-----
 include/asm-i386/cpufeature.h          |   17 +++--
 include/asm-i386/required-features.h   |   38 ++++++++---
 include/asm-x86_64/alternative.h       |   68 ++++++++++---------
 include/asm-x86_64/cpufeature.h        |  115 +++----------------------------
 include/asm-x86_64/processor.h         |    2 -
 include/asm-x86_64/required-features.h |   45 ++++++++++++
 10 files changed, 159 insertions(+), 188 deletions(-)
 create mode 100644 include/asm-x86_64/required-features.h

diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index 89d91e6..ed73091 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -29,7 +29,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
-		NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext", "3dnow",
+		NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm",
+		"3dnowext", "3dnow",
 
 		/* Transmeta-defined */
 		"recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
@@ -40,8 +41,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 		/* Other (Linux-defined) */
 		"cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
 		NULL, NULL, NULL, NULL,
-		"constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL,
-		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		"constant_tsc", "up", NULL, "arch_perfmon",
+		"pebs", "bts", NULL, "sync_rdtsc",
+		"rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
 		/* Intel-defined (#2) */
@@ -57,9 +59,10 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
 		/* AMD-defined (#2) */
-		"lahf_lm", "cmp_legacy", "svm", "extapic", "cr8legacy", "abm",
-		"sse4a", "misalignsse",
-		"3dnowprefetch", "osvw", "ibs", NULL, NULL, NULL, NULL, NULL,
+		"lahf_lm", "cmp_legacy", "svm", "extapic", "cr8_legacy",
+		"altmovcr8", "abm", "sse4a",
+		"misalignsse", "3dnowprefetch",
+		"osvw", "ibs", NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	};
diff --git a/arch/i386/kernel/verify_cpu.S b/arch/i386/kernel/verify_cpu.S
index f1d1eac..3efc5c1 100644
--- a/arch/i386/kernel/verify_cpu.S
+++ b/arch/i386/kernel/verify_cpu.S
@@ -20,7 +20,7 @@ verify_cpu:
 	testl	$(1<<18),%eax
 	jz	bad
 #endif
-#if REQUIRED_MASK1 != 0
+#if REQUIRED_MASK0 != 0
 	pushfl				# standard way to check for cpuid
 	popl	%eax
 	movl	%eax,%ebx
@@ -39,14 +39,14 @@ verify_cpu:
 	pushfl
 	popl	%eax
 	cmpl	%eax,%ebx
-	jz	bad			# REQUIRED_MASK1 != 0 requires CPUID
+	jz	bad			# REQUIRED_MASK0 != 0 requires CPUID
 
 	movl	$0x0,%eax		# See if cpuid 1 is implemented
 	cpuid
 	cmpl	$0x1,%eax
 	jb	bad			# no cpuid 1
 
-#if REQUIRED_MASK1 & NEED_CMPXCHG64
+#if REQUIRED_MASK0 & NEED_CMPXCHG64
 	/* Some VIA C3s need magic MSRs to enable CX64. Do this here */
 	cmpl	$0x746e6543,%ebx	# Cent
 	jne	1f
@@ -79,10 +79,10 @@ verify_cpu:
 #error	add proper model checking here
 #endif
 
-	andl	$REQUIRED_MASK1,%edx
-	xorl	$REQUIRED_MASK1,%edx
+	andl	$REQUIRED_MASK0,%edx
+	xorl	$REQUIRED_MASK0,%edx
 	jnz	bad
-#endif /* REQUIRED_MASK1 */
+#endif /* REQUIRED_MASK0 */
 
 	popfl
 	xor	%eax,%eax
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index eb6524f..dc7630d 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -931,7 +931,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 	        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
 	        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
 	        "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
-	        "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
+	        "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
 
 		/* AMD-defined */
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -947,10 +947,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
 		/* Other (Linux-defined) */
-		"cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL,
-		"constant_tsc", NULL, NULL,
-		"up", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		"cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
+		NULL, NULL, NULL, NULL,
+		"constant_tsc", "up", NULL, "arch_perfmon",
+		"pebs", "bts", NULL, "sync_rdtsc",
+		"rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
 		/* Intel-defined (#2) */
@@ -961,7 +962,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 
 		/* VIA/Cyrix/Centaur-defined */
 		NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
-		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		"ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
diff --git a/arch/x86_64/kernel/verify_cpu.S b/arch/x86_64/kernel/verify_cpu.S
index e035f59..45b6f8a 100644
--- a/arch/x86_64/kernel/verify_cpu.S
+++ b/arch/x86_64/kernel/verify_cpu.S
@@ -37,20 +37,6 @@ verify_cpu:
 	pushl	$0			# Kill any dangerous flags
 	popfl
 
-	/* minimum CPUID flags for x86-64 as defined by AMD */
-#define M(x) (1<<(x))
-#define M2(a,b) M(a)|M(b)
-#define M4(a,b,c,d) M(a)|M(b)|M(c)|M(d)
-
-#define SSE_MASK \
-	(M2(X86_FEATURE_XMM,X86_FEATURE_XMM2))
-#define REQUIRED_MASK1 \
-	(M4(X86_FEATURE_FPU,X86_FEATURE_PSE,X86_FEATURE_TSC,X86_FEATURE_MSR)|\
-	 M4(X86_FEATURE_PAE,X86_FEATURE_CX8,X86_FEATURE_PGE,X86_FEATURE_CMOV)|\
-	 M(X86_FEATURE_FXSR))
-#define REQUIRED_MASK2 \
-	(M(X86_FEATURE_LM - 32))
-
 	pushfl				# standard way to check for cpuid
 	popl	%eax
 	movl	%eax,%ebx
@@ -79,8 +65,8 @@ verify_cpu:
 verify_cpu_noamd:
 	movl    $0x1,%eax		# Does the cpu have what it takes
 	cpuid
-	andl	$REQUIRED_MASK1,%edx
-	xorl	$REQUIRED_MASK1,%edx
+	andl	$REQUIRED_MASK0,%edx
+	xorl	$REQUIRED_MASK0,%edx
 	jnz	verify_cpu_no_longmode
 
 	movl    $0x80000000,%eax	# See if extended cpuid is implemented
@@ -90,8 +76,8 @@ verify_cpu_noamd:
 
 	movl    $0x80000001,%eax	# Does the cpu have what it takes
 	cpuid
-	andl    $REQUIRED_MASK2,%edx
-	xorl    $REQUIRED_MASK2,%edx
+	andl    $REQUIRED_MASK1,%edx
+	xorl    $REQUIRED_MASK1,%edx
 	jnz     verify_cpu_no_longmode
 
 verify_cpu_sse_test:
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
index f514e90..7ea5f4a 100644
--- a/include/asm-i386/cpufeature.h
+++ b/include/asm-i386/cpufeature.h
@@ -81,6 +81,7 @@
 #define X86_FEATURE_BTS		(3*32+13)  /* Branch Trace Store */
 #define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */
 #define X86_FEATURE_SYNC_RDTSC	(3*32+15)  /* RDTSC synchronizes the CPU */
+#define X86_FEATURE_REP_GOOD   (3*32+16) /* rep microcode works well on this CPU */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
@@ -108,11 +109,17 @@
 #define X86_FEATURE_LAHF_LM	(6*32+ 0) /* LAHF/SAHF in long mode */
 #define X86_FEATURE_CMP_LEGACY	(6*32+ 1) /* If yes HyperThreading not valid */
 
-#define cpu_has(c, bit)					\
-	((__builtin_constant_p(bit) && (bit) < 32 && 	\
-		(1UL << (bit)) & REQUIRED_MASK1) ?	\
-		1 : 					\
-	test_bit(bit, (c)->x86_capability))
+#define cpu_has(c, bit)							\
+	(__builtin_constant_p(bit) &&					\
+	 ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) ||	\
+	   (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) ||	\
+	   (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) ||	\
+	   (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) ||	\
+	   (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) ||	\
+	   (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) ||	\
+	   (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) )	\
+	  ? 1 :								\
+	  test_bit(bit, (c)->x86_capability))
 #define boot_cpu_has(bit)	cpu_has(&boot_cpu_data, bit)
 
 #define cpu_has_fpu		boot_cpu_has(X86_FEATURE_FPU)
diff --git a/include/asm-i386/required-features.h b/include/asm-i386/required-features.h
index 9db866c..a9c3b11 100644
--- a/include/asm-i386/required-features.h
+++ b/include/asm-i386/required-features.h
@@ -3,32 +3,52 @@
 
 /* Define minimum CPUID feature set for kernel These bits are checked
    really early to actually display a visible error message before the
-   kernel dies.  Only add word 0 bits here
+   kernel dies.  Make sure to assign features to the proper mask!
 
    Some requirements that are not in CPUID yet are also in the
-   CONFIG_X86_MINIMUM_CPU mode which is checked too.
+   CONFIG_X86_MINIMUM_CPU_FAMILY which is checked too.
 
    The real information is in arch/i386/Kconfig.cpu, this just converts
    the CONFIGs into a bitmask */
 
+#ifndef CONFIG_MATH_EMULATION
+# define NEED_FPU	(1<<(X86_FEATURE_FPU & 31))
+#else
+# define NEED_FPU	0
+#endif
+
 #ifdef CONFIG_X86_PAE
-#define NEED_PAE	(1<<X86_FEATURE_PAE)
+# define NEED_PAE	(1<<(X86_FEATURE_PAE & 31))
 #else
-#define NEED_PAE	0
+# define NEED_PAE	0
 #endif
 
 #ifdef CONFIG_X86_CMOV
-#define NEED_CMOV	(1<<X86_FEATURE_CMOV)
+# define NEED_CMOV	(1<<(X86_FEATURE_CMOV & 31))
 #else
-#define NEED_CMOV	0
+# define NEED_CMOV	0
 #endif
 
 #ifdef CONFIG_X86_CMPXCHG64
-#define NEED_CMPXCHG64  (1<<X86_FEATURE_CX8)
+# define NEED_CX8	(1<<(X86_FEATURE_CX8 & 31))
+#else
+# define NEED_CX8	0
+#endif
+
+#define REQUIRED_MASK0	(NEED_FPU|NEED_PAE|NEED_CMOV|NEED_CX8)
+
+#ifdef CONFIG_X86_USE_3DNOW
+# define NEED_3DNOW	(1<<(X86_FEATURE_3DNOW & 31))
 #else
-#define NEED_CMPXCHG64  0
+# define NEED_3DNOW	0
 #endif
 
-#define REQUIRED_MASK1	(NEED_PAE|NEED_CMOV|NEED_CMPXCHG64)
+#define REQUIRED_MASK1	(NEED_3DNOW)
+
+#define REQUIRED_MASK2	0
+#define REQUIRED_MASK3	0
+#define REQUIRED_MASK4	0
+#define REQUIRED_MASK5	0
+#define REQUIRED_MASK6	0
 
 #endif
diff --git a/include/asm-x86_64/alternative.h b/include/asm-x86_64/alternative.h
index a094276..eea7aec 100644
--- a/include/asm-x86_64/alternative.h
+++ b/include/asm-x86_64/alternative.h
@@ -5,6 +5,41 @@
 
 #include <linux/types.h>
 #include <linux/stddef.h>
+
+/*
+ * Alternative inline assembly for SMP.
+ *
+ * The LOCK_PREFIX macro defined here replaces the LOCK and
+ * LOCK_PREFIX macros used everywhere in the source tree.
+ *
+ * SMP alternatives use the same data structures as the other
+ * alternatives and the X86_FEATURE_UP flag to indicate the case of a
+ * UP system running a SMP kernel.  The existing apply_alternatives()
+ * works fine for patching a SMP kernel for UP.
+ *
+ * The SMP alternative tables can be kept after boot and contain both
+ * UP and SMP versions of the instructions to allow switching back to
+ * SMP at runtime, when hotplugging in a new CPU, which is especially
+ * useful in virtualized environments.
+ *
+ * The very common lock prefix is handled as special case in a
+ * separate table which is a pure address list without replacement ptr
+ * and size information.  That keeps the table sizes small.
+ */
+
+#ifdef CONFIG_SMP
+#define LOCK_PREFIX \
+		".section .smp_locks,\"a\"\n"	\
+		"  .align 8\n"			\
+		"  .quad 661f\n" /* address */	\
+		".previous\n"			\
+	       	"661:\n\tlock; "
+
+#else /* ! CONFIG_SMP */
+#define LOCK_PREFIX ""
+#endif
+
+/* This must be included *after* the definition of LOCK_PREFIX */
 #include <asm/cpufeature.h>
 
 struct alt_instr {
@@ -108,39 +143,6 @@ static inline void alternatives_smp_switch(int smp) {}
  */
 #define ASM_OUTPUT2(a, b) a, b
 
-/*
- * Alternative inline assembly for SMP.
- *
- * The LOCK_PREFIX macro defined here replaces the LOCK and
- * LOCK_PREFIX macros used everywhere in the source tree.
- *
- * SMP alternatives use the same data structures as the other
- * alternatives and the X86_FEATURE_UP flag to indicate the case of a
- * UP system running a SMP kernel.  The existing apply_alternatives()
- * works fine for patching a SMP kernel for UP.
- *
- * The SMP alternative tables can be kept after boot and contain both
- * UP and SMP versions of the instructions to allow switching back to
- * SMP at runtime, when hotplugging in a new CPU, which is especially
- * useful in virtualized environments.
- *
- * The very common lock prefix is handled as special case in a
- * separate table which is a pure address list without replacement ptr
- * and size information.  That keeps the table sizes small.
- */
-
-#ifdef CONFIG_SMP
-#define LOCK_PREFIX \
-		".section .smp_locks,\"a\"\n"	\
-		"  .align 8\n"			\
-		"  .quad 661f\n" /* address */	\
-		".previous\n"			\
-	       	"661:\n\tlock; "
-
-#else /* ! CONFIG_SMP */
-#define LOCK_PREFIX ""
-#endif
-
 struct paravirt_patch;
 #ifdef CONFIG_PARAVIRT
 void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end);
diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h
index 0b3c686..8baefc3 100644
--- a/include/asm-x86_64/cpufeature.h
+++ b/include/asm-x86_64/cpufeature.h
@@ -7,115 +7,24 @@
 #ifndef __ASM_X8664_CPUFEATURE_H
 #define __ASM_X8664_CPUFEATURE_H
 
-#define NCAPINTS	7	/* N 32-bit words worth of info */
+#include <asm-i386/cpufeature.h>
 
-/* Intel-defined CPU features, CPUID level 0x00000001, word 0 */
-#define X86_FEATURE_FPU		(0*32+ 0) /* Onboard FPU */
-#define X86_FEATURE_VME		(0*32+ 1) /* Virtual Mode Extensions */
-#define X86_FEATURE_DE		(0*32+ 2) /* Debugging Extensions */
-#define X86_FEATURE_PSE 	(0*32+ 3) /* Page Size Extensions */
-#define X86_FEATURE_TSC		(0*32+ 4) /* Time Stamp Counter */
-#define X86_FEATURE_MSR		(0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
-#define X86_FEATURE_PAE		(0*32+ 6) /* Physical Address Extensions */
-#define X86_FEATURE_MCE		(0*32+ 7) /* Machine Check Architecture */
-#define X86_FEATURE_CX8		(0*32+ 8) /* CMPXCHG8 instruction */
-#define X86_FEATURE_APIC	(0*32+ 9) /* Onboard APIC */
-#define X86_FEATURE_SEP		(0*32+11) /* SYSENTER/SYSEXIT */
-#define X86_FEATURE_MTRR	(0*32+12) /* Memory Type Range Registers */
-#define X86_FEATURE_PGE		(0*32+13) /* Page Global Enable */
-#define X86_FEATURE_MCA		(0*32+14) /* Machine Check Architecture */
-#define X86_FEATURE_CMOV	(0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
-#define X86_FEATURE_PAT		(0*32+16) /* Page Attribute Table */
-#define X86_FEATURE_PSE36	(0*32+17) /* 36-bit PSEs */
-#define X86_FEATURE_PN		(0*32+18) /* Processor serial number */
-#define X86_FEATURE_CLFLSH	(0*32+19) /* Supports the CLFLUSH instruction */
-#define X86_FEATURE_DS		(0*32+21) /* Debug Store */
-#define X86_FEATURE_ACPI	(0*32+22) /* ACPI via MSR */
-#define X86_FEATURE_MMX		(0*32+23) /* Multimedia Extensions */
-#define X86_FEATURE_FXSR	(0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
-				          /* of FPU context), and CR4.OSFXSR available */
-#define X86_FEATURE_XMM		(0*32+25) /* Streaming SIMD Extensions */
-#define X86_FEATURE_XMM2	(0*32+26) /* Streaming SIMD Extensions-2 */
-#define X86_FEATURE_SELFSNOOP	(0*32+27) /* CPU self snoop */
-#define X86_FEATURE_HT		(0*32+28) /* Hyper-Threading */
-#define X86_FEATURE_ACC		(0*32+29) /* Automatic clock control */
-#define X86_FEATURE_IA64	(0*32+30) /* IA-64 processor */
-
-/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
-/* Don't duplicate feature flags which are redundant with Intel! */
-#define X86_FEATURE_SYSCALL	(1*32+11) /* SYSCALL/SYSRET */
-#define X86_FEATURE_MMXEXT	(1*32+22) /* AMD MMX extensions */
-#define X86_FEATURE_FXSR_OPT	(1*32+25) /* FXSR optimizations */
-#define X86_FEATURE_RDTSCP	(1*32+27) /* RDTSCP */
-#define X86_FEATURE_LM		(1*32+29) /* Long Mode (x86-64) */
-#define X86_FEATURE_3DNOWEXT	(1*32+30) /* AMD 3DNow! extensions */
-#define X86_FEATURE_3DNOW	(1*32+31) /* 3DNow! */
-
-/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
-#define X86_FEATURE_RECOVERY	(2*32+ 0) /* CPU in recovery mode */
-#define X86_FEATURE_LONGRUN	(2*32+ 1) /* Longrun power control */
-#define X86_FEATURE_LRTI	(2*32+ 3) /* LongRun table interface */
-
-/* Other features, Linux-defined mapping, word 3 */
-/* This range is used for feature bits which conflict or are synthesized */
-#define X86_FEATURE_CXMMX	(3*32+ 0) /* Cyrix MMX extensions */
-#define X86_FEATURE_K6_MTRR	(3*32+ 1) /* AMD K6 nonstandard MTRRs */
-#define X86_FEATURE_CYRIX_ARR	(3*32+ 2) /* Cyrix ARRs (= MTRRs) */
-#define X86_FEATURE_CENTAUR_MCR	(3*32+ 3) /* Centaur MCRs (= MTRRs) */
-#define X86_FEATURE_REP_GOOD	(3*32+ 4) /* rep microcode works well on this CPU */
-#define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */
-#define X86_FEATURE_SYNC_RDTSC  (3*32+6)  /* RDTSC syncs CPU core */
-#define X86_FEATURE_FXSAVE_LEAK (3*32+7)  /* FIP/FOP/FDP leaks through FXSAVE */
-#define X86_FEATURE_UP		(3*32+8) /* SMP kernel running on UP */
-#define X86_FEATURE_ARCH_PERFMON (3*32+9) /* Intel Architectural PerfMon */
-#define X86_FEATURE_PEBS	(3*32+10) /* Precise-Event Based Sampling */
-#define X86_FEATURE_BTS		(3*32+11) /* Branch Trace Store */
-
-/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
-#define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
-#define X86_FEATURE_MWAIT	(4*32+ 3) /* Monitor/Mwait support */
-#define X86_FEATURE_DSCPL	(4*32+ 4) /* CPL Qualified Debug Store */
-#define X86_FEATURE_EST		(4*32+ 7) /* Enhanced SpeedStep */
-#define X86_FEATURE_TM2		(4*32+ 8) /* Thermal Monitor 2 */
-#define X86_FEATURE_CID		(4*32+10) /* Context ID */
-#define X86_FEATURE_CX16	(4*32+13) /* CMPXCHG16B */
-#define X86_FEATURE_XTPR	(4*32+14) /* Send Task Priority Messages */
-
-/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
-#define X86_FEATURE_XSTORE	(5*32+ 2) /* on-CPU RNG present (xstore insn) */
-#define X86_FEATURE_XSTORE_EN	(5*32+ 3) /* on-CPU RNG enabled */
-#define X86_FEATURE_XCRYPT	(5*32+ 6) /* on-CPU crypto (xcrypt insn) */
-#define X86_FEATURE_XCRYPT_EN	(5*32+ 7) /* on-CPU crypto enabled */
-
-/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
-#define X86_FEATURE_LAHF_LM	(6*32+ 0) /* LAHF/SAHF in long mode */
-#define X86_FEATURE_CMP_LEGACY	(6*32+ 1) /* If yes HyperThreading not valid */
-
-#define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
-#define boot_cpu_has(bit)      test_bit(bit, boot_cpu_data.x86_capability)
-
-#define cpu_has_fpu            1
+#undef  cpu_has_vme
 #define cpu_has_vme            0
-#define cpu_has_de             1
-#define cpu_has_pse            1
-#define cpu_has_tsc            1
+
+#undef  cpu_has_pae
 #define cpu_has_pae            ___BUG___
-#define cpu_has_pge            1
-#define cpu_has_apic           boot_cpu_has(X86_FEATURE_APIC)
-#define cpu_has_mtrr           1
-#define cpu_has_mmx            1
-#define cpu_has_fxsr           1
-#define cpu_has_xmm            1
-#define cpu_has_xmm2           1
-#define cpu_has_xmm3           boot_cpu_has(X86_FEATURE_XMM3)
-#define cpu_has_ht             boot_cpu_has(X86_FEATURE_HT)
+
+#undef  cpu_has_mp
 #define cpu_has_mp             1 /* XXX */
+
+#undef  cpu_has_k6_mtrr
 #define cpu_has_k6_mtrr        0
+
+#undef  cpu_has_cyrix_arr
 #define cpu_has_cyrix_arr      0
+
+#undef  cpu_has_centaur_mcr
 #define cpu_has_centaur_mcr    0
-#define cpu_has_clflush	       boot_cpu_has(X86_FEATURE_CLFLSH)
-#define cpu_has_ds 	       boot_cpu_has(X86_FEATURE_DS)
-#define cpu_has_pebs 	       boot_cpu_has(X86_FEATURE_PEBS)
-#define cpu_has_bts 	       boot_cpu_has(X86_FEATURE_BTS)
 
 #endif /* __ASM_X8664_CPUFEATURE_H */
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
index 461ffe4..df64572 100644
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -368,8 +368,6 @@ static inline void sync_core(void)
 	asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
 } 
 
-#define cpu_has_fpu 1
-
 #define ARCH_HAS_PREFETCH
 static inline void prefetch(void *x) 
 { 
diff --git a/include/asm-x86_64/required-features.h b/include/asm-x86_64/required-features.h
new file mode 100644
index 0000000..262f315
--- /dev/null
+++ b/include/asm-x86_64/required-features.h
@@ -0,0 +1,45 @@
+#ifndef _ASM_REQUIRED_FEATURES_H
+#define _ASM_REQUIRED_FEATURES_H 1
+
+/* Define minimum CPUID feature set for kernel These bits are checked
+   really early to actually display a visible error message before the
+   kernel dies.  Make sure to assign features to the proper mask!
+
+   The real information is in arch/x86_64/Kconfig.cpu, this just converts
+   the CONFIGs into a bitmask */
+
+/* x86-64 baseline features */
+#define NEED_FPU	(1<<(X86_FEATURE_FPU & 31))
+#define NEED_PSE	(1<<(X86_FEATURE_PSE & 31))
+#define NEED_MSR	(1<<(X86_FEATURE_MSR & 31))
+#define NEED_PAE	(1<<(X86_FEATURE_PAE & 31))
+#define NEED_CX8	(1<<(X86_FEATURE_CX8 & 31))
+#define NEED_PGE	(1<<(X86_FEATURE_PGE & 31))
+#define NEED_FXSR	(1<<(X86_FEATURE_FXSR & 31))
+#define NEED_CMOV	(1<<(X86_FEATURE_CMOV & 31))
+#define NEED_XMM	(1<<(X86_FEATURE_XMM & 31))
+#define NEED_XMM2	(1<<(X86_FEATURE_XMM2 & 31))
+
+#define REQUIRED_MASK0	(NEED_FPU|NEED_PSE|NEED_MSR|NEED_PAE|\
+			 NEED_CX8|NEED_PGE|NEED_FXSR|NEED_CMOV|\
+			 NEED_XMM|NEED_XMM2)
+#define SSE_MASK	(NEED_XMM|NEED_XMM2)
+
+/* x86-64 baseline features */
+#define NEED_LM		(1<<(X86_FEATURE_LM & 31))
+
+#ifdef CONFIG_X86_USE_3DNOW
+# define NEED_3DNOW	(1<<(X86_FEATURE_3DNOW & 31))
+#else
+# define NEED_3DNOW	0
+#endif
+
+#define REQUIRED_MASK1	(NEED_LM|NEED_3DNOW)
+
+#define REQUIRED_MASK2	0
+#define REQUIRED_MASK3	0
+#define REQUIRED_MASK4	0
+#define REQUIRED_MASK5	0
+#define REQUIRED_MASK6	0
+
+#endif
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 05/33] Change CONFIG_X86_MINIMUM_CPU_MODEL to CONFIG_X86_MINIMUM_CPU_FAMILY
       [not found]   ` <8376b111bbf6bf6c8c884fabcb9c1844950737b0.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

CONFIG_X86_MINIMUM_CPU_MODEL, so change it to
CONFIG_X86_MINIMUM_CPU_FAMILY.  Also, the default minimum should be
3, not 0.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/Kconfig.cpu         |    6 +++---
 arch/i386/kernel/verify_cpu.S |    4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu
index 5c95ceb..9cbe76c 100644
--- a/arch/i386/Kconfig.cpu
+++ b/arch/i386/Kconfig.cpu
@@ -344,8 +344,8 @@ config X86_CMOV
 	depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
 	default y
 
-config X86_MINIMUM_CPU_MODEL
+config X86_MINIMUM_CPU_FAMILY
 	int
-	default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP
-	default "0"
+	default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK
+	default "3"
 
diff --git a/arch/i386/kernel/verify_cpu.S b/arch/i386/kernel/verify_cpu.S
index 3efc5c1..fff4aa6 100644
--- a/arch/i386/kernel/verify_cpu.S
+++ b/arch/i386/kernel/verify_cpu.S
@@ -9,7 +9,7 @@ verify_cpu:
 	pushl	$0			# Kill any dangerous flags
 	popfl
 
-#if CONFIG_X86_MINIMUM_CPU_MODEL >= 4
+#if CONFIG_X86_MINIMUM_CPU_FAMILY >= 4
 	pushfl
 	pop	%eax
 	orl	$(1<<18),%eax		# try setting AC
@@ -75,7 +75,7 @@ verify_cpu:
 	movl    $0x1,%eax		# Does the cpu have what it takes
 	cpuid
 
-#if CONFIG_X86_MINIMUM_CPU_MODEL > 4
+#if CONFIG_X86_MINIMUM_CPU_FAMILY > 4
 #error	add proper model checking here
 #endif
 
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 06/33] Clean up struct screen_info (<linux/screen_info.h>)
       [not found]   ` <06a26dd135e1fc3b7f8b238c5b1bc8404d23acac.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

struct screen_info has unaligned members, it needs to be packed.
In the process, fix the naming of some of the members, which don't
belong in this structure but are part of it anyway.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 include/linux/screen_info.h |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
index b02308e..3ee412b 100644
--- a/include/linux/screen_info.h
+++ b/include/linux/screen_info.h
@@ -10,7 +10,7 @@
 struct screen_info {
 	u8  orig_x;		/* 0x00 */
 	u8  orig_y;		/* 0x01 */
-	u16 dontuse1;		/* 0x02 -- EXT_MEM_K sits here */
+	u16 ext_mem_k;		/* 0x02 */
 	u16 orig_video_page;	/* 0x04 */
 	u8  orig_video_mode;	/* 0x06 */
 	u8  orig_video_cols;	/* 0x07 */
@@ -27,7 +27,7 @@ struct screen_info {
 	u16 lfb_depth;		/* 0x16 */
 	u32 lfb_base;		/* 0x18 */
 	u32 lfb_size;		/* 0x1c */
-	u16 dontuse2, dontuse3;	/* 0x20 -- CL_MAGIC and CL_OFFSET here */
+	u16 cl_magic, cl_offset; /* 0x20 */
 	u16 lfb_linelength;	/* 0x24 */
 	u8  red_size;		/* 0x26 */
 	u8  red_pos;		/* 0x27 */
@@ -42,9 +42,8 @@ struct screen_info {
 	u16 pages;		/* 0x32 */
 	u16 vesa_attributes;	/* 0x34 */
 	u32 capabilities;       /* 0x36 */
-				/* 0x3a -- 0x3b reserved for future expansion */
-				/* 0x3c -- 0x3f micro stack for relocatable kernels */
-};
+	u8  _reserved[6];	/* 0x3a */
+} __attribute__((packed));
 
 extern struct screen_info screen_info;
 
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 07/33] Use a new CPU feature word to cover all Intel features that are spread around
       [not found]   ` <32e7eb05f31e6fbff33ecce6580ee4f7bdf38fef.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: Venki Pallipadi, H. Peter Anvin

From: Venki Pallipadi <venkatesh.pallipadi@intel.com>

in different CPUID leafs like 0x5, 0x6 and 0xA. Make this
feature detection code common across i386 and x86_64.

Display Intel Dynamic Acceleration feature in /proc/cpuinfo. This feature
will be enabled automatically by current acpi-cpufreq driver.

Refer to Intel Software Developer's Manual for more details about the feature.

Thanks to hpa (H Peter Anvin) for the making the actual code detecting the
scattered features data-driven.

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/kernel/cpu/Makefile               |    2 +-
 arch/i386/kernel/cpu/addon_cpuid_features.c |   50 +++++++++++++++++++++++++++
 arch/i386/kernel/cpu/common.c               |    2 +
 arch/i386/kernel/cpu/proc.c                 |    6 +++
 arch/x86_64/kernel/Makefile                 |    2 +
 arch/x86_64/kernel/setup.c                  |    8 ++++
 include/asm-i386/cpufeature.h               |   11 +++++-
 include/asm-i386/processor.h                |    1 +
 include/asm-i386/required-features.h        |    1 +
 include/asm-x86_64/processor.h              |    1 +
 include/asm-x86_64/required-features.h      |    1 +
 11 files changed, 82 insertions(+), 3 deletions(-)
 create mode 100644 arch/i386/kernel/cpu/addon_cpuid_features.c

diff --git a/arch/i386/kernel/cpu/Makefile b/arch/i386/kernel/cpu/Makefile
index 74f27a4..0b6a855 100644
--- a/arch/i386/kernel/cpu/Makefile
+++ b/arch/i386/kernel/cpu/Makefile
@@ -8,7 +8,7 @@ obj-y	+=	amd.o
 obj-y	+=	cyrix.o
 obj-y	+=	centaur.o
 obj-y	+=	transmeta.o
-obj-y	+=	intel.o intel_cacheinfo.o
+obj-y	+=	intel.o intel_cacheinfo.o addon_cpuid_features.o
 obj-y	+=	rise.o
 obj-y	+=	nexgen.o
 obj-y	+=	umc.o
diff --git a/arch/i386/kernel/cpu/addon_cpuid_features.c b/arch/i386/kernel/cpu/addon_cpuid_features.c
new file mode 100644
index 0000000..3e91d3e
--- /dev/null
+++ b/arch/i386/kernel/cpu/addon_cpuid_features.c
@@ -0,0 +1,50 @@
+
+/*
+ *	Routines to indentify additional cpu features that are scattered in
+ *	cpuid space.
+ */
+
+#include <linux/cpu.h>
+
+#include <asm/processor.h>
+
+struct cpuid_bit {
+	u16 feature;
+	u8 reg;
+	u8 bit;
+	u32 level;
+};
+
+enum cpuid_regs {
+	CR_EAX = 0,
+	CR_ECX,
+	CR_EDX,
+	CR_EBX
+};
+
+void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
+{
+	u32 max_level;
+	u32 regs[4];
+	const struct cpuid_bit *cb;
+
+	static const struct cpuid_bit cpuid_bits[] = {
+		{ X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
+		{ 0, 0, 0, 0 }
+	};
+
+	for (cb = cpuid_bits; cb->feature; cb++) {
+
+		/* Verify that the level is valid */
+		max_level = cpuid_eax(cb->level & 0xffff0000);
+		if (max_level < cb->level ||
+		    max_level > (cb->level | 0xffff))
+			continue;
+
+		cpuid(cb->level, &regs[CR_EAX], &regs[CR_EBX],
+			&regs[CR_ECX], &regs[CR_EDX]);
+
+		if (regs[cb->reg] & (1 << cb->bit))
+			set_bit(cb->feature, c->x86_capability);
+	}
+}
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 794d593..e5419a9 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -353,6 +353,8 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
 			if ( xlvl >= 0x80000004 )
 				get_model_name(c); /* Default name */
 		}
+
+		init_scattered_cpuid_features(c);
 	}
 
 	early_intel_workaround(c);
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index ed73091..1e31b6c 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -65,6 +65,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 		"osvw", "ibs", NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+		/* Auxiliary (Linux-defined) */
+		"ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	};
 	static const char * const x86_power_flags[] = {
 		"ts",	/* temperature sensor */
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index de1de8a..47f1dc3 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_PCI)		+= early-quirks.o
 
 obj-y				+= topology.o
 obj-y				+= intel_cacheinfo.o
+obj-y				+= addon_cpuid_features.o
 obj-y				+= pcspeaker.o
 
 CFLAGS_vsyscall.o		:= $(PROFILING) -g0
@@ -55,6 +56,7 @@ cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  += ../../i386/kernel/cpuid.o
 topology-y                     += ../../i386/kernel/topology.o
 microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../i386/kernel/microcode.o
 intel_cacheinfo-y		+= ../../i386/kernel/cpu/intel_cacheinfo.o
+addon_cpuid_features-y		+= ../../i386/kernel/cpu/addon_cpuid_features.o
 quirks-y			+= ../../i386/kernel/quirks.o
 i8237-y				+= ../../i386/kernel/i8237.o
 msr-$(subst m,y,$(CONFIG_X86_MSR))  += ../../i386/kernel/msr.o
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index dc7630d..33ef718 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -846,6 +846,8 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 			c->x86_capability[2] = cpuid_edx(0x80860001);
 	}
 
+	init_scattered_cpuid_features(c);
+
 	c->apicid = phys_pkg_id(0);
 
 	/*
@@ -973,6 +975,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 		"osvw", "ibs", NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+		/* Auxiliary (Linux-defined) */
+		"ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	};
 	static char *x86_power_flags[] = { 
 		"ts",	/* temperature sensor */
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
index 7ea5f4a..c961c03 100644
--- a/include/asm-i386/cpufeature.h
+++ b/include/asm-i386/cpufeature.h
@@ -12,7 +12,7 @@
 #endif
 #include <asm/required-features.h>
 
-#define NCAPINTS	7	/* N 32-bit words worth of info */
+#define NCAPINTS	8	/* N 32-bit words worth of info */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
 #define X86_FEATURE_FPU		(0*32+ 0) /* Onboard FPU */
@@ -109,6 +109,12 @@
 #define X86_FEATURE_LAHF_LM	(6*32+ 0) /* LAHF/SAHF in long mode */
 #define X86_FEATURE_CMP_LEGACY	(6*32+ 1) /* If yes HyperThreading not valid */
 
+/*
+ * Auxiliary flags: Linux defined - For features scattered in various
+ * CPUID levels like 0x6, 0xA etc
+ */
+#define X86_FEATURE_IDA		(7*32+ 0) /* Intel Dynamic Acceleration */
+
 #define cpu_has(c, bit)							\
 	(__builtin_constant_p(bit) &&					\
 	 ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) ||	\
@@ -117,7 +123,8 @@
 	   (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) ||	\
 	   (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) ||	\
 	   (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) ||	\
-	   (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) )	\
+	   (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) ||	\
+	   (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) )	\
 	  ? 1 :								\
 	  test_bit(bit, (c)->x86_capability))
 #define boot_cpu_has(bit)	cpu_has(&boot_cpu_data, bit)
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 338668b..94e0c14 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -119,6 +119,7 @@ void __init cpu_detect(struct cpuinfo_x86 *c);
 extern void identify_boot_cpu(void);
 extern void identify_secondary_cpu(struct cpuinfo_x86 *);
 extern void print_cpu_info(struct cpuinfo_x86 *);
+extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern unsigned short num_cache_leaves;
 
diff --git a/include/asm-i386/required-features.h b/include/asm-i386/required-features.h
index a9c3b11..65848a0 100644
--- a/include/asm-i386/required-features.h
+++ b/include/asm-i386/required-features.h
@@ -50,5 +50,6 @@
 #define REQUIRED_MASK4	0
 #define REQUIRED_MASK5	0
 #define REQUIRED_MASK6	0
+#define REQUIRED_MASK7	0
 
 #endif
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
index df64572..efc87a5 100644
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -100,6 +100,7 @@ extern char ignore_irq13;
 
 extern void identify_cpu(struct cpuinfo_x86 *);
 extern void print_cpu_info(struct cpuinfo_x86 *);
+extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern unsigned short num_cache_leaves;
 
diff --git a/include/asm-x86_64/required-features.h b/include/asm-x86_64/required-features.h
index 262f315..e80d576 100644
--- a/include/asm-x86_64/required-features.h
+++ b/include/asm-x86_64/required-features.h
@@ -41,5 +41,6 @@
 #define REQUIRED_MASK4	0
 #define REQUIRED_MASK5	0
 #define REQUIRED_MASK6	0
+#define REQUIRED_MASK7	0
 
 #endif
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 08/33] Define zero-page offset 0x1e4 as a scratch field, and use it
       [not found]   ` <a8e9d4bffc9fa216d32c930606475fd8d1df9405.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

The relocatable kernel code needs a scratch field for the decompressor
to determine its own location.  It was using a location inside
struct screen_info; reserve a free location and document it as scratch
instead.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 Documentation/i386/zero-page.txt   |    1 +
 arch/i386/boot/compressed/head.S   |    6 +++---
 arch/x86_64/boot/compressed/head.S |    6 +++---
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/Documentation/i386/zero-page.txt b/Documentation/i386/zero-page.txt
index c04a421..75b3680 100644
--- a/Documentation/i386/zero-page.txt
+++ b/Documentation/i386/zero-page.txt
@@ -37,6 +37,7 @@ Offset	Type		Description
 0x1d0	unsigned long	EFI memory descriptor map pointer
 0x1d4	unsigned long	EFI memory descriptor map size
 0x1e0	unsigned long	ALT_MEM_K, alternative mem check, in Kb
+0x1e4	unsigned long	Scratch field for the kernel setup code
 0x1e8	char		number of entries in E820MAP (below)
 0x1e9	unsigned char	number of entries in EDDBUF (below)
 0x1ea	unsigned char	number of entries in EDD_MBR_SIG_BUFFER (below)
diff --git a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S
index 3517a32..f35ea22 100644
--- a/arch/i386/boot/compressed/head.S
+++ b/arch/i386/boot/compressed/head.S
@@ -45,10 +45,10 @@ startup_32:
  * at and where we were actually loaded at.  This can only be done
  * with a short local call on x86.  Nothing  else will tell us what
  * address we are running at.  The reserved chunk of the real-mode
- * data at 0x34-0x3f are used as the stack for this calculation.
- * Only 4 bytes are needed.
+ * data at 0x1e4 (defined as a scratch field) are used as the stack
+ * for this calculation. Only 4 bytes are needed.
  */
-	leal 0x40(%esi), %esp
+	leal (0x1e4+4)(%esi), %esp
 	call 1f
 1:	popl %ebp
 	subl $1b, %ebp
diff --git a/arch/x86_64/boot/compressed/head.S b/arch/x86_64/boot/compressed/head.S
index f9d5692..1312bfa 100644
--- a/arch/x86_64/boot/compressed/head.S
+++ b/arch/x86_64/boot/compressed/head.S
@@ -46,10 +46,10 @@ startup_32:
  * at and where we were actually loaded at.  This can only be done
  * with a short local call on x86.  Nothing  else will tell us what
  * address we are running at.  The reserved chunk of the real-mode
- * data at 0x34-0x3f are used as the stack for this calculation.
- * Only 4 bytes are needed.
+ * data at 0x1e4 (defined as a scratch field) are used as the stack
+ * for this calculation. Only 4 bytes are needed.
  */
-	leal	0x40(%esi), %esp
+	leal	(0x1e4+4)(%esi), %esp
 	call	1f
 1:	popl	%ebp
 	subl	$1b, %ebp
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 09/33] Make definitions for struct e820entry and struct e820map consistent
       [not found]   ` <361d0a8b7b7ea9d41d0c25664b3e2b30fd99e329.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  2007-07-10 11:48     ` Andi Kleen
  1 sibling, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Make definitions for struct e820entry and struct e820map consistent
between i386 and x86-64.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/kernel/e820.c   |    2 +-
 include/asm-i386/e820.h   |   14 ++++++++------
 include/asm-x86_64/e820.h |    6 ++++--
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c
index 9645bb5..fc822a4 100644
--- a/arch/i386/kernel/e820.c
+++ b/arch/i386/kernel/e820.c
@@ -734,7 +734,7 @@ void __init print_memory_map(char *who)
 		case E820_NVS:
 				printk("(ACPI NVS)\n");
 				break;
-		default:	printk("type %lu\n", e820.map[i].type);
+		default:	printk("type %u\n", e820.map[i].type);
 				break;
 		}
 	}
diff --git a/include/asm-i386/e820.h b/include/asm-i386/e820.h
index 096a2a8..c03290c 100644
--- a/include/asm-i386/e820.h
+++ b/include/asm-i386/e820.h
@@ -25,13 +25,15 @@
 
 #ifndef __ASSEMBLY__
 
+struct e820entry {
+	u64 addr;	/* start of memory segment */
+	u64 size;	/* size of memory segment */
+	u32 type;	/* type of memory segment */
+} __attribute__((packed));
+
 struct e820map {
-    int nr_map;
-    struct e820entry {
-	unsigned long long addr;	/* start of memory segment */
-	unsigned long long size;	/* size of memory segment */
-	unsigned long type;		/* type of memory segment */
-    } map[E820MAX];
+	u32 nr_map;
+	struct e820entry map[E820MAX];
 };
 
 extern struct e820map e820;
diff --git a/include/asm-x86_64/e820.h b/include/asm-x86_64/e820.h
index 6216fa3..15eb8e2 100644
--- a/include/asm-x86_64/e820.h
+++ b/include/asm-x86_64/e820.h
@@ -11,7 +11,9 @@
 #ifndef __E820_HEADER
 #define __E820_HEADER
 
-#include <linux/mmzone.h>
+#ifndef _SETUP
+# include <linux/mmzone.h>
+#endif
 
 #define E820MAP	0x2d0		/* our map */
 #define E820MAX	128		/* number of entries in E820MAP */
@@ -30,7 +32,7 @@ struct e820entry {
 } __attribute__((packed));
 
 struct e820map {
-    int nr_map;
+	u32 nr_map;
 	struct e820entry map[E820MAX];
 };
 
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 10/33] Make struct boot_params a real structure, and remove obsolete fields
       [not found]   ` <0ff939788c542b0560ec39668550557dcc134afe.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Make struct boot_params a real structure, and remove the handling of
some obsolete fields, in particular hd*_info, which was only used by
the ST-506 driver, and likely to be wrong for that driver on any
modern BIOS.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/kernel/setup.c       |   12 +-----
 include/asm-i386/bootparam.h   |   85 ++++++++++++++++++++++++++++++++++++++++
 include/asm-i386/setup.h       |   10 +++--
 include/asm-x86_64/boot.h      |   16 +-------
 include/asm-x86_64/bootparam.h |    1 +
 5 files changed, 94 insertions(+), 30 deletions(-)
 create mode 100644 include/asm-i386/bootparam.h
 create mode 100644 include/asm-x86_64/bootparam.h

diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 698c24f..2d61e65 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -102,19 +102,10 @@ static unsigned int highmem_pages = -1;
 /*
  * Setup options
  */
-struct drive_info_struct { char dummy[32]; } drive_info;
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
-    defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-EXPORT_SYMBOL(drive_info);
-#endif
 struct screen_info screen_info;
 EXPORT_SYMBOL(screen_info);
 struct apm_info apm_info;
 EXPORT_SYMBOL(apm_info);
-struct sys_desc_table_struct {
-	unsigned short length;
-	unsigned char table[0];
-};
 struct edid_info edid_info;
 EXPORT_SYMBOL_GPL(edid_info);
 struct ist_info ist_info;
@@ -134,7 +125,7 @@ unsigned long saved_videomode;
 
 static char __initdata command_line[COMMAND_LINE_SIZE];
 
-unsigned char __initdata boot_params[PARAM_SIZE];
+struct boot_params __initdata boot_params;
 
 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
 struct edd edd;
@@ -528,7 +519,6 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
  	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
- 	drive_info = DRIVE_INFO;
  	screen_info = SCREEN_INFO;
 	edid_info = EDID_INFO;
 	apm_info.bios = APM_BIOS_INFO;
diff --git a/include/asm-i386/bootparam.h b/include/asm-i386/bootparam.h
new file mode 100644
index 0000000..427d865
--- /dev/null
+++ b/include/asm-i386/bootparam.h
@@ -0,0 +1,85 @@
+#ifndef _ASM_BOOTPARAM_H
+#define _ASM_BOOTPARAM_H
+
+#include <linux/types.h>
+#include <linux/screen_info.h>
+#include <linux/apm_bios.h>
+#include <asm/e820.h>
+#include <linux/edd.h>
+#include <video/edid.h>
+
+struct setup_header {
+	u8	setup_sects;
+	u16	root_flags;
+	u32	syssize;
+	u16	ram_size;
+	u16	vid_mode;
+	u16	root_dev;
+	u16	boot_flag;
+	u16	jump;
+	u32	header;
+	u16	version;
+	u32	realmode_swtch;
+	u16	start_sys;
+	u16	kernel_version;
+	u8	type_of_loader;
+	u8	loadflags;
+#define LOADED_HIGH	0x01
+#define CAN_USE_HEAP	0x80
+	u16	setup_move_size;
+	u32	code32_start;
+	u32	ramdisk_image;
+	u32	ramdisk_size;
+	u32	bootsect_kludge;
+	u16	heap_end_ptr;
+	u16	_pad1;
+	u32	cmd_line_ptr;
+	u32	initrd_addr_max;
+	u32	kernel_alignment;
+	u8	relocatable_kernel;
+} __attribute__((packed));
+
+struct sys_desc_table {
+	u16 length;
+	u8  table[14];
+};
+
+struct efi_info {
+	u32 _pad1;
+	u32 efi_systab;
+	u32 efi_memdesc_size;
+	u32 efi_memdec_version;
+	u32 efi_memmap;
+	u32 fi_memmap_size;
+	u32 _pad2[2];
+};
+
+/* The so-called "zeropage" */
+struct boot_params {
+	struct screen_info screen_info;			/* 0x000 */
+	struct apm_bios_info apm_bios_info;		/* 0x040 */
+	u8  _pad2[12];					/* 0x054 */
+	u32 speedstep_info[4];				/* 0x060 */
+	u8  _pad3[16];					/* 0x070 */
+	u8  hd0_info[16];	/* obsolete! */		/* 0x080 */
+	u8  hd1_info[16];	/* obsolete! */		/* 0x090 */
+	struct sys_desc_table sys_desc_table;		/* 0x0a0 */
+	u8  _pad4[144];					/* 0x0b0 */
+	struct edid_info edid_info;			/* 0x140 */
+	struct efi_info efi_info;			/* 0x1c0 */
+	u32 alt_mem_k;					/* 0x1e0 */
+	u32 scratch;		/* Scratch field! */	/* 0x1e4 */
+	u8  e820_entries;				/* 0x1e8 */
+	u8  eddbuf_entries;				/* 0x1e9 */
+	u8  edd_mbr_sig_buf_entries;			/* 0x1ea */
+	u8  _pad6[6];					/* 0x1eb */
+	struct setup_header hdr;    /* setup header */	/* 0x1f1 */
+	u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
+	u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];	/* 0x290 */
+	struct e820entry e820_map[E820MAX];		/* 0x2d0 */
+	u8  _pad8[48];					/* 0xcd0 */
+	struct edd_info eddbuf[EDDMAXNR];		/* 0xd00 */
+	u8  _pad9[276];					/* 0xeec */
+} __attribute__((packed));
+
+#endif /* _ASM_BOOTPARAM_H */
diff --git a/include/asm-i386/setup.h b/include/asm-i386/setup.h
index 0e8077c..0d5bff9 100644
--- a/include/asm-i386/setup.h
+++ b/include/asm-i386/setup.h
@@ -26,12 +26,15 @@
 #define NEW_CL_POINTER		0x228	/* Relative to real mode data */
 
 #ifndef __ASSEMBLY__
+
+#include <asm/bootparam.h>
+
 /*
  * This is set up by the setup-routine at boot-time
  */
-extern unsigned char boot_params[PARAM_SIZE];
+extern struct boot_params boot_params;
 
-#define PARAM	(boot_params)
+#define PARAM	((char *)&boot_params)
 #define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
 #define EXT_MEM_K (*(unsigned short *) (PARAM+2))
 #define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
@@ -39,8 +42,7 @@ extern unsigned char boot_params[PARAM_SIZE];
 #define E820_MAP    ((struct e820entry *) (PARAM+E820MAP))
 #define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
 #define IST_INFO   (*(struct ist_info *) (PARAM+0x60))
-#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
-#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
+#define SYS_DESC_TABLE (*(struct sys_desc_table *)(PARAM+0xa0))
 #define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4)))
 #define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8)))
 #define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc)))
diff --git a/include/asm-x86_64/boot.h b/include/asm-x86_64/boot.h
index 96b228e..3c46cea 100644
--- a/include/asm-x86_64/boot.h
+++ b/include/asm-x86_64/boot.h
@@ -1,15 +1 @@
-#ifndef _LINUX_BOOT_H
-#define _LINUX_BOOT_H
-
-/* Don't touch these, unless you really know what you're doing. */
-#define DEF_INITSEG	0x9000
-#define DEF_SYSSEG	0x1000
-#define DEF_SETUPSEG	0x9020
-#define DEF_SYSSIZE	0x7F00
-
-/* Internal svga startup constants */
-#define NORMAL_VGA	0xffff		/* 80x25 mode */
-#define EXTENDED_VGA	0xfffe		/* 80x50 mode */
-#define ASK_VGA		0xfffd		/* ask for it at bootup */
-
-#endif
+#include <asm-i386/boot.h>
diff --git a/include/asm-x86_64/bootparam.h b/include/asm-x86_64/bootparam.h
new file mode 100644
index 0000000..aa82e52
--- /dev/null
+++ b/include/asm-x86_64/bootparam.h
@@ -0,0 +1 @@
+#include <asm-i386/bootparam.h>
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 11/33] x86-64: add CONFIG_PHYSICAL_ALIGN for consistency with i386
       [not found]   ` <bbeadd1995da049cf6880ab58794f84ec8785a08.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Add CONFIG_PHYSICAL_ALIGN (currently as a hardcoded constant) to provide
consistency with i386.  This value is manifest in the bzImage header.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86_64/Kconfig |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 5ce9443..8bdd25a 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -427,6 +427,10 @@ config NR_CPUS
 	  This is purely to save memory - each supported CPU requires
 	  memory in the static kernel configuration.
 
+config PHYSICAL_ALIGN
+	hex
+	default "0x200000"
+
 config HOTPLUG_CPU
 	bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
 	depends on SMP && HOTPLUG && EXPERIMENTAL
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 12/33] x86-64: add symbolic constants for the boot segment selectors
       [not found]   ` <e3ff2ad47d4610cdafbe24dcabadef42bb3166fb.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Add symbolic constants for the segment selectors/GDT slots used by
the setup code, for consistency with i386.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 include/asm-x86_64/segment.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/include/asm-x86_64/segment.h b/include/asm-x86_64/segment.h
index adf2bf1..04b8ab2 100644
--- a/include/asm-x86_64/segment.h
+++ b/include/asm-x86_64/segment.h
@@ -3,6 +3,14 @@
 
 #include <asm/cache.h>
 
+/* Simple and small GDT entries for booting only */
+
+#define GDT_ENTRY_BOOT_CS		2
+#define __BOOT_CS	(GDT_ENTRY_BOOT_CS * 8)
+
+#define GDT_ENTRY_BOOT_DS		(GDT_ENTRY_BOOT_CS + 1)
+#define __BOOT_DS	(GDT_ENTRY_BOOT_DS * 8)
+
 #define __KERNEL_CS	0x10
 #define __KERNEL_DS	0x18
 
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 13/33] Header file to produce 16-bit code with gcc
       [not found]   ` <96024b4c88d58a8473deb48a8038f6893b8b6b55.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  2007-07-10 14:16       ` Segher Boessenkool
  0 siblings, 1 reply; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

gcc for i386 can be used with the assembly prefix ".code16gcc" to generate
16-bit (real-mode) code.  This header file provides the assembly prefix.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/code16gcc.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/code16gcc.h

diff --git a/arch/i386/boot/code16gcc.h b/arch/i386/boot/code16gcc.h
new file mode 100644
index 0000000..dbc6414
--- /dev/null
+++ b/arch/i386/boot/code16gcc.h
@@ -0,0 +1,9 @@
+/*
+ * code16gcc.h
+ *
+ * This file is -include'd when compiling 16-bit C code.
+ */
+
+#ifndef __ASSEMBLY__
+asm(".code16gcc");
+#endif
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 14/33] Top header file for new x86 setup code
       [not found]   ` <a862328acf06a9587458c615848099f96fbab1ce.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Top header file for the new x86 setup code.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/boot.h |  290 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 290 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/boot.h

diff --git a/arch/i386/boot/boot.h b/arch/i386/boot/boot.h
new file mode 100644
index 0000000..7251ef6
--- /dev/null
+++ b/arch/i386/boot/boot.h
@@ -0,0 +1,290 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/boot.h
+ *
+ * Header file for the real-mode kernel code
+ */
+
+#ifndef BOOT_BOOT_H
+#define BOOT_BOOT_H
+
+#ifndef __ASSEMBLY__
+
+#include <stdarg.h>
+#include <linux/types.h>
+#include <linux/edd.h>
+#include <asm/boot.h>
+#include <asm/bootparam.h>
+
+/* Useful macros */
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+
+extern struct setup_header hdr;
+extern struct boot_params boot_params;
+
+/* Basic port I/O */
+static inline void outb(u8 v, u16 port)
+{
+	asm volatile("outb %0,%1" : : "a" (v), "dN" (port));
+}
+static inline u8 inb(u16 port)
+{
+	u8 v;
+	asm volatile("inb %1,%0" : "=a" (v) : "dN" (port));
+	return v;
+}
+
+static inline void outw(u16 v, u16 port)
+{
+	asm volatile("outw %0,%1" : : "a" (v), "dN" (port));
+}
+static inline u16 inw(u16 port)
+{
+	u16 v;
+	asm volatile("inw %1,%0" : "=a" (v) : "dN" (port));
+	return v;
+}
+
+static inline void outl(u32 v, u16 port)
+{
+	asm volatile("outl %0,%1" : : "a" (v), "dn" (port));
+}
+static inline u32 inl(u32 port)
+{
+	u32 v;
+	asm volatile("inl %1,%0" : "=a" (v) : "dN" (port));
+	return v;
+}
+
+static inline void io_delay(void)
+{
+	const u16 DELAY_PORT = 0x80;
+	asm volatile("outb %%al,%0" : : "dN" (DELAY_PORT));
+}
+
+/* These functions are used to reference data in other segments. */
+
+static inline u16 ds(void)
+{
+	u16 seg;
+	asm("movw %%ds,%0" : "=rm" (seg));
+	return seg;
+}
+
+static inline void set_fs(u16 seg)
+{
+	asm volatile("movw %0,%%fs" : : "rm" (seg));
+}
+static inline u16 fs(void)
+{
+	u16 seg;
+	asm("movw %%fs,%0" : "=rm" (seg));
+	return seg;
+}
+
+static inline void set_gs(u16 seg)
+{
+	asm volatile("movw %0,%%gs" : : "rm" (seg));
+}
+static inline u16 gs(void)
+{
+	u16 seg;
+	asm("movw %%gs,%0" : "=rm" (seg));
+	return seg;
+}
+
+typedef unsigned int addr_t;
+
+static inline u8 rdfs8(addr_t addr)
+{
+	u8 v;
+	asm("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
+	return v;
+}
+static inline u16 rdfs16(addr_t addr)
+{
+	u16 v;
+	asm("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
+	return v;
+}
+static inline u32 rdfs32(addr_t addr)
+{
+	u32 v;
+	asm("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
+	return v;
+}
+
+static inline void wrfs8(u8 v, addr_t addr)
+{
+	asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "r" (v));
+}
+static inline void wrfs16(u16 v, addr_t addr)
+{
+	asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "r" (v));
+}
+static inline void wrfs32(u32 v, addr_t addr)
+{
+	asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "r" (v));
+}
+
+static inline u8 rdgs8(addr_t addr)
+{
+	u8 v;
+	asm("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
+	return v;
+}
+static inline u16 rdgs16(addr_t addr)
+{
+	u16 v;
+	asm("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
+	return v;
+}
+static inline u32 rdgs32(addr_t addr)
+{
+	u32 v;
+	asm("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
+	return v;
+}
+
+static inline void wrgs8(u8 v, addr_t addr)
+{
+	asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "r" (v));
+}
+static inline void wrgs16(u16 v, addr_t addr)
+{
+	asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "r" (v));
+}
+static inline void wrgs32(u32 v, addr_t addr)
+{
+	asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "r" (v));
+}
+
+/* Note: these only return true/false, not a signed return value! */
+static inline int memcmp(const void *s1, const void *s2, size_t len)
+{
+	u8 diff;
+	asm("repe; cmpsb; setnz %0"
+	    : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+	return diff;
+}
+
+static inline int memcmp_fs(const void *s1, addr_t s2, size_t len)
+{
+	u8 diff;
+	asm("fs; repe; cmpsb; setnz %0"
+	    : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+	return diff;
+}
+static inline int memcmp_gs(const void *s1, addr_t s2, size_t len)
+{
+	u8 diff;
+	asm("gs; repe; cmpsb; setnz %0"
+	    : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+	return diff;
+}
+
+/* Heap -- available for dynamic lists. */
+#define STACK_SIZE	512	/* Minimum number of bytes for stack */
+
+extern char _end[];
+extern char *HEAP;
+extern char *heap_end;
+#define RESET_HEAP() ((void *)( HEAP = _end ))
+static inline char *__get_heap(size_t s, size_t a, size_t n)
+{
+	char *tmp;
+
+	HEAP = (char *)(((size_t)HEAP+(a-1)) & ~(a-1));
+	tmp = HEAP;
+	HEAP += s*n;
+	return tmp;
+}
+#define GET_HEAP(type, n) \
+	((type *)__get_heap(sizeof(type),__alignof__(type),(n)))
+
+static inline int heap_free(void)
+{
+	return heap_end-HEAP;
+}
+
+/* copy.S */
+
+void copy_to_fs(addr_t dst, void *src, size_t len);
+void *copy_from_fs(void *dst, addr_t src, size_t len);
+void copy_to_gs(addr_t dst, void *src, size_t len);
+void *copy_from_gs(void *dst, addr_t src, size_t len);
+void *memcpy(void *dst, void *src, size_t len);
+void *memset(void *dst, int c, size_t len);
+
+#define memcpy(d,s,l) __builtin_memcpy(d,s,l)
+#define memset(d,c,l) __builtin_memset(d,c,l)
+
+/* a20.c */
+int enable_a20(void);
+
+/* apm.c */
+int query_apm_bios(void);
+
+/* cmdline.c */
+int cmdline_find_option(const char *option, char *buffer, int bufsize);
+
+/* cpu.c, cpucheck.c */
+int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
+int validate_cpu(void);
+
+/* edd.c */
+void query_edd(void);
+
+/* header.S */
+void __attribute__((noreturn)) die(void);
+
+/* mca.c */
+int query_mca(void);
+
+/* memory.c */
+int detect_memory(void);
+
+/* pm.c */
+void __attribute__((noreturn)) go_to_protected_mode(void);
+
+/* pmjump.S */
+void __attribute__((noreturn))
+	protected_mode_jump(u32 entrypoint, u32 bootparams);
+
+/* printf.c */
+unsigned int atou(const char *s);
+int sprintf(char *buf, const char *fmt, ...);
+int vsprintf(char *buf, const char *fmt, va_list args);
+int printf(const char *fmt, ...);
+
+/* string.c */
+int strcmp(const char *str1, const char *str2);
+
+/* tty.c */
+void puts(const char *);
+void putchar(int);
+int getchar(void);
+void kbd_flush(void);
+int getchar_timeout(void);
+
+/* video.c */
+void set_video(void);
+
+/* video-vesa.c */
+void vesa_store_edid(void);
+
+/* voyager.c */
+int query_voyager(void);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* BOOT_BOOT_H */
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 15/33] Simple bitops for the new x86 setup code.
       [not found]   ` <899e4acb1fe3e4313dfdca5398431274808d71ef.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

A simple collection of bitops for the new x86 setup code.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/bitops.h |   45 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 45 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/bitops.h

diff --git a/arch/i386/boot/bitops.h b/arch/i386/boot/bitops.h
new file mode 100644
index 0000000..8dcc8dc
--- /dev/null
+++ b/arch/i386/boot/bitops.h
@@ -0,0 +1,45 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/bitops.h
+ *
+ * Very simple bitops for the boot code.
+ */
+
+#ifndef BOOT_BITOPS_H
+#define BOOT_BITOPS_H
+#define _LINUX_BITOPS_H		/* Inhibit inclusion of <linux/bitops.h> */
+
+static inline int constant_test_bit(int nr, const void *addr)
+{
+	const u32 *p = (const u32 *)addr;
+	return ((1UL << (nr & 31)) & (p[nr >> 5])) != 0;
+}
+static inline int variable_test_bit(int nr, const void *addr)
+{
+	u8 v;
+	const u32 *p = (const u32 *)addr;
+
+	asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
+	return v;
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ constant_test_bit((nr),(addr)) : \
+ variable_test_bit((nr),(addr)))
+
+static inline void set_bit(int nr, void *addr)
+{
+	asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
+}
+
+#endif /* BOOT_BITOPS_H */
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 16/33] String-handling functions for the new x86 setup code.
       [not found]   ` <d5bd30fc697149284a73e09efe54884ab178de7e.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  2007-07-10 18:25       ` Jan Engelhardt
  0 siblings, 1 reply; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

strcmp(), memcpy(), memset(), as well as routines to copy to and from
other segments (as pointed to by fs and gs).

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/copy.S   |  101 +++++++++++++++++++++++++++++++++++++++++++++++
 arch/i386/boot/string.c |   34 ++++++++++++++++
 2 files changed, 135 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/copy.S
 create mode 100644 arch/i386/boot/string.c

diff --git a/arch/i386/boot/copy.S b/arch/i386/boot/copy.S
new file mode 100644
index 0000000..ef127e5
--- /dev/null
+++ b/arch/i386/boot/copy.S
@@ -0,0 +1,101 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/copy.S
+ *
+ * Memory copy routines
+ */
+
+	.code16gcc
+	.text
+
+	.globl	memcpy
+	.type	memcpy, @function
+memcpy:
+	pushw	%si
+	pushw	%di
+	movw	%ax, %di
+	movw	%dx, %si
+	pushw	%cx
+	shrw	$2, %cx
+	rep; movsl
+	popw	%cx
+	andw	$3, %cx
+	rep; movsb
+	popw	%di
+	popw	%si
+	ret
+	.size	memcpy, .-memcpy
+
+	.globl	memset
+	.type	memset, @function
+memset:
+	pushw	%di
+	movw	%ax, %di
+	movzbl	%dl, %eax
+	imull	$0x01010101,%eax
+	pushw	%cx
+	shrw	$2, %cx
+	rep; stosl
+	popw	%cx
+	andw	$3, %cx
+	rep; stosb
+	popw	%di
+	ret
+	.size	memset, .-memset
+
+	.globl	copy_from_fs
+	.type	copy_from_fs, @function
+copy_from_fs:
+	pushw	%ds
+	pushw	%fs
+	popw	%ds
+	call	memcpy
+	popw	%ds
+	ret
+	.size	copy_from_fs, .-copy_from_fs
+
+	.globl	copy_to_fs
+	.type	copy_to_fs, @function
+copy_to_fs:
+	pushw	%es
+	pushw	%fs
+	popw	%es
+	call	memcpy
+	popw	%es
+	ret
+	.size	copy_to_fs, .-copy_to_fs
+
+#if 0 /* Not currently used, but can be enabled as needed */
+
+	.globl	copy_from_gs
+	.type	copy_from_gs, @function
+copy_from_gs:
+	pushw	%ds
+	pushw	%gs
+	popw	%ds
+	call	memcpy
+	popw	%ds
+	ret
+	.size	copy_from_gs, .-copy_from_gs
+	.globl	copy_to_gs
+
+	.type	copy_to_gs, @function
+copy_to_gs:
+	pushw	%es
+	pushw	%gs
+	popw	%es
+	call	memcpy
+	popw	%es
+	ret
+	.size	copy_to_gs, .-copy_to_gs
+
+#endif
diff --git a/arch/i386/boot/string.c b/arch/i386/boot/string.c
new file mode 100644
index 0000000..0808197
--- /dev/null
+++ b/arch/i386/boot/string.c
@@ -0,0 +1,34 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/string.c
+ *
+ * Very basic string functions
+ */
+
+#include "boot.h"
+#include <linux/edd.h>
+
+int strcmp(const char *str1, const char *str2)
+{
+	const unsigned char *s1 = (const unsigned char *)str1;
+	const unsigned char *s2 = (const unsigned char *)str2;
+	int delta = 0;
+
+	while (*s1 || *s2) {
+		delta = *s2 - *s1;
+		if (delta)
+			return delta;
+		s1++;
+		s2++;
+	}
+	return 0;
+}
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 17/33] A20 handling code
       [not found]   ` <17db5b2c8a43cf36b2eb36afc142ce9ca0552282.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  2007-07-10 18:27       ` Jan Engelhardt
  0 siblings, 1 reply; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

A20 handling code for the new x86 setup code.  This implements the same
algorithms as the assembly version.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/a20.c |  161 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 161 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/a20.c

diff --git a/arch/i386/boot/a20.c b/arch/i386/boot/a20.c
new file mode 100644
index 0000000..31348d0
--- /dev/null
+++ b/arch/i386/boot/a20.c
@@ -0,0 +1,161 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/a20.c
+ *
+ * Enable A20 gate (return -1 on failure)
+ */
+
+#include "boot.h"
+
+#define MAX_8042_LOOPS	100000
+
+static int empty_8042(void)
+{
+	u8 status;
+	int loops = MAX_8042_LOOPS;
+
+	while (loops--) {
+		io_delay();
+
+		status = inb(0x64);
+		if (status & 1) {
+			/* Read and discard input data */
+			io_delay();
+			(void)inb(0x60);
+		} else if (!(status & 2)) {
+			/* Buffers empty, finished! */
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+/* Returns nonzero if the A20 line is enabled.  The memory address
+   used as a test is the int $0x80 vector, which should be safe. */
+
+#define A20_TEST_ADDR	(4*0x80)
+#define A20_TEST_SHORT  32
+#define A20_TEST_LONG	2097152	/* 2^21 */
+
+static int a20_test(int loops)
+{
+	int ok = 0;
+	int saved, ctr;
+
+	set_fs(0x0000);
+	set_gs(0xffff);
+
+	saved = ctr = rdfs32(A20_TEST_ADDR);
+
+	while (loops--) {
+		wrfs32(++ctr, A20_TEST_ADDR);
+		io_delay();	/* Serialize and make delay constant */
+		ok = rdgs32(A20_TEST_ADDR+0x10) ^ ctr;
+		if (ok)
+			break;
+	}
+
+	wrfs32(saved, A20_TEST_ADDR);
+	return ok;
+}
+
+/* Quick test to see if A20 is already enabled */
+static int a20_test_short(void)
+{
+	return a20_test(A20_TEST_SHORT);
+}
+
+/* Longer test that actually waits for A20 to come on line; this
+   is useful when dealing with the KBC or other slow external circuitry. */
+static int a20_test_long(void)
+{
+	return a20_test(A20_TEST_LONG);
+}
+
+static void enable_a20_bios(void)
+{
+	asm volatile("pushfl; int $0x15; popfl"
+		     : : "a" ((u16)0x2401));
+}
+
+static void enable_a20_kbc(void)
+{
+	empty_8042();
+
+	outb(0xd1, 0x64);	/* Command write */
+	empty_8042();
+
+	outb(0xdf, 0x60);	/* A20 on */
+	empty_8042();
+}
+
+static void enable_a20_fast(void)
+{
+	u8 port_a;
+
+	port_a = inb(0x92);	/* Configuration port A */
+	port_a |=  0x02;	/* Enable A20 */
+	port_a &= ~0x01;	/* Do not reset machine */
+	outb(port_a, 0x92);
+}
+
+/*
+ * Actual routine to enable A20; return 0 on ok, -1 on failure
+ */
+
+#define A20_ENABLE_LOOPS 255	/* Number of times to try */
+
+int enable_a20(void)
+{
+	int loops = A20_ENABLE_LOOPS;
+
+#if defined(CONFIG_X86_ELAN)
+	/* Elan croaks if we try to touch the KBC */
+	enable_a20_fast();
+	while (!a20_test_long())
+		;
+	return 0;
+#elif defined(CONFIG_X86_VOYAGER)
+	/* On Voyager, a20_test() is unsafe? */
+	enable_a20_kbc();
+	return 0;
+#else
+	while (loops--) {
+		/* First, check to see if A20 is already enabled
+		   (legacy free, etc.) */
+		if (a20_test_short())
+			return 0;
+
+		/* Next, try the BIOS (INT 0x15, AX=0x2401) */
+		enable_a20_bios();
+		if (a20_test_short())
+			return 0;
+
+		/* Try enabling A20 through the keyboard controller */
+		empty_8042();
+		if (a20_test_short())
+			return 0; /* BIOS worked, but with delayed reaction */
+
+		enable_a20_kbc();
+		if (a20_test_long())
+			return 0;
+
+		/* Finally, try enabling the "fast A20 gate" */
+		enable_a20_fast();
+		if (a20_test_long())
+			return 0;
+	}
+
+	return -1;
+#endif
+}
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 18/33] APM probing code
       [not found]   ` <c488ae7cd0ddd799b666f55652248be3c346a076.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

APM probing code for the new x86 setup code.  This implements the
same functionality as the assembly version.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/apm.c |   97 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 97 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/apm.c

diff --git a/arch/i386/boot/apm.c b/arch/i386/boot/apm.c
new file mode 100644
index 0000000..a34087c
--- /dev/null
+++ b/arch/i386/boot/apm.c
@@ -0,0 +1,97 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   Original APM BIOS checking by Stephen Rothwell, May 1994
+ *   (sfr@canb.auug.org.au)
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/apm.c
+ *
+ * Get APM BIOS information
+ */
+
+#include "boot.h"
+
+#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
+
+int query_apm_bios(void)
+{
+	u16 ax, bx, cx, dx, di;
+	u32 ebx, esi;
+	u8 err;
+
+	/* APM BIOS installation check */
+	ax = 0x5300;
+	bx = cx = 0;
+	asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
+		     : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
+		     : : "esi", "edi");
+
+	if (err)
+		return -1;		/* No APM BIOS */
+
+	if (bx != 0x504d)	/* "PM" signature */
+		return -1;
+
+	if (cx & 0x02)		/* 32 bits supported? */
+		return -1;
+
+	/* Disconnect first, just in case */
+	ax = 0x5304;
+	asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
+		     : "+a" (ax)
+		     : : "ebx", "ecx", "edx", "esi", "edi");
+
+	/* Paranoia */
+	ebx = esi = 0;
+	cx = dx = di = 0;
+
+	/* 32-bit connect */
+	asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6"
+		     : "=a" (ax), "+b" (ebx), "+c" (cx), "+d" (dx),
+		       "+S" (esi), "+D" (di), "=m" (err)
+		     : "a" (0x5303));
+
+	boot_params.apm_bios_info.cseg = ax;
+	boot_params.apm_bios_info.offset = ebx;
+	boot_params.apm_bios_info.cseg_16 = cx;
+	boot_params.apm_bios_info.dseg = dx;
+	boot_params.apm_bios_info.cseg_len = (u16)esi;
+	boot_params.apm_bios_info.cseg_16_len = esi >> 16;
+	boot_params.apm_bios_info.dseg_len = di;
+
+	if (err)
+		return -1;
+
+	/* Redo the installation check as the 32-bit connect;
+	   some BIOSes return different flags this way... */
+
+	ax = 0x5300;
+	bx = cx = 0;
+	asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
+		     : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
+		     : : "esi", "edi");
+
+	if (err || bx != 0x504d) {
+		/* Failure with 32-bit connect, try to disconect and ignore */
+		ax = 0x5304;
+		bx = 0;
+		asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
+			     : "+a" (ax), "+b" (bx)
+			     : : "ecx", "edx", "esi", "edi");
+		return -1;
+	}
+
+	boot_params.apm_bios_info.version = ax;
+	boot_params.apm_bios_info.flags = cx;
+	return 0;
+}
+
+#endif
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 19/33] Command-line parsing code for the new x86 setup code
       [not found]   ` <3726c75f36dc97c1fce93835e872bbc814857990.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Simple command-line parser which allows us to access the kernel command
line from the setup code.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/cmdline.c |   97 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 97 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/cmdline.c

diff --git a/arch/i386/boot/cmdline.c b/arch/i386/boot/cmdline.c
new file mode 100644
index 0000000..34bb778
--- /dev/null
+++ b/arch/i386/boot/cmdline.c
@@ -0,0 +1,97 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/cmdline.c
+ *
+ * Simple command-line parser for early boot.
+ */
+
+#include "boot.h"
+
+static inline int myisspace(u8 c)
+{
+	return c <= ' ';	/* Close enough approximation */
+}
+
+/*
+ * Find a non-boolean option, that is, "option=argument".  In accordance
+ * with standard Linux practice, if this option is repeated, this returns
+ * the last instance on the command line.
+ *
+ * Returns the length of the argument (regardless of if it was
+ * truncated to fit in the buffer), or -1 on not found.
+ */
+int cmdline_find_option(const char *option, char *buffer, int bufsize)
+{
+	u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr;
+	addr_t cptr;
+	char c;
+	int len = -1;
+	const char *opptr = NULL;
+	char *bufptr = buffer;
+	enum {
+		st_wordstart,	/* Start of word/after whitespace */
+		st_wordcmp,	/* Comparing this word */
+		st_wordskip,	/* Miscompare, skip */
+		st_bufcpy	/* Copying this to buffer */
+	} state = st_wordstart;
+
+	if (!cmdline_ptr || cmdline_ptr >= 0x100000)
+		return -1;	/* No command line, or inaccessible */
+
+	cptr = cmdline_ptr & 0xf;
+	set_fs(cmdline_ptr >> 4);
+
+	while (cptr < 0x10000 && (c = rdfs8(cptr++))) {
+		switch (state) {
+		case st_wordstart:
+			if (myisspace(c))
+				break;
+
+			/* else */
+			state = st_wordcmp;
+			opptr = option;
+			/* fall through */
+
+		case st_wordcmp:
+			if (c == '=' && !*opptr) {
+				len = 0;
+				bufptr = buffer;
+				state = st_bufcpy;
+			} else if (myisspace(c)) {
+				state = st_wordstart;
+			} else if (c != *opptr++) {
+				state = st_wordskip;
+			}
+			break;
+
+		case st_wordskip:
+			if (myisspace(c))
+				state = st_wordstart;
+			break;
+
+		case st_bufcpy:
+			if (myisspace(c)) {
+				state = st_wordstart;
+			} else {
+				if (len < bufsize-1)
+					*bufptr++ = c;
+				len++;
+			}
+			break;
+		}
+	}
+
+	if (bufsize)
+		*bufptr = '\0';
+
+	return len;
+}
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 20/33] Console-writing code for the new x86 setup code
       [not found]   ` <bf3e29f3d8c12230b38cae29ef5b476267d40cd1.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:51     ` H. Peter Anvin
  2007-07-10 18:35       ` Jan Engelhardt
  0 siblings, 1 reply; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:51 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

This implements writing text to the console, including printf().

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/printf.c |  331 +++++++++++++++++++++++++++++++++++++++++++++++
 arch/i386/boot/tty.c    |  112 ++++++++++++++++
 2 files changed, 443 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/printf.c
 create mode 100644 arch/i386/boot/tty.c

diff --git a/arch/i386/boot/printf.c b/arch/i386/boot/printf.c
new file mode 100644
index 0000000..ee3d9fc
--- /dev/null
+++ b/arch/i386/boot/printf.c
@@ -0,0 +1,331 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/printf.c
+ *
+ * Oh, it's a waste of space, but oh-so-yummy for debugging.  This
+ * version of printf() does not include 64-bit support.  "Live with
+ * it."
+ *
+ */
+
+#include "boot.h"
+
+static inline int isdigit(int ch)
+{
+	return (ch >= '0') && (ch <= '9');
+}
+
+static int skip_atoi(const char **s)
+{
+	int i = 0;
+
+	while (isdigit(**s))
+		i = i * 10 + *((*s)++) - '0';
+	return i;
+}
+
+unsigned int atou(const char *s)
+{
+	unsigned int i = 0;
+	while (isdigit(*s))
+		i = i * 10 + (*s++ - '0');
+	return i;
+}
+
+static int strnlen(const char *s, int maxlen)
+{
+	const char *es = s;
+	while (*es && maxlen) {
+		es++;
+		maxlen--;
+	}
+
+	return (es - s);
+}
+
+#define ZEROPAD	1		/* pad with zero */
+#define SIGN	2		/* unsigned/signed long */
+#define PLUS	4		/* show plus */
+#define SPACE	8		/* space if plus */
+#define LEFT	16		/* left justified */
+#define SPECIAL	32		/* 0x */
+#define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */
+
+#define do_div(n,base) ({ \
+int __res; \
+__res = ((unsigned long) n) % (unsigned) base; \
+n = ((unsigned long) n) / (unsigned) base; \
+__res; })
+
+static char *number(char *str, long num, int base, int size, int precision,
+		    int type)
+{
+	char c, sign, tmp[66];
+	const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
+	int i;
+
+	if (type & LARGE)
+		digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+	if (type & LEFT)
+		type &= ~ZEROPAD;
+	if (base < 2 || base > 36)
+		return 0;
+	c = (type & ZEROPAD) ? '0' : ' ';
+	sign = 0;
+	if (type & SIGN) {
+		if (num < 0) {
+			sign = '-';
+			num = -num;
+			size--;
+		} else if (type & PLUS) {
+			sign = '+';
+			size--;
+		} else if (type & SPACE) {
+			sign = ' ';
+			size--;
+		}
+	}
+	if (type & SPECIAL) {
+		if (base == 16)
+			size -= 2;
+		else if (base == 8)
+			size--;
+	}
+	i = 0;
+	if (num == 0)
+		tmp[i++] = '0';
+	else
+		while (num != 0)
+			tmp[i++] = digits[do_div(num, base)];
+	if (i > precision)
+		precision = i;
+	size -= precision;
+	if (!(type & (ZEROPAD + LEFT)))
+		while (size-- > 0)
+			*str++ = ' ';
+	if (sign)
+		*str++ = sign;
+	if (type & SPECIAL) {
+		if (base == 8)
+			*str++ = '0';
+		else if (base == 16) {
+			*str++ = '0';
+			*str++ = digits[33];
+		}
+	}
+	if (!(type & LEFT))
+		while (size-- > 0)
+			*str++ = c;
+	while (i < precision--)
+		*str++ = '0';
+	while (i-- > 0)
+		*str++ = tmp[i];
+	while (size-- > 0)
+		*str++ = ' ';
+	return str;
+}
+
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+	int len;
+	unsigned long num;
+	int i, base;
+	char *str;
+	const char *s;
+
+	int flags;		/* flags to number() */
+
+	int field_width;	/* width of output field */
+	int precision;		/* min. # of digits for integers; max
+				   number of chars for from string */
+	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
+
+	for (str = buf; *fmt; ++fmt) {
+		if (*fmt != '%') {
+			*str++ = *fmt;
+			continue;
+		}
+
+		/* process flags */
+		flags = 0;
+	      repeat:
+		++fmt;		/* this also skips first '%' */
+		switch (*fmt) {
+		case '-':
+			flags |= LEFT;
+			goto repeat;
+		case '+':
+			flags |= PLUS;
+			goto repeat;
+		case ' ':
+			flags |= SPACE;
+			goto repeat;
+		case '#':
+			flags |= SPECIAL;
+			goto repeat;
+		case '0':
+			flags |= ZEROPAD;
+			goto repeat;
+		}
+
+		/* get field width */
+		field_width = -1;
+		if (isdigit(*fmt))
+			field_width = skip_atoi(&fmt);
+		else if (*fmt == '*') {
+			++fmt;
+			/* it's the next argument */
+			field_width = va_arg(args, int);
+			if (field_width < 0) {
+				field_width = -field_width;
+				flags |= LEFT;
+			}
+		}
+
+		/* get the precision */
+		precision = -1;
+		if (*fmt == '.') {
+			++fmt;
+			if (isdigit(*fmt))
+				precision = skip_atoi(&fmt);
+			else if (*fmt == '*') {
+				++fmt;
+				/* it's the next argument */
+				precision = va_arg(args, int);
+			}
+			if (precision < 0)
+				precision = 0;
+		}
+
+		/* get the conversion qualifier */
+		qualifier = -1;
+		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
+			qualifier = *fmt;
+			++fmt;
+		}
+
+		/* default base */
+		base = 10;
+
+		switch (*fmt) {
+		case 'c':
+			if (!(flags & LEFT))
+				while (--field_width > 0)
+					*str++ = ' ';
+			*str++ = (unsigned char)va_arg(args, int);
+			while (--field_width > 0)
+				*str++ = ' ';
+			continue;
+
+		case 's':
+			s = va_arg(args, char *);
+			len = strnlen(s, precision);
+
+			if (!(flags & LEFT))
+				while (len < field_width--)
+					*str++ = ' ';
+			for (i = 0; i < len; ++i)
+				*str++ = *s++;
+			while (len < field_width--)
+				*str++ = ' ';
+			continue;
+
+		case 'p':
+			if (field_width == -1) {
+				field_width = 2 * sizeof(void *);
+				flags |= ZEROPAD;
+			}
+			str = number(str,
+				     (unsigned long)va_arg(args, void *), 16,
+				     field_width, precision, flags);
+			continue;
+
+		case 'n':
+			if (qualifier == 'l') {
+				long *ip = va_arg(args, long *);
+				*ip = (str - buf);
+			} else {
+				int *ip = va_arg(args, int *);
+				*ip = (str - buf);
+			}
+			continue;
+
+		case '%':
+			*str++ = '%';
+			continue;
+
+			/* integer number formats - set up the flags and "break" */
+		case 'o':
+			base = 8;
+			break;
+
+		case 'X':
+			flags |= LARGE;
+		case 'x':
+			base = 16;
+			break;
+
+		case 'd':
+		case 'i':
+			flags |= SIGN;
+		case 'u':
+			break;
+
+		default:
+			*str++ = '%';
+			if (*fmt)
+				*str++ = *fmt;
+			else
+				--fmt;
+			continue;
+		}
+		if (qualifier == 'l')
+			num = va_arg(args, unsigned long);
+		else if (qualifier == 'h') {
+			num = (unsigned short)va_arg(args, int);
+			if (flags & SIGN)
+				num = (short)num;
+		} else if (flags & SIGN)
+			num = va_arg(args, int);
+		else
+			num = va_arg(args, unsigned int);
+		str = number(str, num, base, field_width, precision, flags);
+	}
+	*str = '\0';
+	return str - buf;
+}
+
+int sprintf(char *buf, const char *fmt, ...)
+{
+	va_list args;
+	int i;
+
+	va_start(args, fmt);
+	i = vsprintf(buf, fmt, args);
+	va_end(args);
+	return i;
+}
+
+int printf(const char *fmt, ...)
+{
+	char printf_buf[1024];
+	va_list args;
+	int printed;
+
+	va_start(args, fmt);
+	printed = vsprintf(printf_buf, fmt, args);
+	va_end(args);
+
+	puts(printf_buf);
+
+	return printed;
+}
diff --git a/arch/i386/boot/tty.c b/arch/i386/boot/tty.c
new file mode 100644
index 0000000..a8db787
--- /dev/null
+++ b/arch/i386/boot/tty.c
@@ -0,0 +1,112 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/tty.c
+ *
+ * Very simple screen I/O
+ * XXX: Probably should add very simple serial I/O?
+ */
+
+#include "boot.h"
+
+/*
+ * These functions are in .inittext so they can be used to signal
+ * error during initialization.
+ */
+
+void __attribute__((section(".inittext"))) putchar(int ch)
+{
+	unsigned char c = ch;
+
+	if (c == '\n')
+		putchar('\r');	/* \n -> \r\n */
+
+	/* int $0x10 is known to have bugs involving touching registers
+	   it shouldn't.  Be extra conservative... */
+	asm volatile("pushal; int $0x10; popal"
+		     : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
+}
+
+void __attribute__((section(".inittext"))) puts(const char *str)
+{
+	int n = 0;
+	while (*str) {
+		putchar(*str++);
+		n++;
+	}
+}
+
+/*
+ * Read the CMOS clock through the BIOS, and return the
+ * seconds in BCD.
+ */
+
+static u8 gettime(void)
+{
+	u16 ax = 0x0200;
+	u16 cx, dx;
+
+	asm("int $0x1a"
+	    : "+a" (ax), "=c" (cx), "=d" (dx)
+	    : : "ebx", "esi", "edi");
+
+	return dx >> 8;
+}
+
+/*
+ * Read from the keyboard
+ */
+int getchar(void)
+{
+	u16 ax = 0;
+	asm("int $0x16" : "+a" (ax));
+
+	return ax & 0xff;
+}
+
+static int kbd_pending(void)
+{
+	u8 pending;
+	asm("int $0x16; setnz %0"
+	    : "=rm" (pending)
+	    : "a" (0x0100));
+	return pending;
+}
+
+void kbd_flush(void)
+{
+	for (;;) {
+		if (!kbd_pending())
+			break;
+		getchar();
+	}
+}
+
+int getchar_timeout(void)
+{
+	int cnt = 30;
+	int t0, t1;
+
+	t0 = gettime();
+
+	while (cnt) {
+		if (kbd_pending())
+			return getchar();
+
+		t1 = gettime();
+		if (t0 != t1) {
+			cnt--;
+			t0 = t1;
+		}
+	}
+
+	return 0;		/* Timeout! */
+}
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 21/33] Version string for the new x86 setup code
       [not found]   ` <b4eed00df1889f94e8799ca6c0ce081bc5140688.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:52     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:52 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Module which only includes the kernel version string.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/version.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/version.c

diff --git a/arch/i386/boot/version.c b/arch/i386/boot/version.c
new file mode 100644
index 0000000..c61462f
--- /dev/null
+++ b/arch/i386/boot/version.c
@@ -0,0 +1,23 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/version.c
+ *
+ * Kernel version string
+ */
+
+#include "boot.h"
+#include <linux/utsrelease.h>
+#include <linux/compile.h>
+
+const char kernel_version[] =
+	UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") "
+	UTS_VERSION;
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 22/33] CPU features verification for the new x86 setup code
       [not found]   ` <f1626ee0c265de9c41725f61eaee8a9017d8c8ff.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:52     ` H. Peter Anvin
  2007-07-10  7:37       ` Sébastien Dugué
  0 siblings, 1 reply; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:52 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Verify that the CPU has enough features to run the kernel.  This may
entail enabling features on some CPUs.

By doing this in the setup code we can be guaranteed to still be able to
write to the console through the BIOS.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/cpu.c      |   69 ++++++++++++
 arch/i386/boot/cpucheck.c |  267 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 336 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/cpu.c
 create mode 100644 arch/i386/boot/cpucheck.c

diff --git a/arch/i386/boot/cpu.c b/arch/i386/boot/cpu.c
new file mode 100644
index 0000000..042d894
--- /dev/null
+++ b/arch/i386/boot/cpu.c
@@ -0,0 +1,69 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/cpucheck.c
+ *
+ * Check for obligatory CPU features and abort if the features are not
+ * present.
+ */
+
+#include "boot.h"
+#include "bitops.h"
+#include <asm/cpufeature.h>
+
+static char *cpu_name(int level)
+{
+	static char buf[6];
+
+	if (level == 64) {
+		return "x86-64";
+	} else {
+		sprintf(buf, "i%d86", level);
+		return buf;
+	}
+}
+
+int validate_cpu(void)
+{
+	u32 *err_flags;
+	int cpu_level, req_level;
+
+	check_cpu(&cpu_level, &req_level, &err_flags);
+
+	if (cpu_level < req_level) {
+		printf("This kernel requires an %s CPU, ",
+		       cpu_name(req_level));
+		printf("but only detected an %s CPU.\n",
+		       cpu_name(cpu_level));
+		return -1;
+	}
+
+	if (err_flags) {
+		int i, j;
+		puts("This kernel requires the following features "
+		     "not present on the CPU:\n");
+
+		for (i = 0; i < NCAPINTS; i++) {
+			u32 e = err_flags[i];
+
+			for (j = 0; j < 32; j++) {
+				if (e & 1)
+					printf("%d:%d ", i, j);
+
+				e >>= 1;
+			}
+		}
+		putchar('\n');
+		return -1;
+	} else {
+		return 0;
+	}
+}
diff --git a/arch/i386/boot/cpucheck.c b/arch/i386/boot/cpucheck.c
new file mode 100644
index 0000000..431bef8
--- /dev/null
+++ b/arch/i386/boot/cpucheck.c
@@ -0,0 +1,267 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/cpu.c
+ *
+ * Check for obligatory CPU features and abort if the features are not
+ * present.  This code should be compilable as 16-, 32- or 64-bit
+ * code, so be very careful with types and inline assembly.
+ *
+ * This code should not contain any messages; that requires an
+ * additional wrapper.
+ *
+ * As written, this code is not safe for inclusion into the kernel
+ * proper (after FPU initialization, in particular).
+ */
+
+#ifdef _SETUP
+# include "boot.h"
+# include "bitops.h"
+#endif
+#include <linux/types.h>
+#include <asm/cpufeature.h>
+#include <asm/processor-flags.h>
+#include <asm/required-features.h>
+#include <asm/msr-index.h>
+
+struct cpu_features {
+	int level;		/* Family, or 64 for x86-64 */
+	int model;
+	u32 flags[NCAPINTS];
+};
+
+static struct cpu_features cpu;
+static u32 cpu_vendor[3];
+static u32 err_flags[NCAPINTS];
+
+#ifdef CONFIG_X86_64
+static const int req_level = 64;
+#elif defined(CONFIG_X86_MINIMUM_CPU_FAMILY)
+static const int req_level = CONFIG_X86_MINIMUM_CPU_FAMILY;
+#else
+static const int req_level = 3;
+#endif
+
+static const u32 req_flags[NCAPINTS] =
+{
+	REQUIRED_MASK0,
+	REQUIRED_MASK1,
+	REQUIRED_MASK2,
+	REQUIRED_MASK3,
+	REQUIRED_MASK4,
+	REQUIRED_MASK5,
+	REQUIRED_MASK6,
+	REQUIRED_MASK7,
+};
+
+#define A32(a,b,c,d) (((d) << 24)+((c) << 16)+((b) << 8)+(a))
+
+static int is_amd(void)
+{
+	return cpu_vendor[0] == A32('A','u','t','h') &&
+	       cpu_vendor[1] == A32('e','n','t','i') &&
+	       cpu_vendor[2] == A32('c','A','M','D');
+}
+
+static int is_centaur(void)
+{
+	return cpu_vendor[0] == A32('C','e','n','t') &&
+	       cpu_vendor[1] == A32('a','u','r','H') &&
+	       cpu_vendor[2] == A32('a','u','l','s');
+}
+
+static int is_transmeta(void)
+{
+	return cpu_vendor[0] == A32('G','e','n','u') &&
+	       cpu_vendor[1] == A32('i','n','e','T') &&
+	       cpu_vendor[2] == A32('M','x','8','6');
+}
+
+static int has_fpu(void)
+{
+	u16 fcw = -1, fsw = -1;
+	u32 cr0;
+
+	asm("movl %%cr0,%0" : "=r" (cr0));
+	if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
+		cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
+		asm volatile("movl %0,%%cr0" : : "r" (cr0));
+	}
+
+	asm("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw));
+
+	return fsw == 0 && (fcw & 0x103f) == 0x003f;
+}
+
+static int has_eflag(u32 mask)
+{
+	u32 f0, f1;
+
+	asm("pushfl ; "
+	    "pushfl ; "
+	    "popl %0 ; "
+	    "movl %0,%1 ; "
+	    "xorl %2,%1 ; "
+	    "pushl %1 ; "
+	    "popfl ; "
+	    "pushfl ; "
+	    "popl %1 ; "
+	    "popfl"
+	    : "=r" (f0), "=r" (f1)
+	    : "g" (mask));
+
+	return !!((f0^f1) & mask);
+}
+
+static void get_flags(void)
+{
+	u32 max_intel_level, max_amd_level;
+	u32 tfms;
+
+	if (has_fpu())
+		set_bit(X86_FEATURE_FPU, cpu.flags);
+
+	if (has_eflag(X86_EFLAGS_ID)) {
+		asm("cpuid"
+		    : "=a" (max_intel_level),
+		      "=b" (cpu_vendor[0]),
+		      "=d" (cpu_vendor[1]),
+		      "=c" (cpu_vendor[2])
+		    : "a" (0));
+
+		if (max_intel_level >= 0x00000001 &&
+		    max_intel_level <= 0x0000ffff) {
+			asm("cpuid"
+			    : "=a" (tfms),
+			      "=c" (cpu.flags[4]),
+			      "=d" (cpu.flags[0])
+			    : "a" (0x00000001)
+			    : "ebx");
+			cpu.level = (tfms >> 8) & 15;
+			cpu.model = (tfms >> 4) & 15;
+			if (cpu.level >= 6)
+				cpu.model += ((tfms >> 16) & 0xf) << 4;
+		}
+
+		asm("cpuid"
+		    : "=a" (max_amd_level)
+		    : "a" (0x80000000)
+		    : "ebx", "ecx", "edx");
+
+		if (max_amd_level >= 0x80000001 &&
+		    max_amd_level <= 0x8000ffff) {
+			u32 eax = 0x80000001;
+			asm("cpuid"
+			    : "+a" (eax),
+			      "=c" (cpu.flags[6]),
+			      "=d" (cpu.flags[1])
+			    : : "ebx");
+		}
+	}
+}
+
+/* Returns a bitmask of which words we have error bits in */
+static int check_flags(void)
+{
+	u32 err;
+	int i;
+
+	err = 0;
+	for (i = 0; i < NCAPINTS; i++) {
+		err_flags[i] = req_flags[i] & ~cpu.flags[i];
+		if (err_flags[i])
+			err |= 1 << i;
+	}
+
+	return err;
+}
+
+/*
+ * Returns -1 on error.
+ *
+ * *cpu_level is set to the current CPU level; *req_level to the required
+ * level.  x86-64 is considered level 64 for this purpose.
+ *
+ * *err_flags_ptr is set to the flags error array if there are flags missing.
+ */
+int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
+{
+	int err;
+
+	memset(&cpu.flags, 0, sizeof cpu.flags);
+	cpu.level = 3;
+
+	if (has_eflag(X86_EFLAGS_AC))
+		cpu.level = 4;
+
+	get_flags();
+	err = check_flags();
+
+	if (test_bit(X86_FEATURE_LM, cpu.flags))
+		cpu.level = 64;
+
+	if (err == 0x01 &&
+	    !(err_flags[0] &
+	      ~((1 << X86_FEATURE_XMM)|(1 << X86_FEATURE_XMM2))) &&
+	    is_amd()) {
+		/* If this is an AMD and we're only missing SSE+SSE2, try to
+		   turn them on */
+
+		u32 ecx = MSR_K7_HWCR;
+		u32 eax, edx;
+
+		asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
+		eax &= ~(1 << 15);
+		asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
+
+		get_flags();	/* Make sure it really did something */
+		err = check_flags();
+	} else if (err == 0x01 &&
+		   !(err_flags[0] & ~(1 << X86_FEATURE_CX8)) &&
+		   is_centaur() && cpu.model >= 6) {
+		/* If this is a VIA C3, we might have to enable CX8
+		   explicitly */
+
+		u32 ecx = MSR_VIA_FCR;
+		u32 eax, edx;
+
+		asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
+		eax |= (1<<1)|(1<<7);
+		asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
+
+		set_bit(X86_FEATURE_CX8, cpu.flags);
+		err = check_flags();
+	} else if (err == 0x01 && is_transmeta()) {
+		/* Transmeta might have masked feature bits in word 0 */
+
+		u32 ecx = 0x80860004;
+		u32 eax, edx;
+		u32 level = 1;
+
+		asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
+		asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
+		asm("cpuid"
+		    : "+a" (level), "=d" (cpu.flags[0])
+		    : : "ecx", "ebx");
+		asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
+
+		err = check_flags();
+	}
+
+	if (err_flags_ptr)
+		*err_flags_ptr = err ? err_flags : NULL;
+	if (cpu_level_ptr)
+		*cpu_level_ptr = cpu.level;
+	if (req_level_ptr)
+		*req_level_ptr = req_level;
+
+	return (cpu.level < req_level || err) ? -1 : 0;
+}
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 23/33] EDD probing code for the new x86 setup code
       [not found]   ` <b577403d806edfbb1c17ecfec94971fc757a066c.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:52     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:52 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Probe EDD and MBR signatures, in order to make it easier to map
physical hard drives to BIOS drives.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/edd.c |  196 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 196 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/edd.c

diff --git a/arch/i386/boot/edd.c b/arch/i386/boot/edd.c
new file mode 100644
index 0000000..25a2824
--- /dev/null
+++ b/arch/i386/boot/edd.c
@@ -0,0 +1,196 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/edd.c
+ *
+ * Get EDD BIOS disk information
+ */
+
+#include "boot.h"
+#include <linux/edd.h>
+
+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+
+struct edd_dapa {
+	u8	pkt_size;
+	u8	rsvd;
+	u16	sector_cnt;
+	u16	buf_off, buf_seg;
+	u64	lba;
+	u64	buf_lin_addr;
+};
+
+/*
+ * Read the MBR (first sector) from a specific device.
+ */
+static int read_mbr(u8 devno, void *buf)
+{
+	struct edd_dapa dapa;
+	u16 ax, bx, cx, dx, si;
+
+	memset(&dapa, 0, sizeof dapa);
+	dapa.pkt_size = sizeof(dapa);
+	dapa.sector_cnt = 1;
+	dapa.buf_off = (size_t)buf;
+	dapa.buf_seg = ds();
+	/* dapa.lba = 0; */
+
+	ax = 0x4200;		/* Extended Read */
+	si = (size_t)&dapa;
+	dx = devno;
+	asm("pushfl; stc; int $0x13; setc %%al; popfl"
+	    : "+a" (ax), "+S" (si), "+d" (dx)
+	    : "m" (dapa)
+	    : "ebx", "ecx", "edi", "memory");
+
+	if (!(u8)ax)
+		return 0;	/* OK */
+
+	ax = 0x0201;		/* Legacy Read, one sector */
+	cx = 0x0001;		/* Sector 0-0-1 */
+	dx = devno;
+	bx = (size_t)buf;
+	asm("pushfl; stc; int $0x13; setc %%al; popfl"
+	    : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
+	    : : "esi", "edi", "memory");
+
+	return -(u8)ax;		/* 0 or -1 */
+}
+
+static u32 read_mbr_sig(u8 devno, struct edd_info *ei)
+{
+	int sector_size;
+	char *mbrbuf_ptr, *mbrbuf_end;
+	u32 mbrsig;
+	u32 buf_base, mbr_base;
+	extern char _end[];
+	static char mbr_buf[1024];
+
+	sector_size = ei->params.bytes_per_sector;
+	if (!sector_size)
+		sector_size = 512; /* Best available guess */
+
+	buf_base = (ds() << 4) + (u32)&_end;
+	mbr_base = (buf_base+sector_size-1) & ~(sector_size-1);
+	mbrbuf_ptr = mbr_buf + (mbr_base-buf_base);
+	mbrbuf_end = mbrbuf_ptr + sector_size;
+
+	if (!(boot_params.hdr.loadflags & CAN_USE_HEAP))
+		return 0;
+	if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr)
+		return 0;
+
+	if (read_mbr(devno, mbrbuf_ptr))
+		return 0;
+
+	mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET];
+	return mbrsig;
+}
+
+static int get_edd_info(u8 devno, struct edd_info *ei)
+{
+	u16 ax, bx, cx, dx, di;
+
+	memset(ei, 0, sizeof *ei);
+
+	/* Check Extensions Present */
+
+	ax = 0x4100;
+	bx = EDDMAGIC1;
+	dx = devno;
+	asm("pushfl; stc; int $0x13; setc %%al; popfl"
+	    : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
+	    : : "esi", "edi");
+
+	if ((u8)ax)
+		return -1;	/* No extended information */
+
+	if (bx != EDDMAGIC2)
+		return -1;
+
+	ei->device  = devno;
+	ei->version = ax >> 8;	/* EDD version number */
+	ei->interface_support = cx; /* EDD functionality subsets */
+
+	/* Extended Get Device Parameters */
+
+	ei->params.length = sizeof(ei->params);
+	ax = 0x4800;
+	dx = devno;
+	asm("pushfl; int $0x13; popfl"
+	    : "+a" (ax), "+d" (dx)
+	    : "S" (&ei->params)
+	    : "ebx", "ecx", "edi");
+
+	/* Get legacy CHS parameters */
+
+	/* Ralf Brown recommends setting ES:DI to 0:0 */
+	ax = 0x0800;
+	dx = devno;
+	di = 0;
+	asm("pushw %%es; "
+	    "movw %%di,%%es; "
+	    "pushfl; stc; int $0x13; setc %%al; popfl; "
+	    "popw %%es"
+	    : "+a" (ax), "=b" (bx), "=c" (cx), "+d" (dx), "+D" (di)
+	    : : "esi");
+
+	if ((u8)ax == 0) {
+		ei->legacy_max_cylinder = (cx >> 8) + ((cx & 0xc0) << 2);
+		ei->legacy_max_head = dx >> 8;
+		ei->legacy_sectors_per_track = cx & 0x3f;
+	}
+
+	return 0;
+}
+
+void query_edd(void)
+{
+	char eddarg[8];
+	int do_mbr = 1;
+	int do_edd = 1;
+	int devno;
+	struct edd_info ei, *edp;
+
+	if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) {
+		if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip"))
+			do_mbr = 0;
+		else if (!strcmp(eddarg, "off"))
+			do_edd = 0;
+	}
+
+	edp = (struct edd_info *)boot_params.eddbuf;
+
+	if (!do_edd)
+		return;
+
+	for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
+		/*
+		 * Scan the BIOS-supported hard disks and query EDD
+		 * information...
+		 */
+		get_edd_info(devno, &ei);
+
+		if (boot_params.eddbuf_entries < EDDMAXNR) {
+			memcpy(edp, &ei, sizeof ei);
+			edp++;
+			boot_params.eddbuf_entries++;
+		}
+
+		if (do_mbr) {
+			u32 mbr_sig;
+			mbr_sig = read_mbr_sig(devno, &ei);
+			boot_params.edd_mbr_sig_buffer[devno-0x80] = mbr_sig;
+		}
+	}
+}
+
+#endif
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 24/33] MCA support for new x86 setup code
       [not found]   ` <77f7b2e92bb1de0f9d423b6537b8156296bcf931.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:52     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:52 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

MCA probing support for the new x86 setup code.  This implements the
same functionality as the assembly version.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/mca.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 43 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/mca.c

diff --git a/arch/i386/boot/mca.c b/arch/i386/boot/mca.c
new file mode 100644
index 0000000..9b68bd1
--- /dev/null
+++ b/arch/i386/boot/mca.c
@@ -0,0 +1,43 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/mca.c
+ *
+ * Get the MCA system description table
+ */
+
+#include "boot.h"
+
+int query_mca(void)
+{
+	u8 err;
+	u16 es, bx, len;
+
+	asm("pushw %%es ; "
+	    "int $0x15 ; "
+	    "setc %0 ; "
+	    "movw %%es, %1 ; "
+	    "popw %%es"
+	    : "=acdSDm" (err), "=acdSDm" (es), "=b" (bx)
+	    : "a" (0xc000));
+
+	if (err)
+		return -1;	/* No MCA present */
+
+	set_fs(es);
+	len = rdfs16(bx);
+
+	if (len > sizeof(boot_params.sys_desc_table))
+		len = sizeof(boot_params.sys_desc_table);
+
+	copy_from_fs(&boot_params.sys_desc_table, bx, len);
+	return 0;
+}
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 25/33] Memory probing support for the new x86 setup code
       [not found]   ` <75642968817648a7816a4782f76138e4f608f1ab.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:52     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:52 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Probe memory (INT 15h: E820, E801, 88).

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/memory.c |   99 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 99 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/memory.c

diff --git a/arch/i386/boot/memory.c b/arch/i386/boot/memory.c
new file mode 100644
index 0000000..1a2e62d
--- /dev/null
+++ b/arch/i386/boot/memory.c
@@ -0,0 +1,99 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/memory.c
+ *
+ * Memory detection code
+ */
+
+#include "boot.h"
+
+#define SMAP	0x534d4150	/* ASCII "SMAP" */
+
+static int detect_memory_e820(void)
+{
+	u32 next = 0;
+	u32 size, id;
+	u8 err;
+	struct e820entry *desc = boot_params.e820_map;
+
+	do {
+		size = sizeof(struct e820entry);
+		id = SMAP;
+		asm("int $0x15; setc %0"
+		    : "=am" (err), "+b" (next), "+d" (id), "+c" (size),
+		      "=m" (*desc)
+		    : "D" (desc), "a" (0xe820));
+
+		if (err || id != SMAP)
+			break;
+
+		boot_params.e820_entries++;
+		desc++;
+	} while (next && boot_params.e820_entries < E820MAX);
+
+	return boot_params.e820_entries;
+}
+
+static int detect_memory_e801(void)
+{
+	u16 ax, bx, cx, dx;
+	u8 err;
+
+	bx = cx = dx = 0;
+	ax = 0xe801;
+	asm("stc; int $0x15; setc %0"
+	    : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
+
+	if (err)
+		return -1;
+
+	/* Do we really need to do this? */
+	if (cx || dx) {
+		ax = cx;
+		bx = dx;
+	}
+
+	if (ax > 15*1024)
+		return -1;	/* Bogus! */
+
+	/* This ignores memory above 16MB if we have a memory hole
+	   there.  If someone actually finds a machine with a memory
+	   hole at 16MB and no support for 0E820h they should probably
+	   generate a fake e820 map. */
+	boot_params.alt_mem_k = (ax == 15*1024) ? (dx << 6)+ax : ax;
+
+	return 0;
+}
+
+static int detect_memory_88(void)
+{
+	u16 ax;
+	u8 err;
+
+	ax = 0x8800;
+	asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
+
+	boot_params.screen_info.ext_mem_k = ax;
+
+	return -err;
+}
+
+int detect_memory(void)
+{
+	if (detect_memory_e820() > 0)
+		return 0;
+
+	if (!detect_memory_e801())
+		return 0;
+
+	return detect_memory_88();
+}
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 26/33] Voyager support for the new x86 setup code
       [not found]   ` <dd2fade47882935c137f6d2a3c955eac1f6f8ecf.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:52     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:52 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Voyager support for the new x86 setup code.  This implements the same
functionality as the assembly version.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/voyager.c |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 46 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/voyager.c

diff --git a/arch/i386/boot/voyager.c b/arch/i386/boot/voyager.c
new file mode 100644
index 0000000..9221614
--- /dev/null
+++ b/arch/i386/boot/voyager.c
@@ -0,0 +1,46 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/voyager.c
+ *
+ * Get the Voyager config information
+ */
+
+#include "boot.h"
+
+#ifdef CONFIG_X86_VOYAGER
+
+int query_voyager(void)
+{
+	u8 err;
+	u16 es, di;
+	/* Abuse the apm_bios_info area for this */
+	u8 *data_ptr = (u8 *)&boot_params.apm_bios_info;
+
+	data_ptr[0] = 0xff;	/* Flag on config not found(?) */
+
+	asm("pushw %%es ; "
+	    "int $0x15 ; "
+	    "setc %0 ; "
+	    "movw %%es, %1 ; "
+	    "popw %%es"
+	    : "=qm" (err), "=rm" (es), "=D" (di)
+	    : "a" (0xffc0));
+
+	if (err)
+		return -1;	/* Not Voyager */
+
+	set_fs(es);
+	copy_from_fs(data_ptr, di, 7);	/* Table is 7 bytes apparently */
+	return 0;
+}
+
+#endif /* CONFIG_X86_VOYAGER */
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 27/33] Video mode probing support for the new x86 setup code
       [not found]   ` <f8afa57a4934b75080449e8dd3a23d178be77a41.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:52     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:52 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Video mode probing for the new x86 setup code.  This code breaks down
different drivers into modules.  This code deliberately drops support
for a lot of the vendor-specific mode probing present in the assembly
version, since a lot of those probes have been found to be stale in
current versions of those chips -- frequently, support for those modes
have been dropped from recent video BIOSes due to space constraints,
but the video BIOS signatures are still the same.

However, additional drivers should be extremely straightforward to plug
in, if desirable.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/vesa.h       |   79 ++++++++
 arch/i386/boot/video-bios.c |  125 ++++++++++++
 arch/i386/boot/video-vesa.c |  284 +++++++++++++++++++++++++++
 arch/i386/boot/video-vga.c  |  260 ++++++++++++++++++++++++
 arch/i386/boot/video.c      |  456 +++++++++++++++++++++++++++++++++++++++++++
 arch/i386/boot/video.h      |  145 ++++++++++++++
 6 files changed, 1349 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/vesa.h
 create mode 100644 arch/i386/boot/video-bios.c
 create mode 100644 arch/i386/boot/video-vesa.c
 create mode 100644 arch/i386/boot/video-vga.c
 create mode 100644 arch/i386/boot/video.c
 create mode 100644 arch/i386/boot/video.h

diff --git a/arch/i386/boot/vesa.h b/arch/i386/boot/vesa.h
new file mode 100644
index 0000000..ff5b73c
--- /dev/null
+++ b/arch/i386/boot/vesa.h
@@ -0,0 +1,79 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1999-2007 H. Peter Anvin - All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef BOOT_VESA_H
+#define BOOT_VESA_H
+
+typedef struct {
+	u16 off, seg;
+} far_ptr;
+
+/* VESA General Information table */
+struct vesa_general_info {
+	u32 signature;		/* 0 Magic number = "VESA" */
+	u16 version;		/* 4 */
+	far_ptr vendor_string;	/* 6 */
+	u32 capabilities;	/* 10 */
+	far_ptr video_mode_ptr;	/* 14 */
+	u16 total_memory;	/* 18 */
+
+	u16 oem_software_rev;	/* 20 */
+	far_ptr oem_vendor_name_ptr;	/* 22 */
+	far_ptr oem_product_name_ptr;	/* 26 */
+	far_ptr oem_product_rev_ptr;	/* 30 */
+
+	u8 reserved[222];	/* 34 */
+	u8 oem_data[256];	/* 256 */
+} __attribute__ ((packed));
+
+#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
+#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24))
+
+struct vesa_mode_info {
+	u16 mode_attr;		/* 0 */
+	u8 win_attr[2];		/* 2 */
+	u16 win_grain;		/* 4 */
+	u16 win_size;		/* 6 */
+	u16 win_seg[2];		/* 8 */
+	far_ptr win_scheme;	/* 12 */
+	u16 logical_scan;	/* 16 */
+
+	u16 h_res;		/* 18 */
+	u16 v_res;		/* 20 */
+	u8 char_width;		/* 22 */
+	u8 char_height;		/* 23 */
+	u8 memory_planes;	/* 24 */
+	u8 bpp;			/* 25 */
+	u8 banks;		/* 26 */
+	u8 memory_layout;	/* 27 */
+	u8 bank_size;		/* 28 */
+	u8 image_planes;	/* 29 */
+	u8 page_function;	/* 30 */
+
+	u8 rmask;		/* 31 */
+	u8 rpos;		/* 32 */
+	u8 gmask;		/* 33 */
+	u8 gpos;		/* 34 */
+	u8 bmask;		/* 35 */
+	u8 bpos;		/* 36 */
+	u8 resv_mask;		/* 37 */
+	u8 resv_pos;		/* 38 */
+	u8 dcm_info;		/* 39 */
+
+	u32 lfb_ptr;		/* 40 Linear frame buffer address */
+	u32 offscreen_ptr;	/* 44 Offscreen memory address */
+	u16 offscreen_size;	/* 48 */
+
+	u8 reserved[206];	/* 50 */
+} __attribute__ ((packed));
+
+#endif				/* LIB_SYS_VESA_H */
diff --git a/arch/i386/boot/video-bios.c b/arch/i386/boot/video-bios.c
new file mode 100644
index 0000000..afea46c
--- /dev/null
+++ b/arch/i386/boot/video-bios.c
@@ -0,0 +1,125 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video-bios.c
+ *
+ * Standard video BIOS modes
+ *
+ * We have two options for this; silent and scanned.
+ */
+
+#include "boot.h"
+#include "video.h"
+
+__videocard video_bios;
+
+/* Set a conventional BIOS mode */
+static int set_bios_mode(u8 mode);
+
+static int bios_set_mode(struct mode_info *mi)
+{
+	return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS);
+}
+
+static int set_bios_mode(u8 mode)
+{
+	u16 ax;
+	u8 new_mode;
+
+	ax = mode;		/* AH=0x00 Set Video Mode */
+	asm volatile(INT10
+		     : "+a" (ax)
+		     : : "ebx", "ecx", "edx", "esi", "edi");
+
+	ax = 0x0f00;		/* Get Current Video Mode */
+	asm volatile(INT10
+		     : "+a" (ax)
+		     : : "ebx", "ecx", "edx", "esi", "edi");
+
+	do_restore = 1;		/* Assume video contents was lost */
+	new_mode = ax & 0x7f;	/* Not all BIOSes are clean with the top bit */
+
+	if (new_mode == mode)
+		return 0;	/* Mode change OK */
+
+	if (new_mode != boot_params.screen_info.orig_video_mode) {
+		/* Mode setting failed, but we didn't end up where we
+		   started.  That's bad.  Try to revert to the original
+		   video mode. */
+		ax = boot_params.screen_info.orig_video_mode;
+		asm volatile(INT10
+			     : "+a" (ax)
+			     : : "ebx", "ecx", "edx", "esi", "edi");
+	}
+	return -1;
+}
+
+static int bios_probe(void)
+{
+	u8 mode;
+	u8 saved_mode = boot_params.screen_info.orig_video_mode;
+	u16 crtc;
+	struct mode_info *mi;
+	int nmodes = 0;
+
+	if (adapter != ADAPTER_EGA && adapter != ADAPTER_VGA)
+		return 0;
+
+	set_fs(0);
+	crtc = vga_crtc();
+
+	video_bios.modes = GET_HEAP(struct mode_info, 0);
+
+	for (mode = 0x14; mode <= 0x7f; mode++) {
+		if (heap_free() < sizeof(struct mode_info))
+			break;
+
+		if (mode_defined(VIDEO_FIRST_BIOS+mode))
+			continue;
+
+		if (set_bios_mode(mode))
+			continue;
+
+		/* Try to verify that it's a text mode. */
+
+		/* Attribute Controller: make graphics controller disabled */
+		if (in_idx(0x3c0, 0x10) & 0x01)
+			continue;
+
+		/* Graphics Controller: verify Alpha addressing enabled */
+		if (in_idx(0x3ce, 0x06) & 0x01)
+			continue;
+
+		/* CRTC cursor location low should be zero(?) */
+		if (in_idx(crtc, 0x0f))
+			continue;
+
+		mi = GET_HEAP(struct mode_info, 1);
+		mi->mode = VIDEO_FIRST_BIOS+mode;
+		mi->x = rdfs16(0x44a);
+		mi->y = rdfs8(0x484)+1;
+		nmodes++;
+	}
+
+	set_bios_mode(saved_mode);
+
+	return nmodes;
+}
+
+__videocard video_bios =
+{
+	.card_name	= "BIOS (scanned)",
+	.probe		= bios_probe,
+	.set_mode	= bios_set_mode,
+	.unsafe		= 1,
+	.xmode_first	= VIDEO_FIRST_BIOS,
+	.xmode_n	= 0x80,
+};
diff --git a/arch/i386/boot/video-vesa.c b/arch/i386/boot/video-vesa.c
new file mode 100644
index 0000000..e6aa9eb
--- /dev/null
+++ b/arch/i386/boot/video-vesa.c
@@ -0,0 +1,284 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video-vesa.c
+ *
+ * VESA text modes
+ */
+
+#include "boot.h"
+#include "video.h"
+#include "vesa.h"
+
+/* VESA information */
+static struct vesa_general_info vginfo;
+static struct vesa_mode_info vminfo;
+
+__videocard video_vesa;
+
+static void vesa_store_mode_params_graphics(void);
+
+static int vesa_probe(void)
+{
+#if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID)
+	u16 ax;
+	u16 mode;
+	addr_t mode_ptr;
+	struct mode_info *mi;
+	int nmodes = 0;
+
+	video_vesa.modes = GET_HEAP(struct mode_info, 0);
+
+	vginfo.signature = VBE2_MAGIC;
+
+	/* Optimistically assume a VESA BIOS is register-clean... */
+	ax = 0x4f00;
+	asm("int $0x10" : "+a" (ax), "=m" (vginfo) : "D" (&vginfo));
+
+	if (ax != 0x004f ||
+	    vginfo.signature != VESA_MAGIC ||
+	    vginfo.version < 0x0102)
+		return 0;	/* Not present */
+#endif /* CONFIG_VIDEO_VESA || CONFIG_FIRMWARE_EDID */
+#ifdef CONFIG_VIDEO_VESA
+	set_fs(vginfo.video_mode_ptr.seg);
+	mode_ptr = vginfo.video_mode_ptr.off;
+
+	while ((mode = rdfs16(mode_ptr)) != 0xffff) {
+		mode_ptr += 2;
+
+		if (heap_free() < sizeof(struct mode_info))
+			break;	/* Heap full, can't save mode info */
+
+		if (mode & ~0x1ff)
+			continue;
+
+		memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
+
+		ax = 0x4f01;
+		asm("int $0x10"
+		    : "+a" (ax), "=m" (vminfo)
+		    : "c" (mode), "D" (&vminfo));
+
+		if (ax != 0x004f)
+			continue;
+
+		if ((vminfo.mode_attr & 0x15) == 0x05) {
+			/* Text Mode, TTY BIOS supported,
+			   supported by hardware */
+			mi = GET_HEAP(struct mode_info, 1);
+			mi->mode = mode + VIDEO_FIRST_VESA;
+			mi->x    = vminfo.h_res;
+			mi->y    = vminfo.v_res;
+			nmodes++;
+		} else if ((vminfo.mode_attr & 0x99) == 0x99) {
+#ifdef CONFIG_FB
+			/* Graphics mode, color, linear frame buffer
+			   supported -- register the mode but hide from
+			   the menu.  Only do this if framebuffer is
+			   configured, however, otherwise the user will
+			   be left without a screen. */
+			mi = GET_HEAP(struct mode_info, 1);
+			mi->mode = mode + VIDEO_FIRST_VESA;
+			mi->x = mi->y = 0;
+			nmodes++;
+#endif
+		}
+	}
+
+	return nmodes;
+#else
+	return 0;
+#endif /* CONFIG_VIDEO_VESA */
+}
+
+static int vesa_set_mode(struct mode_info *mode)
+{
+	u16 ax;
+	int is_graphic;
+	u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;
+
+	memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
+
+	ax = 0x4f01;
+	asm("int $0x10"
+	    : "+a" (ax), "=m" (vminfo)
+	    : "c" (vesa_mode), "D" (&vminfo));
+
+	if (ax != 0x004f)
+		return -1;
+
+	if ((vminfo.mode_attr & 0x15) == 0x05) {
+		/* It's a supported text mode */
+		is_graphic = 0;
+	} else if ((vminfo.mode_attr & 0x99) == 0x99) {
+		/* It's a graphics mode with linear frame buffer */
+		is_graphic = 1;
+		vesa_mode |= 0x4000; /* Request linear frame buffer */
+	} else {
+		return -1;	/* Invalid mode */
+	}
+
+
+	ax = 0x4f02;
+	asm volatile("int $0x10"
+		     : "+a" (ax)
+		     : "b" (vesa_mode), "D" (0));
+
+	if (ax != 0x004f)
+		return -1;
+
+	graphic_mode = is_graphic;
+	if (!is_graphic) {
+		/* Text mode */
+		force_x = mode->x;
+		force_y = mode->y;
+		do_restore = 1;
+	} else {
+		/* Graphics mode */
+		vesa_store_mode_params_graphics();
+	}
+
+	return 0;
+}
+
+
+/* Switch DAC to 8-bit mode */
+static void vesa_dac_set_8bits(void)
+{
+	u8 dac_size = 6;
+
+	/* If possible, switch the DAC to 8-bit mode */
+	if (vginfo.capabilities & 1) {
+		u16 ax, bx;
+
+		ax = 0x4f08;
+		bx = 0x0800;
+		asm volatile(INT10
+			     : "+a" (ax), "+b" (bx)
+			     : : "ecx", "edx", "esi", "edi");
+
+		if (ax == 0x004f)
+			dac_size = bx >> 8;
+	}
+
+	/* Set the color sizes to the DAC size, and offsets to 0 */
+	boot_params.screen_info.red_size = dac_size;
+	boot_params.screen_info.green_size = dac_size;
+	boot_params.screen_info.blue_size = dac_size;
+	boot_params.screen_info.rsvd_size = dac_size;
+
+	boot_params.screen_info.red_pos = 0;
+	boot_params.screen_info.green_pos = 0;
+	boot_params.screen_info.blue_pos = 0;
+	boot_params.screen_info.rsvd_pos = 0;
+}
+
+/* Save the VESA protected mode info */
+static void vesa_store_pm_info(void)
+{
+	u16 ax, bx, di, es;
+
+	ax = 0x4f0a;
+	bx = di = 0;
+	asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
+	    : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
+	    : : "ecx", "esi");
+
+	if (ax != 0x004f)
+		return;
+
+	boot_params.screen_info.vesapm_seg = es;
+	boot_params.screen_info.vesapm_off = di;
+}
+
+/*
+ * Save video mode parameters for graphics mode
+ */
+static void vesa_store_mode_params_graphics(void)
+{
+	/* Tell the kernel we're in VESA graphics mode */
+	boot_params.screen_info.orig_video_isVGA = 0x23;
+
+	/* Mode parameters */
+	boot_params.screen_info.vesa_attributes = vminfo.mode_attr;
+	boot_params.screen_info.lfb_linelength = vminfo.logical_scan;
+	boot_params.screen_info.lfb_width = vminfo.h_res;
+	boot_params.screen_info.lfb_height = vminfo.v_res;
+	boot_params.screen_info.lfb_depth = vminfo.bpp;
+	boot_params.screen_info.pages = vminfo.image_planes;
+	boot_params.screen_info.lfb_base = vminfo.lfb_ptr;
+	memcpy(&boot_params.screen_info.red_size,
+	       &vminfo.rmask, 8);
+
+	/* General parameters */
+	boot_params.screen_info.lfb_size = vginfo.total_memory;
+
+	if (vminfo.bpp <= 8)
+		vesa_dac_set_8bits();
+
+	vesa_store_pm_info();
+}
+
+/*
+ * Save EDID information for the kernel; this is invoked, separately,
+ * after mode-setting.
+ */
+void vesa_store_edid(void)
+{
+#ifdef CONFIG_FIRMWARE_EDID
+	u16 ax, bx, cx, dx, di;
+
+	/* Apparently used as a nonsense token... */
+	memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info);
+
+	if (vginfo.version < 0x0200)
+		return;		/* EDID requires VBE 2.0+ */
+
+	ax = 0x4f15;		/* VBE DDC */
+	bx = 0x0000;		/* Report DDC capabilities */
+	cx = 0;			/* Controller 0 */
+	di = 0;			/* ES:DI must be 0 by spec */
+
+	/* Note: The VBE DDC spec is different from the main VESA spec;
+	   we genuinely have to assume all registers are destroyed here. */
+
+	asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
+	    : "+a" (ax), "+b" (bx)
+	    :  "c" (cx), "D" (di)
+	    : "esi");
+
+	if (ax != 0x004f)
+		return;		/* No EDID */
+
+	/* BH = time in seconds to transfer EDD information */
+	/* BL = DDC level supported */
+
+	ax = 0x4f15;		/* VBE DDC */
+	bx = 0x0001;		/* Read EDID */
+	cx = 0;			/* Controller 0 */
+	dx = 0;			/* EDID block number */
+	di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
+	asm(INT10
+	    : "+a" (ax), "+b" (bx), "+d" (dx)
+	    : "c" (cx), "D" (di)
+	    : "esi");
+#endif /* CONFIG_FIRMWARE_EDID */
+}
+
+__videocard video_vesa =
+{
+	.card_name	= "VESA",
+	.probe		= vesa_probe,
+	.set_mode	= vesa_set_mode,
+	.xmode_first	= VIDEO_FIRST_VESA,
+	.xmode_n	= 0x200,
+};
diff --git a/arch/i386/boot/video-vga.c b/arch/i386/boot/video-vga.c
new file mode 100644
index 0000000..700d09a
--- /dev/null
+++ b/arch/i386/boot/video-vga.c
@@ -0,0 +1,260 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video-vga.c
+ *
+ * Common all-VGA modes
+ */
+
+#include "boot.h"
+#include "video.h"
+
+static struct mode_info vga_modes[] = {
+	{ VIDEO_80x25,  80, 25 },
+	{ VIDEO_8POINT, 80, 50 },
+	{ VIDEO_80x43,  80, 43 },
+	{ VIDEO_80x28,  80, 28 },
+	{ VIDEO_80x30,  80, 30 },
+	{ VIDEO_80x34,  80, 34 },
+	{ VIDEO_80x60,  80, 60 },
+};
+
+static struct mode_info ega_modes[] = {
+	{ VIDEO_80x25,  80, 25 },
+	{ VIDEO_8POINT, 80, 43 },
+};
+
+static struct mode_info cga_modes[] = {
+	{ VIDEO_80x25,  80, 25 },
+};
+
+__videocard video_vga;
+
+/* Set basic 80x25 mode */
+static u8 vga_set_basic_mode(void)
+{
+	u16 ax;
+	u8 rows;
+	u8 mode;
+
+#ifdef CONFIG_VIDEO_400_HACK
+	if (adapter >= ADAPTER_VGA) {
+		asm(INT10
+		    : : "a" (0x1202), "b" (0x0030)
+		    : "ecx", "edx", "esi", "edi");
+	}
+#endif
+
+	ax = 0x0f00;
+	asm(INT10
+	    : "+a" (ax)
+	    : : "ebx", "ecx", "edx", "esi", "edi");
+
+	mode = (u8)ax;
+
+	set_fs(0);
+	rows = rdfs8(0x484);	/* rows minus one */
+
+#ifndef CONFIG_VIDEO_400_HACK
+	if ((ax == 0x5003 || ax == 0x5007) &&
+	    (rows == 0 || rows == 24))
+		return mode;
+#endif
+
+	if (mode != 3 && mode != 7)
+		mode = 3;
+
+	/* Set the mode */
+	asm volatile(INT10
+		     : : "a" (mode)
+		     : "ebx", "ecx", "edx", "esi", "edi");
+	do_restore = 1;
+	return mode;
+}
+
+static void vga_set_8font(void)
+{
+	/* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
+
+	/* Set 8x8 font */
+	asm volatile(INT10 : : "a" (0x1112), "b" (0));
+
+	/* Use alternate print screen */
+	asm volatile(INT10 : : "a" (0x1200), "b" (0x20));
+
+	/* Turn off cursor emulation */
+	asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
+
+	/* Cursor is scan lines 6-7 */
+	asm volatile(INT10 : : "a" (0x0100), "c" (0x0607));
+}
+
+static void vga_set_14font(void)
+{
+	/* Set 9x14 font - 80x28 on VGA */
+
+	/* Set 9x14 font */
+	asm volatile(INT10 : : "a" (0x1111), "b" (0));
+
+	/* Turn off cursor emulation */
+	asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
+
+	/* Cursor is scan lines 11-12 */
+	asm volatile(INT10 : : "a" (0x0100), "c" (0x0b0c));
+}
+
+static void vga_set_80x43(void)
+{
+	/* Set 80x43 mode on VGA (not EGA) */
+
+	/* Set 350 scans */
+	asm volatile(INT10 : : "a" (0x1201), "b" (0x30));
+
+	/* Reset video mode */
+	asm volatile(INT10 : : "a" (0x0003));
+
+	vga_set_8font();
+}
+
+/* I/O address of the VGA CRTC */
+u16 vga_crtc(void)
+{
+	return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
+}
+
+static void vga_set_480_scanlines(int end)
+{
+	u16 crtc;
+	u8  csel;
+
+	crtc = vga_crtc();
+
+	out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */
+	out_idx(0x0b, crtc, 0x06); /* Vertical total */
+	out_idx(0x3e, crtc, 0x07); /* Vertical overflow */
+	out_idx(0xea, crtc, 0x10); /* Vertical sync start */
+	out_idx(end, crtc, 0x12); /* Vertical display end */
+	out_idx(0xe7, crtc, 0x15); /* Vertical blank start */
+	out_idx(0x04, crtc, 0x16); /* Vertical blank end */
+	csel = inb(0x3cc);
+	csel &= 0x0d;
+	csel |= 0xe2;
+	outb(csel, 0x3cc);
+}
+
+static void vga_set_80x30(void)
+{
+	vga_set_480_scanlines(0xdf);
+}
+
+static void vga_set_80x34(void)
+{
+	vga_set_14font();
+	vga_set_480_scanlines(0xdb);
+}
+
+static void vga_set_80x60(void)
+{
+	vga_set_8font();
+	vga_set_480_scanlines(0xdf);
+}
+
+static int vga_set_mode(struct mode_info *mode)
+{
+	/* Set the basic mode */
+	vga_set_basic_mode();
+
+	/* Override a possibly broken BIOS */
+	force_x = mode->x;
+	force_y = mode->y;
+
+	switch (mode->mode) {
+	case VIDEO_80x25:
+		break;
+	case VIDEO_8POINT:
+		vga_set_8font();
+		break;
+	case VIDEO_80x43:
+		vga_set_80x43();
+		break;
+	case VIDEO_80x28:
+		vga_set_14font();
+		break;
+	case VIDEO_80x30:
+		vga_set_80x30();
+		break;
+	case VIDEO_80x34:
+		vga_set_80x34();
+		break;
+	case VIDEO_80x60:
+		vga_set_80x60();
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ * Note: this probe includes basic information required by all
+ * systems.  It should be executed first, by making sure
+ * video-vga.c is listed first in the Makefile.
+ */
+static int vga_probe(void)
+{
+	static const char *card_name[] = {
+		"CGA/MDA/HGC", "EGA", "VGA"
+	};
+	static struct mode_info *mode_lists[] = {
+		cga_modes,
+		ega_modes,
+		vga_modes,
+	};
+	static int mode_count[] = {
+		sizeof(cga_modes)/sizeof(struct mode_info),
+		sizeof(ega_modes)/sizeof(struct mode_info),
+		sizeof(vga_modes)/sizeof(struct mode_info),
+	};
+	u8 vga_flag;
+
+	asm(INT10
+	    : "=b" (boot_params.screen_info.orig_video_ega_bx)
+	    : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
+	    : "ecx", "edx", "esi", "edi");
+
+	/* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
+	if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
+		/* EGA/VGA */
+		asm(INT10
+		    : "=a" (vga_flag)
+		    : "a" (0x1a00)
+		    : "ebx", "ecx", "edx", "esi", "edi");
+
+		if (vga_flag == 0x1a) {
+			adapter = ADAPTER_VGA;
+			boot_params.screen_info.orig_video_isVGA = 1;
+		} else {
+			adapter = ADAPTER_EGA;
+		}
+	} else {
+		adapter = ADAPTER_CGA;
+	}
+
+	video_vga.modes = mode_lists[adapter];
+	video_vga.card_name = card_name[adapter];
+	return mode_count[adapter];
+}
+
+__videocard video_vga =
+{
+	.card_name	= "VGA",
+	.probe		= vga_probe,
+	.set_mode	= vga_set_mode,
+};
diff --git a/arch/i386/boot/video.c b/arch/i386/boot/video.c
new file mode 100644
index 0000000..3bb3573
--- /dev/null
+++ b/arch/i386/boot/video.c
@@ -0,0 +1,456 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video.c
+ *
+ * Select video mode
+ */
+
+#include "boot.h"
+#include "video.h"
+#include "vesa.h"
+
+/*
+ * Mode list variables
+ */
+static struct card_info cards[];    /* List of cards to probe for */
+
+/*
+ * Common variables
+ */
+int adapter;			/* 0=CGA/MDA/HGC, 1=EGA, 2=VGA+ */
+u16 video_segment;
+int force_x, force_y;	/* Don't query the BIOS for cols/rows */
+
+int do_restore = 0;	/* Screen contents changed during mode flip */
+int graphic_mode;	/* Graphic mode with linear frame buffer */
+
+static void store_cursor_position(void)
+{
+	u16 curpos;
+	u16 ax, bx;
+
+	ax = 0x0300;
+	bx = 0;
+	asm(INT10
+	    : "=d" (curpos), "+a" (ax), "+b" (bx)
+	    : : "ecx", "esi", "edi");
+
+	boot_params.screen_info.orig_x = curpos;
+	boot_params.screen_info.orig_y = curpos >> 8;
+}
+
+static void store_video_mode(void)
+{
+	u16 ax, page;
+
+	/* N.B.: the saving of the video page here is a bit silly,
+	   since we pretty much assume page 0 everywhere. */
+	ax = 0x0f00;
+	asm(INT10
+	    : "+a" (ax), "=b" (page)
+	    : : "ecx", "edx", "esi", "edi");
+
+	/* Not all BIOSes are clean with respect to the top bit */
+	boot_params.screen_info.orig_video_mode = ax & 0x7f;
+	boot_params.screen_info.orig_video_page = page;
+}
+
+/*
+ * Store the video mode parameters for later usage by the kernel.
+ * This is done by asking the BIOS except for the rows/columns
+ * parameters in the default 80x25 mode -- these are set directly,
+ * because some very obscure BIOSes supply insane values.
+ */
+static void store_mode_params(void)
+{
+	u16 font_size;
+	int x, y;
+
+	/* For graphics mode, it is up to the mode-setting driver
+	   (currently only video-vesa.c) to store the parameters */
+	if (graphic_mode)
+		return;
+
+	store_cursor_position();
+	store_video_mode();
+
+	if (boot_params.screen_info.orig_video_mode == 0x07) {
+		/* MDA, HGC, or VGA in monochrome mode */
+		video_segment = 0xb000;
+	} else {
+		/* CGA, EGA, VGA and so forth */
+		video_segment = 0xb800;
+	}
+
+	set_fs(0);
+	font_size = rdfs16(0x485); /* Font size, BIOS area */
+	boot_params.screen_info.orig_video_points = font_size;
+
+	x = rdfs16(0x44a);
+	y = (adapter == ADAPTER_CGA) ? 25 : rdfs8(0x484)+1;
+
+	if (force_x)
+		x = force_x;
+	if (force_y)
+		y = force_y;
+
+	boot_params.screen_info.orig_video_cols  = x;
+	boot_params.screen_info.orig_video_lines = y;
+}
+
+/* Probe the video drivers and have them generate their mode lists. */
+static void probe_cards(int unsafe)
+{
+	struct card_info *card;
+	static u8 probed[2];
+
+	if (probed[unsafe])
+		return;
+
+	probed[unsafe] = 1;
+
+	for (card = video_cards; card < video_cards_end; card++) {
+		if (card->unsafe == unsafe) {
+			if (card->probe)
+				card->nmodes = card->probe();
+			else
+				card->nmodes = 0;
+		}
+	}
+}
+
+/* Test if a mode is defined */
+int mode_defined(u16 mode)
+{
+	struct card_info *card;
+	struct mode_info *mi;
+	int i;
+
+	for (card = video_cards; card < video_cards_end; card++) {
+		mi = card->modes;
+		for (i = 0; i < card->nmodes; i++, mi++) {
+			if (mi->mode == mode)
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+/* Set mode (without recalc) */
+static int raw_set_mode(u16 mode)
+{
+	int nmode, i;
+	struct card_info *card;
+	struct mode_info *mi;
+
+	/* Drop the recalc bit if set */
+	mode &= ~VIDEO_RECALC;
+
+	/* Scan for mode based on fixed ID, position, or resolution */
+	nmode = 0;
+	for (card = video_cards; card < video_cards_end; card++) {
+		mi = card->modes;
+		for (i = 0; i < card->nmodes; i++, mi++) {
+			int visible = mi->x || mi->y;
+
+			if ((mode == nmode && visible) ||
+			    mode == mi->mode ||
+			    mode == (mi->y << 8)+mi->x)
+				return card->set_mode(mi);
+
+			if (visible)
+				nmode++;
+		}
+	}
+
+	/* Nothing found?  Is it an "exceptional" (unprobed) mode? */
+	for (card = video_cards; card < video_cards_end; card++) {
+		if (mode >= card->xmode_first &&
+		    mode < card->xmode_first+card->xmode_n) {
+			struct mode_info mix;
+			mix.mode = mode;
+			mix.x = mix.y = 0;
+			return card->set_mode(&mix);
+		}
+	}
+
+	/* Otherwise, failure... */
+	return -1;
+}
+
+/*
+ * Recalculate the vertical video cutoff (hack!)
+ */
+static void vga_recalc_vertical(void)
+{
+	unsigned int font_size, rows;
+	u16 crtc;
+	u8 ov;
+
+	set_fs(0);
+	font_size = rdfs8(0x485); /* BIOS: font size (pixels) */
+	rows = force_y ? force_y : rdfs8(0x484)+1; /* Text rows */
+
+	rows *= font_size;	/* Visible scan lines */
+	rows--;			/* ... minus one */
+
+	crtc = vga_crtc();
+
+	out_idx((u8)rows, crtc, 0x12); /* Lower height register */
+	ov = in_idx(crtc, 0x07); /* Overflow register */
+	ov &= 0xbd;
+	ov |= (rows >> (8-1)) & 0x02;
+	ov |= (rows >> (9-6)) & 0x40;
+	out_idx(ov, crtc, 0x07);
+}
+
+/* Set mode (with recalc if specified) */
+static int set_mode(u16 mode)
+{
+	int rv;
+
+	/* Very special mode numbers... */
+	if (mode == VIDEO_CURRENT_MODE)
+		return 0;	/* Nothing to do... */
+	else if (mode == NORMAL_VGA)
+		mode = VIDEO_80x25;
+	else if (mode == EXTENDED_VGA)
+		mode = VIDEO_8POINT;
+
+	rv = raw_set_mode(mode);
+	if (rv)
+		return rv;
+
+	if (mode & VIDEO_RECALC)
+		vga_recalc_vertical();
+
+	return 0;
+}
+
+static unsigned int get_entry(void)
+{
+	char entry_buf[4];
+	int i, len = 0;
+	int key;
+	unsigned int v;
+
+	do {
+		key = getchar();
+
+		if (key == '\b') {
+			if (len > 0) {
+				puts("\b \b");
+				len--;
+			}
+		} else if ((key >= '0' && key <= '9') ||
+			   (key >= 'A' && key <= 'Z') ||
+			   (key >= 'a' && key <= 'z')) {
+			if (len < sizeof entry_buf) {
+				entry_buf[len++] = key;
+				putchar(key);
+			}
+		}
+	} while (key != '\r');
+	putchar('\n');
+
+	if (len == 0)
+		return VIDEO_CURRENT_MODE; /* Default */
+
+	v = 0;
+	for (i = 0; i < len; i++) {
+		v <<= 4;
+		key = entry_buf[i] | 0x20;
+		v += (key > '9') ? key-'a'+10 : key-'0';
+	}
+
+	return v;
+}
+
+static void display_menu(void)
+{
+	struct card_info *card;
+	struct mode_info *mi;
+	char ch;
+	int i;
+
+	puts("Mode:    COLSxROWS:\n");
+
+	ch = '0';
+	for (card = video_cards; card < video_cards_end; card++) {
+		mi = card->modes;
+		for (i = 0; i < card->nmodes; i++, mi++) {
+			int visible = mi->x && mi->y;
+			u16 mode_id = mi->mode ? mi->mode :
+				(mi->y << 8)+mi->x;
+
+			if (!visible)
+				continue; /* Hidden mode */
+
+			printf("%c  %04X  %3dx%-3d  %s\n",
+			       ch, mode_id, mi->x, mi->y, card->card_name);
+
+			if (ch == '9')
+				ch = 'a';
+			else if (ch == 'z' || ch == ' ')
+				ch = ' '; /* Out of keys... */
+			else
+				ch++;
+		}
+	}
+}
+
+#define H(x)	((x)-'a'+10)
+#define SCAN	((H('s')<<12)+(H('c')<<8)+(H('a')<<4)+H('n'))
+
+static unsigned int mode_menu(void)
+{
+	int key;
+	unsigned int sel;
+
+	puts("Press <ENTER> to see video modes available, "
+	     "<SPACE> to continue, or wait 30 sec\n");
+
+	kbd_flush();
+	while (1) {
+		key = getchar_timeout();
+		if (key == ' ' || key == 0)
+			return VIDEO_CURRENT_MODE; /* Default */
+		if (key == '\r')
+			break;
+		putchar('\a');	/* Beep! */
+	}
+
+
+	for (;;) {
+		display_menu();
+
+		puts("Enter a video mode or \"scan\" to scan for "
+		     "additional modes: ");
+		sel = get_entry();
+		if (sel != SCAN)
+			return sel;
+
+		probe_cards(1);
+	}
+}
+
+#ifdef CONFIG_VIDEO_RETAIN
+/* Save screen content to the heap */
+struct saved_screen {
+	int x, y;
+	int curx, cury;
+	u16 *data;
+} saved;
+
+static void save_screen(void)
+{
+	/* Should be called after store_mode_params() */
+	saved.x = boot_params.screen_info.orig_video_cols;
+	saved.y = boot_params.screen_info.orig_video_lines;
+	saved.curx = boot_params.screen_info.orig_x;
+	saved.cury = boot_params.screen_info.orig_y;
+
+	if (heap_free() < saved.x*saved.y*sizeof(u16)+512)
+		return;		/* Not enough heap to save the screen */
+
+	saved.data = GET_HEAP(u16, saved.x*saved.y);
+
+	set_fs(video_segment);
+	copy_from_fs(saved.data, 0, saved.x*saved.y*sizeof(u16));
+}
+
+static void restore_screen(void)
+{
+	/* Should be called after store_mode_params() */
+	int xs = boot_params.screen_info.orig_video_cols;
+	int ys = boot_params.screen_info.orig_video_lines;
+	int y;
+	addr_t dst = 0;
+	u16 *src = saved.data;
+	u16 ax, bx, dx;
+
+	if (graphic_mode)
+		return;		/* Can't restore onto a graphic mode */
+
+	if (!src)
+		return;		/* No saved screen contents */
+
+	/* Restore screen contents */
+
+	set_fs(video_segment);
+	for (y = 0; y < ys; y++) {
+		int npad;
+
+		if (y < saved.y) {
+			int copy = (xs < saved.x) ? xs : saved.x;
+			copy_to_fs(dst, src, copy*sizeof(u16));
+			dst += copy*sizeof(u16);
+			src += saved.x;
+			npad = (xs < saved.x) ? 0 : xs-saved.x;
+		} else {
+			npad = xs;
+		}
+
+		/* Writes "npad" blank characters to
+		   video_segment:dst and advances dst */
+		asm volatile("pushw %%es ; "
+			     "movw %2,%%es ; "
+			     "shrw %%cx ; "
+			     "jnc 1f ; "
+			     "stosw \n\t"
+			     "1: rep;stosl ; "
+			     "popw %%es"
+			     : "+D" (dst), "+c" (npad)
+			     : "bdSm" (video_segment),
+			       "a" (0x07200720));
+	}
+
+	/* Restore cursor position */
+	ax = 0x0200;		/* Set cursor position */
+	bx = 0;			/* Page number (<< 8) */
+	dx = (saved.cury << 8)+saved.curx;
+	asm volatile(INT10
+		     : "+a" (ax), "+b" (bx), "+d" (dx)
+		     : : "ecx", "esi", "edi");
+}
+#else
+#define save_screen()		((void)0)
+#define restore_screen()	((void)0)
+#endif
+
+void set_video(void)
+{
+	u16 mode = boot_params.hdr.vid_mode;
+
+	RESET_HEAP();
+
+	store_mode_params();
+	save_screen();
+	probe_cards(0);
+
+	for (;;) {
+		if (mode == ASK_VGA)
+			mode = mode_menu();
+
+		if (!set_mode(mode))
+			break;
+
+		printf("Undefined video mode number: %x\n", mode);
+		mode = ASK_VGA;
+	}
+	vesa_store_edid();
+	store_mode_params();
+
+	if (do_restore)
+		restore_screen();
+}
diff --git a/arch/i386/boot/video.h b/arch/i386/boot/video.h
new file mode 100644
index 0000000..29eca17
--- /dev/null
+++ b/arch/i386/boot/video.h
@@ -0,0 +1,145 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video.h
+ *
+ * Header file for the real-mode video probing code
+ */
+
+#ifndef BOOT_VIDEO_H
+#define BOOT_VIDEO_H
+
+#include <linux/types.h>
+
+/* Enable autodetection of SVGA adapters and modes. */
+#undef CONFIG_VIDEO_SVGA
+
+/* Enable autodetection of VESA modes */
+#define CONFIG_VIDEO_VESA
+
+/* Retain screen contents when switching modes */
+#define CONFIG_VIDEO_RETAIN
+
+/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
+#undef CONFIG_VIDEO_400_HACK
+
+/* This code uses an extended set of video mode numbers. These include:
+ * Aliases for standard modes
+ *      NORMAL_VGA (-1)
+ *      EXTENDED_VGA (-2)
+ *      ASK_VGA (-3)
+ * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
+ * of compatibility when extending the table. These are between 0x00 and 0xff.
+ */
+#define VIDEO_FIRST_MENU 0x0000
+
+/* Standard BIOS video modes (BIOS number + 0x0100) */
+#define VIDEO_FIRST_BIOS 0x0100
+
+/* VESA BIOS video modes (VESA number + 0x0200) */
+#define VIDEO_FIRST_VESA 0x0200
+
+/* Video7 special modes (BIOS number + 0x0900) */
+#define VIDEO_FIRST_V7 0x0900
+
+/* Special video modes */
+#define VIDEO_FIRST_SPECIAL 0x0f00
+#define VIDEO_80x25 0x0f00
+#define VIDEO_8POINT 0x0f01
+#define VIDEO_80x43 0x0f02
+#define VIDEO_80x28 0x0f03
+#define VIDEO_CURRENT_MODE 0x0f04
+#define VIDEO_80x30 0x0f05
+#define VIDEO_80x34 0x0f06
+#define VIDEO_80x60 0x0f07
+#define VIDEO_GFX_HACK 0x0f08
+#define VIDEO_LAST_SPECIAL 0x0f09
+
+/* Video modes given by resolution */
+#define VIDEO_FIRST_RESOLUTION 0x1000
+
+/* The "recalculate timings" flag */
+#define VIDEO_RECALC 0x8000
+
+/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
+#ifdef CONFIG_VIDEO_RETAIN
+void store_screen(void);
+#define DO_STORE() store_screen()
+#else
+#define DO_STORE() ((void)0)
+#endif /* CONFIG_VIDEO_RETAIN */
+
+/*
+ * Mode table structures
+ */
+
+struct mode_info {
+	u16 mode;		/* Mode number (vga= style) */
+	u8  x, y;		/* Width, height */
+};
+
+struct card_info {
+	const char *card_name;
+	int (*set_mode)(struct mode_info *mode);
+	int (*probe)(void);
+	struct mode_info *modes;
+	int nmodes;		/* Number of probed modes so far */
+	int unsafe;		/* Probing is unsafe, only do after "scan" */
+	u16 xmode_first;	/* Unprobed modes to try to call anyway */
+	u16 xmode_n;		/* Size of unprobed mode range */
+};
+
+#define __videocard struct card_info __attribute__((section(".videocards")))
+extern struct card_info video_cards[], video_cards_end[];
+
+int mode_defined(u16 mode);	/* video.c */
+
+/* Basic video information */
+#define ADAPTER_CGA	0	/* CGA/MDA/HGC */
+#define ADAPTER_EGA	1
+#define ADAPTER_VGA	2
+
+extern int adapter;
+extern u16 video_segment;
+extern int force_x, force_y;	/* Don't query the BIOS for cols/rows */
+extern int do_restore;		/* Restore screen contents */
+extern int graphic_mode;	/* Graphics mode with linear frame buffer */
+
+/*
+ * int $0x10 is notorious for touching registers it shouldn't.
+ * gcc doesn't like %ebp being clobbered, so define it as a push/pop
+ * sequence here.
+ */
+#define INT10 "pushl %%ebp; int $0x10; popl %%ebp"
+
+/* Accessing VGA indexed registers */
+static inline u8 in_idx(u16 port, u8 index)
+{
+	outb(index, port);
+	return inb(port+1);
+}
+
+static inline void out_idx(u8 v, u16 port, u8 index)
+{
+	outw(index+(v << 8), port);
+}
+
+/* Writes a value to an indexed port and then reads the port again */
+static inline u8 tst_idx(u8 v, u16 port, u8 index)
+{
+	out_idx(port, index, v);
+	return in_idx(port, index);
+}
+
+/* Get the I/O port of the VGA CRTC */
+u16 vga_crtc(void);		/* video-vga.c */
+
+#endif /* BOOT_VIDEO_H */
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 28/33] Code for actual protected-mode entry
       [not found]   ` <ae628cbaed0874c2c552ddbd77d61340438f9820.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:52     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:52 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

This is the code which actually does the switch to protected mode,
including all preparation.  It is also responsible for invoking the
boot loader hooks, if present.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/pm.c     |  170 +++++++++++++++++++++++++++++++++++++++++++++++
 arch/i386/boot/pmjump.S |   54 +++++++++++++++
 2 files changed, 224 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/pm.c
 create mode 100644 arch/i386/boot/pmjump.S

diff --git a/arch/i386/boot/pm.c b/arch/i386/boot/pm.c
new file mode 100644
index 0000000..4deb298
--- /dev/null
+++ b/arch/i386/boot/pm.c
@@ -0,0 +1,170 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/pm.c
+ *
+ * Prepare the machine for transition to protected mode.
+ */
+
+#include "boot.h"
+#include <asm/segment.h>
+
+/*
+ * Invoke the realmode switch hook if present; otherwise
+ * disable all interrupts.
+ */
+static void realmode_switch_hook(void)
+{
+	if (boot_params.hdr.realmode_swtch) {
+		asm volatile("lcallw *%0"
+			     : : "m" (boot_params.hdr.realmode_swtch)
+			     : "eax", "ebx", "ecx", "edx");
+	} else {
+		asm volatile("cli");
+		outb(0x80, 0x70); /* Disable NMI */
+		io_delay();
+	}
+}
+
+/*
+ * A zImage kernel is loaded at 0x10000 but wants to run at 0x1000.
+ * A bzImage kernel is loaded and runs at 0x100000.
+ */
+static void move_kernel_around(void)
+{
+	/* Note: rely on the compile-time option here rather than
+	   the LOADED_HIGH flag.  The Qemu kernel loader unconditionally
+	   sets the loadflags to zero. */
+#ifndef __BIG_KERNEL__
+	u16 dst_seg, src_seg;
+	u32 syssize;
+
+	dst_seg =  0x1000 >> 4;
+	src_seg = 0x10000 >> 4;
+	syssize = boot_params.hdr.syssize; /* Size in 16-byte paragraps */
+
+	while (syssize) {
+		int paras  = (syssize >= 0x1000) ? 0x1000 : syssize;
+		int dwords = paras << 2;
+
+		asm volatile("pushw %%es ; "
+			     "pushw %%ds ; "
+			     "movw %1,%%es ; "
+			     "movw %2,%%ds ; "
+			     "xorw %%di,%%di ; "
+			     "xorw %%si,%%si ; "
+			     "rep;movsl ; "
+			     "popw %%ds ; "
+			     "popw %%es"
+			     : "+c" (dwords)
+			     : "rm" (dst_seg), "rm" (src_seg)
+			     : "esi", "edi");
+
+		syssize -= paras;
+		dst_seg += paras;
+		src_seg += paras;
+	}
+#endif
+}
+
+/*
+ * Disable all interrupts at the legacy PIC.
+ */
+static void mask_all_interrupts(void)
+{
+	outb(0xff, 0xa1);	/* Mask all interrupts on the seconday PIC */
+	io_delay();
+	outb(0xfb, 0x21);	/* Mask all but cascade on the primary PIC */
+	io_delay();
+}
+
+/*
+ * Reset IGNNE# if asserted in the FPU.
+ */
+static void reset_coprocessor(void)
+{
+	outb(0, 0xf0);
+	io_delay();
+	outb(0, 0xf1);
+	io_delay();
+}
+
+/*
+ * Set up the GDT
+ */
+#define GDT_ENTRY(flags,base,limit)		\
+	(((u64)(base & 0xff000000) << 32) |	\
+	 ((u64)flags << 40) |			\
+	 ((u64)(limit & 0x00ff0000) << 32) |	\
+	 ((u64)(base & 0x00ffff00) << 16) |	\
+	 ((u64)(limit & 0x0000ffff)))
+
+struct gdt_ptr {
+	u16 len;
+	u32 ptr;
+} __attribute__((packed));
+
+static void setup_gdt(void)
+{
+	/* There are machines which are known to not boot with the GDT
+	   being 8-byte unaligned.  Intel recommends 16 byte alignment. */
+	static const u64 boot_gdt[] __attribute__((aligned(16))) = {
+		/* CS: code, read/execute, 4 GB, base 0 */
+		[GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
+		/* DS: data, read/write, 4 GB, base 0 */
+		[GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
+	};
+	struct gdt_ptr gdt;
+
+	gdt.len = sizeof(boot_gdt)-1;
+	gdt.ptr = (u32)&boot_gdt + (ds() << 4);
+
+	asm volatile("lgdtl %0" : : "m" (gdt));
+}
+
+/*
+ * Set up the IDT
+ */
+static void setup_idt(void)
+{
+	static const struct gdt_ptr null_idt = {0, 0};
+	asm volatile("lidtl %0" : : "m" (null_idt));
+}
+
+/*
+ * Actual invocation sequence
+ */
+void go_to_protected_mode(void)
+{
+	/* Hook before leaving real mode, also disables interrupts */
+	realmode_switch_hook();
+
+	/* Move the kernel/setup to their final resting places */
+	move_kernel_around();
+
+	/* Enable the A20 gate */
+	if (enable_a20()) {
+		puts("A20 gate not responding, unable to boot...\n");
+		die();
+	}
+
+	/* Reset coprocessor (IGNNE#) */
+	reset_coprocessor();
+
+	/* Mask all interrupts in the PIC */
+	mask_all_interrupts();
+
+	/* Actual transition to protected mode... */
+	setup_idt();
+	setup_gdt();
+	protected_mode_jump(boot_params.hdr.code32_start,
+			    (u32)&boot_params + (ds() << 4));
+}
diff --git a/arch/i386/boot/pmjump.S b/arch/i386/boot/pmjump.S
new file mode 100644
index 0000000..2e55923
--- /dev/null
+++ b/arch/i386/boot/pmjump.S
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/pmjump.S
+ *
+ * The actual transition into protected mode
+ */
+
+#include <asm/boot.h>
+#include <asm/segment.h>
+
+	.text
+
+	.globl	protected_mode_jump
+	.type	protected_mode_jump, @function
+
+	.code16
+
+/*
+ * void protected_mode_jump(u32 entrypoint, u32 bootparams);
+ */
+protected_mode_jump:
+	xorl	%ebx, %ebx		# Flag to indicate this is a boot
+	movl	%edx, %esi		# Pointer to boot_params table
+	movl	%eax, 2f		# Patch ljmpl instruction
+	jmp	1f			# Short jump to flush instruction q.
+
+1:
+	movw	$__BOOT_DS, %cx
+
+	movl	%cr0, %edx
+	orb	$1, %dl			# Protected mode (PE) bit
+	movl	%edx, %cr0
+
+	movw	%cx, %ds
+	movw	%cx, %es
+	movw	%cx, %fs
+	movw	%cx, %gs
+	movw	%cx, %ss
+
+	# Jump to the 32-bit entrypoint
+	.byte	0x66, 0xea		# ljmpl opcode
+2:	.long	0			# offset
+	.word	__BOOT_CS		# segment
+
+	.size	protected_mode_jump, .-protected_mode_jump
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 29/33] Assembly header and main routine for new x86 setup code
       [not found]   ` <26d4ebeefed3e0b1593d4fa2357db6912ee944cb.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:52     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:52 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

The assembly header and initialization code, and the main() routine.
main.c also contains some miscellaneous very short routines.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/header.S |  283 +++++++++++++++++++++++++++++++++++++++++++++++
 arch/i386/boot/main.c   |  161 +++++++++++++++++++++++++++
 2 files changed, 444 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/header.S
 create mode 100644 arch/i386/boot/main.c

diff --git a/arch/i386/boot/header.S b/arch/i386/boot/header.S
new file mode 100644
index 0000000..6b9923f
--- /dev/null
+++ b/arch/i386/boot/header.S
@@ -0,0 +1,283 @@
+/*
+ *	header.S
+ *
+ *	Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ *	Based on bootsect.S and setup.S
+ *	modified by more people than can be counted
+ *
+ *	Rewritten as a common file by H. Peter Anvin (Apr 2007)
+ *
+ * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
+ * addresses must be multiplied by 16 to obtain their respective linear
+ * addresses. To avoid confusion, linear addresses are written using leading
+ * hex while segment addresses are written as segment:offset.
+ *
+ */
+
+#include <asm/segment.h>
+#include <linux/utsrelease.h>
+#include <asm/boot.h>
+#include <asm/e820.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include "boot.h"
+
+SETUPSECTS	= 4			/* default nr of setup-sectors */
+BOOTSEG		= 0x07C0		/* original address of boot-sector */
+SYSSEG		= DEF_SYSSEG		/* system loaded at 0x10000 (65536) */
+SYSSIZE		= DEF_SYSSIZE		/* system size: # of 16-byte clicks */
+					/* to be loaded */
+ROOT_DEV	= 0			/* ROOT_DEV is now written by "build" */
+SWAP_DEV	= 0			/* SWAP_DEV is now written by "build" */
+
+#ifndef SVGA_MODE
+#define SVGA_MODE ASK_VGA
+#endif
+
+#ifndef RAMDISK
+#define RAMDISK 0
+#endif
+
+#ifndef ROOT_RDONLY
+#define ROOT_RDONLY 1
+#endif
+
+	.code16
+	.section ".bstext", "ax"
+
+	.global bootsect_start
+bootsect_start:
+
+	# Normalize the start address
+	ljmp	$BOOTSEG, $start2
+
+start2:
+	movw	%cs, %ax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %ss
+	xorw	%sp, %sp
+	sti
+	cld
+
+	movw	$bugger_off_msg, %si
+
+msg_loop:
+	lodsb
+	andb	%al, %al
+	jz	bs_die
+	movb	$0xe, %ah
+	movw	$7, %bx
+	int	$0x10
+	jmp	msg_loop
+
+bs_die:
+	# Allow the user to press a key, then reboot
+	xorw	%ax, %ax
+	int	$0x16
+	int	$0x19
+
+	# int 0x19 should never return.  In case it does anyway,
+	# invoke the BIOS reset code...
+	ljmp	$0xf000,$0xfff0
+
+	.section ".bsdata", "a"
+bugger_off_msg:
+	.ascii	"Direct booting from floppy is no longer supported.\r\n"
+	.ascii	"Please use a boot loader program instead.\r\n"
+	.ascii	"\n"
+	.ascii	"Remove disk and press any key to reboot . . .\r\n"
+	.byte	0
+
+
+	# Kernel attributes; used by setup.  This is part 1 of the
+	# header, from the old boot sector.
+
+	.section ".header", "a"
+	.globl	hdr
+hdr:
+setup_sects:	.byte SETUPSECTS
+root_flags:	.word ROOT_RDONLY
+syssize:	.long SYSSIZE
+ram_size:	.word RAMDISK
+vid_mode:	.word SVGA_MODE
+root_dev:	.word ROOT_DEV
+boot_flag:	.word 0xAA55
+
+	# offset 512, entry point
+
+	.globl	_start
+_start:
+		# Explicitly enter this as bytes, or the assembler
+		# tries to generate a 3-byte jump here, which causes
+		# everything else to push off to the wrong offset.
+		.byte	0xeb		# short (2-byte) jump
+		.byte	start_of_setup-1f
+1:
+
+	# Part 2 of the header, from the old setup.S
+
+		.ascii	"HdrS"		# header signature
+		.word	0x0206		# header version number (>= 0x0105)
+					# or else old loadlin-1.5 will fail)
+		.globl realmode_swtch
+realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
+start_sys_seg:	.word	SYSSEG
+		.word	kernel_version-512 # pointing to kernel version string
+					# above section of header is compatible
+					# with loadlin-1.5 (header v1.5). Don't
+					# change it.
+
+type_of_loader:	.byte	0		# = 0, old one (LILO, Loadlin,
+					#      Bootlin, SYSLX, bootsect...)
+					# See Documentation/i386/boot.txt for
+					# assigned ids
+
+# flags, unused bits must be zero (RFU) bit within loadflags
+loadflags:
+LOADED_HIGH	= 1			# If set, the kernel is loaded high
+CAN_USE_HEAP	= 0x80			# If set, the loader also has set
+					# heap_end_ptr to tell how much
+					# space behind setup.S can be used for
+					# heap purposes.
+					# Only the loader knows what is free
+#ifndef __BIG_KERNEL__
+		.byte	0
+#else
+		.byte	LOADED_HIGH
+#endif
+
+setup_move_size: .word  0x8000		# size to move, when setup is not
+					# loaded at 0x90000. We will move setup
+					# to 0x90000 then just before jumping
+					# into the kernel. However, only the
+					# loader knows how much data behind
+					# us also needs to be loaded.
+
+code32_start:				# here loaders can put a different
+					# start address for 32-bit code.
+#ifndef __BIG_KERNEL__
+		.long	0x1000		#   0x1000 = default for zImage
+#else
+		.long	0x100000	# 0x100000 = default for big kernel
+#endif
+
+ramdisk_image:	.long	0		# address of loaded ramdisk image
+					# Here the loader puts the 32-bit
+					# address where it loaded the image.
+					# This only will be read by the kernel.
+
+ramdisk_size:	.long	0		# its size in bytes
+
+bootsect_kludge:
+		.long	0		# obsolete
+
+heap_end_ptr:	.word	_end+1024	# (Header version 0x0201 or later)
+					# space from here (exclusive) down to
+					# end of setup code can be used by setup
+					# for local heap purposes.
+
+pad1:		.word	0
+cmd_line_ptr:	.long	0		# (Header version 0x0202 or later)
+					# If nonzero, a 32-bit pointer
+					# to the kernel command line.
+					# The command line should be
+					# located between the start of
+					# setup and the end of low
+					# memory (0xa0000), or it may
+					# get overwritten before it
+					# gets read.  If this field is
+					# used, there is no longer
+					# anything magical about the
+					# 0x90000 segment; the setup
+					# can be located anywhere in
+					# low memory 0x10000 or higher.
+
+ramdisk_max:	.long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
+					# (Header version 0x0203 or later)
+					# The highest safe address for
+					# the contents of an initrd
+
+kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN	#physical addr alignment
+						#required for protected mode
+						#kernel
+#ifdef CONFIG_RELOCATABLE
+relocatable_kernel:    .byte 1
+#else
+relocatable_kernel:    .byte 0
+#endif
+pad2:			.byte 0
+pad3:			.word 0
+
+cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
+                                                #added with boot protocol
+                                                #version 2.06
+
+# End of setup header #####################################################
+
+	.section ".inittext", "ax"
+start_of_setup:
+#ifdef SAFE_RESET_DISK_CONTROLLER
+# Reset the disk controller.
+	movw	$0x0000, %ax		# Reset disk controller
+	movb	$0x80, %dl		# All disks
+	int	$0x13
+#endif
+
+# We will have entired with %cs = %ds+0x20, normalize %cs so
+# it is on par with the other segments.
+	pushw	%ds
+	pushw	$setup2
+	lretw
+
+setup2:
+# Force %es = %ds
+	movw	%ds, %ax
+	movw	%ax, %es
+	cld
+
+# Stack paranoia: align the stack and make sure it is good
+# for both 16- and 32-bit references.  In particular, if we
+# were meant to have been using the full 16-bit segment, the
+# caller might have set %sp to zero, which breaks %esp-based
+# references.
+	andw	$~3, %sp	# dword align (might as well...)
+	jnz	1f
+	movw	$0xfffc, %sp	# Make sure we're not zero
+1:	movzwl	%sp, %esp	# Clear upper half of %esp
+	sti
+
+# Check signature at end of setup
+	cmpl	$0x5a5aaa55, setup_sig
+	jne	setup_bad
+
+# Zero the bss
+	movw	$__bss_start, %di
+	movw	$_end+3, %cx
+	xorl	%eax, %eax
+	subw	%di, %cx
+	shrw	$2, %cx
+	rep; stosl
+
+# Jump to C code (should not return)
+	calll	main
+
+# Setup corrupt somehow...
+setup_bad:
+	movl	$setup_corrupt, %eax
+	calll	puts
+	# Fall through...
+
+	.globl	die
+	.type	die, @function
+die:
+	hlt
+	jmp	die
+
+	.size	die, .-due
+
+	.section ".initdata", "a"
+setup_corrupt:
+	.byte	7
+	.string	"No setup signature found..."
diff --git a/arch/i386/boot/main.c b/arch/i386/boot/main.c
new file mode 100644
index 0000000..7f01f96
--- /dev/null
+++ b/arch/i386/boot/main.c
@@ -0,0 +1,161 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/main.c
+ *
+ * Main module for the real-mode kernel code
+ */
+
+#include "boot.h"
+
+struct boot_params boot_params __attribute__((aligned(16)));
+
+char *HEAP = _end;
+char *heap_end = _end;		/* Default end of heap = no heap */
+
+/*
+ * Copy the header into the boot parameter block.  Since this
+ * screws up the old-style command line protocol, adjust by
+ * filling in the new-style command line pointer instead.
+ */
+#define OLD_CL_MAGIC	0xA33F
+#define OLD_CL_ADDRESS	0x20
+
+static void copy_boot_params(void)
+{
+	struct old_cmdline {
+		u16 cl_magic;
+		u16 cl_offset;
+	};
+	const struct old_cmdline * const oldcmd =
+		(const struct old_cmdline *)OLD_CL_ADDRESS;
+
+	BUILD_BUG_ON(sizeof boot_params != 4096);
+	memcpy(&boot_params.hdr, &hdr, sizeof hdr);
+
+	if (!boot_params.hdr.cmd_line_ptr &&
+	    oldcmd->cl_magic == OLD_CL_MAGIC) {
+		/* Old-style command line protocol. */
+		u16 cmdline_seg;
+
+		/* Figure out if the command line falls in the region
+		   of memory that an old kernel would have copied up
+		   to 0x90000... */
+		if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
+			cmdline_seg = ds();
+		else
+			cmdline_seg = 0x9000;
+
+		boot_params.hdr.cmd_line_ptr =
+			(cmdline_seg << 4) + oldcmd->cl_offset;
+	}
+}
+
+/*
+ * Set the keyboard repeat rate to maximum.  Unclear why this
+ * is done here; this might be possible to kill off as stale code.
+ */
+static void keyboard_set_repeat(void)
+{
+	u16 ax = 0x0305;
+	u16 bx = 0;
+	asm volatile("int $0x16"
+		     : "+a" (ax), "+b" (bx)
+		     : : "ecx", "edx", "esi", "edi");
+}
+
+/*
+ * Get Intel SpeedStep IST information.
+ */
+static void query_speedstep_ist(void)
+{
+	asm("int $0x15"
+	    : "=a" (boot_params.speedstep_info[0]),
+	      "=b" (boot_params.speedstep_info[1]),
+	      "=c" (boot_params.speedstep_info[2]),
+	      "=d" (boot_params.speedstep_info[3])
+	    : "a" (0x0000e980),	 /* IST Support */
+	      "d" (0x47534943)); /* Request value */
+}
+
+/*
+ * Tell the BIOS what CPU mode we intend to run in.
+ */
+static void set_bios_mode(void)
+{
+#ifdef CONFIG_X86_64
+	u32 eax, ebx;
+
+	eax = 0xec00;
+	ebx = 2;
+	asm volatile("int $0x15"
+		     : "+a" (eax), "+b" (ebx)
+		     : : "ecx", "edx", "esi", "edi");
+#endif
+}
+
+void main(void)
+{
+	/* First, copy the boot header into the "zeropage" */
+	copy_boot_params();
+
+	/* End of heap check */
+	if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
+		heap_end = (char *)(boot_params.hdr.heap_end_ptr
+				    +0x200-STACK_SIZE);
+	} else {
+		/* Boot protocol 2.00 only, no heap available */
+		puts("WARNING: Ancient bootloader, some functionality "
+		     "may be limited!\n");
+	}
+
+	/* Make sure we have all the proper CPU support */
+	if (validate_cpu()) {
+		puts("Unable to boot - please use a kernel appropriate "
+		     "for your CPU.\n");
+		die();
+	}
+
+	/* Tell the BIOS what CPU mode we intend to run in. */
+	set_bios_mode();
+
+	/* Detect memory layout */
+	detect_memory();
+
+	/* Set keyboard repeat rate (why?) */
+	keyboard_set_repeat();
+
+	/* Set the video mode */
+	set_video();
+
+	/* Query MCA information */
+	query_mca();
+
+	/* Voyager */
+#ifdef CONFIG_X86_VOYAGER
+	query_voyager();
+#endif
+
+	/* Query SpeedStep IST information */
+	query_speedstep_ist();
+
+	/* Query APM information */
+#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
+	query_apm_bios();
+#endif
+
+	/* Query EDD information */
+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+	query_edd();
+#endif
+	/* Do the last things and invoke protected mode */
+	go_to_protected_mode();
+}
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 30/33] Linker script for the new x86 setup code
       [not found]   ` <fd5cf379a91de82890893de655876e39e78c1dc9.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:52     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:52 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

Linker script to define the layout of the new x86 setup code.
Includes assert for size overflow and a misaligned setup header.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/setup.ld |   54 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 54 insertions(+), 0 deletions(-)
 create mode 100644 arch/i386/boot/setup.ld

diff --git a/arch/i386/boot/setup.ld b/arch/i386/boot/setup.ld
new file mode 100644
index 0000000..df9234b
--- /dev/null
+++ b/arch/i386/boot/setup.ld
@@ -0,0 +1,54 @@
+/*
+ * setup.ld
+ *
+ * Linker script for the i386 setup code
+ */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+
+SECTIONS
+{
+	. = 0;
+	.bstext		: { *(.bstext) }
+	.bsdata		: { *(.bsdata) }
+
+	. = 497;
+	.header		: { *(.header) }
+	.inittext	: { *(.inittext) }
+	.initdata	: { *(.initdata) }
+	.text		: { *(.text*) }
+
+	. = ALIGN(16);
+	.rodata		: { *(.rodata*) }
+
+	.videocards	: {
+		video_cards = .;
+		*(.videocards)
+		video_cards_end = .;
+	}
+
+	. = ALIGN(16);
+	.data		: { *(.data*) }
+
+	.signature	: {
+		setup_sig = .;
+		LONG(0x5a5aaa55)
+	}
+
+
+	. = ALIGN(16);
+	.bss		:
+	{
+		__bss_start = .;
+		*(.bss)
+		__bss_end = .;
+	}
+	. = ALIGN(16);
+	_end = .;
+
+	/DISCARD/ : { *(.note*) }
+
+	. = ASSERT(_end <= 0x8000, "Setup too big!");
+	. = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
+}
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 31/33] Use the new x86 setup code for i386
       [not found]   ` <842bbe280e87886e7a1b187434841c7f7334244c.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:52     ` H. Peter Anvin
  2007-07-10  7:55       ` Tilman Schmidt
  0 siblings, 1 reply; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:52 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

This patch hooks the new x86 setup code into the Makefile machinery.  It
also adapts boot/tools/build.c to a two-file (as opposed to three-file)
universe, and simplifies it substantially.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/Makefile            |   46 +++++++++--
 arch/i386/boot/compressed/Makefile |    7 ++-
 arch/i386/boot/tools/build.c       |  160 ++++++++++++++++--------------------
 3 files changed, 116 insertions(+), 97 deletions(-)

diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile
index bfbc320..e9f46fd 100644
--- a/arch/i386/boot/Makefile
+++ b/arch/i386/boot/Makefile
@@ -25,27 +25,54 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
 
 #RAMDISK := -DRAMDISK=512
 
-targets		:= vmlinux.bin bootsect bootsect.o \
-		   setup setup.o zImage bzImage
+targets		:= vmlinux.bin setup.bin setup.elf zImage bzImage
 subdir- 	:= compressed
 
+setup-y		+= a20.o apm.o cmdline.o copy.o cpu.o cpucheck.o edd.o
+setup-y		+= header.o main.o mca.o memory.o pm.o pmjump.o
+setup-y		+= printf.o string.o tty.o video.o version.o voyager.o
+
+# The link order of the video-*.o modules can matter.  In particular,
+# video-vga.o *must* be listed first, followed by video-vesa.o.
+# Hardware-specific drivers should follow in the order they should be
+# probed, and video-bios.o should typically be last.
+setup-y		+= video-vga.o
+setup-y		+= video-vesa.o
+setup-y		+= video-bios.o
+
 hostprogs-y	:= tools/build
 
 HOSTCFLAGS_build.o := $(LINUXINCLUDE)
 
 # ---------------------------------------------------------------------------
 
+# How to compile the 16-bit code.  Note we always compile for -march=i386,
+# that way we can complain to the user if the CPU is insufficient.
+cflags-i386   := 
+cflags-x86_64 := -m32
+CFLAGS		:= $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
+		   $(cflags-$(ARCH)) \
+		   -Wall -Wstrict-prototypes \
+		   -march=i386 -mregparm=3 \
+		   -include $(srctree)/$(src)/code16gcc.h \
+		   -fno-strict-aliasing -fomit-frame-pointer \
+		   $(call cc-option, -ffreestanding) \
+		   $(call cc-option, -fno-stack-protector) \
+		   $(call cc-option, -mpreferred-stack-boundary=2)
+AFLAGS		:= $(CFLAGS) -D__ASSEMBLY__
+
 $(obj)/zImage:  IMAGE_OFFSET := 0x1000
 $(obj)/zImage:  EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK)
 $(obj)/bzImage: IMAGE_OFFSET := 0x100000
+$(obj)/bzImage: EXTRA_CFLAGS := -D__BIG_KERNEL__
 $(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
 $(obj)/bzImage: BUILDFLAGS   := -b
 
 quiet_cmd_image = BUILD   $@
-cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
+cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/setup.bin \
 	    $(obj)/vmlinux.bin $(ROOT_DEV) > $@
 
-$(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
+$(obj)/zImage $(obj)/bzImage: $(obj)/setup.bin \
 			      $(obj)/vmlinux.bin $(obj)/tools/build FORCE
 	$(call if_changed,image)
 	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
@@ -53,12 +80,17 @@ $(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
 $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
 	$(call if_changed,objcopy)
 
-LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
-LDFLAGS_setup	 := -Ttext 0x0 -s --oformat binary -e begtext
+SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
 
-$(obj)/setup $(obj)/bootsect: %: %.o FORCE
+LDFLAGS_setup.elf	:= -T
+$(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
 	$(call if_changed,ld)
 
+OBJCOPYFLAGS_setup.bin	:= -O binary
+
+$(obj)/setup.bin: $(obj)/setup.elf FORCE
+	$(call if_changed,objcopy)
+
 $(obj)/compressed/vmlinux: FORCE
 	$(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
 
diff --git a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile
index a661217..189fa1d 100644
--- a/arch/i386/boot/compressed/Makefile
+++ b/arch/i386/boot/compressed/Makefile
@@ -9,9 +9,14 @@ targets		:= vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o \
 EXTRA_AFLAGS	:= -traditional
 
 LDFLAGS_vmlinux := -T
-CFLAGS_misc.o += -fPIC
 hostprogs-y	:= relocs
 
+CFLAGS  := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
+	   -fno-strict-aliasing -fPIC \
+	   $(call cc-option,-ffreestanding) \
+	   $(call cc-option,-fno-stack-protector)
+LDFLAGS := -m elf_i386
+
 $(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
 	$(call if_changed,ld)
 	@:
diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c
index 0579841..886f47d 100644
--- a/arch/i386/boot/tools/build.c
+++ b/arch/i386/boot/tools/build.c
@@ -1,13 +1,12 @@
 /*
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *  Copyright (C) 1997 Martin Mares
+ *  Copyright (C) 2007 H. Peter Anvin
  */
 
 /*
  * This file builds a disk-image from three different files:
  *
- * - bootsect: compatibility mbr which prints an error message if
- *             someone tries to boot the kernel directly.
  * - setup: 8086 machine code, sets up system parm
  * - system: 80386 code for actual system
  *
@@ -21,6 +20,7 @@
  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  * Cross compiling fixes by Gertjan van Wingerde, July 1996
  * Rewritten by Martin Mares, April 1997
+ * Substantially overhauled by H. Peter Anvin, April 2007
  */
 
 #include <stdio.h>
@@ -32,23 +32,25 @@
 #include <sys/sysmacros.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <sys/mman.h>
 #include <asm/boot.h>
 
-typedef unsigned char byte;
-typedef unsigned short word;
-typedef unsigned long u32;
+typedef unsigned char  u8;
+typedef unsigned short u16;
+typedef unsigned long  u32;
 
 #define DEFAULT_MAJOR_ROOT 0
 #define DEFAULT_MINOR_ROOT 0
 
-/* Minimal number of setup sectors (see also bootsect.S) */
-#define SETUP_SECTS 4
+/* Minimal number of setup sectors */
+#define SETUP_SECT_MIN 5
+#define SETUP_SECT_MAX 64
 
-byte buf[1024];
-int fd;
+/* This must be large enough to hold the entire setup */
+u8 buf[SETUP_SECT_MAX*512];
 int is_big_kernel;
 
-void die(const char * str, ...)
+static void die(const char * str, ...)
 {
 	va_list args;
 	va_start(args, str);
@@ -57,15 +59,9 @@ void die(const char * str, ...)
 	exit(1);
 }
 
-void file_open(const char *name)
+static void usage(void)
 {
-	if ((fd = open(name, O_RDONLY, 0)) < 0)
-		die("Unable to open `%s': %m", name);
-}
-
-void usage(void)
-{
-	die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
+	die("Usage: build [-b] setup system [rootdev] [> image]");
 }
 
 int main(int argc, char ** argv)
@@ -73,27 +69,30 @@ int main(int argc, char ** argv)
 	unsigned int i, sz, setup_sectors;
 	int c;
 	u32 sys_size;
-	byte major_root, minor_root;
+	u8 major_root, minor_root;
 	struct stat sb;
+	FILE *file;
+	int fd;
+	void *kernel;
 
 	if (argc > 2 && !strcmp(argv[1], "-b"))
 	  {
 	    is_big_kernel = 1;
 	    argc--, argv++;
 	  }
-	if ((argc < 4) || (argc > 5))
+	if ((argc < 3) || (argc > 4))
 		usage();
-	if (argc > 4) {
-		if (!strcmp(argv[4], "CURRENT")) {
+	if (argc > 3) {
+		if (!strcmp(argv[3], "CURRENT")) {
 			if (stat("/", &sb)) {
 				perror("/");
 				die("Couldn't stat /");
 			}
 			major_root = major(sb.st_dev);
 			minor_root = minor(sb.st_dev);
-		} else if (strcmp(argv[4], "FLOPPY")) {
-			if (stat(argv[4], &sb)) {
-				perror(argv[4]);
+		} else if (strcmp(argv[3], "FLOPPY")) {
+			if (stat(argv[3], &sb)) {
+				perror(argv[3]);
 				die("Couldn't stat root device.");
 			}
 			major_root = major(sb.st_rdev);
@@ -108,79 +107,62 @@ int main(int argc, char ** argv)
 	}
 	fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
 
-	file_open(argv[1]);
-	i = read(fd, buf, sizeof(buf));
-	fprintf(stderr,"Boot sector %d bytes.\n",i);
-	if (i != 512)
-		die("Boot block must be exactly 512 bytes");
+	/* Copy the setup code */
+	file = fopen(argv[1], "r");
+	if (!file)
+		die("Unable to open `%s': %m", argv[1]);
+	c = fread(buf, 1, sizeof(buf), file);
+	if (ferror(file))
+		die("read-error on `setup'");
+	if (c < 1024)
+		die("The setup must be at least 1024 bytes");
 	if (buf[510] != 0x55 || buf[511] != 0xaa)
 		die("Boot block hasn't got boot flag (0xAA55)");
+	fclose(file);
+
+	/* Pad unused space with zeros */
+	setup_sectors = (c + 511) / 512;
+	if (setup_sectors < SETUP_SECT_MIN)
+		setup_sectors = SETUP_SECT_MIN;
+	i = setup_sectors*512;
+	memset(buf+c, 0, i-c);
+
+	/* Set the default root device */
 	buf[508] = minor_root;
 	buf[509] = major_root;
-	if (write(1, buf, 512) != 512)
-		die("Write call failed");
-	close (fd);
-
-	file_open(argv[2]);				    /* Copy the setup code */
-	for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
-		if (write(1, buf, c) != c)
-			die("Write call failed");
-	if (c != 0)
-		die("read-error on `setup'");
-	close (fd);
-
-	setup_sectors = (i + 511) / 512;	/* Pad unused space with zeros */
-	/* for compatibility with ancient versions of LILO. */
-	if (setup_sectors < SETUP_SECTS)
-		setup_sectors = SETUP_SECTS;
-	fprintf(stderr, "Setup is %d bytes.\n", i);
-	memset(buf, 0, sizeof(buf));
-	while (i < setup_sectors * 512) {
-		c = setup_sectors * 512 - i;
-		if (c > sizeof(buf))
-			c = sizeof(buf);
-		if (write(1, buf, c) != c)
-			die("Write call failed");
-		i += c;
-	}
 
-	file_open(argv[3]);
-	if (fstat (fd, &sb))
-		die("Unable to stat `%s': %m", argv[3]);
+	fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
+
+	/* Open and stat the kernel file */
+	fd = open(argv[2], O_RDONLY);
+	if (fd < 0)
+		die("Unable to open `%s': %m", argv[2]);
+	if (fstat(fd, &sb))
+		die("Unable to stat `%s': %m", argv[2]);
 	sz = sb.st_size;
-	fprintf (stderr, "System is %d kB\n", sz/1024);
+	fprintf (stderr, "System is %d kB\n", (sz+1023)/1024);
+	kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
+	if (kernel == MAP_FAILED)
+		die("Unable to mmap '%s': %m", argv[2]);
 	sys_size = (sz + 15) / 16;
 	if (!is_big_kernel && sys_size > DEF_SYSSIZE)
 		die("System is too big. Try using bzImage or modules.");
-	while (sz > 0) {
-		int l, n;
-
-		l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
-		if ((n=read(fd, buf, l)) != l) {
-			if (n < 0)
-				die("Error reading %s: %m", argv[3]);
-			else
-				die("%s: Unexpected EOF", argv[3]);
-		}
-		if (write(1, buf, l) != l)
-			die("Write failed");
-		sz -= l;
-	}
+
+	/* Patch the setup code with the appropriate size parameters */
+	buf[0x1f1] = setup_sectors-1;
+	buf[0x1f4] = sys_size;
+	buf[0x1f5] = sys_size >> 8;
+	buf[0x1f6] = sys_size >> 16;
+	buf[0x1f7] = sys_size >> 24;
+
+	if (fwrite(buf, 1, i, stdout) != i)
+		die("Writing setup failed");
+
+	/* Copy the kernel code */
+	if (fwrite(kernel, 1, sz, stdout) != sz)
+		die("Writing kernel failed");
 	close(fd);
 
-	if (lseek(1, 497, SEEK_SET) != 497)		    /* Write sizes to the bootsector */
-		die("Output: seek failed");
-	buf[0] = setup_sectors;
-	if (write(1, buf, 1) != 1)
-		die("Write of setup sector count failed");
-	if (lseek(1, 500, SEEK_SET) != 500)
-		die("Output: seek failed");
-	buf[0] = (sys_size & 0xff);
-	buf[1] = ((sys_size >> 8) & 0xff);
-	buf[2] = ((sys_size >> 16) & 0xff);
-	buf[3] = ((sys_size >> 24) & 0xff);
-	if (write(1, buf, 4) != 4)
-		die("Write of image length failed");
-
-	return 0;					    /* Everything is OK */
+	/* Everything is OK */
+	return 0;
 }
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 32/33] Use the new x86 setup code for x86-64; unify with i386
       [not found]   ` <0daaab19675363b0c9126a9b98a8325883bbcfea.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:52     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:52 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

This unifies arch/*/boot (except arch/*/boot/compressed) between
i386 and x86-64, and uses the new x86 setup code for x86-64 as well.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86_64/boot/Makefile            |  136 +------
 arch/x86_64/boot/bootsect.S          |   98 ----
 arch/x86_64/boot/compressed/Makefile |    9 +-
 arch/x86_64/boot/install.sh          |    2 -
 arch/x86_64/boot/mtools.conf.in      |   17 -
 arch/x86_64/boot/setup.S             |  826 ----------------------------------
 arch/x86_64/boot/tools/build.c       |  185 --------
 7 files changed, 10 insertions(+), 1263 deletions(-)
 delete mode 100644 arch/x86_64/boot/bootsect.S
 delete mode 100644 arch/x86_64/boot/install.sh
 delete mode 100644 arch/x86_64/boot/mtools.conf.in
 delete mode 100644 arch/x86_64/boot/setup.S
 delete mode 100644 arch/x86_64/boot/tools/build.c

diff --git a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile
index ee6f650..6709638 100644
--- a/arch/x86_64/boot/Makefile
+++ b/arch/x86_64/boot/Makefile
@@ -1,135 +1,9 @@
 #
 # arch/x86_64/boot/Makefile
 #
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1994 by Linus Torvalds
-#
-
-# ROOT_DEV specifies the default root-device when making the image.
-# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
-# the default of FLOPPY is used by 'build'.
-
-ROOT_DEV := CURRENT
-
-# If you want to preset the SVGA mode, uncomment the next line and
-# set SVGA_MODE to whatever number you want.
-# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
-# The number is the same as you would ordinarily press at bootup.
-
-SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
-
-# If you want the RAM disk device, define this to be the size in blocks.
-
-#RAMDISK := -DRAMDISK=512
-
-targets		:= vmlinux.bin bootsect bootsect.o \
-		   setup setup.o bzImage mtools.conf
-
-EXTRA_CFLAGS := -m32
-
-hostprogs-y	:= tools/build
-HOST_EXTRACFLAGS += $(LINUXINCLUDE)
-subdir-		:= compressed/	#Let make clean descend in compressed/
-# ---------------------------------------------------------------------------
-
-$(obj)/bzImage: IMAGE_OFFSET := 0x100000
-$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
-$(obj)/bzImage: BUILDFLAGS   := -b
-
-quiet_cmd_image = BUILD   $@
-cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
-	    $(obj)/vmlinux.bin $(ROOT_DEV) > $@
-
-$(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
-			      $(obj)/vmlinux.bin $(obj)/tools/build FORCE
-	$(call if_changed,image)
-	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
-
-$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
-	$(call if_changed,objcopy)
-
-LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
-LDFLAGS_setup	 := -Ttext 0x0 -s --oformat binary -e begtext
-
-$(obj)/setup $(obj)/bootsect: %: %.o FORCE
-	$(call if_changed,ld)
-
-$(obj)/compressed/vmlinux: FORCE
-	$(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
-
-# Set this if you want to pass append arguments to the zdisk/fdimage/isoimage kernel
-FDARGS = 
-# Set this if you want an initrd included with the zdisk/fdimage/isoimage kernel
-FDINITRD =
-
-image_cmdline = default linux $(FDARGS) $(if $(FDINITRD),initrd=initrd.img,)
-
-$(obj)/mtools.conf: $(src)/mtools.conf.in
-	sed -e 's|@OBJ@|$(obj)|g' < $< > $@
-
-# This requires write access to /dev/fd0
-zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
-	MTOOLSRC=$(obj)/mtools.conf mformat a:			; sync
-	syslinux /dev/fd0					; sync
-	echo '$(image_cmdline)' | \
-		MTOOLSRC=$(obj)/mtools.conf mcopy - a:syslinux.cfg
-	if [ -f '$(FDINITRD)' ] ; then \
-		MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' a:initrd.img ; \
-	fi
-	MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux	; sync
-
-# These require being root or having syslinux 2.02 or higher installed
-fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf
-	dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440
-	MTOOLSRC=$(obj)/mtools.conf mformat v:			; sync
-	syslinux $(obj)/fdimage					; sync
-	echo '$(image_cmdline)' | \
-		MTOOLSRC=$(obj)/mtools.conf mcopy - v:syslinux.cfg
-	if [ -f '$(FDINITRD)' ] ; then \
-		MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' v:initrd.img ; \
-	fi
-	MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux	; sync
-
-fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf
-	dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880
-	MTOOLSRC=$(obj)/mtools.conf mformat w:			; sync
-	syslinux $(obj)/fdimage					; sync
-	echo '$(image_cmdline)' | \
-		MTOOLSRC=$(obj)/mtools.conf mcopy - w:syslinux.cfg
-	if [ -f '$(FDINITRD)' ] ; then \
-		MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' w:initrd.img ; \
-	fi
-	MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux	; sync
-
-isoimage: $(BOOTIMAGE)
-	-rm -rf $(obj)/isoimage
-	mkdir $(obj)/isoimage
-	for i in lib lib64 share end ; do \
-		if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
-			cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
-			break ; \
-		fi ; \
-		if [ $$i = end ] ; then exit 1 ; fi ; \
-	done
-	cp $(BOOTIMAGE) $(obj)/isoimage/linux
-	echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg
-	if [ -f '$(FDINITRD)' ] ; then \
-		cp '$(FDINITRD)' $(obj)/isoimage/initrd.img ; \
-	fi
-	mkisofs -J -r -o $(obj)/image.iso -b isolinux.bin -c boot.cat \
-		-no-emul-boot -boot-load-size 4 -boot-info-table \
-		$(obj)/isoimage
-	rm -rf $(obj)/isoimage
-
-zlilo: $(BOOTIMAGE)
-	if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
-	if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
-	cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
-	cp System.map $(INSTALL_PATH)/
-	if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
+# The actual boot code is shared with i386 including the Makefile.
+# So tell kbuild that we fetch the code from i386 and include the
+# Makefile from i386 too.
 
-install:
-	sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
+src := arch/i386/boot
+include $(src)/Makefile
diff --git a/arch/x86_64/boot/bootsect.S b/arch/x86_64/boot/bootsect.S
deleted file mode 100644
index 011b7a4..0000000
--- a/arch/x86_64/boot/bootsect.S
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *	bootsect.S		Copyright (C) 1991, 1992 Linus Torvalds
- *
- *	modified by Drew Eckhardt
- *	modified by Bruce Evans (bde)
- *	modified by Chris Noe (May 1999) (as86 -> gas)
- *	gutted by H. Peter Anvin (Jan 2003)
- *
- * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
- * addresses must be multiplied by 16 to obtain their respective linear
- * addresses. To avoid confusion, linear addresses are written using leading
- * hex while segment addresses are written as segment:offset.
- *
- */
-
-#include <asm/boot.h>
-
-SETUPSECTS	= 4			/* default nr of setup-sectors */
-BOOTSEG		= 0x07C0		/* original address of boot-sector */
-INITSEG		= DEF_INITSEG		/* we move boot here - out of the way */
-SETUPSEG	= DEF_SETUPSEG		/* setup starts here */
-SYSSEG		= DEF_SYSSEG		/* system loaded at 0x10000 (65536) */
-SYSSIZE		= DEF_SYSSIZE		/* system size: # of 16-byte clicks */
-					/* to be loaded */
-ROOT_DEV	= 0 			/* ROOT_DEV is now written by "build" */
-SWAP_DEV	= 0			/* SWAP_DEV is now written by "build" */
-
-#ifndef SVGA_MODE
-#define SVGA_MODE ASK_VGA
-#endif
-
-#ifndef RAMDISK
-#define RAMDISK 0
-#endif
-
-#ifndef ROOT_RDONLY
-#define ROOT_RDONLY 1
-#endif
-
-.code16
-.text
-
-.global _start
-_start:
-
-	# Normalize the start address
-	jmpl	$BOOTSEG, $start2
-
-start2:
-	movw	%cs, %ax
-	movw	%ax, %ds
-	movw	%ax, %es
-	movw	%ax, %ss
-	movw	$0x7c00, %sp
-	sti
-	cld
-
-	movw	$bugger_off_msg, %si
-
-msg_loop:
-	lodsb
-	andb	%al, %al
-	jz	die
-	movb	$0xe, %ah
-	movw	$7, %bx
-	int	$0x10
-	jmp	msg_loop
-
-die:
-	# Allow the user to press a key, then reboot
-	xorw	%ax, %ax
-	int	$0x16
-	int	$0x19
-
-	# int 0x19 should never return.  In case it does anyway,
-	# invoke the BIOS reset code...
-	ljmp	$0xf000,$0xfff0
-
-
-bugger_off_msg:
-	.ascii	"Direct booting from floppy is no longer supported.\r\n"
-	.ascii	"Please use a boot loader program instead.\r\n"
-	.ascii	"\n"
-	.ascii	"Remove disk and press any key to reboot . . .\r\n"
-	.byte	0
-
-
-	# Kernel attributes; used by setup
-
-	.org 497
-setup_sects:	.byte SETUPSECTS
-root_flags:	.word ROOT_RDONLY
-syssize:	.word SYSSIZE
-swap_dev:	.word SWAP_DEV
-ram_size:	.word RAMDISK
-vid_mode:	.word SVGA_MODE
-root_dev:	.word ROOT_DEV
-boot_flag:	.word 0xAA55
diff --git a/arch/x86_64/boot/compressed/Makefile b/arch/x86_64/boot/compressed/Makefile
index 705a3e3..c9f2da7 100644
--- a/arch/x86_64/boot/compressed/Makefile
+++ b/arch/x86_64/boot/compressed/Makefile
@@ -7,11 +7,12 @@
 #
 
 targets		:= vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
-EXTRA_AFLAGS	:= -traditional
 
-# cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with
-# -m32
-CFLAGS := -m64 -D__KERNEL__ -Iinclude -O2  -fno-strict-aliasing -fPIC -mcmodel=small -fno-builtin
+CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2  \
+	  -fno-strict-aliasing -fPIC -mcmodel=small \
+	   $(call cc-option, -ffreestanding) \
+	   $(call cc-option, -fno-stack-protector)
+AFLAGS  := $(CFLAGS) -D__ASSEMBLY__
 LDFLAGS := -m elf_x86_64
 
 LDFLAGS_vmlinux := -T
diff --git a/arch/x86_64/boot/install.sh b/arch/x86_64/boot/install.sh
deleted file mode 100644
index baaa236..0000000
--- a/arch/x86_64/boot/install.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-. $srctree/arch/i386/boot/install.sh
diff --git a/arch/x86_64/boot/mtools.conf.in b/arch/x86_64/boot/mtools.conf.in
deleted file mode 100644
index efd6d24..0000000
--- a/arch/x86_64/boot/mtools.conf.in
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# mtools configuration file for "make (b)zdisk"
-#
-
-# Actual floppy drive
-drive a:
-  file="/dev/fd0"
-
-# 1.44 MB floppy disk image
-drive v:
-  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=18 filter
-
-# 2.88 MB floppy disk image (mostly for virtual uses)
-drive w:
-  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=36 filter
-
-
diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S
deleted file mode 100644
index e9e33f9..0000000
--- a/arch/x86_64/boot/setup.S
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
- *	setup.S		Copyright (C) 1991, 1992 Linus Torvalds
- *
- * setup.s is responsible for getting the system data from the BIOS,
- * and putting them into the appropriate places in system memory.
- * both setup.s and system has been loaded by the bootblock.
- *
- * This code asks the bios for memory/disk/other parameters, and
- * puts them in a "safe" place: 0x90000-0x901FF, ie where the
- * boot-block used to be. It is then up to the protected mode
- * system to read them from there before the area is overwritten
- * for buffer-blocks.
- *
- * Move PS/2 aux init code to psaux.c
- * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
- *
- * some changes and additional features by Christoph Niemann,
- * March 1993/June 1994 (Christoph.Niemann@linux.org)
- *
- * add APM BIOS checking by Stephen Rothwell, May 1994
- * (sfr@canb.auug.org.au)
- *
- * High load stuff, initrd support and position independency
- * by Hans Lermen & Werner Almesberger, February 1996
- * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
- *
- * Video handling moved to video.S by Martin Mares, March 1996
- * <mj@k332.feld.cvut.cz>
- *
- * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
- * parsons) to avoid loadlin confusion, July 1997
- *
- * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
- * <stiker@northlink.com>
- *
- * Fix to work around buggy BIOSes which don't use carry bit correctly
- * and/or report extended memory in CX/DX for e801h memory size detection 
- * call.  As a result the kernel got wrong figures.  The int15/e801h docs
- * from Ralf Brown interrupt list seem to indicate AX/BX should be used
- * anyway.  So to avoid breaking many machines (presumably there was a reason
- * to orginally use CX/DX instead of AX/BX), we do a kludge to see
- * if CX/DX have been changed in the e801 call and if so use AX/BX .
- * Michael Miller, April 2001 <michaelm@mjmm.org>
- *
- * Added long mode checking and SSE force. March 2003, Andi Kleen.		
- */
-
-#include <asm/segment.h>
-#include <linux/utsrelease.h>
-#include <linux/compile.h>
-#include <asm/boot.h>
-#include <asm/e820.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-
-/* Signature words to ensure LILO loaded us right */
-#define SIG1	0xAA55
-#define SIG2	0x5A5A
-
-INITSEG  = DEF_INITSEG		# 0x9000, we move boot here, out of the way
-SYSSEG   = DEF_SYSSEG		# 0x1000, system loaded at 0x10000 (65536).
-SETUPSEG = DEF_SETUPSEG		# 0x9020, this is the current segment
-				# ... and the former contents of CS
-
-DELTA_INITSEG = SETUPSEG - INITSEG	# 0x0020
-
-.code16
-.globl begtext, begdata, begbss, endtext, enddata, endbss
-
-.text
-begtext:
-.data
-begdata:
-.bss
-begbss:
-.text
-
-start:
-	jmp	trampoline
-
-# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
-
-		.ascii	"HdrS"		# header signature
-		.word	0x0206		# header version number (>= 0x0105)
-					# or else old loadlin-1.5 will fail)
-realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
-start_sys_seg:	.word	SYSSEG
-		.word	kernel_version	# pointing to kernel version string
-					# above section of header is compatible
-					# with loadlin-1.5 (header v1.5). Don't
-					# change it.
-
-type_of_loader:	.byte	0		# = 0, old one (LILO, Loadlin,
-					#      Bootlin, SYSLX, bootsect...)
-					# See Documentation/i386/boot.txt for
-					# assigned ids
-	
-# flags, unused bits must be zero (RFU) bit within loadflags
-loadflags:
-LOADED_HIGH	= 1			# If set, the kernel is loaded high
-CAN_USE_HEAP	= 0x80			# If set, the loader also has set
-					# heap_end_ptr to tell how much
-					# space behind setup.S can be used for
-					# heap purposes.
-					# Only the loader knows what is free
-#ifndef __BIG_KERNEL__
-		.byte	0
-#else
-		.byte	LOADED_HIGH
-#endif
-
-setup_move_size: .word  0x8000		# size to move, when setup is not
-					# loaded at 0x90000. We will move setup 
-					# to 0x90000 then just before jumping
-					# into the kernel. However, only the
-					# loader knows how much data behind
-					# us also needs to be loaded.
-
-code32_start:				# here loaders can put a different
-					# start address for 32-bit code.
-#ifndef __BIG_KERNEL__
-		.long	0x1000		#   0x1000 = default for zImage
-#else
-		.long	0x100000	# 0x100000 = default for big kernel
-#endif
-
-ramdisk_image:	.long	0		# address of loaded ramdisk image
-					# Here the loader puts the 32-bit
-					# address where it loaded the image.
-					# This only will be read by the kernel.
-
-ramdisk_size:	.long	0		# its size in bytes
-
-bootsect_kludge:
-		.long	0		# obsolete
-
-heap_end_ptr:	.word	modelist+1024	# (Header version 0x0201 or later)
-					# space from here (exclusive) down to
-					# end of setup code can be used by setup
-					# for local heap purposes.
-
-pad1:		.word	0
-cmd_line_ptr:	.long 0			# (Header version 0x0202 or later)
-					# If nonzero, a 32-bit pointer
-					# to the kernel command line.
-					# The command line should be
-					# located between the start of
-					# setup and the end of low
-					# memory (0xa0000), or it may
-					# get overwritten before it
-					# gets read.  If this field is
-					# used, there is no longer
-					# anything magical about the
-					# 0x90000 segment; the setup
-					# can be located anywhere in
-					# low memory 0x10000 or higher.
-
-ramdisk_max:	.long 0xffffffff
-kernel_alignment:  .long 0x200000       # physical addr alignment required for
-					# protected mode relocatable kernel
-#ifdef CONFIG_RELOCATABLE
-relocatable_kernel:    .byte 1
-#else
-relocatable_kernel:    .byte 0
-#endif
-pad2:                  .byte 0
-pad3:                  .word 0
-
-cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
-                                                #added with boot protocol
-                                                #version 2.06
-
-trampoline:	call	start_of_setup
-		.align 16
-					# The offset at this point is 0x240
-		.space  (0xeff-0x240+1)	# E820 & EDD space (ending at 0xeff)
-# End of setup header #####################################################
-
-start_of_setup:
-# Bootlin depends on this being done early
-	movw	$0x01500, %ax
-	movb	$0x81, %dl
-	int	$0x13
-
-#ifdef SAFE_RESET_DISK_CONTROLLER
-# Reset the disk controller.
-	movw	$0x0000, %ax
-	movb	$0x80, %dl
-	int	$0x13
-#endif
-
-# Set %ds = %cs, we know that SETUPSEG = %cs at this point
-	movw	%cs, %ax		# aka SETUPSEG
-	movw	%ax, %ds
-# Check signature at end of setup
-	cmpw	$SIG1, setup_sig1
-	jne	bad_sig
-
-	cmpw	$SIG2, setup_sig2
-	jne	bad_sig
-
-	jmp	good_sig1
-
-# Routine to print asciiz string at ds:si
-prtstr:
-	lodsb
-	andb	%al, %al
-	jz	fin
-
-	call	prtchr
-	jmp	prtstr
-
-fin:	ret
-
-# Space printing
-prtsp2:	call	prtspc		# Print double space
-prtspc:	movb	$0x20, %al	# Print single space (note: fall-thru)
-
-prtchr:	
-	pushw	%ax
-	pushw	%cx
-	movw	$0007,%bx
-	movw	$0x01, %cx
-	movb	$0x0e, %ah
-	int	$0x10
-	popw	%cx
-	popw	%ax
-	ret
-
-beep:	movb	$0x07, %al
-	jmp	prtchr
-	
-no_sig_mess: .string	"No setup signature found ..."
-
-good_sig1:
-	jmp	good_sig
-
-# We now have to find the rest of the setup code/data
-bad_sig:
-	movw	%cs, %ax			# SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# INITSEG
-	movw	%ax, %ds
-	xorb	%bh, %bh
-	movb	(497), %bl			# get setup sect from bootsect
-	subw	$4, %bx				# LILO loads 4 sectors of setup
-	shlw	$8, %bx				# convert to words (1sect=2^8 words)
-	movw	%bx, %cx
-	shrw	$3, %bx				# convert to segment
-	addw	$SYSSEG, %bx
-	movw	%bx, %cs:start_sys_seg
-# Move rest of setup code/data to here
-	movw	$2048, %di			# four sectors loaded by LILO
-	subw	%si, %si
-	movw	%cs, %ax			# aka SETUPSEG
-	movw	%ax, %es
-	movw	$SYSSEG, %ax
-	movw	%ax, %ds
-	rep
-	movsw
-	movw	%cs, %ax			# aka SETUPSEG
-	movw	%ax, %ds
-	cmpw	$SIG1, setup_sig1
-	jne	no_sig
-
-	cmpw	$SIG2, setup_sig2
-	jne	no_sig
-
-	jmp	good_sig
-
-no_sig:
-	lea	no_sig_mess, %si
-	call	prtstr
-
-no_sig_loop:
-	jmp	no_sig_loop
-
-good_sig:
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax 		# aka INITSEG
-	movw	%ax, %ds
-# Check if an old loader tries to load a big-kernel
-	testb	$LOADED_HIGH, %cs:loadflags	# Do we have a big kernel?
-	jz	loader_ok			# No, no danger for old loaders.
-
-	cmpb	$0, %cs:type_of_loader 		# Do we have a loader that
-						# can deal with us?
-	jnz	loader_ok			# Yes, continue.
-
-	pushw	%cs				# No, we have an old loader,
-	popw	%ds				# die. 
-	lea	loader_panic_mess, %si
-	call	prtstr
-
-	jmp	no_sig_loop
-
-loader_panic_mess: .string "Wrong loader, giving up..."
-
-loader_ok:
-	/* check for long mode. */
-	/* we have to do this before the VESA setup, otherwise the user
-	   can't see the error message. */
-	
-	pushw	%ds
-	movw	%cs,%ax
-	movw	%ax,%ds
-	
-	call verify_cpu
-	testl %eax,%eax
-	jz sse_ok
-
-no_longmode:
-	call	beep
-	lea	long_mode_panic,%si
-	call	prtstr
-no_longmode_loop:		
-	jmp	no_longmode_loop
-long_mode_panic:
-	.string "Your CPU does not support long mode. Use a 32bit distribution."
-	.byte 0
-
-#include "../kernel/verify_cpu.S"
-sse_ok:
-	popw	%ds
-	
-# tell BIOS we want to go to long mode
-	movl  $0xec00,%eax	# declare target operating mode
-	movl  $2,%ebx		# long mode
-	int $0x15			
-	
-# Get memory size (extended mem, kB)
-
-	xorl	%eax, %eax
-	movl	%eax, (0x1e0)
-#ifndef STANDARD_MEMORY_BIOS_CALL
-	movb	%al, (E820NR)
-# Try three different memory detection schemes.  First, try
-# e820h, which lets us assemble a memory map, then try e801h,
-# which returns a 32-bit memory size, and finally 88h, which
-# returns 0-64m
-
-# method E820H:
-# the memory map from hell.  e820h returns memory classified into
-# a whole bunch of different types, and allows memory holes and
-# everything.  We scan through this memory map and build a list
-# of the first 32 memory areas, which we return at [E820MAP].
-# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
-
-#define SMAP  0x534d4150
-
-meme820:
-	xorl	%ebx, %ebx			# continuation counter
-	movw	$E820MAP, %di			# point into the whitelist
-						# so we can have the bios
-						# directly write into it.
-
-jmpe820:
-	movl	$0x0000e820, %eax		# e820, upper word zeroed
-	movl	$SMAP, %edx			# ascii 'SMAP'
-	movl	$20, %ecx			# size of the e820rec
-	pushw	%ds				# data record.
-	popw	%es
-	int	$0x15				# make the call
-	jc	bail820				# fall to e801 if it fails
-
-	cmpl	$SMAP, %eax			# check the return is `SMAP'
-	jne	bail820				# fall to e801 if it fails
-
-#	cmpl	$1, 16(%di)			# is this usable memory?
-#	jne	again820
-
-	# If this is usable memory, we save it by simply advancing %di by
-	# sizeof(e820rec).
-	#
-good820:
-	movb	(E820NR), %al			# up to 128 entries
-	cmpb	$E820MAX, %al
-	jae	bail820
-
-	incb	(E820NR)
-	movw	%di, %ax
-	addw	$20, %ax
-	movw	%ax, %di
-again820:
-	cmpl	$0, %ebx			# check to see if
-	jne	jmpe820				# %ebx is set to EOF
-bail820:
-
-
-# method E801H:
-# memory size is in 1k chunksizes, to avoid confusing loadlin.
-# we store the 0xe801 memory size in a completely different place,
-# because it will most likely be longer than 16 bits.
-# (use 1e0 because that's what Larry Augustine uses in his
-# alternative new memory detection scheme, and it's sensible
-# to write everything into the same place.)
-
-meme801:
-	stc					# fix to work around buggy
-	xorw	%cx,%cx				# BIOSes which don't clear/set
-	xorw	%dx,%dx				# carry on pass/error of
-						# e801h memory size call
-						# or merely pass cx,dx though
-						# without changing them.
-	movw	$0xe801, %ax
-	int	$0x15
-	jc	mem88
-
-	cmpw	$0x0, %cx			# Kludge to handle BIOSes
-	jne	e801usecxdx			# which report their extended
-	cmpw	$0x0, %dx			# memory in AX/BX rather than
-	jne	e801usecxdx			# CX/DX.  The spec I have read
-	movw	%ax, %cx			# seems to indicate AX/BX 
-	movw	%bx, %dx			# are more reasonable anyway...
-
-e801usecxdx:
-	andl	$0xffff, %edx			# clear sign extend
-	shll	$6, %edx			# and go from 64k to 1k chunks
-	movl	%edx, (0x1e0)			# store extended memory size
-	andl	$0xffff, %ecx			# clear sign extend
- 	addl	%ecx, (0x1e0)			# and add lower memory into
-						# total size.
-
-# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
-# 64mb, depending on the bios) in ax.
-mem88:
-
-#endif
-	movb	$0x88, %ah
-	int	$0x15
-	movw	%ax, (2)
-
-# Set the keyboard repeat rate to the max
-	movw	$0x0305, %ax
-	xorw	%bx, %bx
-	int	$0x16
-
-# Check for video adapter and its parameters and allow the
-# user to browse video modes.
-	call	video				# NOTE: we need %ds pointing
-						# to bootsector
-
-# Get hd0 data...
-	xorw	%ax, %ax
-	movw	%ax, %ds
-	ldsw	(4 * 0x41), %si
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	pushw	%ax
-	movw	%ax, %es
-	movw	$0x0080, %di
-	movw	$0x10, %cx
-	pushw	%cx
-	cld
-	rep
- 	movsb
-# Get hd1 data...
-	xorw	%ax, %ax
-	movw	%ax, %ds
-	ldsw	(4 * 0x46), %si
-	popw	%cx
-	popw	%es
-	movw	$0x0090, %di
-	rep
-	movsb
-# Check that there IS a hd1 :-)
-	movw	$0x01500, %ax
-	movb	$0x81, %dl
-	int	$0x13
-	jc	no_disk1
-	
-	cmpb	$3, %ah
-	je	is_disk1
-
-no_disk1:
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax 		# aka INITSEG
-	movw	%ax, %es
-	movw	$0x0090, %di
-	movw	$0x10, %cx
-	xorw	%ax, %ax
-	cld
-	rep
-	stosb
-is_disk1:
-
-# Check for PS/2 pointing device
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	movw	%ax, %ds
-	movb	$0, (0x1ff)			# default is no pointing device
-	int	$0x11				# int 0x11: equipment list
-	testb	$0x04, %al			# check if mouse installed
-	jz	no_psmouse
-
-	movb	$0xAA, (0x1ff)			# device present
-no_psmouse:
-
-#include "../../i386/boot/edd.S"
-
-# Now we want to move to protected mode ...
-	cmpw	$0, %cs:realmode_swtch
-	jz	rmodeswtch_normal
-
-	lcall	*%cs:realmode_swtch
-
-	jmp	rmodeswtch_end
-
-rmodeswtch_normal:
-        pushw	%cs
-	call	default_switch
-
-rmodeswtch_end:
-# we get the code32 start address and modify the below 'jmpi'
-# (loader may have changed it)
-	movl	%cs:code32_start, %eax
-	movl	%eax, %cs:code32
-
-# Now we move the system to its rightful place ... but we check if we have a
-# big-kernel. In that case we *must* not move it ...
-	testb	$LOADED_HIGH, %cs:loadflags
-	jz	do_move0			# .. then we have a normal low
-						# loaded zImage
-						# .. or else we have a high
-						# loaded bzImage
-	jmp	end_move			# ... and we skip moving
-
-do_move0:
-	movw	$0x100, %ax			# start of destination segment
-	movw	%cs, %bp			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %bp		# aka INITSEG
-	movw	%cs:start_sys_seg, %bx		# start of source segment
-	cld
-do_move:
-	movw	%ax, %es			# destination segment
-	incb	%ah				# instead of add ax,#0x100
-	movw	%bx, %ds			# source segment
-	addw	$0x100, %bx
-	subw	%di, %di
-	subw	%si, %si
-	movw 	$0x800, %cx
-	rep
-	movsw
-	cmpw	%bp, %bx			# assume start_sys_seg > 0x200,
-						# so we will perhaps read one
-						# page more than needed, but
-						# never overwrite INITSEG
-						# because destination is a
-						# minimum one page below source
-	jb	do_move
-
-end_move:
-# then we load the segment descriptors
-	movw	%cs, %ax			# aka SETUPSEG
-	movw	%ax, %ds
-		
-# Check whether we need to be downward compatible with version <=201
-	cmpl	$0, cmd_line_ptr
-	jne	end_move_self		# loader uses version >=202 features
-	cmpb	$0x20, type_of_loader
-	je	end_move_self		# bootsect loader, we know of it
-
-# Boot loader doesnt support boot protocol version 2.02.
-# If we have our code not at 0x90000, we need to move it there now.
-# We also then need to move the params behind it (commandline)
-# Because we would overwrite the code on the current IP, we move
-# it in two steps, jumping high after the first one.
-	movw	%cs, %ax
-	cmpw	$SETUPSEG, %ax
-	je	end_move_self
-
-	cli					# make sure we really have
-						# interrupts disabled !
-						# because after this the stack
-						# should not be used
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	movw	%ss, %dx
-	cmpw	%ax, %dx
-	jb	move_self_1
-
-	addw	$INITSEG, %dx
-	subw	%ax, %dx			# this will go into %ss after
-						# the move
-move_self_1:
-	movw	%ax, %ds
-	movw	$INITSEG, %ax			# real INITSEG
-	movw	%ax, %es
-	movw	%cs:setup_move_size, %cx
-	std					# we have to move up, so we use
-						# direction down because the
-						# areas may overlap
-	movw	%cx, %di
-	decw	%di
-	movw	%di, %si
-	subw	$move_self_here+0x200, %cx
-	rep
-	movsb
-	ljmp	$SETUPSEG, $move_self_here
-
-move_self_here:
-	movw	$move_self_here+0x200, %cx
-	rep
-	movsb
-	movw	$SETUPSEG, %ax
-	movw	%ax, %ds
-	movw	%dx, %ss
-end_move_self:					# now we are at the right place
-	lidt	idt_48				# load idt with 0,0
-	xorl	%eax, %eax			# Compute gdt_base
-	movw	%ds, %ax			# (Convert %ds:gdt to a linear ptr)
-	shll	$4, %eax
-	addl	$gdt, %eax
-	movl	%eax, (gdt_48+2)
-	lgdt	gdt_48				# load gdt with whatever is
-						# appropriate
-
-# that was painless, now we enable a20
-	call	empty_8042
-
-	movb	$0xD1, %al			# command write
-	outb	%al, $0x64
-	call	empty_8042
-
-	movb	$0xDF, %al			# A20 on
-	outb	%al, $0x60
-	call	empty_8042
-
-#
-#	You must preserve the other bits here. Otherwise embarrasing things
-#	like laptops powering off on boot happen. Corrected version by Kira
-#	Brown from Linux 2.2
-#
-	inb	$0x92, %al			# 
-	orb	$02, %al			# "fast A20" version
-	outb	%al, $0x92			# some chips have only this
-
-# wait until a20 really *is* enabled; it can take a fair amount of
-# time on certain systems; Toshiba Tecras are known to have this
-# problem.  The memory location used here (0x200) is the int 0x80
-# vector, which should be safe to use.
-
-	xorw	%ax, %ax			# segment 0x0000
-	movw	%ax, %fs
-	decw	%ax				# segment 0xffff (HMA)
-	movw	%ax, %gs
-a20_wait:
-	incw	%ax				# unused memory location <0xfff0
-	movw	%ax, %fs:(0x200)		# we use the "int 0x80" vector
-	cmpw	%gs:(0x210), %ax		# and its corresponding HMA addr
-	je	a20_wait			# loop until no longer aliased
-
-# make sure any possible coprocessor is properly reset..
-	xorw	%ax, %ax
-	outb	%al, $0xf0
-	call	delay
-
-	outb	%al, $0xf1
-	call	delay
-
-# well, that went ok, I hope. Now we mask all interrupts - the rest
-# is done in init_IRQ().
-	movb	$0xFF, %al			# mask all interrupts for now
-	outb	%al, $0xA1
-	call	delay
-	
-	movb	$0xFB, %al			# mask all irq's but irq2 which
-	outb	%al, $0x21			# is cascaded
-
-# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
-# need no steenking BIOS anyway (except for the initial loading :-).
-# The BIOS-routine wants lots of unnecessary data, and it's less
-# "interesting" anyway. This is how REAL programmers do it.
-#
-# Well, now's the time to actually move into protected mode. To make
-# things as simple as possible, we do no register set-up or anything,
-# we let the gnu-compiled 32-bit programs do that. We just jump to
-# absolute address 0x1000 (or the loader supplied one),
-# in 32-bit protected mode.
-#
-# Note that the short jump isn't strictly needed, although there are
-# reasons why it might be a good idea. It won't hurt in any case.
-	movw	$1, %ax				# protected mode (PE) bit
-	lmsw	%ax				# This is it!
-	jmp	flush_instr
-
-flush_instr:
-	xorw	%bx, %bx			# Flag to indicate a boot
-	xorl	%esi, %esi			# Pointer to real-mode code
-	movw	%cs, %si
-	subw	$DELTA_INITSEG, %si
-	shll	$4, %esi			# Convert to 32-bit pointer
-# NOTE: For high loaded big kernels we need a
-#	jmpi    0x100000,__KERNEL_CS
-#
-#	but we yet haven't reloaded the CS register, so the default size 
-#	of the target offset still is 16 bit.
-#	However, using an operand prefix (0x66), the CPU will properly
-#	take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
-#	Manual, Mixing 16-bit and 32-bit code, page 16-6)
-
-	.byte 0x66, 0xea			# prefix + jmpi-opcode
-code32:	.long	0x1000				# will be set to 0x100000
-						# for big kernels
-	.word	__KERNEL_CS
-
-# Here's a bunch of information about your current kernel..
-kernel_version:	.ascii	UTS_RELEASE
-		.ascii	" ("
-		.ascii	LINUX_COMPILE_BY
-		.ascii	"@"
-		.ascii	LINUX_COMPILE_HOST
-		.ascii	") "
-		.ascii	UTS_VERSION
-		.byte	0
-
-# This is the default real mode switch routine.
-# to be called just before protected mode transition
-default_switch:
-	cli					# no interrupts allowed !
-	movb	$0x80, %al			# disable NMI for bootup
-						# sequence
-	outb	%al, $0x70
-	lret
-
-
-# This routine checks that the keyboard command queue is empty
-# (after emptying the output buffers)
-#
-# Some machines have delusions that the keyboard buffer is always full
-# with no keyboard attached...
-#
-# If there is no keyboard controller, we will usually get 0xff
-# to all the reads.  With each IO taking a microsecond and
-# a timeout of 100,000 iterations, this can take about half a
-# second ("delay" == outb to port 0x80). That should be ok,
-# and should also be plenty of time for a real keyboard controller
-# to empty.
-#
-
-empty_8042:
-	pushl	%ecx
-	movl	$100000, %ecx
-
-empty_8042_loop:
-	decl	%ecx
-	jz	empty_8042_end_loop
-
-	call	delay
-
-	inb	$0x64, %al			# 8042 status port
-	testb	$1, %al				# output buffer?
-	jz	no_output
-
-	call	delay
-	inb	$0x60, %al			# read it
-	jmp	empty_8042_loop
-
-no_output:
-	testb	$2, %al				# is input buffer full?
-	jnz	empty_8042_loop			# yes - loop
-empty_8042_end_loop:
-	popl	%ecx
-	ret
-
-# Read the cmos clock. Return the seconds in al
-gettime:
-	pushw	%cx
-	movb	$0x02, %ah
-	int	$0x1a
-	movb	%dh, %al			# %dh contains the seconds
-	andb	$0x0f, %al
-	movb	%dh, %ah
-	movb	$0x04, %cl
-	shrb	%cl, %ah
-	aad
-	popw	%cx
-	ret
-
-# Delay is needed after doing I/O
-delay:
-	outb	%al,$0x80
-	ret
-
-# Descriptor tables
-gdt:
-	.word	0, 0, 0, 0			# dummy
-
-	.word	0, 0, 0, 0			# unused
-
-	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
-	.word	0				# base address = 0
-	.word	0x9A00				# code read/exec
-	.word	0x00CF				# granularity = 4096, 386
-						#  (+5th nibble of limit)
-
-	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
-	.word	0				# base address = 0
-	.word	0x9200				# data read/write
-	.word	0x00CF				# granularity = 4096, 386
-						#  (+5th nibble of limit)
-gdt_end:
-idt_48:
-	.word	0				# idt limit = 0
-	.word	0, 0				# idt base = 0L
-gdt_48:
-	.word	gdt_end-gdt-1			# gdt limit
-	.word	0, 0				# gdt base (filled in later)
-
-# Include video setup & detection code
-
-#include "../../i386/boot/video.S"
-
-# Setup signature -- must be last
-setup_sig1:	.word	SIG1
-setup_sig2:	.word	SIG2
-
-# After this point, there is some free space which is used by the video mode
-# handling code to store the temporary mode table (not used by the kernel).
-
-modelist:
-
-.text
-endtext:
-.data
-enddata:
-.bss
-endbss:
diff --git a/arch/x86_64/boot/tools/build.c b/arch/x86_64/boot/tools/build.c
deleted file mode 100644
index eae8669..0000000
--- a/arch/x86_64/boot/tools/build.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *  Copyright (C) 1997 Martin Mares
- */
-
-/*
- * This file builds a disk-image from three different files:
- *
- * - bootsect: compatibility mbr which prints an error message if
- *             someone tries to boot the kernel directly.
- * - setup: 8086 machine code, sets up system parm
- * - system: 80386 code for actual system
- *
- * It does some checking that all files are of the correct type, and
- * just writes the result to stdout, removing headers and padding to
- * the right amount. It also writes some system data to stderr.
- */
-
-/*
- * Changes by tytso to allow root device specification
- * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
- * Cross compiling fixes by Gertjan van Wingerde, July 1996
- * Rewritten by Martin Mares, April 1997
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <asm/boot.h>
-
-typedef unsigned char byte;
-typedef unsigned short word;
-typedef unsigned long u32;
-
-#define DEFAULT_MAJOR_ROOT 0
-#define DEFAULT_MINOR_ROOT 0
-
-/* Minimal number of setup sectors (see also bootsect.S) */
-#define SETUP_SECTS 4
-
-byte buf[1024];
-int fd;
-int is_big_kernel;
-
-void die(const char * str, ...)
-{
-	va_list args;
-	va_start(args, str);
-	vfprintf(stderr, str, args);
-	fputc('\n', stderr);
-	exit(1);
-}
-
-void file_open(const char *name)
-{
-	if ((fd = open(name, O_RDONLY, 0)) < 0)
-		die("Unable to open `%s': %m", name);
-}
-
-void usage(void)
-{
-	die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
-}
-
-int main(int argc, char ** argv)
-{
-	unsigned int i, c, sz, setup_sectors;
-	u32 sys_size;
-	byte major_root, minor_root;
-	struct stat sb;
-
-	if (argc > 2 && !strcmp(argv[1], "-b"))
-	  {
-	    is_big_kernel = 1;
-	    argc--, argv++;
-	  }
-	if ((argc < 4) || (argc > 5))
-		usage();
-	if (argc > 4) {
-		if (!strcmp(argv[4], "CURRENT")) {
-			if (stat("/", &sb)) {
-				perror("/");
-				die("Couldn't stat /");
-			}
-			major_root = major(sb.st_dev);
-			minor_root = minor(sb.st_dev);
-		} else if (strcmp(argv[4], "FLOPPY")) {
-			if (stat(argv[4], &sb)) {
-				perror(argv[4]);
-				die("Couldn't stat root device.");
-			}
-			major_root = major(sb.st_rdev);
-			minor_root = minor(sb.st_rdev);
-		} else {
-			major_root = 0;
-			minor_root = 0;
-		}
-	} else {
-		major_root = DEFAULT_MAJOR_ROOT;
-		minor_root = DEFAULT_MINOR_ROOT;
-	}
-	fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
-
-	file_open(argv[1]);
-	i = read(fd, buf, sizeof(buf));
-	fprintf(stderr,"Boot sector %d bytes.\n",i);
-	if (i != 512)
-		die("Boot block must be exactly 512 bytes");
-	if (buf[510] != 0x55 || buf[511] != 0xaa)
-		die("Boot block hasn't got boot flag (0xAA55)");
-	buf[508] = minor_root;
-	buf[509] = major_root;
-	if (write(1, buf, 512) != 512)
-		die("Write call failed");
-	close (fd);
-
-	file_open(argv[2]);				    /* Copy the setup code */
-	for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
-		if (write(1, buf, c) != c)
-			die("Write call failed");
-	if (c != 0)
-		die("read-error on `setup'");
-	close (fd);
-
-	setup_sectors = (i + 511) / 512;	/* Pad unused space with zeros */
-	/* for compatibility with ancient versions of LILO. */
-	if (setup_sectors < SETUP_SECTS)
-		setup_sectors = SETUP_SECTS;
-	fprintf(stderr, "Setup is %d bytes.\n", i);
-	memset(buf, 0, sizeof(buf));
-	while (i < setup_sectors * 512) {
-		c = setup_sectors * 512 - i;
-		if (c > sizeof(buf))
-			c = sizeof(buf);
-		if (write(1, buf, c) != c)
-			die("Write call failed");
-		i += c;
-	}
-
-	file_open(argv[3]);
-	if (fstat (fd, &sb))
-		die("Unable to stat `%s': %m", argv[3]);
-	sz = sb.st_size;
-	fprintf (stderr, "System is %d kB\n", sz/1024);
-	sys_size = (sz + 15) / 16;
-	if (!is_big_kernel && sys_size > DEF_SYSSIZE)
-		die("System is too big. Try using bzImage or modules.");
-	while (sz > 0) {
-		int l, n;
-
-		l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
-		if ((n=read(fd, buf, l)) != l) {
-			if (n < 0)
-				die("Error reading %s: %m", argv[3]);
-			else
-				die("%s: Unexpected EOF", argv[3]);
-		}
-		if (write(1, buf, l) != l)
-			die("Write failed");
-		sz -= l;
-	}
-	close(fd);
-
-	if (lseek(1, 497, SEEK_SET) != 497)		    /* Write sizes to the bootsector */
-		die("Output: seek failed");
-	buf[0] = setup_sectors;
-	if (write(1, buf, 1) != 1)
-		die("Write of setup sector count failed");
-	if (lseek(1, 500, SEEK_SET) != 500)
-		die("Output: seek failed");
-	buf[0] = (sys_size & 0xff);
-	buf[1] = ((sys_size >> 8) & 0xff);
-	buf[2] = ((sys_size >> 16) & 0xff);
-	buf[3] = ((sys_size >> 24) & 0xff);
-	if (write(1, buf, 4) != 4)
-		die("Write of image length failed");
-
-	return 0;					    /* Everything is OK */
-}
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [x86 setup 33/33] Remove old i386 setup code
       [not found]   ` <51664bcb2a5a2f1fe130229d34128a642dc81a4c.1184032749.git.hpa@zytor.com>
@ 2007-07-10  2:52     ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  2:52 UTC (permalink / raw)
  To: linux-kernel, linux-arch, andi, akpm; +Cc: H. Peter Anvin

From: H. Peter Anvin <hpa@zytor.com>

This removes the old i386 setup code.  This is done as a separate patch
to avoid breaking git bisect as some of the i386 code was also used by
the old x86-64 code.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/i386/boot/bootsect.S     |   98 --
 arch/i386/boot/edd.S          |  231 -----
 arch/i386/boot/setup.S        | 1075 ----------------------
 arch/i386/boot/video.S        | 2043 -----------------------------------------
 arch/i386/kernel/verify_cpu.S |   94 --
 include/linux/edd.h           |    4 -
 6 files changed, 0 insertions(+), 3545 deletions(-)
 delete mode 100644 arch/i386/boot/bootsect.S
 delete mode 100644 arch/i386/boot/edd.S
 delete mode 100644 arch/i386/boot/setup.S
 delete mode 100644 arch/i386/boot/video.S
 delete mode 100644 arch/i386/kernel/verify_cpu.S

diff --git a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S
deleted file mode 100644
index 011b7a4..0000000
--- a/arch/i386/boot/bootsect.S
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *	bootsect.S		Copyright (C) 1991, 1992 Linus Torvalds
- *
- *	modified by Drew Eckhardt
- *	modified by Bruce Evans (bde)
- *	modified by Chris Noe (May 1999) (as86 -> gas)
- *	gutted by H. Peter Anvin (Jan 2003)
- *
- * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
- * addresses must be multiplied by 16 to obtain their respective linear
- * addresses. To avoid confusion, linear addresses are written using leading
- * hex while segment addresses are written as segment:offset.
- *
- */
-
-#include <asm/boot.h>
-
-SETUPSECTS	= 4			/* default nr of setup-sectors */
-BOOTSEG		= 0x07C0		/* original address of boot-sector */
-INITSEG		= DEF_INITSEG		/* we move boot here - out of the way */
-SETUPSEG	= DEF_SETUPSEG		/* setup starts here */
-SYSSEG		= DEF_SYSSEG		/* system loaded at 0x10000 (65536) */
-SYSSIZE		= DEF_SYSSIZE		/* system size: # of 16-byte clicks */
-					/* to be loaded */
-ROOT_DEV	= 0 			/* ROOT_DEV is now written by "build" */
-SWAP_DEV	= 0			/* SWAP_DEV is now written by "build" */
-
-#ifndef SVGA_MODE
-#define SVGA_MODE ASK_VGA
-#endif
-
-#ifndef RAMDISK
-#define RAMDISK 0
-#endif
-
-#ifndef ROOT_RDONLY
-#define ROOT_RDONLY 1
-#endif
-
-.code16
-.text
-
-.global _start
-_start:
-
-	# Normalize the start address
-	jmpl	$BOOTSEG, $start2
-
-start2:
-	movw	%cs, %ax
-	movw	%ax, %ds
-	movw	%ax, %es
-	movw	%ax, %ss
-	movw	$0x7c00, %sp
-	sti
-	cld
-
-	movw	$bugger_off_msg, %si
-
-msg_loop:
-	lodsb
-	andb	%al, %al
-	jz	die
-	movb	$0xe, %ah
-	movw	$7, %bx
-	int	$0x10
-	jmp	msg_loop
-
-die:
-	# Allow the user to press a key, then reboot
-	xorw	%ax, %ax
-	int	$0x16
-	int	$0x19
-
-	# int 0x19 should never return.  In case it does anyway,
-	# invoke the BIOS reset code...
-	ljmp	$0xf000,$0xfff0
-
-
-bugger_off_msg:
-	.ascii	"Direct booting from floppy is no longer supported.\r\n"
-	.ascii	"Please use a boot loader program instead.\r\n"
-	.ascii	"\n"
-	.ascii	"Remove disk and press any key to reboot . . .\r\n"
-	.byte	0
-
-
-	# Kernel attributes; used by setup
-
-	.org 497
-setup_sects:	.byte SETUPSECTS
-root_flags:	.word ROOT_RDONLY
-syssize:	.word SYSSIZE
-swap_dev:	.word SWAP_DEV
-ram_size:	.word RAMDISK
-vid_mode:	.word SVGA_MODE
-root_dev:	.word ROOT_DEV
-boot_flag:	.word 0xAA55
diff --git a/arch/i386/boot/edd.S b/arch/i386/boot/edd.S
deleted file mode 100644
index 3432136..0000000
--- a/arch/i386/boot/edd.S
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * BIOS Enhanced Disk Drive support
- * Copyright (C) 2002, 2003, 2004 Dell, Inc.
- * by Matt Domsch <Matt_Domsch@dell.com> October 2002
- * conformant to T13 Committee www.t13.org
- *   projects 1572D, 1484D, 1386D, 1226DT
- * disk signature read by Matt Domsch <Matt_Domsch@dell.com>
- *	and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004
- * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net>
- *      March 2004
- * Command line option parsing, Matt Domsch, November 2004
- */
-
-#include <linux/edd.h>
-#include <asm/setup.h>
-
-#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
-
-# It is assumed that %ds == INITSEG here
-
-	movb	$0, (EDD_MBR_SIG_NR_BUF)
-	movb	$0, (EDDNR)
-
-# Check the command line for options:
-# edd=of  disables EDD completely  (edd=off)
-# edd=sk  skips the MBR test    (edd=skipmbr)
-# edd=on  re-enables EDD (edd=on)
-
-	pushl	%esi
-	movw	$edd_mbr_sig_start, %di	# Default to edd=on
-
-	movl	%cs:(cmd_line_ptr), %esi
-	andl	%esi, %esi
-	jz	old_cl			# Old boot protocol?
-
-# Convert to a real-mode pointer in fs:si
-	movl	%esi, %eax
-	shrl	$4, %eax
-	movw	%ax, %fs
-	andw	$0xf, %si
-	jmp	have_cl_pointer
-
-# Old-style boot protocol?
-old_cl:
-	push	%ds			# aka INITSEG
-	pop	%fs
-
-	cmpw	$0xa33f, (0x20)
-	jne	done_cl			# No command line at all?
-	movw	(0x22), %si		# Pointer relative to INITSEG
-
-# fs:si has the pointer to the command line now
-have_cl_pointer:
-
-# Loop through kernel command line one byte at a time.  Just in
-# case the loader is buggy and failed to null-terminate the command line
-# terminate if we get close enough to the end of the segment that we
-# cannot fit "edd=XX"...
-cl_atspace:
-	cmpw	$-5, %si		# Watch for segment wraparound
-	jae	done_cl
-	movl	%fs:(%si), %eax
-	andb	%al, %al		# End of line?
-	jz	done_cl
-	cmpl	$EDD_CL_EQUALS, %eax
-	jz	found_edd_equals
-	cmpb	$0x20, %al		# <= space consider whitespace
-	ja	cl_skipword
-	incw	%si
-	jmp	cl_atspace
-
-cl_skipword:
-	cmpw	$-5, %si		# Watch for segment wraparound
-	jae	done_cl
-	movb	%fs:(%si), %al		# End of string?
-	andb	%al, %al
-	jz	done_cl
-	cmpb	$0x20, %al
-	jbe	cl_atspace
-	incw	%si
-	jmp	cl_skipword
-
-found_edd_equals:
-# only looking at first two characters after equals
-# late overrides early on the command line, so keep going after finding something
-	movw	%fs:4(%si), %ax
-	cmpw	$EDD_CL_OFF, %ax	# edd=of
-	je	do_edd_off
-	cmpw	$EDD_CL_SKIP, %ax	# edd=sk
-	je	do_edd_skipmbr
-	cmpw	$EDD_CL_ON, %ax		# edd=on
-	je	do_edd_on
-	jmp	cl_skipword
-do_edd_skipmbr:
-	movw	$edd_start, %di
-	jmp	cl_skipword
-do_edd_off:
-	movw	$edd_done, %di
-	jmp	cl_skipword
-do_edd_on:
-	movw	$edd_mbr_sig_start, %di
-	jmp	cl_skipword
-
-done_cl:
-	popl	%esi
-	jmpw	*%di
-
-# Read the first sector of each BIOS disk device and store the 4-byte signature
-edd_mbr_sig_start:
-	movb	$0x80, %dl			# from device 80
-	movw	$EDD_MBR_SIG_BUF, %bx		# store buffer ptr in bx
-edd_mbr_sig_read:
-	movl	$0xFFFFFFFF, %eax
-	movl	%eax, (%bx)			# assume failure
-	pushw	%bx
-	movb	$READ_SECTORS, %ah
-	movb	$1, %al				# read 1 sector
-	movb	$0, %dh				# at head 0
-	movw	$1, %cx				# cylinder 0, sector 0
-	pushw	%es
-	pushw	%ds
-	popw	%es
-    	movw	$EDDBUF, %bx			# disk's data goes into EDDBUF
-	pushw	%dx             # work around buggy BIOSes
-	stc                     # work around buggy BIOSes
-	int	$0x13
-	sti                     # work around buggy BIOSes
-	popw	%dx
-	popw	%es
-	popw	%bx
-	jc	edd_mbr_sig_done		# on failure, we're done.
-	cmpb	$0, %ah		# some BIOSes do not set CF
-	jne	edd_mbr_sig_done		# on failure, we're done.
-	movl	(EDDBUF+EDD_MBR_SIG_OFFSET), %eax # read sig out of the MBR
-	movl	%eax, (%bx)			# store success
-	incb	(EDD_MBR_SIG_NR_BUF)		# note that we stored something
-	incb	%dl				# increment to next device
-	addw	$4, %bx				# increment sig buffer ptr
-	cmpb	$EDD_MBR_SIG_MAX, (EDD_MBR_SIG_NR_BUF)	# Out of space?
-	jb	edd_mbr_sig_read		# keep looping
-edd_mbr_sig_done:
-
-# Do the BIOS Enhanced Disk Drive calls
-# This consists of two calls:
-#    int 13h ah=41h "Check Extensions Present"
-#    int 13h ah=48h "Get Device Parameters"
-#    int 13h ah=08h "Legacy Get Device Parameters"
-#
-# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use
-# in the boot_params at EDDBUF.  The first four bytes of which are
-# used to store the device number, interface support map and version
-# results from fn41.  The next four bytes are used to store the legacy
-# cylinders, heads, and sectors from fn08. The following 74 bytes are used to
-# store the results from fn48.  Starting from device 80h, fn41, then fn48
-# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE).
-# Then the pointer is incremented to store the data for the next call.
-# This repeats until either a device doesn't exist, or until EDDMAXNR
-# devices have been stored.
-# The one tricky part is that ds:si always points EDDEXTSIZE bytes into
-# the structure, and the fn41 and fn08 results are stored at offsets
-# from there.  This removes the need to increment the pointer for
-# every store, and leaves it ready for the fn48 call.
-# A second one-byte buffer, EDDNR, in the boot_params stores
-# the number of BIOS devices which exist, up to EDDMAXNR.
-# In setup.c, copy_edd() stores both boot_params buffers away
-# for later use, as they would get overwritten otherwise.
-# This code is sensitive to the size of the structs in edd.h
-edd_start:
-						# %ds points to the bootsector
-       						# result buffer for fn48
-	movw	$EDDBUF+EDDEXTSIZE, %si		# in ds:si, fn41 results
-						# kept just before that
-	movb	$0x80, %dl			# BIOS device 0x80
-
-edd_check_ext:
-	movb	$CHECKEXTENSIONSPRESENT, %ah    # Function 41
-	movw	$EDDMAGIC1, %bx			# magic
-	int	$0x13				# make the call
-	jc	edd_done			# no more BIOS devices
-
-	cmpw	$EDDMAGIC2, %bx			# is magic right?
-	jne	edd_next			# nope, next...
-
-	movb	%dl, %ds:-8(%si)		# store device number
-	movb	%ah, %ds:-7(%si)		# store version
-	movw	%cx, %ds:-6(%si)		# store extensions
-	incb	(EDDNR)				# note that we stored something
-
-edd_get_device_params:
-	movw	$EDDPARMSIZE, %ds:(%si)		# put size
-	movw	$0x0, %ds:2(%si)		# work around buggy BIOSes
-	movb	$GETDEVICEPARAMETERS, %ah	# Function 48
-	int	$0x13				# make the call
-						# Don't check for fail return
-						# it doesn't matter.
-edd_get_legacy_chs:
-	xorw    %ax, %ax
-	movw    %ax, %ds:-4(%si)
-	movw    %ax, %ds:-2(%si)
-        # Ralf Brown's Interrupt List says to set ES:DI to
-	# 0000h:0000h "to guard against BIOS bugs"
-	pushw   %es
-	movw    %ax, %es
-	movw    %ax, %di
-	pushw   %dx                             # legacy call clobbers %dl
-	movb    $LEGACYGETDEVICEPARAMETERS, %ah # Function 08
-	int     $0x13                           # make the call
-	jc      edd_legacy_done                 # failed
-	movb    %cl, %al                        # Low 6 bits are max
-	andb    $0x3F, %al                      #   sector number
-	movb	%al, %ds:-1(%si)                # Record max sect
-	movb    %dh, %ds:-2(%si)                # Record max head number
-	movb    %ch, %al                        # Low 8 bits of max cyl
-	shr     $6, %cl
-	movb    %cl, %ah                        # High 2 bits of max cyl
-	movw    %ax, %ds:-4(%si)
-
-edd_legacy_done:
-	popw    %dx
-	popw    %es
-	movw	%si, %ax			# increment si
-	addw	$EDDPARMSIZE+EDDEXTSIZE, %ax
-	movw	%ax, %si
-
-edd_next:
-	incb	%dl				# increment to next device
-	cmpb	$EDDMAXNR, (EDDNR) 		# Out of space?
-	jb	edd_check_ext			# keep looping
-
-edd_done:
-#endif
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S
deleted file mode 100644
index 6dbcc95..0000000
--- a/arch/i386/boot/setup.S
+++ /dev/null
@@ -1,1075 +0,0 @@
-/*
- *	setup.S		Copyright (C) 1991, 1992 Linus Torvalds
- *
- * setup.s is responsible for getting the system data from the BIOS,
- * and putting them into the appropriate places in system memory.
- * both setup.s and system has been loaded by the bootblock.
- *
- * This code asks the bios for memory/disk/other parameters, and
- * puts them in a "safe" place: 0x90000-0x901FF, ie where the
- * boot-block used to be. It is then up to the protected mode
- * system to read them from there before the area is overwritten
- * for buffer-blocks.
- *
- * Move PS/2 aux init code to psaux.c
- * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
- *
- * some changes and additional features by Christoph Niemann,
- * March 1993/June 1994 (Christoph.Niemann@linux.org)
- *
- * add APM BIOS checking by Stephen Rothwell, May 1994
- * (sfr@canb.auug.org.au)
- *
- * High load stuff, initrd support and position independency
- * by Hans Lermen & Werner Almesberger, February 1996
- * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
- *
- * Video handling moved to video.S by Martin Mares, March 1996
- * <mj@k332.feld.cvut.cz>
- *
- * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
- * parsons) to avoid loadlin confusion, July 1997
- *
- * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
- * <stiker@northlink.com>
- *
- * Fix to work around buggy BIOSes which don't use carry bit correctly
- * and/or report extended memory in CX/DX for e801h memory size detection 
- * call.  As a result the kernel got wrong figures.  The int15/e801h docs
- * from Ralf Brown interrupt list seem to indicate AX/BX should be used
- * anyway.  So to avoid breaking many machines (presumably there was a reason
- * to orginally use CX/DX instead of AX/BX), we do a kludge to see
- * if CX/DX have been changed in the e801 call and if so use AX/BX .
- * Michael Miller, April 2001 <michaelm@mjmm.org>
- *
- * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes
- * by Robert Schwebel, December 2001 <robert@schwebel.de>
- */
-
-#include <asm/segment.h>
-#include <linux/utsrelease.h>
-#include <linux/compile.h>
-#include <asm/boot.h>
-#include <asm/e820.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-	
-/* Signature words to ensure LILO loaded us right */
-#define SIG1	0xAA55
-#define SIG2	0x5A5A
-
-INITSEG  = DEF_INITSEG		# 0x9000, we move boot here, out of the way
-SYSSEG   = DEF_SYSSEG		# 0x1000, system loaded at 0x10000 (65536).
-SETUPSEG = DEF_SETUPSEG		# 0x9020, this is the current segment
-				# ... and the former contents of CS
-
-DELTA_INITSEG = SETUPSEG - INITSEG	# 0x0020
-
-.code16
-.globl begtext, begdata, begbss, endtext, enddata, endbss
-
-.text
-begtext:
-.data
-begdata:
-.bss
-begbss:
-.text
-
-start:
-	jmp	trampoline
-
-# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
-
-		.ascii	"HdrS"		# header signature
-		.word	0x0206		# header version number (>= 0x0105)
-					# or else old loadlin-1.5 will fail)
-realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
-start_sys_seg:	.word	SYSSEG
-		.word	kernel_version	# pointing to kernel version string
-					# above section of header is compatible
-					# with loadlin-1.5 (header v1.5). Don't
-					# change it.
-
-type_of_loader:	.byte	0		# = 0, old one (LILO, Loadlin,
-					#      Bootlin, SYSLX, bootsect...)
-					# See Documentation/i386/boot.txt for
-					# assigned ids
-	
-# flags, unused bits must be zero (RFU) bit within loadflags
-loadflags:
-LOADED_HIGH	= 1			# If set, the kernel is loaded high
-CAN_USE_HEAP	= 0x80			# If set, the loader also has set
-					# heap_end_ptr to tell how much
-					# space behind setup.S can be used for
-					# heap purposes.
-					# Only the loader knows what is free
-#ifndef __BIG_KERNEL__
-		.byte	0
-#else
-		.byte	LOADED_HIGH
-#endif
-
-setup_move_size: .word  0x8000		# size to move, when setup is not
-					# loaded at 0x90000. We will move setup 
-					# to 0x90000 then just before jumping
-					# into the kernel. However, only the
-					# loader knows how much data behind
-					# us also needs to be loaded.
-
-code32_start:				# here loaders can put a different
-					# start address for 32-bit code.
-#ifndef __BIG_KERNEL__
-		.long	0x1000		#   0x1000 = default for zImage
-#else
-		.long	0x100000	# 0x100000 = default for big kernel
-#endif
-
-ramdisk_image:	.long	0		# address of loaded ramdisk image
-					# Here the loader puts the 32-bit
-					# address where it loaded the image.
-					# This only will be read by the kernel.
-
-ramdisk_size:	.long	0		# its size in bytes
-
-bootsect_kludge:
-		.long	0		# obsolete
-
-heap_end_ptr:	.word	modelist+1024	# (Header version 0x0201 or later)
-					# space from here (exclusive) down to
-					# end of setup code can be used by setup
-					# for local heap purposes.
-
-pad1:		.word	0
-cmd_line_ptr:	.long 0			# (Header version 0x0202 or later)
-					# If nonzero, a 32-bit pointer
-					# to the kernel command line.
-					# The command line should be
-					# located between the start of
-					# setup and the end of low
-					# memory (0xa0000), or it may
-					# get overwritten before it
-					# gets read.  If this field is
-					# used, there is no longer
-					# anything magical about the
-					# 0x90000 segment; the setup
-					# can be located anywhere in
-					# low memory 0x10000 or higher.
-
-ramdisk_max:	.long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
-					# (Header version 0x0203 or later)
-					# The highest safe address for
-					# the contents of an initrd
-
-kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN 	#physical addr alignment
-						#required for protected mode
-						#kernel
-#ifdef CONFIG_RELOCATABLE
-relocatable_kernel:    .byte 1
-#else
-relocatable_kernel:    .byte 0
-#endif
-pad2:			.byte 0
-pad3:			.word 0
-
-cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
-                                                #added with boot protocol
-                                                #version 2.06
-
-trampoline:	call	start_of_setup
-		.align 16
-					# The offset at this point is 0x240
-		.space	(0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
-# End of setup header #####################################################
-
-start_of_setup:
-# Bootlin depends on this being done early
-	movw	$0x01500, %ax
-	movb	$0x81, %dl
-	int	$0x13
-
-#ifdef SAFE_RESET_DISK_CONTROLLER
-# Reset the disk controller.
-	movw	$0x0000, %ax
-	movb	$0x80, %dl
-	int	$0x13
-#endif
-
-# Set %ds = %cs, we know that SETUPSEG = %cs at this point
-	movw	%cs, %ax		# aka SETUPSEG
-	movw	%ax, %ds
-# Check signature at end of setup
-	cmpw	$SIG1, setup_sig1
-	jne	bad_sig
-
-	cmpw	$SIG2, setup_sig2
-	jne	bad_sig
-
-	jmp	good_sig1
-
-# Routine to print asciiz string at ds:si
-prtstr:
-	lodsb
-	andb	%al, %al
-	jz	fin
-
-	call	prtchr
-	jmp	prtstr
-
-fin:	ret
-
-# Space printing
-prtsp2:	call	prtspc		# Print double space
-prtspc:	movb	$0x20, %al	# Print single space (note: fall-thru)
-
-# Part of above routine, this one just prints ascii al
-prtchr:	pushw	%ax
-	pushw	%cx
-	movw	$7,%bx
-	movw	$0x01, %cx
-	movb	$0x0e, %ah
-	int	$0x10
-	popw	%cx
-	popw	%ax
-	ret
-
-beep:	movb	$0x07, %al
-	jmp	prtchr
-	
-no_sig_mess: .string	"No setup signature found ..."
-
-good_sig1:
-	jmp	good_sig
-
-# We now have to find the rest of the setup code/data
-bad_sig:
-	movw	%cs, %ax			# SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# INITSEG
-	movw	%ax, %ds
-	xorb	%bh, %bh
-	movb	(497), %bl			# get setup sect from bootsect
-	subw	$4, %bx				# LILO loads 4 sectors of setup
-	shlw	$8, %bx				# convert to words (1sect=2^8 words)
-	movw	%bx, %cx
-	shrw	$3, %bx				# convert to segment
-	addw	$SYSSEG, %bx
-	movw	%bx, %cs:start_sys_seg
-# Move rest of setup code/data to here
-	movw	$2048, %di			# four sectors loaded by LILO
-	subw	%si, %si
-	pushw	%cs
-	popw	%es
-	movw	$SYSSEG, %ax
-	movw	%ax, %ds
-	rep
-	movsw
-	movw	%cs, %ax			# aka SETUPSEG
-	movw	%ax, %ds
-	cmpw	$SIG1, setup_sig1
-	jne	no_sig
-
-	cmpw	$SIG2, setup_sig2
-	jne	no_sig
-
-	jmp	good_sig
-
-no_sig:
-	lea	no_sig_mess, %si
-	call	prtstr
-
-no_sig_loop:
-	hlt
-	jmp	no_sig_loop
-
-good_sig:
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax 		# aka INITSEG
-	movw	%ax, %ds
-# Check if an old loader tries to load a big-kernel
-	testb	$LOADED_HIGH, %cs:loadflags	# Do we have a big kernel?
-	jz	loader_ok			# No, no danger for old loaders.
-
-	cmpb	$0, %cs:type_of_loader 		# Do we have a loader that
-						# can deal with us?
-	jnz	loader_ok			# Yes, continue.
-
-	pushw	%cs				# No, we have an old loader,
-	popw	%ds				# die. 
-	lea	loader_panic_mess, %si
-	call	prtstr
-
-	jmp	no_sig_loop
-
-loader_panic_mess: .string "Wrong loader, giving up..."
-
-# check minimum cpuid
-# we do this here because it is the last place we can actually
-# show a user visible error message. Later the video modus
-# might be already messed up.
-loader_ok:
-	call verify_cpu
-	testl  %eax,%eax
-	jz	cpu_ok
-	movw	%cs,%ax		# aka SETUPSEG
-	movw	%ax,%ds
-	lea	cpu_panic_mess,%si
-	call	prtstr
-1:	jmp	1b
-
-cpu_panic_mess:
-	.asciz  "PANIC: CPU too old for this kernel."
-
-#include "../kernel/verify_cpu.S"
-
-cpu_ok:
-# Get memory size (extended mem, kB)
-
-	xorl	%eax, %eax
-	movl	%eax, (0x1e0)
-#ifndef STANDARD_MEMORY_BIOS_CALL
-	movb	%al, (E820NR)
-# Try three different memory detection schemes.  First, try
-# e820h, which lets us assemble a memory map, then try e801h,
-# which returns a 32-bit memory size, and finally 88h, which
-# returns 0-64m
-
-# method E820H:
-# the memory map from hell.  e820h returns memory classified into
-# a whole bunch of different types, and allows memory holes and
-# everything.  We scan through this memory map and build a list
-# of the first 32 memory areas, which we return at [E820MAP].
-# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
-
-#define SMAP  0x534d4150
-
-meme820:
-	xorl	%ebx, %ebx			# continuation counter
-	movw	$E820MAP, %di			# point into the whitelist
-						# so we can have the bios
-						# directly write into it.
-
-jmpe820:
-	movl	$0x0000e820, %eax		# e820, upper word zeroed
-	movl	$SMAP, %edx			# ascii 'SMAP'
-	movl	$20, %ecx			# size of the e820rec
-	pushw	%ds				# data record.
-	popw	%es
-	int	$0x15				# make the call
-	jc	bail820				# fall to e801 if it fails
-
-	cmpl	$SMAP, %eax			# check the return is `SMAP'
-	jne	bail820				# fall to e801 if it fails
-
-#	cmpl	$1, 16(%di)			# is this usable memory?
-#	jne	again820
-
-	# If this is usable memory, we save it by simply advancing %di by
-	# sizeof(e820rec).
-	#
-good820:
-	movb	(E820NR), %al			# up to 128 entries
-	cmpb	$E820MAX, %al
-	jae	bail820
-
-	incb	(E820NR)
-	movw	%di, %ax
-	addw	$20, %ax
-	movw	%ax, %di
-again820:
-	cmpl	$0, %ebx			# check to see if
-	jne	jmpe820				# %ebx is set to EOF
-bail820:
-
-
-# method E801H:
-# memory size is in 1k chunksizes, to avoid confusing loadlin.
-# we store the 0xe801 memory size in a completely different place,
-# because it will most likely be longer than 16 bits.
-# (use 1e0 because that's what Larry Augustine uses in his
-# alternative new memory detection scheme, and it's sensible
-# to write everything into the same place.)
-
-meme801:
-	stc					# fix to work around buggy
-	xorw	%cx,%cx				# BIOSes which don't clear/set
-	xorw	%dx,%dx				# carry on pass/error of
-						# e801h memory size call
-						# or merely pass cx,dx though
-						# without changing them.
-	movw	$0xe801, %ax
-	int	$0x15
-	jc	mem88
-
-	cmpw	$0x0, %cx			# Kludge to handle BIOSes
-	jne	e801usecxdx			# which report their extended
-	cmpw	$0x0, %dx			# memory in AX/BX rather than
-	jne	e801usecxdx			# CX/DX.  The spec I have read
-	movw	%ax, %cx			# seems to indicate AX/BX 
-	movw	%bx, %dx			# are more reasonable anyway...
-
-e801usecxdx:
-	andl	$0xffff, %edx			# clear sign extend
-	shll	$6, %edx			# and go from 64k to 1k chunks
-	movl	%edx, (0x1e0)			# store extended memory size
-	andl	$0xffff, %ecx			# clear sign extend
- 	addl	%ecx, (0x1e0)			# and add lower memory into
-						# total size.
-
-# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
-# 64mb, depending on the bios) in ax.
-mem88:
-
-#endif
-	movb	$0x88, %ah
-	int	$0x15
-	movw	%ax, (2)
-
-# Set the keyboard repeat rate to the max
-	movw	$0x0305, %ax
-	xorw	%bx, %bx
-	int	$0x16
-
-# Check for video adapter and its parameters and allow the
-# user to browse video modes.
-	call	video				# NOTE: we need %ds pointing
-						# to bootsector
-
-# Get hd0 data...
-	xorw	%ax, %ax
-	movw	%ax, %ds
-	ldsw	(4 * 0x41), %si
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	pushw	%ax
-	movw	%ax, %es
-	movw	$0x0080, %di
-	movw	$0x10, %cx
-	pushw	%cx
-	cld
-	rep
- 	movsb
-# Get hd1 data...
-	xorw	%ax, %ax
-	movw	%ax, %ds
-	ldsw	(4 * 0x46), %si
-	popw	%cx
-	popw	%es
-	movw	$0x0090, %di
-	rep
-	movsb
-# Check that there IS a hd1 :-)
-	movw	$0x01500, %ax
-	movb	$0x81, %dl
-	int	$0x13
-	jc	no_disk1
-	
-	cmpb	$3, %ah
-	je	is_disk1
-
-no_disk1:
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax 		# aka INITSEG
-	movw	%ax, %es
-	movw	$0x0090, %di
-	movw	$0x10, %cx
-	xorw	%ax, %ax
-	cld
-	rep
-	stosb
-is_disk1:
-# check for Micro Channel (MCA) bus
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	movw	%ax, %ds
-	xorw	%ax, %ax
-	movw	%ax, (0xa0)			# set table length to 0
-	movb	$0xc0, %ah
-	stc
-	int	$0x15				# moves feature table to es:bx
-	jc	no_mca
-
-	pushw	%ds
-	movw	%es, %ax
-	movw	%ax, %ds
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	movw	%ax, %es
-	movw	%bx, %si
-	movw	$0xa0, %di
-	movw	(%si), %cx
-	addw	$2, %cx				# table length is a short
-	cmpw	$0x10, %cx
-	jc	sysdesc_ok
-
-	movw	$0x10, %cx			# we keep only first 16 bytes
-sysdesc_ok:
-	rep
-	movsb
-	popw	%ds
-no_mca:
-#ifdef CONFIG_X86_VOYAGER
-	movb	$0xff, 0x40	# flag on config found
-	movb	$0xc0, %al
-	mov	$0xff, %ah
-	int	$0x15		# put voyager config info at es:di
-	jc	no_voyager
-	movw	$0x40, %si	# place voyager info in apm table
-	cld
-	movw	$7, %cx
-voyager_rep:
-	movb	%es:(%di), %al
-	movb	%al,(%si)
-	incw	%di
-	incw	%si
-	decw	%cx
-	jnz	voyager_rep
-no_voyager:	
-#endif
-# Check for PS/2 pointing device
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	movw	%ax, %ds
-	movb	$0, (0x1ff)			# default is no pointing device
-	int	$0x11				# int 0x11: equipment list
-	testb	$0x04, %al			# check if mouse installed
-	jz	no_psmouse
-
-	movb	$0xAA, (0x1ff)			# device present
-no_psmouse:
-
-#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
-	movl	$0x0000E980, %eax		# IST Support 
-	movl	$0x47534943, %edx		# Request value
-	int	$0x15
-
-	movl	%eax, (96)
-	movl	%ebx, (100)
-	movl	%ecx, (104)
-	movl	%edx, (108)
-#endif
-
-#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
-# Then check for an APM BIOS...
-						# %ds points to the bootsector
-	movw	$0, 0x40			# version = 0 means no APM BIOS
-	movw	$0x05300, %ax			# APM BIOS installation check
-	xorw	%bx, %bx
-	int	$0x15
-	jc	done_apm_bios			# Nope, no APM BIOS
-	
-	cmpw	$0x0504d, %bx			# Check for "PM" signature
-	jne	done_apm_bios			# No signature, no APM BIOS
-
-	andw	$0x02, %cx			# Is 32 bit supported?
-	je	done_apm_bios			# No 32-bit, no (good) APM BIOS
-
-	movw	$0x05304, %ax			# Disconnect first just in case
-	xorw	%bx, %bx
-	int	$0x15				# ignore return code
-	movw	$0x05303, %ax			# 32 bit connect
-	xorl	%ebx, %ebx
-	xorw	%cx, %cx			# paranoia :-)
-	xorw	%dx, %dx			#   ...
-	xorl	%esi, %esi			#   ...
-	xorw	%di, %di			#   ...
-	int	$0x15
-	jc	no_32_apm_bios			# Ack, error. 
-
-	movw	%ax,  (66)			# BIOS code segment
-	movl	%ebx, (68)			# BIOS entry point offset
-	movw	%cx,  (72)			# BIOS 16 bit code segment
-	movw	%dx,  (74)			# BIOS data segment
-	movl	%esi, (78)			# BIOS code segment lengths
-	movw	%di,  (82)			# BIOS data segment length
-# Redo the installation check as the 32 bit connect
-# modifies the flags returned on some BIOSs
-	movw	$0x05300, %ax			# APM BIOS installation check
-	xorw	%bx, %bx
-	xorw	%cx, %cx			# paranoia
-	int	$0x15
-	jc	apm_disconnect			# error -> shouldn't happen
-
-	cmpw	$0x0504d, %bx			# check for "PM" signature
-	jne	apm_disconnect			# no sig -> shouldn't happen
-
-	movw	%ax, (64)			# record the APM BIOS version
-	movw	%cx, (76)			# and flags
-	jmp	done_apm_bios
-
-apm_disconnect:					# Tidy up
-	movw	$0x05304, %ax			# Disconnect
-	xorw	%bx, %bx
-	int	$0x15				# ignore return code
-
-	jmp	done_apm_bios
-
-no_32_apm_bios:
-	andw	$0xfffd, (76)			# remove 32 bit support bit
-done_apm_bios:
-#endif
-
-#include "edd.S"
-
-# Now we want to move to protected mode ...
-	cmpw	$0, %cs:realmode_swtch
-	jz	rmodeswtch_normal
-
-	lcall	*%cs:realmode_swtch
-
-	jmp	rmodeswtch_end
-
-rmodeswtch_normal:
-        pushw	%cs
-	call	default_switch
-
-rmodeswtch_end:
-# Now we move the system to its rightful place ... but we check if we have a
-# big-kernel. In that case we *must* not move it ...
-	testb	$LOADED_HIGH, %cs:loadflags
-	jz	do_move0			# .. then we have a normal low
-						# loaded zImage
-						# .. or else we have a high
-						# loaded bzImage
-	jmp	end_move			# ... and we skip moving
-
-do_move0:
-	movw	$0x100, %ax			# start of destination segment
-	movw	%cs, %bp			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %bp		# aka INITSEG
-	movw	%cs:start_sys_seg, %bx		# start of source segment
-	cld
-do_move:
-	movw	%ax, %es			# destination segment
-	incb	%ah				# instead of add ax,#0x100
-	movw	%bx, %ds			# source segment
-	addw	$0x100, %bx
-	subw	%di, %di
-	subw	%si, %si
-	movw 	$0x800, %cx
-	rep
-	movsw
-	cmpw	%bp, %bx			# assume start_sys_seg > 0x200,
-						# so we will perhaps read one
-						# page more than needed, but
-						# never overwrite INITSEG
-						# because destination is a
-						# minimum one page below source
-	jb	do_move
-
-end_move:
-# then we load the segment descriptors
-	movw	%cs, %ax			# aka SETUPSEG
-	movw	%ax, %ds
-		
-# Check whether we need to be downward compatible with version <=201
-	cmpl	$0, cmd_line_ptr
-	jne	end_move_self		# loader uses version >=202 features
-	cmpb	$0x20, type_of_loader
-	je	end_move_self		# bootsect loader, we know of it
-
-# Boot loader doesnt support boot protocol version 2.02.
-# If we have our code not at 0x90000, we need to move it there now.
-# We also then need to move the params behind it (commandline)
-# Because we would overwrite the code on the current IP, we move
-# it in two steps, jumping high after the first one.
-	movw	%cs, %ax
-	cmpw	$SETUPSEG, %ax
-	je	end_move_self
-
-	cli					# make sure we really have
-						# interrupts disabled !
-						# because after this the stack
-						# should not be used
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	movw	%ss, %dx
-	cmpw	%ax, %dx
-	jb	move_self_1
-
-	addw	$INITSEG, %dx
-	subw	%ax, %dx			# this will go into %ss after
-						# the move
-move_self_1:
-	movw	%ax, %ds
-	movw	$INITSEG, %ax			# real INITSEG
-	movw	%ax, %es
-	movw	%cs:setup_move_size, %cx
-	std					# we have to move up, so we use
-						# direction down because the
-						# areas may overlap
-	movw	%cx, %di
-	decw	%di
-	movw	%di, %si
-	subw	$move_self_here+0x200, %cx
-	rep
-	movsb
-	ljmp	$SETUPSEG, $move_self_here
-
-move_self_here:
-	movw	$move_self_here+0x200, %cx
-	rep
-	movsb
-	movw	$SETUPSEG, %ax
-	movw	%ax, %ds
-	movw	%dx, %ss
-end_move_self:					# now we are at the right place
-
-#
-# Enable A20.  This is at the very best an annoying procedure.
-# A20 code ported from SYSLINUX 1.52-1.63 by H. Peter Anvin.
-# AMD Elan bug fix by Robert Schwebel.
-#
-
-#if defined(CONFIG_X86_ELAN)
-	movb $0x02, %al			# alternate A20 gate
-	outb %al, $0x92			# this works on SC410/SC520
-a20_elan_wait:
-	call a20_test
-	jz a20_elan_wait
-	jmp a20_done
-#endif
-
-
-A20_TEST_LOOPS		=  32		# Iterations per wait
-A20_ENABLE_LOOPS	= 255		# Total loops to try		
-
-
-#ifndef CONFIG_X86_VOYAGER
-a20_try_loop:
-
-	# First, see if we are on a system with no A20 gate.
-a20_none:
-	call	a20_test
-	jnz	a20_done
-
-	# Next, try the BIOS (INT 0x15, AX=0x2401)
-a20_bios:
-	movw	$0x2401, %ax
-	pushfl					# Be paranoid about flags
-	int	$0x15
-	popfl
-
-	call	a20_test
-	jnz	a20_done
-
-	# Try enabling A20 through the keyboard controller
-#endif /* CONFIG_X86_VOYAGER */
-a20_kbc:
-	call	empty_8042
-
-#ifndef CONFIG_X86_VOYAGER
-	call	a20_test			# Just in case the BIOS worked
-	jnz	a20_done			# but had a delayed reaction.
-#endif
-
-	movb	$0xD1, %al			# command write
-	outb	%al, $0x64
-	call	empty_8042
-
-	movb	$0xDF, %al			# A20 on
-	outb	%al, $0x60
-	call	empty_8042
-
-#ifndef CONFIG_X86_VOYAGER
-	# Wait until a20 really *is* enabled; it can take a fair amount of
-	# time on certain systems; Toshiba Tecras are known to have this
-	# problem.
-a20_kbc_wait:
-	xorw	%cx, %cx
-a20_kbc_wait_loop:
-	call	a20_test
-	jnz	a20_done
-	loop	a20_kbc_wait_loop
-
-	# Final attempt: use "configuration port A"
-a20_fast:
-	inb	$0x92, %al			# Configuration Port A
-	orb	$0x02, %al			# "fast A20" version
-	andb	$0xFE, %al			# don't accidentally reset
-	outb	%al, $0x92
-
-	# Wait for configuration port A to take effect
-a20_fast_wait:
-	xorw	%cx, %cx
-a20_fast_wait_loop:
-	call	a20_test
-	jnz	a20_done
-	loop	a20_fast_wait_loop
-
-	# A20 is still not responding.  Try frobbing it again.
-	# 
-	decb	(a20_tries)
-	jnz	a20_try_loop
-	
-	movw	$a20_err_msg, %si
-	call	prtstr
-
-a20_die:
-	hlt
-	jmp	a20_die
-
-a20_tries:
-	.byte	A20_ENABLE_LOOPS
-
-a20_err_msg:
-	.ascii	"linux: fatal error: A20 gate not responding!"
-	.byte	13, 10, 0
-
-	# If we get here, all is good
-a20_done:
-
-#endif /* CONFIG_X86_VOYAGER */
-# set up gdt and idt and 32bit start address
-	lidt	idt_48				# load idt with 0,0
-	xorl	%eax, %eax			# Compute gdt_base
-	movw	%ds, %ax			# (Convert %ds:gdt to a linear ptr)
-	shll	$4, %eax
-	addl	%eax, code32
-	addl	$gdt, %eax
-	movl	%eax, (gdt_48+2)
-	lgdt	gdt_48				# load gdt with whatever is
-						# appropriate
-
-# make sure any possible coprocessor is properly reset..
-	xorw	%ax, %ax
-	outb	%al, $0xf0
-	call	delay
-
-	outb	%al, $0xf1
-	call	delay
-
-# well, that went ok, I hope. Now we mask all interrupts - the rest
-# is done in init_IRQ().
-	movb	$0xFF, %al			# mask all interrupts for now
-	outb	%al, $0xA1
-	call	delay
-	
-	movb	$0xFB, %al			# mask all irq's but irq2 which
-	outb	%al, $0x21			# is cascaded
-
-# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
-# need no steenking BIOS anyway (except for the initial loading :-).
-# The BIOS-routine wants lots of unnecessary data, and it's less
-# "interesting" anyway. This is how REAL programmers do it.
-#
-# Well, now's the time to actually move into protected mode. To make
-# things as simple as possible, we do no register set-up or anything,
-# we let the gnu-compiled 32-bit programs do that. We just jump to
-# absolute address 0x1000 (or the loader supplied one),
-# in 32-bit protected mode.
-#
-# Note that the short jump isn't strictly needed, although there are
-# reasons why it might be a good idea. It won't hurt in any case.
-	movw	$1, %ax				# protected mode (PE) bit
-	lmsw	%ax				# This is it!
-	jmp	flush_instr
-
-flush_instr:
-	xorw	%bx, %bx			# Flag to indicate a boot
-	xorl	%esi, %esi			# Pointer to real-mode code
-	movw	%cs, %si
-	subw	$DELTA_INITSEG, %si
-	shll	$4, %esi			# Convert to 32-bit pointer
-
-# jump to startup_32 in arch/i386/boot/compressed/head.S
-#	
-# NOTE: For high loaded big kernels we need a
-#	jmpi    0x100000,__BOOT_CS
-#
-#	but we yet haven't reloaded the CS register, so the default size 
-#	of the target offset still is 16 bit.
-#	However, using an operand prefix (0x66), the CPU will properly
-#	take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
-#	Manual, Mixing 16-bit and 32-bit code, page 16-6)
-
-	.byte 0x66, 0xea			# prefix + jmpi-opcode
-code32:	.long	startup_32			# will be set to %cs+startup_32
-	.word	__BOOT_CS
-.code32
-startup_32:
-	movl $(__BOOT_DS), %eax
-	movl %eax, %ds
-	movl %eax, %es
-	movl %eax, %fs
-	movl %eax, %gs
-	movl %eax, %ss
-
-	xorl %eax, %eax
-1:	incl %eax				# check that A20 really IS enabled
-	movl %eax, 0x00000000			# loop forever if it isn't
-	cmpl %eax, 0x00100000
-	je 1b
-
-	# Jump to the 32bit entry point
-	jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi)
-.code16
-
-# Here's a bunch of information about your current kernel..
-kernel_version:	.ascii	UTS_RELEASE
-		.ascii	" ("
-		.ascii	LINUX_COMPILE_BY
-		.ascii	"@"
-		.ascii	LINUX_COMPILE_HOST
-		.ascii	") "
-		.ascii	UTS_VERSION
-		.byte	0
-
-# This is the default real mode switch routine.
-# to be called just before protected mode transition
-default_switch:
-	cli					# no interrupts allowed !
-	movb	$0x80, %al			# disable NMI for bootup
-						# sequence
-	outb	%al, $0x70
-	lret
-
-
-#ifndef CONFIG_X86_VOYAGER
-# This routine tests whether or not A20 is enabled.  If so, it
-# exits with zf = 0.
-#
-# The memory address used, 0x200, is the int $0x80 vector, which
-# should be safe.
-
-A20_TEST_ADDR = 4*0x80
-
-a20_test:
-	pushw	%cx
-	pushw	%ax
-	xorw	%cx, %cx
-	movw	%cx, %fs			# Low memory
-	decw	%cx
-	movw	%cx, %gs			# High memory area
-	movw	$A20_TEST_LOOPS, %cx
-	movw	%fs:(A20_TEST_ADDR), %ax
-	pushw	%ax
-a20_test_wait:
-	incw	%ax
-	movw	%ax, %fs:(A20_TEST_ADDR)
-	call	delay				# Serialize and make delay constant
-	cmpw	%gs:(A20_TEST_ADDR+0x10), %ax
-	loope	a20_test_wait
-
-	popw	%fs:(A20_TEST_ADDR)
-	popw	%ax
-	popw	%cx
-	ret	
-
-#endif /* CONFIG_X86_VOYAGER */
-
-# This routine checks that the keyboard command queue is empty
-# (after emptying the output buffers)
-#
-# Some machines have delusions that the keyboard buffer is always full
-# with no keyboard attached...
-#
-# If there is no keyboard controller, we will usually get 0xff
-# to all the reads.  With each IO taking a microsecond and
-# a timeout of 100,000 iterations, this can take about half a
-# second ("delay" == outb to port 0x80). That should be ok,
-# and should also be plenty of time for a real keyboard controller
-# to empty.
-#
-
-empty_8042:
-	pushl	%ecx
-	movl	$100000, %ecx
-
-empty_8042_loop:
-	decl	%ecx
-	jz	empty_8042_end_loop
-
-	call	delay
-
-	inb	$0x64, %al			# 8042 status port
-	testb	$1, %al				# output buffer?
-	jz	no_output
-
-	call	delay
-	inb	$0x60, %al			# read it
-	jmp	empty_8042_loop
-
-no_output:
-	testb	$2, %al				# is input buffer full?
-	jnz	empty_8042_loop			# yes - loop
-empty_8042_end_loop:
-	popl	%ecx
-	ret
-
-# Read the cmos clock. Return the seconds in al
-gettime:
-	pushw	%cx
-	movb	$0x02, %ah
-	int	$0x1a
-	movb	%dh, %al			# %dh contains the seconds
-	andb	$0x0f, %al
-	movb	%dh, %ah
-	movb	$0x04, %cl
-	shrb	%cl, %ah
-	aad
-	popw	%cx
-	ret
-
-# Delay is needed after doing I/O
-delay:
-	outb	%al,$0x80
-	ret
-
-# Descriptor tables
-#
-# NOTE: The intel manual says gdt should be sixteen bytes aligned for
-# efficiency reasons.  However, there are machines which are known not
-# to boot with misaligned GDTs, so alter this at your peril!  If you alter
-# GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two
-# empty GDT entries (one for NULL and one reserved).
-#
-# NOTE:	On some CPUs, the GDT must be 8 byte aligned.  This is
-# true for the Voyager Quad CPU card which will not boot without
-# This directive.  16 byte aligment is recommended by intel.
-#
-	.align 16
-gdt:
-	.fill GDT_ENTRY_BOOT_CS,8,0
-
-	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
-	.word	0				# base address = 0
-	.word	0x9A00				# code read/exec
-	.word	0x00CF				# granularity = 4096, 386
-						#  (+5th nibble of limit)
-
-	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
-	.word	0				# base address = 0
-	.word	0x9200				# data read/write
-	.word	0x00CF				# granularity = 4096, 386
-						#  (+5th nibble of limit)
-gdt_end:
-	.align	4
-	
-	.word	0				# alignment byte
-idt_48:
-	.word	0				# idt limit = 0
-	.word	0, 0				# idt base = 0L
-
-	.word	0				# alignment byte
-gdt_48:
-	.word	gdt_end - gdt - 1		# gdt limit
-	.word	0, 0				# gdt base (filled in later)
-
-# Include video setup & detection code
-
-#include "video.S"
-
-# Setup signature -- must be last
-setup_sig1:	.word	SIG1
-setup_sig2:	.word	SIG2
-
-# After this point, there is some free space which is used by the video mode
-# handling code to store the temporary mode table (not used by the kernel).
-
-modelist:
-
-.text
-endtext:
-.data
-enddata:
-.bss
-endbss:
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
deleted file mode 100644
index 8143c95..0000000
--- a/arch/i386/boot/video.S
+++ /dev/null
@@ -1,2043 +0,0 @@
-/*	video.S
- *
- *	Display adapter & video mode setup, version 2.13 (14-May-99)
- *
- *	Copyright (C) 1995 -- 1998 Martin Mares <mj@ucw.cz>
- *	Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
- *
- *	Rewritten to use GNU 'as' by Chris Noe <stiker@northlink.com> May 1999
- *
- *	For further information, look at Documentation/svga.txt.
- *
- */
-
-/* Enable autodetection of SVGA adapters and modes. */
-#undef CONFIG_VIDEO_SVGA
-
-/* Enable autodetection of VESA modes */
-#define CONFIG_VIDEO_VESA
-
-/* Enable compacting of mode table */
-#define CONFIG_VIDEO_COMPACT
-
-/* Retain screen contents when switching modes */
-#define CONFIG_VIDEO_RETAIN
-
-/* Enable local mode list */
-#undef CONFIG_VIDEO_LOCAL
-
-/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
-#undef CONFIG_VIDEO_400_HACK
-
-/* Hack that lets you force specific BIOS mode ID and specific dimensions */
-#undef CONFIG_VIDEO_GFX_HACK
-#define VIDEO_GFX_BIOS_AX 0x4f02	/* 800x600 on ThinkPad */
-#define VIDEO_GFX_BIOS_BX 0x0102
-#define VIDEO_GFX_DUMMY_RESOLUTION 0x6425	/* 100x37 */
-
-/* This code uses an extended set of video mode numbers. These include:
- * Aliases for standard modes
- *	NORMAL_VGA (-1)
- *	EXTENDED_VGA (-2)
- *	ASK_VGA (-3)
- * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
- * of compatibility when extending the table. These are between 0x00 and 0xff.
- */
-#define VIDEO_FIRST_MENU 0x0000
-
-/* Standard BIOS video modes (BIOS number + 0x0100) */
-#define VIDEO_FIRST_BIOS 0x0100
-
-/* VESA BIOS video modes (VESA number + 0x0200) */
-#define VIDEO_FIRST_VESA 0x0200
-
-/* Video7 special modes (BIOS number + 0x0900) */
-#define VIDEO_FIRST_V7 0x0900
-
-/* Special video modes */
-#define VIDEO_FIRST_SPECIAL 0x0f00
-#define VIDEO_80x25 0x0f00
-#define VIDEO_8POINT 0x0f01
-#define VIDEO_80x43 0x0f02
-#define VIDEO_80x28 0x0f03
-#define VIDEO_CURRENT_MODE 0x0f04
-#define VIDEO_80x30 0x0f05
-#define VIDEO_80x34 0x0f06
-#define VIDEO_80x60 0x0f07
-#define VIDEO_GFX_HACK 0x0f08
-#define VIDEO_LAST_SPECIAL 0x0f09
-
-/* Video modes given by resolution */
-#define VIDEO_FIRST_RESOLUTION 0x1000
-
-/* The "recalculate timings" flag */
-#define VIDEO_RECALC 0x8000
-
-/* Positions of various video parameters passed to the kernel */
-/* (see also include/linux/tty.h) */
-#define PARAM_CURSOR_POS	0x00
-#define PARAM_VIDEO_PAGE	0x04
-#define PARAM_VIDEO_MODE	0x06
-#define PARAM_VIDEO_COLS	0x07
-#define PARAM_VIDEO_EGA_BX	0x0a
-#define PARAM_VIDEO_LINES	0x0e
-#define PARAM_HAVE_VGA		0x0f
-#define PARAM_FONT_POINTS	0x10
-
-#define PARAM_LFB_WIDTH		0x12
-#define PARAM_LFB_HEIGHT	0x14
-#define PARAM_LFB_DEPTH		0x16
-#define PARAM_LFB_BASE		0x18
-#define PARAM_LFB_SIZE		0x1c
-#define PARAM_LFB_LINELENGTH	0x24
-#define PARAM_LFB_COLORS	0x26
-#define PARAM_VESAPM_SEG	0x2e
-#define PARAM_VESAPM_OFF	0x30
-#define PARAM_LFB_PAGES		0x32
-#define PARAM_VESA_ATTRIB	0x34
-#define PARAM_CAPABILITIES	0x36
-
-/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
-#ifdef CONFIG_VIDEO_RETAIN
-#define DO_STORE call store_screen
-#else
-#define DO_STORE
-#endif /* CONFIG_VIDEO_RETAIN */
-
-# This is the main entry point called by setup.S
-# %ds *must* be pointing to the bootsector
-video:	pushw	%ds		# We use different segments
-	pushw	%ds		# FS contains original DS
-	popw	%fs
-	pushw	%cs		# DS is equal to CS
-	popw	%ds
-	pushw	%cs		# ES is equal to CS
-	popw	%es
-	xorw	%ax, %ax
-	movw	%ax, %gs	# GS is zero
-	cld
-	call	basic_detect	# Basic adapter type testing (EGA/VGA/MDA/CGA)
-#ifdef CONFIG_VIDEO_SELECT
-	movw	%fs:(0x01fa), %ax		# User selected video mode
-	cmpw	$ASK_VGA, %ax			# Bring up the menu
-	jz	vid2
-
-	call	mode_set			# Set the mode
-	jc	vid1
-
-	leaw	badmdt, %si			# Invalid mode ID
-	call	prtstr
-vid2:	call	mode_menu
-vid1:
-#ifdef CONFIG_VIDEO_RETAIN
-	call	restore_screen			# Restore screen contents
-#endif /* CONFIG_VIDEO_RETAIN */
-	call	store_edid
-#endif /* CONFIG_VIDEO_SELECT */
-	call	mode_params			# Store mode parameters
-	popw	%ds				# Restore original DS
-	ret
-
-# Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel.
-basic_detect:
-	movb	$0, %fs:(PARAM_HAVE_VGA)
-	movb	$0x12, %ah	# Check EGA/VGA
-	movb	$0x10, %bl
-	int	$0x10
-	movw	%bx, %fs:(PARAM_VIDEO_EGA_BX)	# Identifies EGA to the kernel
-	cmpb	$0x10, %bl			# No, it's a CGA/MDA/HGA card.
-	je	basret
-
-	incb	adapter
-	movw	$0x1a00, %ax			# Check EGA or VGA?
-	int	$0x10
-	cmpb	$0x1a, %al			# 1a means VGA...
-	jne	basret				# anything else is EGA.
-	
-	incb	%fs:(PARAM_HAVE_VGA)		# We've detected a VGA
-	incb	adapter
-basret:	ret
-
-# Store the video mode parameters for later usage by the kernel.
-# This is done by asking the BIOS except for the rows/columns
-# parameters in the default 80x25 mode -- these are set directly,
-# because some very obscure BIOSes supply insane values.
-mode_params:
-#ifdef CONFIG_VIDEO_SELECT
-	cmpb	$0, graphic_mode
-	jnz	mopar_gr
-#endif
-	movb	$0x03, %ah			# Read cursor position
-	xorb	%bh, %bh
-	int	$0x10
-	movw	%dx, %fs:(PARAM_CURSOR_POS)
-	movb	$0x0f, %ah			# Read page/mode/width
-	int	$0x10
-	movw	%bx, %fs:(PARAM_VIDEO_PAGE)
-	movw	%ax, %fs:(PARAM_VIDEO_MODE)	# Video mode and screen width
-	cmpb	$0x7, %al			# MDA/HGA => segment differs
-	jnz	mopar0
-
-	movw	$0xb000, video_segment
-mopar0: movw	%gs:(0x485), %ax		# Font size
-	movw	%ax, %fs:(PARAM_FONT_POINTS)	# (valid only on EGA/VGA)
-	movw	force_size, %ax			# Forced size?
-	orw	%ax, %ax
-	jz	mopar1
-
-	movb	%ah, %fs:(PARAM_VIDEO_COLS)
-	movb	%al, %fs:(PARAM_VIDEO_LINES)
-	ret
-
-mopar1:	movb	$25, %al
-	cmpb	$0, adapter			# If we are on CGA/MDA/HGA, the
-	jz	mopar2				# screen must have 25 lines.
-
-	movb	%gs:(0x484), %al		# On EGA/VGA, use the EGA+ BIOS
-	incb	%al				# location of max lines.
-mopar2: movb	%al, %fs:(PARAM_VIDEO_LINES)
-	ret
-
-#ifdef CONFIG_VIDEO_SELECT
-# Fetching of VESA frame buffer parameters
-mopar_gr:
-	leaw	modelist+1024, %di
-	movb	$0x23, %fs:(PARAM_HAVE_VGA)
-	movw	16(%di), %ax
-	movw	%ax, %fs:(PARAM_LFB_LINELENGTH)
-	movw	18(%di), %ax
-	movw	%ax, %fs:(PARAM_LFB_WIDTH)
-	movw	20(%di), %ax
-	movw	%ax, %fs:(PARAM_LFB_HEIGHT)
-	movb	25(%di), %al
-	movb	$0, %ah
-	movw	%ax, %fs:(PARAM_LFB_DEPTH)
-	movb	29(%di), %al	
-	movb	$0, %ah
-	movw	%ax, %fs:(PARAM_LFB_PAGES)
-	movl	40(%di), %eax
-	movl	%eax, %fs:(PARAM_LFB_BASE)
-	movl	31(%di), %eax
-	movl	%eax, %fs:(PARAM_LFB_COLORS)
-	movl	35(%di), %eax
-	movl	%eax, %fs:(PARAM_LFB_COLORS+4)
-	movw	0(%di), %ax
-	movw	%ax, %fs:(PARAM_VESA_ATTRIB)
-
-# get video mem size
-	leaw	modelist+1024, %di
-	movw	$0x4f00, %ax
-	int	$0x10
-	xorl	%eax, %eax
-	movw	18(%di), %ax
-	movl	%eax, %fs:(PARAM_LFB_SIZE)
-
-# store mode capabilities
-	movl 10(%di), %eax
-	movl %eax, %fs:(PARAM_CAPABILITIES)
-
-# switching the DAC to 8-bit is for <= 8 bpp only
-	movw	%fs:(PARAM_LFB_DEPTH), %ax
-	cmpw	$8, %ax
-	jg	dac_done
-
-# get DAC switching capability
-	xorl	%eax, %eax
-	movb	10(%di), %al
-	testb	$1, %al
-	jz	dac_set
-
-# attempt to switch DAC to 8-bit
-	movw	$0x4f08, %ax
-	movw	$0x0800, %bx
-	int	$0x10
-	cmpw	$0x004f, %ax
-	jne     dac_set
-	movb    %bh, dac_size		# store actual DAC size
-
-dac_set:
-# set color size to DAC size
-	movb	dac_size, %al
-	movb	%al, %fs:(PARAM_LFB_COLORS+0)
-	movb	%al, %fs:(PARAM_LFB_COLORS+2)
-	movb	%al, %fs:(PARAM_LFB_COLORS+4)
-	movb	%al, %fs:(PARAM_LFB_COLORS+6)
-
-# set color offsets to 0
-	movb	$0, %fs:(PARAM_LFB_COLORS+1)
-	movb	$0, %fs:(PARAM_LFB_COLORS+3)
-	movb	$0, %fs:(PARAM_LFB_COLORS+5)
-	movb	$0, %fs:(PARAM_LFB_COLORS+7)
-
-dac_done:
-# get protected mode interface informations
-	movw	$0x4f0a, %ax
-	xorw	%bx, %bx
-	xorw	%di, %di
-	int	$0x10
-	cmp	$0x004f, %ax
-	jnz	no_pm
-
-	movw	%es, %fs:(PARAM_VESAPM_SEG)
-	movw	%di, %fs:(PARAM_VESAPM_OFF)
-no_pm:	ret
-
-# The video mode menu
-mode_menu:
-	leaw	keymsg, %si			# "Return/Space/Timeout" message
-	call	prtstr
-	call	flush
-nokey:	call	getkt
-
-	cmpb	$0x0d, %al			# ENTER ?
-	je	listm				# yes - manual mode selection
-
-	cmpb	$0x20, %al			# SPACE ?
-	je	defmd1				# no - repeat
-
-	call 	beep
-	jmp	nokey
-
-defmd1:	ret					# No mode chosen? Default 80x25
-
-listm:	call	mode_table			# List mode table
-listm0:	leaw	name_bann, %si			# Print adapter name
-	call	prtstr
-	movw	card_name, %si
-	orw	%si, %si
-	jnz	an2
-
-	movb	adapter, %al
-	leaw	old_name, %si
-	orb	%al, %al
-	jz	an1
-
-	leaw	ega_name, %si
-	decb	%al
-	jz	an1
-
-	leaw	vga_name, %si
-	jmp	an1
-
-an2:	call	prtstr
-	leaw	svga_name, %si
-an1:	call	prtstr
-	leaw	listhdr, %si			# Table header
-	call	prtstr
-	movb	$0x30, %dl			# DL holds mode number
-	leaw	modelist, %si
-lm1:	cmpw	$ASK_VGA, (%si)			# End?
-	jz	lm2
-
-	movb	%dl, %al			# Menu selection number
-	call	prtchr
-	call	prtsp2
-	lodsw
-	call	prthw				# Mode ID
-	call	prtsp2
-	movb	0x1(%si), %al
-	call	prtdec				# Rows
-	movb	$0x78, %al			# the letter 'x'
-	call	prtchr
-	lodsw
-	call	prtdec				# Columns
-	movb	$0x0d, %al			# New line
-	call	prtchr
-	movb	$0x0a, %al
-	call	prtchr
-	incb	%dl				# Next character
-	cmpb	$0x3a, %dl
-	jnz	lm1
-
-	movb	$0x61, %dl
-	jmp	lm1
-
-lm2:	leaw	prompt, %si			# Mode prompt
-	call	prtstr
-	leaw	edit_buf, %di			# Editor buffer
-lm3:	call	getkey
-	cmpb	$0x0d, %al			# Enter?
-	jz	lment
-
-	cmpb	$0x08, %al			# Backspace?
-	jz	lmbs
-
-	cmpb	$0x20, %al			# Printable?
-	jc	lm3
-
-	cmpw	$edit_buf+4, %di		# Enough space?
-	jz	lm3
-
-	stosb
-	call	prtchr
-	jmp	lm3
-
-lmbs:	cmpw	$edit_buf, %di			# Backspace
-	jz	lm3
-
-	decw	%di
-	movb	$0x08, %al
-	call	prtchr
-	call	prtspc
-	movb	$0x08, %al
-	call	prtchr
-	jmp	lm3
-	
-lment:	movb	$0, (%di)
-	leaw	crlft, %si
-	call	prtstr
-	leaw	edit_buf, %si
-	cmpb	$0, (%si)			# Empty string = default mode
-	jz	lmdef
-
-	cmpb	$0, 1(%si)			# One character = menu selection
-	jz	mnusel
-
-	cmpw	$0x6373, (%si)			# "scan" => mode scanning
-	jnz	lmhx
-
-	cmpw	$0x6e61, 2(%si)
-	jz	lmscan
-
-lmhx:	xorw	%bx, %bx			# Else => mode ID in hex
-lmhex:	lodsb
-	orb	%al, %al
-	jz	lmuse1
-
-	subb	$0x30, %al
-	jc	lmbad
-
-	cmpb	$10, %al
-	jc	lmhx1
-
-	subb	$7, %al
-	andb	$0xdf, %al
-	cmpb	$10, %al
-	jc	lmbad
-
-	cmpb	$16, %al
-	jnc	lmbad
-
-lmhx1:	shlw	$4, %bx
-	orb	%al, %bl
-	jmp	lmhex
-
-lmuse1:	movw	%bx, %ax
-	jmp	lmuse
-
-mnusel:	lodsb					# Menu selection
-	xorb	%ah, %ah
-	subb	$0x30, %al
-	jc	lmbad
-
-	cmpb	$10, %al
-	jc	lmuse
-	
-	cmpb	$0x61-0x30, %al
-	jc	lmbad
-	
-	subb	$0x61-0x30-10, %al
-	cmpb	$36, %al
-	jnc	lmbad
-
-lmuse:	call	mode_set
-	jc	lmdef
-
-lmbad:	leaw	unknt, %si
-	call	prtstr
-	jmp	lm2
-lmscan:	cmpb	$0, adapter			# Scanning only on EGA/VGA
-	jz	lmbad
-
-	movw	$0, mt_end			# Scanning of modes is
-	movb	$1, scanning			# done as new autodetection.
-	call	mode_table
-	jmp	listm0
-lmdef:	ret
-
-# Additional parts of mode_set... (relative jumps, you know)
-setv7:						# Video7 extended modes
-	DO_STORE
-	subb	$VIDEO_FIRST_V7>>8, %bh
-	movw	$0x6f05, %ax
-	int	$0x10
-	stc
-	ret
-
-_setrec:	jmp	setrec			# Ugly...
-_set_80x25:	jmp	set_80x25
-
-# Aliases for backward compatibility.
-setalias:
-	movw	$VIDEO_80x25, %ax
-	incw	%bx
-	jz	mode_set
-
-	movb	$VIDEO_8POINT-VIDEO_FIRST_SPECIAL, %al
-	incw	%bx
-	jnz	setbad				# Fall-through!
-
-# Setting of user mode (AX=mode ID) => CF=success
-mode_set:
-	movw	%ax, %fs:(0x01fa)		# Store mode for use in acpi_wakeup.S
-	movw	%ax, %bx
-	cmpb	$0xff, %ah
-	jz	setalias
-
-	testb	$VIDEO_RECALC>>8, %ah
-	jnz	_setrec
-
-	cmpb	$VIDEO_FIRST_RESOLUTION>>8, %ah
-	jnc	setres
-	
-	cmpb	$VIDEO_FIRST_SPECIAL>>8, %ah
-	jz	setspc
-	
-	cmpb	$VIDEO_FIRST_V7>>8, %ah
-	jz	setv7
-	
-	cmpb	$VIDEO_FIRST_VESA>>8, %ah
-	jnc	check_vesa
-	
-	orb	%ah, %ah
-	jz	setmenu
-	
-	decb	%ah
-	jz	setbios
-
-setbad:	clc
-	movb	$0, do_restore			# The screen needn't be restored
-	ret
-
-setvesa:
-	DO_STORE
-	subb	$VIDEO_FIRST_VESA>>8, %bh
-	movw	$0x4f02, %ax			# VESA BIOS mode set call
-	int	$0x10
-	cmpw	$0x004f, %ax			# AL=4f if implemented
-	jnz	setbad				# AH=0 if OK
-
-	stc
-	ret
-
-setbios:
-	DO_STORE
-	int	$0x10				# Standard BIOS mode set call
-	pushw	%bx
-	movb	$0x0f, %ah			# Check if really set
-	int	$0x10
-	popw	%bx
-	cmpb	%bl, %al
-	jnz	setbad
-	
-	stc
-	ret
-
-setspc:	xorb	%bh, %bh			# Set special mode
-	cmpb	$VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl
-	jnc	setbad
-	
-	addw	%bx, %bx
-	jmp	*spec_inits(%bx)
-
-setmenu:
-	orb	%al, %al			# 80x25 is an exception
-	jz	_set_80x25
-	
-	pushw	%bx				# Set mode chosen from menu
-	call	mode_table			# Build the mode table
-	popw	%ax
-	shlw	$2, %ax
-	addw	%ax, %si
-	cmpw	%di, %si
-	jnc	setbad
-	
-	movw	(%si), %ax			# Fetch mode ID
-_m_s:	jmp	mode_set
-
-setres:	pushw	%bx				# Set mode chosen by resolution
-	call	mode_table
-	popw	%bx
-	xchgb	%bl, %bh
-setr1:	lodsw
-	cmpw	$ASK_VGA, %ax			# End of the list?
-	jz	setbad
-	
-	lodsw
-	cmpw	%bx, %ax
-	jnz	setr1
-	
-	movw	-4(%si), %ax			# Fetch mode ID
-	jmp	_m_s
-
-check_vesa:
-#ifdef CONFIG_FIRMWARE_EDID
-	leaw	modelist+1024, %di
-	movw	$0x4f00, %ax
-	int	$0x10
-	cmpw	$0x004f, %ax
-	jnz	setbad
-
-	movw	4(%di), %ax
-	movw	%ax, vbe_version
-#endif
-	leaw	modelist+1024, %di
-	subb	$VIDEO_FIRST_VESA>>8, %bh
-	movw	%bx, %cx			# Get mode information structure
-	movw	$0x4f01, %ax
-	int	$0x10
-	addb	$VIDEO_FIRST_VESA>>8, %bh
-	cmpw	$0x004f, %ax
-	jnz	setbad
-
-	movb	(%di), %al			# Check capabilities.
-	andb	$0x19, %al
-	cmpb	$0x09, %al
-	jz	setvesa				# This is a text mode
-
-	movb	(%di), %al			# Check capabilities.
-	andb	$0x99, %al
-	cmpb	$0x99, %al
-	jnz	_setbad				# Doh! No linear frame buffer.
-
-	subb	$VIDEO_FIRST_VESA>>8, %bh
-	orw	$0x4000, %bx			# Use linear frame buffer
-	movw	$0x4f02, %ax			# VESA BIOS mode set call
-	int	$0x10
-	cmpw	$0x004f, %ax			# AL=4f if implemented
-	jnz	_setbad				# AH=0 if OK
-
-	movb	$1, graphic_mode		# flag graphic mode
-	movb	$0, do_restore			# no screen restore
-	stc
-	ret
-
-_setbad:	jmp	setbad          	# Ugly...
-
-# Recalculate vertical display end registers -- this fixes various
-# inconsistencies of extended modes on many adapters. Called when
-# the VIDEO_RECALC flag is set in the mode ID.
-
-setrec:	subb	$VIDEO_RECALC>>8, %ah		# Set the base mode
-	call	mode_set
-	jnc	rct3
-
-	movw	%gs:(0x485), %ax		# Font size in pixels
-	movb	%gs:(0x484), %bl		# Number of rows
-	incb	%bl
-	mulb	%bl				# Number of visible
-	decw	%ax				# scan lines - 1
-	movw	$0x3d4, %dx
-	movw	%ax, %bx
-	movb	$0x12, %al			# Lower 8 bits
-	movb	%bl, %ah
-	outw	%ax, %dx
-	movb	$0x07, %al		# Bits 8 and 9 in the overflow register
-	call	inidx
-	xchgb	%al, %ah
-	andb	$0xbd, %ah
-	shrb	%bh
-	jnc	rct1
-	orb	$0x02, %ah
-rct1:	shrb	%bh
-	jnc	rct2
-	orb	$0x40, %ah
-rct2:	movb	$0x07, %al
-	outw	%ax, %dx
-	stc
-rct3:	ret
-
-# Table of routines for setting of the special modes.
-spec_inits:
-	.word	set_80x25
-	.word	set_8pixel
-	.word	set_80x43
-	.word	set_80x28
-	.word	set_current
-	.word	set_80x30
-	.word	set_80x34
-	.word	set_80x60
-	.word	set_gfx
-
-# Set the 80x25 mode. If already set, do nothing.
-set_80x25:
-	movw	$0x5019, force_size		# Override possibly broken BIOS
-use_80x25:
-#ifdef CONFIG_VIDEO_400_HACK
-	movw	$0x1202, %ax			# Force 400 scan lines
-	movb	$0x30, %bl
-	int	$0x10
-#else
-	movb	$0x0f, %ah			# Get current mode ID
-	int	$0x10
-	cmpw	$0x5007, %ax	# Mode 7 (80x25 mono) is the only one available
-	jz	st80		# on CGA/MDA/HGA and is also available on EGAM
-
-	cmpw	$0x5003, %ax	# Unknown mode, force 80x25 color
-	jnz	force3
-
-st80:	cmpb	$0, adapter	# CGA/MDA/HGA => mode 3/7 is always 80x25
-	jz	set80
-
-	movb	%gs:(0x0484), %al	# This is EGA+ -- beware of 80x50 etc.
-	orb	%al, %al		# Some buggy BIOS'es set 0 rows
-	jz	set80
-	
-	cmpb	$24, %al		# It's hopefully correct
-	jz	set80
-#endif /* CONFIG_VIDEO_400_HACK */
-force3:	DO_STORE
-	movw	$0x0003, %ax			# Forced set
-	int	$0x10
-set80:	stc
-	ret
-
-# Set the 80x50/80x43 8-pixel mode. Simple BIOS calls.
-set_8pixel:
-	DO_STORE
-	call	use_80x25			# The base is 80x25
-set_8pt:
-	movw	$0x1112, %ax			# Use 8x8 font
-	xorb	%bl, %bl
-	int	$0x10
-	movw	$0x1200, %ax			# Use alternate print screen
-	movb	$0x20, %bl
-	int	$0x10
-	movw	$0x1201, %ax			# Turn off cursor emulation
-	movb	$0x34, %bl
-	int	$0x10
-	movb	$0x01, %ah			# Define cursor scan lines 6-7
-	movw	$0x0607, %cx
-	int	$0x10
-set_current:
-	stc
-	ret
-
-# Set the 80x28 mode. This mode works on all VGA's, because it's a standard
-# 80x25 mode with 14-point fonts instead of 16-point.
-set_80x28:
-	DO_STORE
-	call	use_80x25			# The base is 80x25
-set14:	movw	$0x1111, %ax			# Use 9x14 font
-	xorb	%bl, %bl
-	int	$0x10
-	movb	$0x01, %ah			# Define cursor scan lines 11-12
-	movw	$0x0b0c, %cx
-	int	$0x10
-	stc
-	ret
-
-# Set the 80x43 mode. This mode is works on all VGA's.
-# It's a 350-scanline mode with 8-pixel font.
-set_80x43:
-	DO_STORE
-	movw	$0x1201, %ax			# Set 350 scans
-	movb	$0x30, %bl
-	int	$0x10
-	movw	$0x0003, %ax			# Reset video mode
-	int	$0x10
-	jmp	set_8pt				# Use 8-pixel font
-
-# Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font.
-set_80x30:
-	call	use_80x25			# Start with real 80x25
-	DO_STORE
-	movw	$0x3cc, %dx			# Get CRTC port
-	inb	%dx, %al
-	movb	$0xd4, %dl
-	rorb	%al				# Mono or color?
-	jc	set48a
-
-	movb	$0xb4, %dl
-set48a:	movw	$0x0c11, %ax		# Vertical sync end (also unlocks CR0-7)
- 	call	outidx
-	movw	$0x0b06, %ax			# Vertical total
- 	call	outidx
-	movw	$0x3e07, %ax			# (Vertical) overflow
- 	call	outidx
-	movw	$0xea10, %ax			# Vertical sync start
- 	call	outidx
-	movw	$0xdf12, %ax			# Vertical display end
-	call	outidx
-	movw	$0xe715, %ax			# Vertical blank start
- 	call	outidx
-	movw	$0x0416, %ax			# Vertical blank end
- 	call	outidx
-	pushw	%dx
-	movb	$0xcc, %dl			# Misc output register (read)
- 	inb	%dx, %al
- 	movb	$0xc2, %dl			# (write)
- 	andb	$0x0d, %al	# Preserve clock select bits and color bit
- 	orb	$0xe2, %al			# Set correct sync polarity
- 	outb	%al, %dx
-	popw	%dx
-	movw	$0x501e, force_size
-	stc					# That's all.
-	ret
-
-# Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font.
-set_80x34:
-	call	set_80x30			# Set 480 scans
-	call	set14				# And 14-pt font
-	movw	$0xdb12, %ax			# VGA vertical display end
-	movw	$0x5022, force_size
-setvde:	call	outidx
-	stc
-	ret
-
-# Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font.
-set_80x60:
-	call	set_80x30			# Set 480 scans
-	call	set_8pt				# And 8-pt font
-	movw	$0xdf12, %ax			# VGA vertical display end
-	movw	$0x503c, force_size
-	jmp	setvde
-
-# Special hack for ThinkPad graphics
-set_gfx:
-#ifdef CONFIG_VIDEO_GFX_HACK
-	movw	$VIDEO_GFX_BIOS_AX, %ax
-	movw	$VIDEO_GFX_BIOS_BX, %bx
-	int	$0x10
-	movw	$VIDEO_GFX_DUMMY_RESOLUTION, force_size
-	stc
-#endif
-	ret
-
-#ifdef CONFIG_VIDEO_RETAIN
-
-# Store screen contents to temporary buffer.
-store_screen:
-	cmpb	$0, do_restore			# Already stored?
-	jnz	stsr
-
-	testb	$CAN_USE_HEAP, loadflags	# Have we space for storing?
-	jz	stsr
-	
-	pushw	%ax
-	pushw	%bx
-	pushw	force_size			# Don't force specific size
-	movw	$0, force_size
-	call	mode_params			# Obtain params of current mode
-	popw	force_size
-	movb	%fs:(PARAM_VIDEO_LINES), %ah
-	movb	%fs:(PARAM_VIDEO_COLS), %al
-	movw	%ax, %bx			# BX=dimensions
-	mulb	%ah
-	movw	%ax, %cx			# CX=number of characters
-	addw	%ax, %ax			# Calculate image size
-	addw	$modelist+1024+4, %ax
-	cmpw	heap_end_ptr, %ax
-	jnc	sts1				# Unfortunately, out of memory
-
-	movw	%fs:(PARAM_CURSOR_POS), %ax	# Store mode params
-	leaw	modelist+1024, %di
-	stosw
-	movw	%bx, %ax
-	stosw
-	pushw	%ds				# Store the screen
-	movw	video_segment, %ds
-	xorw	%si, %si
-	rep
-	movsw
-	popw	%ds
-	incb	do_restore			# Screen will be restored later
-sts1:	popw	%bx
-	popw	%ax
-stsr:	ret
-
-# Restore screen contents from temporary buffer.
-restore_screen:
-	cmpb	$0, do_restore			# Has the screen been stored?
-	jz	res1
-
-	call	mode_params			# Get parameters of current mode
-	movb	%fs:(PARAM_VIDEO_LINES), %cl
-	movb	%fs:(PARAM_VIDEO_COLS), %ch
-	leaw	modelist+1024, %si		# Screen buffer
-	lodsw					# Set cursor position
-	movw	%ax, %dx
-	cmpb	%cl, %dh
-	jc	res2
-	
-	movb	%cl, %dh
-	decb	%dh
-res2:	cmpb	%ch, %dl
-	jc	res3
-	
-	movb	%ch, %dl
-	decb	%dl
-res3:	movb	$0x02, %ah
-	movb	$0x00, %bh
-	int	$0x10
-	lodsw					# Display size
-	movb	%ah, %dl			# DL=number of lines
-	movb	$0, %ah				# BX=phys. length of orig. line
-	movw	%ax, %bx
-	cmpb	%cl, %dl			# Too many?
-	jc	res4
-
-	pushw	%ax
-	movb	%dl, %al
-	subb	%cl, %al
-	mulb	%bl
-	addw	%ax, %si
-	addw	%ax, %si
-	popw	%ax
-	movb	%cl, %dl
-res4:	cmpb	%ch, %al			# Too wide?
-	jc	res5
-	
-	movb	%ch, %al			# AX=width of src. line
-res5:	movb	$0, %cl
-	xchgb	%ch, %cl
-	movw	%cx, %bp			# BP=width of dest. line
-	pushw	%es
-	movw	video_segment, %es
-	xorw	%di, %di			# Move the data
-	addw	%bx, %bx			# Convert BX and BP to _bytes_
-	addw	%bp, %bp
-res6:	pushw	%si
-	pushw	%di
-	movw	%ax, %cx
-	rep
-	movsw
-	popw	%di
-	popw	%si
-	addw	%bp, %di
-	addw	%bx, %si
-	decb	%dl
-	jnz	res6
-	
-	popw	%es				# Done
-res1:	ret
-#endif /* CONFIG_VIDEO_RETAIN */
-
-# Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)
-outidx:	outb	%al, %dx
-	pushw	%ax
-	movb	%ah, %al
-	incw	%dx
-	outb	%al, %dx
-	decw	%dx
-	popw	%ax
-	ret
-
-# Build the table of video modes (stored after the setup.S code at the
-# `modelist' label. Each video mode record looks like:
-#	.word	MODE-ID		(our special mode ID (see above))
-#	.byte	rows		(number of rows)
-#	.byte	columns		(number of columns)
-# Returns address of the end of the table in DI, the end is marked
-# with a ASK_VGA ID.
-mode_table:
-	movw	mt_end, %di			# Already filled?
-	orw	%di, %di
-	jnz	mtab1x
-	
-	leaw	modelist, %di			# Store standard modes:
-	movl	$VIDEO_80x25 + 0x50190000, %eax	# The 80x25 mode (ALL)
-	stosl
-	movb	adapter, %al			# CGA/MDA/HGA -- no more modes
-	orb	%al, %al
-	jz	mtabe
-	
-	decb	%al
-	jnz	mtabv
-	
-	movl	$VIDEO_8POINT + 0x502b0000, %eax	# The 80x43 EGA mode
-	stosl
-	jmp	mtabe
-
-mtab1x:	jmp	mtab1
-
-mtabv:	leaw	vga_modes, %si			# All modes for std VGA
-	movw	$vga_modes_end-vga_modes, %cx
-	rep	# I'm unable to use movsw as I don't know how to store a half
-	movsb	# of the expression above to cx without using explicit shr.
-
-	cmpb	$0, scanning			# Mode scan requested?
-	jz	mscan1
-	
-	call	mode_scan
-mscan1:
-
-#ifdef CONFIG_VIDEO_LOCAL
-	call	local_modes
-#endif /* CONFIG_VIDEO_LOCAL */
-
-#ifdef CONFIG_VIDEO_VESA
-	call	vesa_modes			# Detect VESA VGA modes
-#endif /* CONFIG_VIDEO_VESA */
-
-#ifdef CONFIG_VIDEO_SVGA
-	cmpb	$0, scanning			# Bypass when scanning
-	jnz	mscan2
-	
-	call	svga_modes			# Detect SVGA cards & modes
-mscan2:
-#endif /* CONFIG_VIDEO_SVGA */
-
-mtabe:
-
-#ifdef CONFIG_VIDEO_COMPACT
-	leaw	modelist, %si
-	movw	%di, %dx
-	movw	%si, %di
-cmt1:	cmpw	%dx, %si			# Scan all modes
-	jz	cmt2
-
-	leaw	modelist, %bx			# Find in previous entries
-	movw	2(%si), %cx
-cmt3:	cmpw	%bx, %si
-	jz	cmt4
-
-	cmpw	2(%bx), %cx			# Found => don't copy this entry
-	jz	cmt5
-
-	addw	$4, %bx
-	jmp	cmt3
-
-cmt4:	movsl					# Copy entry
-	jmp	cmt1
-
-cmt5:	addw	$4, %si				# Skip entry
-	jmp	cmt1
-
-cmt2:
-#endif	/* CONFIG_VIDEO_COMPACT */
-
-	movw	$ASK_VGA, (%di)			# End marker
-	movw	%di, mt_end
-mtab1:	leaw	modelist, %si			# SI=mode list, DI=list end
-ret0:	ret
-
-# Modes usable on all standard VGAs
-vga_modes:
-	.word	VIDEO_8POINT
-	.word	0x5032				# 80x50
-	.word	VIDEO_80x43
-	.word	0x502b				# 80x43
-	.word	VIDEO_80x28
-	.word	0x501c				# 80x28
-	.word	VIDEO_80x30
-	.word	0x501e				# 80x30
-	.word	VIDEO_80x34
-	.word	0x5022				# 80x34
-	.word	VIDEO_80x60
-	.word	0x503c				# 80x60
-#ifdef CONFIG_VIDEO_GFX_HACK
-	.word	VIDEO_GFX_HACK
-	.word	VIDEO_GFX_DUMMY_RESOLUTION
-#endif
-
-vga_modes_end:
-# Detect VESA modes.
-
-#ifdef CONFIG_VIDEO_VESA
-vesa_modes:
-	cmpb	$2, adapter			# VGA only
-	jnz	ret0
-
-	movw	%di, %bp			# BP=original mode table end
-	addw	$0x200, %di			# Buffer space
-	movw	$0x4f00, %ax			# VESA Get card info call
-	int	$0x10
-	movw	%bp, %di
-	cmpw	$0x004f, %ax			# Successful?
-	jnz	ret0
-	
-	cmpw	$0x4556, 0x200(%di)
-	jnz	ret0
-	
-	cmpw	$0x4153, 0x202(%di)
-	jnz	ret0
-	
-	movw	$vesa_name, card_name		# Set name to "VESA VGA"
-	pushw	%gs
-	lgsw	0x20e(%di), %si			# GS:SI=mode list
-	movw	$128, %cx			# Iteration limit
-vesa1:
-# gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst.
-# XXX:	lodsw	%gs:(%si), %ax			# Get next mode in the list
-	gs; lodsw
-	cmpw	$0xffff, %ax			# End of the table?
-	jz	vesar
-	
-	cmpw	$0x0080, %ax			# Check validity of mode ID
-	jc	vesa2
-	
-	orb	%ah, %ah		# Valid IDs: 0x0000-0x007f/0x0100-0x07ff
-	jz	vesan			# Certain BIOSes report 0x80-0xff!
-
-	cmpw	$0x0800, %ax
-	jnc	vesae
-
-vesa2:	pushw	%cx
-	movw	%ax, %cx			# Get mode information structure
-	movw	$0x4f01, %ax
-	int	$0x10
-	movw	%cx, %bx			# BX=mode number
-	addb	$VIDEO_FIRST_VESA>>8, %bh
-	popw	%cx
-	cmpw	$0x004f, %ax
-	jnz	vesan			# Don't report errors (buggy BIOSES)
-
-	movb	(%di), %al			# Check capabilities. We require
-	andb	$0x19, %al			# a color text mode.
-	cmpb	$0x09, %al
-	jnz	vesan
-	
-	cmpw	$0xb800, 8(%di)		# Standard video memory address required
-	jnz	vesan
-
-	testb	$2, (%di)			# Mode characteristics supplied?
-	movw	%bx, (%di)			# Store mode number
-	jz	vesa3
-	
-	xorw	%dx, %dx
-	movw	0x12(%di), %bx			# Width
-	orb	%bh, %bh
-	jnz	vesan
-	
-	movb	%bl, 0x3(%di)
-	movw	0x14(%di), %ax			# Height
-	orb	%ah, %ah
-	jnz	vesan
-	
-	movb	%al, 2(%di)
-	mulb	%bl
-	cmpw	$8193, %ax		# Small enough for Linux console driver?
-	jnc	vesan
-
-	jmp	vesaok
-
-vesa3:	subw	$0x8108, %bx	# This mode has no detailed info specified,
-	jc	vesan		# so it must be a standard VESA mode.
-
-	cmpw	$5, %bx
-	jnc	vesan
-
-	movw	vesa_text_mode_table(%bx), %ax
-	movw	%ax, 2(%di)
-vesaok:	addw	$4, %di				# The mode is valid. Store it.
-vesan:	loop	vesa1			# Next mode. Limit exceeded => error
-vesae:	leaw	vesaer, %si
-	call	prtstr
-	movw	%bp, %di			# Discard already found modes.
-vesar:	popw	%gs
-	ret
-
-# Dimensions of standard VESA text modes
-vesa_text_mode_table:
-	.byte	60, 80				# 0108
-	.byte	25, 132				# 0109
-	.byte	43, 132				# 010A
-	.byte	50, 132				# 010B
-	.byte	60, 132				# 010C
-#endif	/* CONFIG_VIDEO_VESA */
-
-# Scan for video modes. A bit dirty, but should work.
-mode_scan:
-	movw	$0x0100, %cx			# Start with mode 0
-scm1:	movb	$0, %ah				# Test the mode
-	movb	%cl, %al
-	int	$0x10
-	movb	$0x0f, %ah
-	int	$0x10
-	cmpb	%cl, %al
-	jnz	scm2				# Mode not set
-
-	movw	$0x3c0, %dx			# Test if it's a text mode
-	movb	$0x10, %al			# Mode bits
-	call	inidx
-	andb	$0x03, %al
-	jnz	scm2
-	
-	movb	$0xce, %dl			# Another set of mode bits
-	movb	$0x06, %al
-	call	inidx
-	shrb	%al
-	jc	scm2
-	
-	movb	$0xd4, %dl			# Cursor location
-	movb	$0x0f, %al
-	call	inidx
-	orb	%al, %al
-	jnz	scm2
-	
-	movw	%cx, %ax			# Ok, store the mode
-	stosw
-	movb	%gs:(0x484), %al		# Number of rows
-	incb	%al
-	stosb
-	movw	%gs:(0x44a), %ax		# Number of columns
-	stosb
-scm2:	incb	%cl
-	jns	scm1
-	
-	movw	$0x0003, %ax			# Return back to mode 3
-	int	$0x10
-	ret
-
-tstidx:	outw	%ax, %dx			# OUT DX,AX and inidx
-inidx:	outb	%al, %dx			# Read from indexed VGA register
-	incw	%dx			# AL=index, DX=index reg port -> AL=data
-	inb	%dx, %al
-	decw	%dx
-	ret
-
-# Try to detect type of SVGA card and supply (usually approximate) video
-# mode table for it.
-
-#ifdef CONFIG_VIDEO_SVGA
-svga_modes:
-	leaw	svga_table, %si			# Test all known SVGA adapters
-dosvga:	lodsw
-	movw	%ax, %bp			# Default mode table
-	orw	%ax, %ax
-	jz	didsv1
-
-	lodsw					# Pointer to test routine
-	pushw	%si
-	pushw	%di
-	pushw	%es
-	movw	$0xc000, %bx
-	movw	%bx, %es
-	call	*%ax				# Call test routine
-	popw	%es
-	popw	%di
-	popw	%si
-	orw	%bp, %bp
-	jz	dosvga
-	
-	movw	%bp, %si			# Found, copy the modes
-	movb	svga_prefix, %ah
-cpsvga:	lodsb
-	orb	%al, %al
-	jz	didsv
-	
-	stosw
-	movsw
-	jmp	cpsvga
-
-didsv:	movw	%si, card_name			# Store pointer to card name
-didsv1:	ret
-
-# Table of all known SVGA cards. For each card, we store a pointer to
-# a table of video modes supported by the card and a pointer to a routine
-# used for testing of presence of the card. The video mode table is always
-# followed by the name of the card or the chipset.
-svga_table:
-	.word	ati_md, ati_test
-	.word	oak_md, oak_test
-	.word	paradise_md, paradise_test
-	.word	realtek_md, realtek_test
-	.word	s3_md, s3_test
-	.word	chips_md, chips_test
-	.word	video7_md, video7_test
-	.word	cirrus5_md, cirrus5_test
-	.word	cirrus6_md, cirrus6_test
-	.word	cirrus1_md, cirrus1_test
-	.word	ahead_md, ahead_test
-	.word	everex_md, everex_test
-	.word	genoa_md, genoa_test
-	.word	trident_md, trident_test
-	.word	tseng_md, tseng_test
-	.word	0
-
-# Test routines and mode tables:
-
-# S3 - The test algorithm was taken from the SuperProbe package
-# for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org
-s3_test:
-	movw	$0x0f35, %cx	# we store some constants in cl/ch
-	movw	$0x03d4, %dx
-	movb	$0x38, %al
-	call	inidx
-	movb	%al, %bh	# store current CRT-register 0x38
-	movw	$0x0038, %ax
-	call	outidx		# disable writing to special regs
-	movb	%cl, %al	# check whether we can write special reg 0x35
-	call	inidx
-	movb	%al, %bl	# save the current value of CRT reg 0x35
-	andb	$0xf0, %al	# clear bits 0-3
-	movb	%al, %ah
-	movb	%cl, %al	# and write it to CRT reg 0x35
-	call	outidx
-	call	inidx		# now read it back
-	andb	%ch, %al	# clear the upper 4 bits
-	jz	s3_2		# the first test failed. But we have a
-
-	movb	%bl, %ah	# second chance
-	movb	%cl, %al
-	call	outidx
-	jmp	s3_1		# do the other tests
-
-s3_2:	movw	%cx, %ax	# load ah with 0xf and al with 0x35
-	orb	%bl, %ah	# set the upper 4 bits of ah with the orig value
-	call	outidx		# write ...
-	call	inidx		# ... and reread 
-	andb	%cl, %al	# turn off the upper 4 bits
-	pushw	%ax
-	movb	%bl, %ah	# restore old value in register 0x35
-	movb	%cl, %al
-	call	outidx
-	popw	%ax
-	cmpb	%ch, %al	# setting lower 4 bits was successful => bad
-	je	no_s3		# writing is allowed => this is not an S3
-
-s3_1:	movw	$0x4838, %ax	# allow writing to special regs by putting
-	call	outidx		# magic number into CRT-register 0x38
-	movb	%cl, %al	# check whether we can write special reg 0x35
-	call	inidx
-	movb	%al, %bl
-	andb	$0xf0, %al
-	movb	%al, %ah
-	movb	%cl, %al
-	call	outidx
-	call	inidx
-	andb	%ch, %al
-	jnz	no_s3		# no, we can't write => no S3
-
-	movw	%cx, %ax
-	orb	%bl, %ah
-	call	outidx
-	call	inidx
-	andb	%ch, %al
-	pushw	%ax
-	movb	%bl, %ah	# restore old value in register 0x35
-	movb	%cl, %al
-	call	outidx
-	popw	%ax
-	cmpb	%ch, %al
-	jne	no_s31		# writing not possible => no S3
-	movb	$0x30, %al
-	call	inidx		# now get the S3 id ...
-	leaw	idS3, %di
-	movw	$0x10, %cx
-	repne
-	scasb
-	je	no_s31
-
-	movb	%bh, %ah
-	movb	$0x38, %al
-	jmp	s3rest
-
-no_s3:	movb	$0x35, %al	# restore CRT register 0x35
-	movb	%bl, %ah
-	call	outidx
-no_s31:	xorw	%bp, %bp	# Detection failed
-s3rest:	movb	%bh, %ah
-	movb	$0x38, %al	# restore old value of CRT register 0x38
-	jmp	outidx
-
-idS3:	.byte	0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
-	.byte	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
-
-s3_md:	.byte	0x54, 0x2b, 0x84
-	.byte	0x55, 0x19, 0x84
-	.byte	0
-	.ascii	"S3"
-	.byte	0
-
-# ATI cards.
-ati_test:
-	leaw 	idati, %si
-	movw	$0x31, %di
-	movw	$0x09, %cx
-	repe
-	cmpsb
-	je	atiok
-
-	xorw	%bp, %bp
-atiok:	ret
-
-idati:	.ascii	"761295520"
-
-ati_md:	.byte	0x23, 0x19, 0x84
-	.byte	0x33, 0x2c, 0x84
-	.byte	0x22, 0x1e, 0x64
-	.byte	0x21, 0x19, 0x64
-	.byte	0x58, 0x21, 0x50
-	.byte	0x5b, 0x1e, 0x50
-	.byte	0
-	.ascii	"ATI"
-	.byte	0
-
-# AHEAD
-ahead_test:
-	movw	$0x200f, %ax
-	movw	$0x3ce, %dx
-	outw	%ax, %dx
-	incw	%dx
-	inb	%dx, %al
-	cmpb	$0x20, %al
-	je	isahed
-
-	cmpb	$0x21, %al
-	je	isahed
-	
-	xorw	%bp, %bp
-isahed:	ret
-
-ahead_md:
-	.byte	0x22, 0x2c, 0x84
-	.byte	0x23, 0x19, 0x84
-	.byte	0x24, 0x1c, 0x84
-	.byte	0x2f, 0x32, 0xa0
-	.byte	0x32, 0x22, 0x50
-	.byte	0x34, 0x42, 0x50
-	.byte	0
-	.ascii	"Ahead"
-	.byte	0
-
-# Chips & Tech.
-chips_test:
-	movw	$0x3c3, %dx
-	inb	%dx, %al
-	orb	$0x10, %al
-	outb	%al, %dx
-	movw	$0x104, %dx
-	inb	%dx, %al
-	movb	%al, %bl
-	movw	$0x3c3, %dx
-	inb	%dx, %al
-	andb	$0xef, %al
-	outb	%al, %dx
-	cmpb	$0xa5, %bl
-	je	cantok
-	
-	xorw	%bp, %bp
-cantok:	ret
-
-chips_md:
-	.byte	0x60, 0x19, 0x84
-	.byte	0x61, 0x32, 0x84
-	.byte	0
-	.ascii	"Chips & Technologies"
-	.byte	0
-
-# Cirrus Logic 5X0
-cirrus1_test:
-	movw	$0x3d4, %dx
-	movb	$0x0c, %al
-	outb	%al, %dx
-	incw	%dx
-	inb	%dx, %al
-	movb	%al, %bl
-	xorb	%al, %al
-	outb	%al, %dx
-	decw	%dx
-	movb	$0x1f, %al
-	outb	%al, %dx
-	incw	%dx
-	inb	%dx, %al
-	movb	%al, %bh
-	xorb	%ah, %ah
-	shlb	$4, %al
-	movw	%ax, %cx
-	movb	%bh, %al
-	shrb	$4, %al
-	addw	%ax, %cx
-	shlw	$8, %cx
-	addw	$6, %cx
-	movw	%cx, %ax
-	movw	$0x3c4, %dx
-	outw	%ax, %dx
-	incw	%dx
-	inb	%dx, %al
-	andb	%al, %al
-	jnz	nocirr
-	
-	movb	%bh, %al
-	outb	%al, %dx
-	inb	%dx, %al
-	cmpb	$0x01, %al
-	je	iscirr
-
-nocirr:	xorw	%bp, %bp
-iscirr: movw	$0x3d4, %dx
-	movb	%bl, %al
-	xorb	%ah, %ah
-	shlw	$8, %ax
-	addw	$0x0c, %ax
-	outw	%ax, %dx
-	ret
-
-cirrus1_md:
-	.byte	0x1f, 0x19, 0x84
-	.byte	0x20, 0x2c, 0x84
-	.byte	0x22, 0x1e, 0x84
-	.byte	0x31, 0x25, 0x64
-	.byte	0
-	.ascii	"Cirrus Logic 5X0"
-	.byte	0
-
-# Cirrus Logic 54XX
-cirrus5_test:
-	movw	$0x3c4, %dx
-	movb	$6, %al
-	call	inidx
-	movb	%al, %bl			# BL=backup
-	movw	$6, %ax
-	call	tstidx
-	cmpb	$0x0f, %al
-	jne	c5fail
-	
-	movw	$0x1206, %ax
-	call	tstidx
-	cmpb	$0x12, %al
-	jne	c5fail
-	
-	movb	$0x1e, %al
-	call	inidx
-	movb	%al, %bh
-	movb	%bh, %ah
-	andb	$0xc0, %ah
-	movb	$0x1e, %al
-	call	tstidx
-	andb	$0x3f, %al
-	jne	c5xx
-	
-	movb	$0x1e, %al
-	movb	%bh, %ah
-	orb	$0x3f, %ah
-	call	tstidx
-	xorb	$0x3f, %al
-	andb	$0x3f, %al
-c5xx:	pushf
-	movb	$0x1e, %al
-	movb	%bh, %ah
-	outw	%ax, %dx
-	popf
-	je	c5done
-
-c5fail:	xorw	%bp, %bp
-c5done:	movb	$6, %al
-	movb	%bl, %ah
-	outw	%ax, %dx
-	ret
-
-cirrus5_md:
-	.byte	0x14, 0x19, 0x84
-	.byte	0x54, 0x2b, 0x84
-	.byte	0
-	.ascii	"Cirrus Logic 54XX"
-	.byte	0
-
-# Cirrus Logic 64XX -- no known extra modes, but must be identified, because
-# it's misidentified by the Ahead test.
-cirrus6_test:
-	movw	$0x3ce, %dx
-	movb	$0x0a, %al
-	call	inidx
-	movb	%al, %bl	# BL=backup
-	movw	$0xce0a, %ax
-	call	tstidx
-	orb	%al, %al
-	jne	c2fail
-	
-	movw	$0xec0a, %ax
-	call	tstidx
-	cmpb	$0x01, %al
-	jne	c2fail
-	
-	movb	$0xaa, %al
-	call	inidx		# 4X, 5X, 7X and 8X are valid 64XX chip ID's. 
-	shrb	$4, %al
-	subb	$4, %al
-	jz	c6done
-	
-	decb	%al
-	jz	c6done
-	
-	subb	$2, %al
-	jz	c6done
-	
-	decb	%al
-	jz	c6done
-	
-c2fail:	xorw	%bp, %bp
-c6done:	movb	$0x0a, %al
-	movb	%bl, %ah
-	outw	%ax, %dx
-	ret
-
-cirrus6_md:
-	.byte	0
-	.ascii	"Cirrus Logic 64XX"
-	.byte	0
-
-# Everex / Trident
-everex_test:
-	movw	$0x7000, %ax
-	xorw	%bx, %bx
-	int	$0x10
-	cmpb	$0x70, %al
-	jne	noevrx
-	
-	shrw	$4, %dx
-	cmpw	$0x678, %dx
-	je	evtrid
-	
-	cmpw	$0x236, %dx
-	jne	evrxok
-
-evtrid:	leaw	trident_md, %bp
-evrxok:	ret
-
-noevrx:	xorw	%bp, %bp
-	ret
-
-everex_md:
-	.byte	0x03, 0x22, 0x50
-	.byte	0x04, 0x3c, 0x50
-	.byte	0x07, 0x2b, 0x64
-	.byte	0x08, 0x4b, 0x64
-	.byte	0x0a, 0x19, 0x84
-	.byte	0x0b, 0x2c, 0x84
-	.byte	0x16, 0x1e, 0x50
-	.byte	0x18, 0x1b, 0x64
-	.byte	0x21, 0x40, 0xa0
-	.byte	0x40, 0x1e, 0x84
-	.byte	0
-	.ascii	"Everex/Trident"
-	.byte	0
-
-# Genoa.
-genoa_test:
-	leaw	idgenoa, %si			# Check Genoa 'clues'
-	xorw	%ax, %ax
-	movb	%es:(0x37), %al
-	movw	%ax, %di
-	movw	$0x04, %cx
-	decw	%si
-	decw	%di
-l1:	incw	%si
-	incw	%di
-	movb	(%si), %al
-	testb	%al, %al
-	jz	l2
-
-	cmpb	%es:(%di), %al
-l2:	loope 	l1
-	orw	%cx, %cx
-	je	isgen
-	
-	xorw	%bp, %bp
-isgen:	ret
-
-idgenoa: .byte	0x77, 0x00, 0x99, 0x66
-
-genoa_md:
-	.byte	0x58, 0x20, 0x50
-	.byte	0x5a, 0x2a, 0x64
-	.byte	0x60, 0x19, 0x84
-	.byte	0x61, 0x1d, 0x84
-	.byte	0x62, 0x20, 0x84
-	.byte	0x63, 0x2c, 0x84
-	.byte	0x64, 0x3c, 0x84
-	.byte	0x6b, 0x4f, 0x64
-	.byte	0x72, 0x3c, 0x50
-	.byte	0x74, 0x42, 0x50
-	.byte	0x78, 0x4b, 0x64
-	.byte	0
-	.ascii	"Genoa"
-	.byte	0
-
-# OAK
-oak_test:
-	leaw	idoakvga, %si
-	movw	$0x08, %di
-	movw	$0x08, %cx
-	repe
-	cmpsb
-	je	isoak
-	
-	xorw	%bp, %bp
-isoak:	ret
-
-idoakvga: .ascii  "OAK VGA "
-
-oak_md: .byte	0x4e, 0x3c, 0x50
-	.byte	0x4f, 0x3c, 0x84
-	.byte	0x50, 0x19, 0x84
-	.byte	0x51, 0x2b, 0x84
-	.byte	0
-	.ascii	"OAK"
-	.byte	0
-
-# WD Paradise.
-paradise_test:
-	leaw	idparadise, %si
-	movw	$0x7d, %di
-	movw	$0x04, %cx
-	repe
-	cmpsb
-	je	ispara
-	
-	xorw	%bp, %bp
-ispara:	ret
-
-idparadise:	.ascii	"VGA="
-
-paradise_md:
-	.byte	0x41, 0x22, 0x50
-	.byte	0x47, 0x1c, 0x84
-	.byte	0x55, 0x19, 0x84
-	.byte	0x54, 0x2c, 0x84
-	.byte	0
-	.ascii	"Paradise"
-	.byte	0
-
-# Trident.
-trident_test:
-	movw	$0x3c4, %dx
-	movb	$0x0e, %al
-	outb	%al, %dx
-	incw	%dx
-	inb	%dx, %al
-	xchgb	%al, %ah
-	xorb	%al, %al
-	outb	%al, %dx
-	inb	%dx, %al
-	xchgb	%ah, %al
-	movb	%al, %bl	# Strange thing ... in the book this wasn't
-	andb	$0x02, %bl	# necessary but it worked on my card which
-	jz	setb2		# is a trident. Without it the screen goes
-				# blurred ...
-	andb	$0xfd, %al
-	jmp	clrb2		
-
-setb2:	orb	$0x02, %al	
-clrb2:	outb	%al, %dx
-	andb	$0x0f, %ah
-	cmpb	$0x02, %ah
-	je	istrid
-
-	xorw	%bp, %bp
-istrid:	ret
-
-trident_md:
-	.byte	0x50, 0x1e, 0x50
-	.byte	0x51, 0x2b, 0x50
-	.byte	0x52, 0x3c, 0x50
-	.byte	0x57, 0x19, 0x84
-	.byte	0x58, 0x1e, 0x84
-	.byte	0x59, 0x2b, 0x84
-	.byte	0x5a, 0x3c, 0x84
-	.byte	0
-	.ascii	"Trident"
-	.byte	0
-
-# Tseng.
-tseng_test:
-	movw	$0x3cd, %dx
-	inb	%dx, %al	# Could things be this simple ! :-)
-	movb	%al, %bl
-	movb	$0x55, %al
-	outb	%al, %dx
-	inb	%dx, %al
-	movb	%al, %ah
-	movb	%bl, %al
-	outb	%al, %dx
-	cmpb	$0x55, %ah
- 	je	istsen
-
-isnot:	xorw	%bp, %bp
-istsen:	ret
-
-tseng_md:
-	.byte	0x26, 0x3c, 0x50
-	.byte	0x2a, 0x28, 0x64
-	.byte	0x23, 0x19, 0x84
-	.byte	0x24, 0x1c, 0x84
-	.byte	0x22, 0x2c, 0x84
-	.byte	0x21, 0x3c, 0x84
-	.byte	0
-	.ascii	"Tseng"
-	.byte	0
-
-# Video7.
-video7_test:
-	movw	$0x3cc, %dx
-	inb	%dx, %al
-	movw	$0x3b4, %dx
-	andb	$0x01, %al
-	jz	even7
-
-	movw	$0x3d4, %dx
-even7:	movb	$0x0c, %al
-	outb	%al, %dx
-	incw	%dx
-	inb	%dx, %al
-	movb	%al, %bl
-	movb	$0x55, %al
-	outb	%al, %dx
-	inb	%dx, %al
-	decw	%dx
-	movb	$0x1f, %al
-	outb	%al, %dx
-	incw	%dx
-	inb	%dx, %al
-	movb	%al, %bh
-	decw	%dx
-	movb	$0x0c, %al
-	outb	%al, %dx
-	incw	%dx
-	movb	%bl, %al
-	outb	%al, %dx
-	movb	$0x55, %al
-	xorb	$0xea, %al
-	cmpb	%bh, %al
-	jne	isnot
-	
-	movb	$VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching
-	ret
-
-video7_md:
-	.byte	0x40, 0x2b, 0x50
-	.byte	0x43, 0x3c, 0x50
-	.byte	0x44, 0x3c, 0x64
-	.byte	0x41, 0x19, 0x84
-	.byte	0x42, 0x2c, 0x84
-	.byte	0x45, 0x1c, 0x84
-	.byte	0
-	.ascii	"Video 7"
-	.byte	0
-
-# Realtek VGA
-realtek_test:
-	leaw	idrtvga, %si
-	movw	$0x45, %di
-	movw	$0x0b, %cx
-	repe
-	cmpsb
-	je	isrt
-	
-	xorw	%bp, %bp
-isrt:	ret
-
-idrtvga:	.ascii	"REALTEK VGA"
-
-realtek_md:
-	.byte	0x1a, 0x3c, 0x50
-	.byte	0x1b, 0x19, 0x84
-	.byte	0x1c, 0x1e, 0x84
-	.byte	0x1d, 0x2b, 0x84
-	.byte	0x1e, 0x3c, 0x84
-	.byte	0
-	.ascii	"REALTEK"
-	.byte	0
-
-#endif	/* CONFIG_VIDEO_SVGA */
-
-# User-defined local mode table (VGA only)
-#ifdef CONFIG_VIDEO_LOCAL
-local_modes:
-	leaw	local_mode_table, %si
-locm1:	lodsw
-	orw	%ax, %ax
-	jz	locm2
-	
-	stosw
-	movsw
-	jmp	locm1
-
-locm2:	ret
-
-# This is the table of local video modes which can be supplied manually
-# by the user. Each entry consists of mode ID (word) and dimensions
-# (byte for column count and another byte for row count). These modes
-# are placed before all SVGA and VESA modes and override them if table
-# compacting is enabled. The table must end with a zero word followed
-# by NUL-terminated video adapter name.
-local_mode_table:
-	.word	0x0100				# Example: 40x25
-	.byte	25,40
-	.word	0
-	.ascii	"Local"
-	.byte	0
-#endif	/* CONFIG_VIDEO_LOCAL */
-
-# Read a key and return the ASCII code in al, scan code in ah
-getkey:	xorb	%ah, %ah
-	int	$0x16
-	ret
-
-# Read a key with a timeout of 30 seconds.
-# The hardware clock is used to get the time.
-getkt:	call	gettime
-	addb	$30, %al			# Wait 30 seconds
-	cmpb	$60, %al
-	jl	lminute
-
-	subb	$60, %al
-lminute:
-	movb	%al, %cl
-again:	movb	$0x01, %ah
-	int	$0x16
-	jnz	getkey				# key pressed, so get it
-
-	call	gettime
-	cmpb	%cl, %al
-	jne	again
-
-	movb	$0x20, %al			# timeout, return `space'
-	ret
-
-# Flush the keyboard buffer
-flush:	movb	$0x01, %ah
-	int	$0x16
-	jz	empty
-	
-	xorb	%ah, %ah
-	int	$0x16
-	jmp	flush
-
-empty:	ret
-
-# Print hexadecimal number.
-prthw:	pushw	%ax
-	movb	%ah, %al
-	call	prthb
-	popw	%ax
-prthb:	pushw	%ax
-	shrb	$4, %al
-	call	prthn
-	popw	%ax
-	andb	$0x0f, %al
-prthn:	cmpb	$0x0a, %al
-	jc	prth1
-
-	addb	$0x07, %al
-prth1:	addb	$0x30, %al
-	jmp	prtchr
-
-# Print decimal number in al
-prtdec:	pushw	%ax
-	pushw	%cx
-	xorb	%ah, %ah
-	movb	$0x0a, %cl
-	idivb	%cl
-	cmpb	$0x09, %al
-	jbe	lt100
-
-	call	prtdec
-	jmp	skip10
-
-lt100:	addb	$0x30, %al
-	call	prtchr
-skip10:	movb	%ah, %al
-	addb	$0x30, %al
-	call	prtchr	
-	popw	%cx
-	popw	%ax
-	ret
-
-store_edid:
-#ifdef CONFIG_FIRMWARE_EDID
-	pushw	%es				# just save all registers
-	pushw	%ax
-	pushw	%bx
-	pushw   %cx
-	pushw	%dx
-	pushw   %di
-
-	pushw	%fs
-	popw    %es
-
-	movl	$0x13131313, %eax		# memset block with 0x13
-	movw    $32, %cx
-	movw	$0x140, %di
-	cld
-	rep
-	stosl
-
-	cmpw	$0x0200, vbe_version		# only do EDID on >= VBE2.0
-	jl	no_edid
-
-	pushw   %es				# save ES
-	xorw    %di, %di                        # Report Capability
-	pushw   %di
-	popw    %es                             # ES:DI must be 0:0
-	movw	$0x4f15, %ax
-	xorw	%bx, %bx
-	xorw	%cx, %cx
-	int	$0x10
-	popw    %es                             # restore ES
-
-	cmpb    $0x00, %ah                      # call successful
-	jne     no_edid
-
-	cmpb    $0x4f, %al                      # function supported
-	jne     no_edid
-
-	movw	$0x4f15, %ax                    # do VBE/DDC
-	movw	$0x01, %bx
-	movw	$0x00, %cx
-	movw    $0x00, %dx
-	movw	$0x140, %di
-	int	$0x10
-
-no_edid:
-	popw	%di				# restore all registers
-	popw	%dx
-	popw	%cx
-	popw	%bx
-	popw	%ax
-	popw	%es
-#endif
-	ret
-
-# VIDEO_SELECT-only variables
-mt_end:		.word	0	# End of video mode table if built
-edit_buf:	.space	6	# Line editor buffer
-card_name:	.word	0	# Pointer to adapter name
-scanning:	.byte	0	# Performing mode scan
-do_restore:	.byte	0	# Screen contents altered during mode change
-svga_prefix:	.byte	VIDEO_FIRST_BIOS>>8	# Default prefix for BIOS modes
-graphic_mode:	.byte	0	# Graphic mode with a linear frame buffer
-dac_size:	.byte	6	# DAC bit depth
-vbe_version:	.word	0	# VBE bios version
-
-# Status messages
-keymsg:		.ascii	"Press <RETURN> to see video modes available, "
-		.ascii	"<SPACE> to continue or wait 30 secs"
-		.byte	0x0d, 0x0a, 0
-
-listhdr:	.byte	0x0d, 0x0a
-		.ascii	"Mode:    COLSxROWS:"
-
-crlft:		.byte	0x0d, 0x0a, 0
-
-prompt:		.byte	0x0d, 0x0a
-		.asciz	"Enter mode number or `scan': "
-
-unknt:		.asciz	"Unknown mode ID. Try again."
-
-badmdt:		.ascii	"You passed an undefined mode number."
-		.byte	0x0d, 0x0a, 0
-
-vesaer:		.ascii	"Error: Scanning of VESA modes failed. Please "
-		.ascii	"report to <mj@ucw.cz>."
-		.byte	0x0d, 0x0a, 0
-
-old_name:	.asciz	"CGA/MDA/HGA"
-
-ega_name:	.asciz	"EGA"
-
-svga_name:	.ascii	" "
-
-vga_name:	.asciz	"VGA"
-
-vesa_name:	.asciz	"VESA"
-
-name_bann:	.asciz	"Video adapter: "
-#endif /* CONFIG_VIDEO_SELECT */
-
-# Other variables:
-adapter:	.byte	0	# Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA
-video_segment:	.word	0xb800	# Video memory segment
-force_size:	.word	0	# Use this size instead of the one in BIOS vars
diff --git a/arch/i386/kernel/verify_cpu.S b/arch/i386/kernel/verify_cpu.S
deleted file mode 100644
index fff4aa6..0000000
--- a/arch/i386/kernel/verify_cpu.S
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Check if CPU has some minimum CPUID bits
-   This runs in 16bit mode so that the caller can still use the BIOS
-   to output errors on the screen */
-#include <asm/cpufeature.h>
-#include <asm/msr.h>
-
-verify_cpu:
-	pushfl				# Save caller passed flags
-	pushl	$0			# Kill any dangerous flags
-	popfl
-
-#if CONFIG_X86_MINIMUM_CPU_FAMILY >= 4
-	pushfl
-	pop	%eax
-	orl	$(1<<18),%eax		# try setting AC
-	push	%eax
-	popfl
-	pushfl
-	popl    %eax
-	testl	$(1<<18),%eax
-	jz	bad
-#endif
-#if REQUIRED_MASK0 != 0
-	pushfl				# standard way to check for cpuid
-	popl	%eax
-	movl	%eax,%ebx
-	xorl	$0x200000,%eax
-	pushl	%eax
-	popfl
-	pushfl
-	popl	%eax
-	cmpl	%eax,%ebx
-	pushfl				# standard way to check for cpuid
-	popl	%eax
-	movl	%eax,%ebx
-	xorl	$0x200000,%eax
-	pushl	%eax
-	popfl
-	pushfl
-	popl	%eax
-	cmpl	%eax,%ebx
-	jz	bad			# REQUIRED_MASK0 != 0 requires CPUID
-
-	movl	$0x0,%eax		# See if cpuid 1 is implemented
-	cpuid
-	cmpl	$0x1,%eax
-	jb	bad			# no cpuid 1
-
-#if REQUIRED_MASK0 & NEED_CMPXCHG64
-	/* Some VIA C3s need magic MSRs to enable CX64. Do this here */
-	cmpl	$0x746e6543,%ebx	# Cent
-	jne	1f
-	cmpl 	$0x48727561,%edx	# aurH
-	jne	1f
-	cmpl	$0x736c7561,%ecx	# auls
-	jne	1f
-	movl	$1,%eax			# check model
-	cpuid
-	movl	%eax,%ebx
-	shr	$8,%ebx
-	andl	$0xf,%ebx
-	cmp	$6,%ebx			# check family == 6
-	jne	1f
-	shr	$4,%eax
-	andl	$0xf,%eax
-	cmpl	$6,%eax			# check model >= 6
-	jb	1f
-	# assume models >= 6 all support this MSR
-	movl	$MSR_VIA_FCR,%ecx
-	rdmsr
-	orl	$((1<<1)|(1<<7)),%eax	# enable CMPXCHG64 and PGE
-	wrmsr
-1:
-#endif
-	movl    $0x1,%eax		# Does the cpu have what it takes
-	cpuid
-
-#if CONFIG_X86_MINIMUM_CPU_FAMILY > 4
-#error	add proper model checking here
-#endif
-
-	andl	$REQUIRED_MASK0,%edx
-	xorl	$REQUIRED_MASK0,%edx
-	jnz	bad
-#endif /* REQUIRED_MASK0 */
-
-	popfl
-	xor	%eax,%eax
-	ret
-
-bad:
-	popfl
-	movl	$1,%eax
-	ret
diff --git a/include/linux/edd.h b/include/linux/edd.h
index b2b3e68..7b64782 100644
--- a/include/linux/edd.h
+++ b/include/linux/edd.h
@@ -49,10 +49,6 @@
 #define EDD_MBR_SIG_MAX 16        /* max number of signatures to store */
 #define EDD_MBR_SIG_NR_BUF 0x1ea  /* addr of number of MBR signtaures at EDD_MBR_SIG_BUF
 				     in boot_params - treat this as 1 byte  */
-#define EDD_CL_EQUALS   0x3d646465     /* "edd=" */
-#define EDD_CL_OFF      0x666f         /* "of" for off  */
-#define EDD_CL_SKIP     0x6b73         /* "sk" for skipmbr */
-#define EDD_CL_ON       0x6e6f	       /* "on" for on */
 
 #ifndef __ASSEMBLY__
 
-- 
1.5.2.2


^ permalink raw reply related	[flat|nested] 69+ messages in thread

* Re: x86 setup code rewrite in C
  2007-07-10  2:51 x86 setup code rewrite in C H. Peter Anvin
       [not found] ` <2034f71d414def30de582fb59573295cadbdabb4.1184032748.git.hpa@zytor.com>
@ 2007-07-10  4:24 ` Yinghai Lu
  2007-07-10  4:39   ` H. Peter Anvin
  2007-07-10  5:25 ` Jeff Garzik
  2007-07-10 16:24 ` Jeremy Fitzhardinge
  3 siblings, 1 reply; 69+ messages in thread
From: Yinghai Lu @ 2007-07-10  4:24 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux-kernel, linux-arch, andi, akpm

On 7/9/07, H. Peter Anvin <hpa@zytor.com> wrote:
> This patch set replaces the x86 setup code, which is currently all in
> assembly, with a version written in C, using the ".code16gcc" feature
> of binutils (which has been present since at least 2001.)
>
> The new code is vastly easier to read, and, I hope, debug.  It should
> be noted that I found a fair number of minor bugs while going through
> this code, and have attempted to correct them.
>
> In the process of doing so, it introduces several cleanups, in
> particular:
>
> - Obsoletes the hd_info field in the boot_params structure; they are
>   only ever used for ST-506 (pre-IDE) drives and are pretty much
>   guaranteed to be wrong on current BIOSes;
> - Unifies the CPU feature bits between i386 and x86-64.  In the
>   future, it should be possible to use arch/i386/boot/cpucheck.c to do
>   the post-invocation CPU check currently done in
>   arch/x86_64/kernel/trampoline.S, although this patch set doesn't
>   introduce that change.
> - boot_params is now a proper structure.
>
> This code has been tested in -mm since early in the 2.6.22 cycle.
>
>  arch/i386/boot/bootsect.S                     |   98 -
>  arch/i386/boot/edd.S                          |  231 --
>  arch/i386/boot/setup.S                        | 1075 -------------
>  arch/i386/boot/video.S                        | 2043 --------------------------
>  arch/i386/kernel/verify_cpu.S                 |   94 -
>  arch/x86_64/boot/bootsect.S                   |   98 -
>  arch/x86_64/boot/install.sh                   |    2
>  arch/x86_64/boot/mtools.conf.in               |   17
>  arch/x86_64/boot/setup.S                      |  826 ----------
>  arch/x86_64/boot/tools/build.c                |  185 --
>  b/Documentation/i386/zero-page.txt            |    1
>  b/MAINTAINERS                                 |    4
>  b/arch/i386/Kconfig.cpu                       |    6
>  b/arch/i386/boot/Makefile                     |   46
>  b/arch/i386/boot/a20.c                        |  161 ++
>  b/arch/i386/boot/apm.c                        |   97 +
>  b/arch/i386/boot/bitops.h                     |   45
>  b/arch/i386/boot/boot.h                       |  290 +++
>  b/arch/i386/boot/cmdline.c                    |   97 +
>  b/arch/i386/boot/code16gcc.h                  |    9
>  b/arch/i386/boot/compressed/Makefile          |    7
>  b/arch/i386/boot/compressed/head.S            |    6
>  b/arch/i386/boot/copy.S                       |  101 +
>  b/arch/i386/boot/cpu.c                        |   69
>  b/arch/i386/boot/cpucheck.c                   |  267 +++
>  b/arch/i386/boot/edd.c                        |  196 ++
>  b/arch/i386/boot/header.S                     |  283 +++
>  b/arch/i386/boot/main.c                       |  161 ++
>  b/arch/i386/boot/mca.c                        |   43
>  b/arch/i386/boot/memory.c                     |   99 +
>  b/arch/i386/boot/pm.c                         |  170 ++
>  b/arch/i386/boot/pmjump.S                     |   54
>  b/arch/i386/boot/printf.c                     |  331 ++++
>  b/arch/i386/boot/setup.ld                     |   54
>  b/arch/i386/boot/string.c                     |   34
>  b/arch/i386/boot/tools/build.c                |  160 --
>  b/arch/i386/boot/tty.c                        |  112 +
>  b/arch/i386/boot/version.c                    |   23
>  b/arch/i386/boot/vesa.h                       |   79 +
>  b/arch/i386/boot/video-bios.c                 |  125 +
>  b/arch/i386/boot/video-vesa.c                 |  284 +++
>  b/arch/i386/boot/video-vga.c                  |  260 +++
>  b/arch/i386/boot/video.c                      |  456 +++++
>  b/arch/i386/boot/video.h                      |  145 +
>  b/arch/i386/boot/voyager.c                    |   46
>  b/arch/i386/kernel/cpu/Makefile               |    2
>  b/arch/i386/kernel/cpu/addon_cpuid_features.c |   50
>  b/arch/i386/kernel/cpu/common.c               |    2
>  b/arch/i386/kernel/cpu/proc.c                 |   21
>  b/arch/i386/kernel/e820.c                     |    2
>  b/arch/i386/kernel/setup.c                    |   12
>  b/arch/x86_64/Kconfig                         |    4
>  b/arch/x86_64/boot/Makefile                   |  136 -
>  b/arch/x86_64/boot/compressed/Makefile        |    9
>  b/arch/x86_64/boot/compressed/head.S          |    6
>  b/arch/x86_64/kernel/Makefile                 |    2
>  b/arch/x86_64/kernel/setup.c                  |   21
>  b/arch/x86_64/kernel/verify_cpu.S             |   22
>  b/drivers/ide/legacy/hd.c                     |   73
>  b/include/asm-i386/boot.h                     |    6
>  b/include/asm-i386/bootparam.h                |   85 +
>  b/include/asm-i386/cpufeature.h               |   26
>  b/include/asm-i386/e820.h                     |   14
>  b/include/asm-i386/processor.h                |    1
>  b/include/asm-i386/required-features.h        |   39
>  b/include/asm-i386/setup.h                    |   10
>  b/include/asm-x86_64/alternative.h            |   68
>  b/include/asm-x86_64/boot.h                   |   16
>  b/include/asm-x86_64/bootparam.h              |    1
>  b/include/asm-x86_64/cpufeature.h             |  115 -
>  b/include/asm-x86_64/e820.h                   |    6
>  b/include/asm-x86_64/processor.h              |    3
>  b/include/asm-x86_64/required-features.h      |   46
>  b/include/asm-x86_64/segment.h                |    8
>  b/include/linux/edd.h                         |    4
>  b/include/linux/screen_info.h                 |    9
>  76 files changed, 4601 insertions(+), 5208 deletions(-)

is possible to put 16bit c in seperate directory. or rename them with _16.c?

YH

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: x86 setup code rewrite in C
  2007-07-10  4:24 ` x86 setup code rewrite in C Yinghai Lu
@ 2007-07-10  4:39   ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10  4:39 UTC (permalink / raw)
  To: Yinghai Lu; +Cc: linux-kernel, linux-arch, akpm

Yinghai Lu wrote:
> 
> is possible to put 16bit c in seperate directory. or rename them with 
> _16.c?
> 

They *ARE* in a separate directory, specifically arch/i386/boot.  All
the *.c files in there are 16 bits; the 32-bit code is in
arch/i386/boot/compressed or arch/i386/kernel.

	-hpa


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: x86 setup code rewrite in C
  2007-07-10  2:51 x86 setup code rewrite in C H. Peter Anvin
       [not found] ` <2034f71d414def30de582fb59573295cadbdabb4.1184032748.git.hpa@zytor.com>
  2007-07-10  4:24 ` x86 setup code rewrite in C Yinghai Lu
@ 2007-07-10  5:25 ` Jeff Garzik
  2007-07-10 16:24 ` Jeremy Fitzhardinge
  3 siblings, 0 replies; 69+ messages in thread
From: Jeff Garzik @ 2007-07-10  5:25 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux-kernel, linux-arch, andi, akpm

H. Peter Anvin wrote:
> This patch set replaces the x86 setup code, which is currently all in
> assembly, with a version written in C, using the ".code16gcc" feature
> of binutils (which has been present since at least 2001.)
> 
> The new code is vastly easier to read, and, I hope, debug.  It should
> be noted that I found a fair number of minor bugs while going through
> this code, and have attempted to correct them.
> 
> In the process of doing so, it introduces several cleanups, in
> particular:
> 
> - Obsoletes the hd_info field in the boot_params structure; they are
>   only ever used for ST-506 (pre-IDE) drives and are pretty much
>   guaranteed to be wrong on current BIOSes;
> - Unifies the CPU feature bits between i386 and x86-64.  In the
>   future, it should be possible to use arch/i386/boot/cpucheck.c to do
>   the post-invocation CPU check currently done in
>   arch/x86_64/kernel/trampoline.S, although this patch set doesn't
>   introduce that change.
> - boot_params is now a proper structure.
> 
> This code has been tested in -mm since early in the 2.6.22 cycle.

ACK

I don't claim to be an expert in this area, but I definitely support 
this going in, and I really did read every patch.  :)

The only minor problem I found was a misspelling "paragrap" (perhaps 
plural) in one of the patches.

	Jeff



^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 22/33] CPU features verification for the new x86 setup code
  2007-07-10  2:52     ` [x86 setup 22/33] CPU features verification " H. Peter Anvin
@ 2007-07-10  7:37       ` Sébastien Dugué
  0 siblings, 0 replies; 69+ messages in thread
From: Sébastien Dugué @ 2007-07-10  7:37 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux-kernel, linux-arch, andi, akpm


  Hi Peter,

  Only two sub-minor nits:

On Mon, 9 Jul 2007 19:52:01 -0700 "H. Peter Anvin" <hpa@zytor.com> wrote:

> From: H. Peter Anvin <hpa@zytor.com>
> 
> Verify that the CPU has enough features to run the kernel.  This may
> entail enabling features on some CPUs.
> 
> By doing this in the setup code we can be guaranteed to still be able to
> write to the console through the BIOS.
> 
> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
> ---
>  arch/i386/boot/cpu.c      |   69 ++++++++++++
>  arch/i386/boot/cpucheck.c |  267 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 336 insertions(+), 0 deletions(-)
>  create mode 100644 arch/i386/boot/cpu.c
>  create mode 100644 arch/i386/boot/cpucheck.c
> 
> diff --git a/arch/i386/boot/cpu.c b/arch/i386/boot/cpu.c
> new file mode 100644
> index 0000000..042d894
> --- /dev/null
> +++ b/arch/i386/boot/cpu.c
> @@ -0,0 +1,69 @@
> +/* -*- linux-c -*- ------------------------------------------------------- *
> + *
> + *   Copyright (C) 1991, 1992 Linus Torvalds
> + *   Copyright 2007 rPath, Inc. - All Rights Reserved
> + *
> + *   This file is part of the Linux kernel, and is made available under
> + *   the terms of the GNU General Public License version 2.
> + *
> + * ----------------------------------------------------------------------- */
> +
> +/*
> + * arch/i386/boot/cpucheck.c

                    ^^^^^
                    cpu.c ?

> + *
> + * Check for obligatory CPU features and abort if the features are not
> + * present.
> + */
> +
> +#include "boot.h"
> +#include "bitops.h"
> +#include <asm/cpufeature.h>
> +
> +static char *cpu_name(int level)
> +{
> +	static char buf[6];
> +
> +	if (level == 64) {
> +		return "x86-64";
> +	} else {
> +		sprintf(buf, "i%d86", level);
> +		return buf;
> +	}
> +}
> +
> +int validate_cpu(void)
> +{
> +	u32 *err_flags;
> +	int cpu_level, req_level;
> +
> +	check_cpu(&cpu_level, &req_level, &err_flags);
> +
> +	if (cpu_level < req_level) {
> +		printf("This kernel requires an %s CPU, ",
> +		       cpu_name(req_level));
> +		printf("but only detected an %s CPU.\n",
> +		       cpu_name(cpu_level));
> +		return -1;
> +	}
> +
> +	if (err_flags) {
> +		int i, j;
> +		puts("This kernel requires the following features "
> +		     "not present on the CPU:\n");
> +
> +		for (i = 0; i < NCAPINTS; i++) {
> +			u32 e = err_flags[i];
> +
> +			for (j = 0; j < 32; j++) {
> +				if (e & 1)
> +					printf("%d:%d ", i, j);
> +
> +				e >>= 1;
> +			}
> +		}
> +		putchar('\n');
> +		return -1;
> +	} else {
> +		return 0;
> +	}
> +}
> diff --git a/arch/i386/boot/cpucheck.c b/arch/i386/boot/cpucheck.c
> new file mode 100644
> index 0000000..431bef8
> --- /dev/null
> +++ b/arch/i386/boot/cpucheck.c
> @@ -0,0 +1,267 @@
> +/* -*- linux-c -*- ------------------------------------------------------- *
> + *
> + *   Copyright (C) 1991, 1992 Linus Torvalds
> + *   Copyright 2007 rPath, Inc. - All Rights Reserved
> + *
> + *   This file is part of the Linux kernel, and is made available under
> + *   the terms of the GNU General Public License version 2.
> + *
> + * ----------------------------------------------------------------------- */
> +
> +/*
> + * arch/i386/boot/cpu.c

                    ^^^^^
                    cpucheck.c ?

> + *
> + * Check for obligatory CPU features and abort if the features are not
> + * present.  This code should be compilable as 16-, 32- or 64-bit
> + * code, so be very careful with types and inline assembly.
> + *
> + * This code should not contain any messages; that requires an
> + * additional wrapper.
> + *


  Sébastien.



^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 31/33] Use the new x86 setup code for i386
  2007-07-10  2:52     ` [x86 setup 31/33] Use the new x86 setup code for i386 H. Peter Anvin
@ 2007-07-10  7:55       ` Tilman Schmidt
  0 siblings, 0 replies; 69+ messages in thread
From: Tilman Schmidt @ 2007-07-10  7:55 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux-kernel, linux-arch, andi, akpm

[-- Attachment #1: Type: text/plain, Size: 985 bytes --]

Minor nitpick:

> diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c
> index 0579841..886f47d 100644
> --- a/arch/i386/boot/tools/build.c
> +++ b/arch/i386/boot/tools/build.c
> @@ -1,13 +1,12 @@
>  /*
>   *  Copyright (C) 1991, 1992  Linus Torvalds
>   *  Copyright (C) 1997 Martin Mares
> + *  Copyright (C) 2007 H. Peter Anvin
>   */
>  
>  /*
>   * This file builds a disk-image from three different files:
                                         ~~~~~
                                         two
>   *
> - * - bootsect: compatibility mbr which prints an error message if
> - *             someone tries to boot the kernel directly.
>   * - setup: 8086 machine code, sets up system parm
>   * - system: 80386 code for actual system
>   *

-- 
Tilman Schmidt                    E-Mail: tilman@imap.cc
Bonn, Germany
Diese Nachricht besteht zu 100% aus wiederverwerteten Bits.
Ungeöffnet mindestens haltbar bis: (siehe Rückseite)


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 09/33] Make definitions for struct e820entry and struct e820map consistent
       [not found]   ` <361d0a8b7b7ea9d41d0c25664b3e2b30fd99e329.1184032749.git.hpa@zytor.com>
  2007-07-10  2:51     ` [x86 setup 09/33] Make definitions for struct e820entry and struct e820map consistent H. Peter Anvin
@ 2007-07-10 11:48     ` Andi Kleen
  1 sibling, 0 replies; 69+ messages in thread
From: Andi Kleen @ 2007-07-10 11:48 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux-kernel, linux-arch, andi, akpm

> diff --git a/include/asm-x86_64/e820.h b/include/asm-x86_64/e820.h
> index 6216fa3..15eb8e2 100644
> --- a/include/asm-x86_64/e820.h
> +++ b/include/asm-x86_64/e820.h
> @@ -11,7 +11,9 @@
>  #ifndef __E820_HEADER
>  #define __E820_HEADER
>  
> -#include <linux/mmzone.h>
> +#ifndef _SETUP
> +# include <linux/mmzone.h>
> +#endif

If the ifdef is valid then the include can be completely removed.

-Andi

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10  2:51     ` [x86 setup 13/33] Header file to produce 16-bit code with gcc H. Peter Anvin
@ 2007-07-10 14:16       ` Segher Boessenkool
  2007-07-10 15:21         ` Andi Kleen
  0 siblings, 1 reply; 69+ messages in thread
From: Segher Boessenkool @ 2007-07-10 14:16 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux-kernel, linux-arch, andi, akpm

> gcc for i386 can be used with the assembly prefix ".code16gcc" to  
> generate
> 16-bit (real-mode) code.  This header file provides the assembly  
> prefix.

This only works correctly with newer GCCs if you pass the
-fno-toplevel-reorder option (and it only works on older
GCC versions by accident).  This option however disables
certain optimisations; but perhaps that doesn't matter all
that much here.


Segher


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 14:16       ` Segher Boessenkool
@ 2007-07-10 15:21         ` Andi Kleen
  2007-07-10 15:48           ` H. Peter Anvin
  2007-07-10 19:57           ` Segher Boessenkool
  0 siblings, 2 replies; 69+ messages in thread
From: Andi Kleen @ 2007-07-10 15:21 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: H. Peter Anvin, linux-kernel, linux-arch, akpm

On Tuesday 10 July 2007 16:16:29 Segher Boessenkool wrote:
> > gcc for i386 can be used with the assembly prefix ".code16gcc" to  
> > generate
> > 16-bit (real-mode) code.  This header file provides the assembly  
> > prefix.
> 
> This only works correctly with newer GCCs if you pass the
> -fno-toplevel-reorder option (and it only works on older
> GCC versions by accident).

And on older ones (gcc-3.3-hammer / 3.4 / 4.0 ) -fno-unit-at-a-time

Still it seems quite fragile to me agreed.

-Andi

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 15:21         ` Andi Kleen
@ 2007-07-10 15:48           ` H. Peter Anvin
  2007-07-10 15:53             ` H. Peter Anvin
  2007-07-10 20:08             ` Segher Boessenkool
  2007-07-10 19:57           ` Segher Boessenkool
  1 sibling, 2 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10 15:48 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Segher Boessenkool, linux-kernel, linux-arch, akpm

Andi Kleen wrote:
> On Tuesday 10 July 2007 16:16:29 Segher Boessenkool wrote:
>>> gcc for i386 can be used with the assembly prefix ".code16gcc" to  
>>> generate
>>> 16-bit (real-mode) code.  This header file provides the assembly  
>>> prefix.
>> This only works correctly with newer GCCs if you pass the
>> -fno-toplevel-reorder option (and it only works on older
>> GCC versions by accident).
> 
> And on older ones (gcc-3.3-hammer / 3.4 / 4.0 ) -fno-unit-at-a-time
> 
> Still it seems quite fragile to me agreed.

The alternative, of course, is to compile to an .s file and insert
.code16gcc into the .s file.  This makes the Makefile uglier, but would
be more resilient against oddball gcc changes.

I'm a bit surprised about the claim w.r.t. -fno-unit-at-a-time (although
I guess that is the default and one would thus typically not see this.)
 Got any pointers why that would cause a global asm() to be scrambled
around?

	-hpa

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 15:48           ` H. Peter Anvin
@ 2007-07-10 15:53             ` H. Peter Anvin
  2007-07-10 20:08             ` Segher Boessenkool
  1 sibling, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10 15:53 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Segher Boessenkool, linux-kernel, linux-arch, akpm

H. Peter Anvin wrote:
> 
> I'm a bit surprised about the claim w.r.t. -fno-unit-at-a-time (although
> I guess that is the default and one would thus typically not see this.)
>  Got any pointers why that would cause a global asm() to be scrambled
> around?
> 

Never mind.  It's quite right there in the gcc doc, and
-fno-unit-at-a-time is documented as the fix.

	-hpa

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: x86 setup code rewrite in C
  2007-07-10  2:51 x86 setup code rewrite in C H. Peter Anvin
                   ` (2 preceding siblings ...)
  2007-07-10  5:25 ` Jeff Garzik
@ 2007-07-10 16:24 ` Jeremy Fitzhardinge
  3 siblings, 0 replies; 69+ messages in thread
From: Jeremy Fitzhardinge @ 2007-07-10 16:24 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux-kernel, linux-arch, andi, akpm

H. Peter Anvin wrote:
> This patch set replaces the x86 setup code, which is currently all in
> assembly, with a version written in C, using the ".code16gcc" feature
> of binutils (which has been present since at least 2001.)
>
> The new code is vastly easier to read, and, I hope, debug.  It should
> be noted that I found a fair number of minor bugs while going through
> this code, and have attempted to correct them.
>
> In the process of doing so, it introduces several cleanups, in
> particular:
>
> - Obsoletes the hd_info field in the boot_params structure; they are
>   only ever used for ST-506 (pre-IDE) drives and are pretty much
>   guaranteed to be wrong on current BIOSes;
> - Unifies the CPU feature bits between i386 and x86-64.  In the
>   future, it should be possible to use arch/i386/boot/cpucheck.c to do
>   the post-invocation CPU check currently done in
>   arch/x86_64/kernel/trampoline.S, although this patch set doesn't
>   introduce that change.
> - boot_params is now a proper structure.
>
> This code has been tested in -mm since early in the 2.6.22 cycle.
>   

This stuff is good.  I haven't read through this series in detail, but I 
have been working on the code in -mm and its a clear improvement.

Acked-by: Jeremy Fitzhardinge <jeremy@xensource.com>

    J

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 16/33] String-handling functions for the new x86 setup code.
  2007-07-10  2:51     ` [x86 setup 16/33] String-handling functions " H. Peter Anvin
@ 2007-07-10 18:25       ` Jan Engelhardt
  2007-07-10 18:35         ` H. Peter Anvin
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Engelhardt @ 2007-07-10 18:25 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux-kernel, linux-arch, andi, akpm


On Jul 9 2007 19:51, H. Peter Anvin wrote:
>
>strcmp(), memcpy(), memset(), as well as routines to copy to and from
>other segments (as pointed to by fs and gs).

I wonder, strcmp() is the only one not done in assembler.
Is there a particular reason? (Or the other way around, why
is memcpy/memset not C.) The opcode is rep[n]z cmps[bl];

Would perhaps using __builtin_memset
and whatever GCC provides also work in 16-bit mode (would save
implementing it again).

>+/*
>+ * arch/i386/boot/string.c
>+ *
>+ * Very basic string functions
>+ */
>+
>+#include "boot.h"
>+#include <linux/edd.h>

What's edd good for here?

>+int strcmp(const char *str1, const char *str2)
>+{
>+	const unsigned char *s1 = (const unsigned char *)str1;
>+	const unsigned char *s2 = (const unsigned char *)str2;
>+	int delta = 0;
>+
>+	while (*s1 || *s2) {
>+		delta = *s2 - *s1;
>+		if (delta)
>+			return delta;
>+		s1++;
>+		s2++;
>+	}
>+	return 0;
>+}



	Jan
-- 

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 17/33] A20 handling code
  2007-07-10  2:51     ` [x86 setup 17/33] A20 handling code H. Peter Anvin
@ 2007-07-10 18:27       ` Jan Engelhardt
  2007-07-10 18:33         ` H. Peter Anvin
  2007-07-10 18:36         ` H. Peter Anvin
  0 siblings, 2 replies; 69+ messages in thread
From: Jan Engelhardt @ 2007-07-10 18:27 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux-kernel, linux-arch, andi, akpm


On Jul 9 2007 19:51, H. Peter Anvin wrote:

>+		status = inb(0x64);
>+		if (status & 1) {
>+			/* Read and discard input data */
>+			io_delay();
>+			(void)inb(0x60);

Is the (void) cast needed for some obscure reason? Let's hope inb _is_ declared
as volatile. (Minus the volatile flames.

>+		} else if (!(status & 2)) {
>+			/* Buffers empty, finished! */
>+			return 0;
>+		}
>+	}
>+
>+	return -1;
>+}
>+
>+
>+#define A20_TEST_ADDR	(4*0x80)
>+#define A20_TEST_SHORT  32
>+#define A20_TEST_LONG	2097152	/* 2^21 */

Maybe...?
#define A20_TEST_LONG (1 << 21)

>+/* Quick test to see if A20 is already enabled */
>+static int a20_test_short(void)
>+{
>+	return a20_test(A20_TEST_SHORT);
>+}
>+
>+/* Longer test that actually waits for A20 to come on line; this
>+   is useful when dealing with the KBC or other slow external circuitry. */
>+static int a20_test_long(void)
>+{
>+	return a20_test(A20_TEST_LONG);
>+}

To me looks like some of these (or other functions) could return bool.



	Jan
-- 

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 17/33] A20 handling code
  2007-07-10 18:27       ` Jan Engelhardt
@ 2007-07-10 18:33         ` H. Peter Anvin
  2007-07-10 18:36         ` H. Peter Anvin
  1 sibling, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10 18:33 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: linux-kernel, linux-arch, andi, akpm

Jan Engelhardt wrote:
> On Jul 9 2007 19:51, H. Peter Anvin wrote:
> 
>> +		status = inb(0x64);
>> +		if (status & 1) {
>> +			/* Read and discard input data */
>> +			io_delay();
>> +			(void)inb(0x60);
> 
> Is the (void) cast needed for some obscure reason? Let's hope inb _is_ declared
> as volatile. (Minus the volatile flames.
> 

The (void) cast is there as a stylistic device, it tells the human
reader "yes, I really meant to read this value and throw it away."

	-hpa


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 20/33] Console-writing code for the new x86 setup code
  2007-07-10  2:51     ` [x86 setup 20/33] Console-writing " H. Peter Anvin
@ 2007-07-10 18:35       ` Jan Engelhardt
  2007-07-10 18:48         ` H. Peter Anvin
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Engelhardt @ 2007-07-10 18:35 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux-kernel, linux-arch, andi, akpm


On Jul 9 2007 19:51, H. Peter Anvin wrote:
>+
>+static inline int isdigit(int ch)
>+{
>+	return (ch >= '0') && (ch <= '9');
>+}

I'd say static inline unsigned int isdigit(unsigned char), since ASCII does not
realistically exceed 255.

>+static int strnlen(const char *s, int maxlen)

unsigned int,  and               unsigned int, too?
The glibc strnlen type also uses unsigned types.




	Jan
-- 

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 16/33] String-handling functions for the new x86 setup code.
  2007-07-10 18:25       ` Jan Engelhardt
@ 2007-07-10 18:35         ` H. Peter Anvin
  2007-07-10 20:10           ` Segher Boessenkool
  0 siblings, 1 reply; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10 18:35 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: linux-kernel, linux-arch, andi, akpm

Jan Engelhardt wrote:
> On Jul 9 2007 19:51, H. Peter Anvin wrote:
>> strcmp(), memcpy(), memset(), as well as routines to copy to and from
>> other segments (as pointed to by fs and gs).
> 
> I wonder, strcmp() is the only one not done in assembler.
> Is there a particular reason? (Or the other way around, why
> is memcpy/memset not C.) The opcode is rep[n]z cmps[bl];

BZZT, wrong.  repz cmpsb is memcmp(), not strcmp().  The reason is
simply that memset and memcpy are in assembly is that they are simple
wrappers around string instructions, plus the need to provide the
other-segment copy functions -- it was cleaner to do them as an assembly
file.

This is not the case for strcmp(), nor for any other string functions
that may want to be used in the future.

> Would perhaps using __builtin_memset
> and whatever GCC provides also work in 16-bit mode (would save
> implementing it again).

Nope.  The builtins not only vary between gcc versions, but they also
have a nasty tendency to generate calls to library functions, sometimes
libgcc functions.  Hence -ffreestanding.

>> +/*
>> + * arch/i386/boot/string.c
>> + *
>> + * Very basic string functions
>> + */
>> +
>> +#include "boot.h"
>> +#include <linux/edd.h>
> 
> What's edd good for here?

It's a copy-and-paste accident; already fixed in the tree.

	-hpa

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 17/33] A20 handling code
  2007-07-10 18:27       ` Jan Engelhardt
  2007-07-10 18:33         ` H. Peter Anvin
@ 2007-07-10 18:36         ` H. Peter Anvin
  1 sibling, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10 18:36 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: linux-kernel, linux-arch, andi, akpm

Jan Engelhardt wrote:
>> +
>> +#define A20_TEST_ADDR	(4*0x80)
>> +#define A20_TEST_SHORT  32
>> +#define A20_TEST_LONG	2097152	/* 2^21 */
> 
> Maybe...?
> #define A20_TEST_LONG (1 << 21)

That makes it look like it's a magic value or bitmask, it's not.  The
value 2^21 is largely arbitrary, it's just what happened to be in the
previous code.

>> +/* Quick test to see if A20 is already enabled */
>> +static int a20_test_short(void)
>> +{
>> +	return a20_test(A20_TEST_SHORT);
>> +}
>> +
>> +/* Longer test that actually waits for A20 to come on line; this
>> +   is useful when dealing with the KBC or other slow external circuitry. */
>> +static int a20_test_long(void)
>> +{
>> +	return a20_test(A20_TEST_LONG);
>> +}
> 
> To me looks like some of these (or other functions) could return bool.

Does it matter?  It will generate worse code.

	-hpa

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 20/33] Console-writing code for the new x86 setup code
  2007-07-10 18:35       ` Jan Engelhardt
@ 2007-07-10 18:48         ` H. Peter Anvin
  0 siblings, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10 18:48 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: linux-kernel, linux-arch, andi, akpm

Jan Engelhardt wrote:
> On Jul 9 2007 19:51, H. Peter Anvin wrote:
>> +
>> +static inline int isdigit(int ch)
>> +{
>> +	return (ch >= '0') && (ch <= '9');
>> +}
> 
> I'd say static inline unsigned int isdigit(unsigned char), since ASCII does not
> realistically exceed 255.

If you're trying to be standard, you're doing the wrong thing (the
standard is int, since -1 is a permitted value.)

It doesn't matter anyway, and your version would probably generate
slightly worse code.

>> +static int strnlen(const char *s, int maxlen)
> 
> unsigned int,  and               unsigned int, too?
> The glibc strnlen type also uses unsigned types.

If anything it should be size_t.  Fixing, and moved to string.c, where
it belongs.

	-hpa

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 15:21         ` Andi Kleen
  2007-07-10 15:48           ` H. Peter Anvin
@ 2007-07-10 19:57           ` Segher Boessenkool
  2007-07-10 20:42             ` H. Peter Anvin
  1 sibling, 1 reply; 69+ messages in thread
From: Segher Boessenkool @ 2007-07-10 19:57 UTC (permalink / raw)
  To: Andi Kleen; +Cc: H. Peter Anvin, linux-kernel, linux-arch, akpm

>>> gcc for i386 can be used with the assembly prefix ".code16gcc" to
>>> generate
>>> 16-bit (real-mode) code.  This header file provides the assembly
>>> prefix.
>>
>> This only works correctly with newer GCCs if you pass the
>> -fno-toplevel-reorder option (and it only works on older
>> GCC versions by accident).
>
> And on older ones (gcc-3.3-hammer / 3.4 / 4.0 ) -fno-unit-at-a-time

...which inhibits even more optimisations.  Still not too
important, but the code size difference probably is
noticeable.

> Still it seems quite fragile to me agreed.

Well at least with -fno-toplevel-reorder it is guaranteed
to work (not the same thing as "is working", heh, but fairly
close).

It seems to me GCC should grow an option to insert .code16gcc
by itself (-m16 perhaps?)  Or GAS could get a flag to include
a file as a prelude before the main thing.  Neither will help
Linux right now of course.


Segher


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 15:48           ` H. Peter Anvin
  2007-07-10 15:53             ` H. Peter Anvin
@ 2007-07-10 20:08             ` Segher Boessenkool
  2007-07-10 20:43               ` H. Peter Anvin
  1 sibling, 1 reply; 69+ messages in thread
From: Segher Boessenkool @ 2007-07-10 20:08 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Andi Kleen, linux-kernel, linux-arch, akpm

>>>> gcc for i386 can be used with the assembly prefix ".code16gcc" to
>>>> generate
>>>> 16-bit (real-mode) code.  This header file provides the assembly
>>>> prefix.
>>> This only works correctly with newer GCCs if you pass the
>>> -fno-toplevel-reorder option (and it only works on older
>>> GCC versions by accident).
>>
>> And on older ones (gcc-3.3-hammer / 3.4 / 4.0 ) -fno-unit-at-a-time
>>
>> Still it seems quite fragile to me agreed.
>
> The alternative, of course, is to compile to an .s file and insert
> .code16gcc into the .s file.  This makes the Makefile uglier, but  
> would
> be more resilient against oddball gcc changes.

This would be even more fragile.  The exact format of GCC's
assembler code output isn't defined at all, so in principle
this is a hopeless task.  In practice just putting the
.code16gcc directive on the first line would likely work
though, GCC never generates a .code32 AFAIK, but it isn't
guaranteed that this will work (or will keep working).

> I'm a bit surprised about the claim w.r.t. -fno-unit-at-a-time  
> (although
> I guess that is the default and one would thus typically not see  
> this.)

-fno-unit-at-a-time is the default on three year old compilers,
yes.  Newer compilers have unit-at-a-time enabled by default.

>  Got any pointers why that would cause a global asm() to be scrambled
> around?

An asm() outside of a function is a top-level thing, just
like functions and file-scope variable definitions, and with
unit-at-a-time compilation all such blocks can be reordered
(or even omitted, or inlined, or whatever).  Note that even
before unit-at-a-time was introduced there was no guarantee
of emitting everything in the order it appears in the source
file.


Segher


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 16/33] String-handling functions for the new x86 setup code.
  2007-07-10 18:35         ` H. Peter Anvin
@ 2007-07-10 20:10           ` Segher Boessenkool
  2007-07-10 20:44             ` H. Peter Anvin
  0 siblings, 1 reply; 69+ messages in thread
From: Segher Boessenkool @ 2007-07-10 20:10 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Jan Engelhardt, linux-kernel, linux-arch, andi, akpm

> Nope.  The builtins not only vary between gcc versions, but they also
> have a nasty tendency to generate calls to library functions,  
> sometimes
> libgcc functions.  Hence -ffreestanding.

-ffreestanding will still generate calls to libgcc functions.
-ffreestanding doesn't disable _all_ of the C library, either.


Segher


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 19:57           ` Segher Boessenkool
@ 2007-07-10 20:42             ` H. Peter Anvin
  2007-07-10 21:10               ` Segher Boessenkool
  2007-07-10 21:43               ` Adrian Bunk
  0 siblings, 2 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10 20:42 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Andi Kleen, linux-kernel, linux-arch, akpm

Segher Boessenkool wrote:
> 
> Well at least with -fno-toplevel-reorder it is guaranteed
> to work (not the same thing as "is working", heh, but fairly
> close).
> 
> It seems to me GCC should grow an option to insert .code16gcc
> by itself (-m16 perhaps?)  Or GAS could get a flag to include
> a file as a prelude before the main thing.  Neither will help
> Linux right now of course.
> 

-m16 is the right thing, and it also provides a proper hook for
eventually having a real 16-bit backend (there are at least two projects
for doing that.)

For now, I have:

CFLAGS          := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
                   $(cflags-$(ARCH)) \
                   -Wall -Wstrict-prototypes \
                   -march=i386 -mregparm=3 \
                   -include $(srctree)/$(src)/code16gcc.h \
                   -fno-strict-aliasing -fomit-frame-pointer \
                   $(call cc-option, -ffreestanding) \
                   $(call cc-option, -fno-unit-at-a-time) \
                   $(call cc-option, -fno-toplevel-reorder) \
                   $(call cc-option, -fno-stack-protector) \
                   $(call cc-option, -mpreferred-stack-boundary=2)

... since that will require less violence to eventually hack in the
proper -m16 option if/when it becomes available.

	-hpa

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 20:08             ` Segher Boessenkool
@ 2007-07-10 20:43               ` H. Peter Anvin
  2007-07-10 21:08                 ` Pawel Dziepak
  0 siblings, 1 reply; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10 20:43 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Andi Kleen, linux-kernel, linux-arch, akpm

Segher Boessenkool wrote:
> 
>> I'm a bit surprised about the claim w.r.t. -fno-unit-at-a-time (although
>> I guess that is the default and one would thus typically not see this.)
> 
> -fno-unit-at-a-time is the default on three year old compilers,
> yes.  Newer compilers have unit-at-a-time enabled by default.
> 

As I said, never mind.  "Unit at a time" does something totally
different from what I somehow had gotten into my head it did.

	-hpa

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 16/33] String-handling functions for the new x86 setup code.
  2007-07-10 20:10           ` Segher Boessenkool
@ 2007-07-10 20:44             ` H. Peter Anvin
  2007-07-10 21:14               ` Segher Boessenkool
  0 siblings, 1 reply; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10 20:44 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Jan Engelhardt, linux-kernel, linux-arch, andi, akpm

Segher Boessenkool wrote:
>> Nope.  The builtins not only vary between gcc versions, but they also
>> have a nasty tendency to generate calls to library functions, sometimes
>> libgcc functions.  Hence -ffreestanding.
> 
> -ffreestanding will still generate calls to libgcc functions.
> -ffreestanding doesn't disable _all_ of the C library, either.
> 

No, it doesn't, but it does inhibit builtin functions, and so provides a
bit more ABI stability.

	-hpa

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 20:43               ` H. Peter Anvin
@ 2007-07-10 21:08                 ` Pawel Dziepak
  2007-07-10 21:20                   ` H. Peter Anvin
  2007-07-11  0:26                   ` Brian Gerst
  0 siblings, 2 replies; 69+ messages in thread
From: Pawel Dziepak @ 2007-07-10 21:08 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Segher Boessenkool, Andi Kleen, linux-kernel, linux-arch, akpm

On 7/10/07, Segher Boessenkool <segher@kernel.crashing.org> wrote:
> > The alternative, of course, is to compile to an .s file and insert
> > .code16gcc into the .s file.  This makes the Makefile uglier, but
> > would
> > be more resilient against oddball gcc changes.
>
> This would be even more fragile.  The exact format of GCC's
> assembler code output isn't defined at all, so in principle
> this is a hopeless task.  In practice just putting the
> .code16gcc directive on the first line would likely work
> though, GCC never generates a .code32 AFAIK, but it isn't
> guaranteed that this will work (or will keep working).

Unfortunately, .code16gcc is still experimental (at least binutils'
website says that). What is worse, it says that it is possible that
16bit code produced on GCC won't work on pre-80386 processors (before
switching to protected mode you have to think about cpu as a
pre-80386).

I don't think that -m16 flag will be introduced quickly. In fact, only
OS developers _sometimes_ use 16 bit code...

I did a fast test and now I know that assembler instructions are
almost ignored by GCC and passed to gas. The situation is the same
with .code16gcc, what mean that gas has to translate 32bit code from
GCC to 16 bit code. The result binary was correct 16 bit program (at
least its code looked good), but it is IMHO too many translations from
C to 32bit assembler and then to 16bit assembler, that can cause
unpredictable errors.

Additionally, I prefer to write architecture depend procedures in
assembler (but is only *my* opinion, and you probably disagree).
Assembler is faster, you have bigger control over the code, and
portability of C is in this circumstances not necessary.

Pawel

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 20:42             ` H. Peter Anvin
@ 2007-07-10 21:10               ` Segher Boessenkool
  2007-07-10 21:40                 ` H. Peter Anvin
  2007-07-10 21:43               ` Adrian Bunk
  1 sibling, 1 reply; 69+ messages in thread
From: Segher Boessenkool @ 2007-07-10 21:10 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Andi Kleen, linux-kernel, linux-arch, akpm

>> It seems to me GCC should grow an option to insert .code16gcc
>> by itself (-m16 perhaps?)

> -m16 is the right thing,

Probably not actually, -m16 might have 16-bit "int" etc.
-mabi=16 is closer to what other architectures do here.

> and it also provides a proper hook for
> eventually having a real 16-bit backend (there are at least two  
> projects
> for doing that.)

Those would use -m16, yes.

> For now, I have:
>
> CFLAGS          := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
>                    $(cflags-$(ARCH)) \
>                    -Wall -Wstrict-prototypes \
>                    -march=i386 -mregparm=3 \
>                    -include $(srctree)/$(src)/code16gcc.h \
>                    -fno-strict-aliasing -fomit-frame-pointer \
>                    $(call cc-option, -ffreestanding) \
>                    $(call cc-option, -fno-unit-at-a-time) \
>                    $(call cc-option, -fno-toplevel-reorder) \
>                    $(call cc-option, -fno-stack-protector) \
>                    $(call cc-option, -mpreferred-stack-boundary=2)
>
> ... since that will require less violence to eventually hack in the
> proper -m16 option if/when it becomes available.

Looks good, except you don't want -fno-unit-at-a-time if
-fno-toplevel-reorder works.  And of course it would be
good to get rid of -fno-strict-aliasing, but let's not
go there today ;-P


Segher


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 16/33] String-handling functions for the new x86 setup code.
  2007-07-10 20:44             ` H. Peter Anvin
@ 2007-07-10 21:14               ` Segher Boessenkool
  2007-07-11 12:46                 ` Andi Kleen
  0 siblings, 1 reply; 69+ messages in thread
From: Segher Boessenkool @ 2007-07-10 21:14 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Jan Engelhardt, linux-kernel, linux-arch, andi, akpm

>>> Nope.  The builtins not only vary between gcc versions, but they  
>>> also
>>> have a nasty tendency to generate calls to library functions,  
>>> sometimes
>>> libgcc functions.  Hence -ffreestanding.
>>
>> -ffreestanding will still generate calls to libgcc functions.
>> -ffreestanding doesn't disable _all_ of the C library, either.
>
> No, it doesn't, but it does inhibit builtin functions, and so  
> provides a
> bit more ABI stability.

Yes, Linux should definitely be compiled with -ffreestanding,
it isn't a hosted application after all ;-)


Segher


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 21:08                 ` Pawel Dziepak
@ 2007-07-10 21:20                   ` H. Peter Anvin
  2007-07-11  0:26                   ` Brian Gerst
  1 sibling, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10 21:20 UTC (permalink / raw)
  To: Pawel Dziepak
  Cc: Segher Boessenkool, Andi Kleen, linux-kernel, linux-arch, akpm

Pawel Dziepak wrote:
> 
> Unfortunately, .code16gcc is still experimental (at least binutils'
> website says that). What is worse, it says that it is possible that
> 16bit code produced on GCC won't work on pre-80386 processors (before
> switching to protected mode you have to think about cpu as a
> pre-80386).
> 

.code16gcc has been in production use in real projects since at least 2001.

16-bit code produced by gcc is indeed, guaranteed to not work on pre-386
x86s, but so is the code we had there before.  Saying "before switching
to protected mode you have to think about [the] cpu as a pre-80386" is
blatantly false; 32-bit registers and addressing are readily available
in real mode using size override prefixes (which is what ".code16gcc"
takes care of.)

> I don't think that -m16 flag will be introduced quickly. In fact, only
> OS developers _sometimes_ use 16 bit code...
> 
> I did a fast test and now I know that assembler instructions are
> almost ignored by GCC and passed to gas. The situation is the same
> with .code16gcc, what mean that gas has to translate 32bit code from
> GCC to 16 bit code. The result binary was correct 16 bit program (at
> least its code looked good), but it is IMHO too many translations from
> C to 32bit assembler and then to 16bit assembler, that can cause
> unpredictable errors.

You're saying "I don't understand it, and it scares me."  The
differences compared to standard .code16 are pretty minute, mostly in
the matter of a couple of different default sizes (e.g. "call" defaults
to "calll" not "callw".)

> Additionally, I prefer to write architecture depend procedures in
> assembler (but is only *my* opinion, and you probably disagree).
> Assembler is faster, you have bigger control over the code, and
> portability of C is in this circumstances not necessary.

... and the code is an utter, unmaintainable mess.

	-hpa

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 21:10               ` Segher Boessenkool
@ 2007-07-10 21:40                 ` H. Peter Anvin
  2007-07-10 22:06                   ` Segher Boessenkool
  0 siblings, 1 reply; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10 21:40 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Andi Kleen, linux-kernel, linux-arch, akpm

Segher Boessenkool wrote:
> 
>> For now, I have:
>>
>> CFLAGS          := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
>>                    $(cflags-$(ARCH)) \
>>                    -Wall -Wstrict-prototypes \
>>                    -march=i386 -mregparm=3 \
>>                    -include $(srctree)/$(src)/code16gcc.h \
>>                    -fno-strict-aliasing -fomit-frame-pointer \
>>                    $(call cc-option, -ffreestanding) \
>>                    $(call cc-option, -fno-unit-at-a-time) \
>>                    $(call cc-option, -fno-toplevel-reorder) \
>>                    $(call cc-option, -fno-stack-protector) \
>>                    $(call cc-option, -mpreferred-stack-boundary=2)
>>
>> ... since that will require less violence to eventually hack in the
>> proper -m16 option if/when it becomes available.
> 
> Looks good, except you don't want -fno-unit-at-a-time if
> -fno-toplevel-reorder works.  And of course it would be
> good to get rid of -fno-strict-aliasing, but let's not
> go there today ;-P
> 

OK, how does this look:

CFLAGS          := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
                   $(cflags-$(ARCH)) \
                   -Wall -Wstrict-prototypes \
                   -march=i386 -mregparm=3 \
                   -include $(srctree)/$(src)/code16gcc.h \
                   -fno-strict-aliasing -fomit-frame-pointer \
                   $(call cc-option, -ffreestanding) \
                   $(call cc-option, -fno-toplevel-reorder,\
                        $(call cc-option, -fno-unit-at-a-time)) \
                   $(call cc-option, -fno-stack-protector) \
                   $(call cc-option, -mpreferred-stack-boundary=2)

I think dropping -fno-strict-aliasing for this code is probably bad...
it's pretty low-level stuff which does a lot of bitlevel manipulation.

	-hpa


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 20:42             ` H. Peter Anvin
  2007-07-10 21:10               ` Segher Boessenkool
@ 2007-07-10 21:43               ` Adrian Bunk
  2007-07-10 21:46                 ` H. Peter Anvin
  2007-07-11  0:30                 ` Brian Gerst
  1 sibling, 2 replies; 69+ messages in thread
From: Adrian Bunk @ 2007-07-10 21:43 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Segher Boessenkool, Andi Kleen, linux-kernel, linux-arch, akpm

On Tue, Jul 10, 2007 at 01:42:48PM -0700, H. Peter Anvin wrote:
> Segher Boessenkool wrote:
> > 
> > Well at least with -fno-toplevel-reorder it is guaranteed
> > to work (not the same thing as "is working", heh, but fairly
> > close).
> > 
> > It seems to me GCC should grow an option to insert .code16gcc
> > by itself (-m16 perhaps?)  Or GAS could get a flag to include
> > a file as a prelude before the main thing.  Neither will help
> > Linux right now of course.
> 
> -m16 is the right thing, and it also provides a proper hook for 
> eventually having a real 16-bit backend (there are at least two 
> projects for doing that.)
> 
> For now, I have:

Can't you use the global CFLAGS and append your specific ones?

> CFLAGS          := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \

-g ???

>                    $(cflags-$(ARCH)) \
>                    -Wall -Wstrict-prototypes \
>                    -march=i386 -mregparm=3 \

Why -march=i386 ?

>                    -include $(srctree)/$(src)/code16gcc.h \
>                    -fno-strict-aliasing -fomit-frame-pointer \
>                    $(call cc-option, -ffreestanding) \

No need to test, -ffreestanding is supported by all gcc versions we 
support.

>                    $(call cc-option, -fno-unit-at-a-time) \
>                    $(call cc-option, -fno-toplevel-reorder) \
>                    $(call cc-option, -fno-stack-protector) \
>                    $(call cc-option, -mpreferred-stack-boundary=2)
> 
> ... since that will require less violence to eventually hack in the
> proper -m16 option if/when it becomes available.
> 
> 	-hpa

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 21:43               ` Adrian Bunk
@ 2007-07-10 21:46                 ` H. Peter Anvin
  2007-07-11  0:30                 ` Brian Gerst
  1 sibling, 0 replies; 69+ messages in thread
From: H. Peter Anvin @ 2007-07-10 21:46 UTC (permalink / raw)
  To: Adrian Bunk
  Cc: Segher Boessenkool, Andi Kleen, linux-kernel, linux-arch, akpm

Adrian Bunk wrote:
>>
>> For now, I have:
> 
> Can't you use the global CFLAGS and append your specific ones?
> 

No.  A lot of the x86-64 flags don't work with -m32.

>> CFLAGS          := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
> 
> -g ???

Leaves debugging information in setup.elf.  It is handy sometimes.

>>                    $(cflags-$(ARCH)) \
>>                    -Wall -Wstrict-prototypes \
>>                    -march=i386 -mregparm=3 \
> 
> Why -march=i386 ?

So we can at least spit out an error message.

	-hpa

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 21:40                 ` H. Peter Anvin
@ 2007-07-10 22:06                   ` Segher Boessenkool
  0 siblings, 0 replies; 69+ messages in thread
From: Segher Boessenkool @ 2007-07-10 22:06 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Andi Kleen, linux-kernel, linux-arch, akpm

>> Looks good, except you don't want -fno-unit-at-a-time if
>> -fno-toplevel-reorder works.  And of course it would be
>> good to get rid of -fno-strict-aliasing, but let's not
>> go there today ;-P
>
> OK, how does this look:
>
> CFLAGS          := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
>                    $(cflags-$(ARCH)) \
>                    -Wall -Wstrict-prototypes \
>                    -march=i386 -mregparm=3 \
>                    -include $(srctree)/$(src)/code16gcc.h \
>                    -fno-strict-aliasing -fomit-frame-pointer \
>                    $(call cc-option, -ffreestanding) \
>                    $(call cc-option, -fno-toplevel-reorder,\
>                         $(call cc-option, -fno-unit-at-a-time)) \
>                    $(call cc-option, -fno-stack-protector) \
>                    $(call cc-option, -mpreferred-stack-boundary=2)

That looks fine.

> I think dropping -fno-strict-aliasing for this code is probably bad...
> it's pretty low-level stuff which does a lot of bitlevel manipulation.

"Which breaks C aliasing rules all over the place".  Well,
probably not all that often, actually.  But, as I said --
let's not go there now, keep the flag in there, removing
it will take a lot of work.


Segher


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 21:08                 ` Pawel Dziepak
  2007-07-10 21:20                   ` H. Peter Anvin
@ 2007-07-11  0:26                   ` Brian Gerst
  1 sibling, 0 replies; 69+ messages in thread
From: Brian Gerst @ 2007-07-11  0:26 UTC (permalink / raw)
  To: Pawel Dziepak
  Cc: H. Peter Anvin, Segher Boessenkool, Andi Kleen, linux-kernel,
	linux-arch, akpm

Pawel Dziepak wrote:
> On 7/10/07, Segher Boessenkool <segher@kernel.crashing.org> wrote:
>> > The alternative, of course, is to compile to an .s file and insert
>> > .code16gcc into the .s file.  This makes the Makefile uglier, but
>> > would
>> > be more resilient against oddball gcc changes.
>>
>> This would be even more fragile.  The exact format of GCC's
>> assembler code output isn't defined at all, so in principle
>> this is a hopeless task.  In practice just putting the
>> .code16gcc directive on the first line would likely work
>> though, GCC never generates a .code32 AFAIK, but it isn't
>> guaranteed that this will work (or will keep working).
> 
> Unfortunately, .code16gcc is still experimental (at least binutils'
> website says that). What is worse, it says that it is possible that
> 16bit code produced on GCC won't work on pre-80386 processors (before
> switching to protected mode you have to think about cpu as a
> pre-80386).

What .code16gcc does is produce 32-bit instructions that are meant to be
run from a 16-bit code segment (real mode or 16-bit protected) by using
address and data size override prefixes.  This means that pre-386
processors cannot run the code because they cannot understand 32-bit
instructions.

--
				Brian Gerst

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 13/33] Header file to produce 16-bit code with gcc
  2007-07-10 21:43               ` Adrian Bunk
  2007-07-10 21:46                 ` H. Peter Anvin
@ 2007-07-11  0:30                 ` Brian Gerst
  1 sibling, 0 replies; 69+ messages in thread
From: Brian Gerst @ 2007-07-11  0:30 UTC (permalink / raw)
  To: Adrian Bunk
  Cc: H. Peter Anvin, Segher Boessenkool, Andi Kleen, linux-kernel,
	linux-arch, akpm

Adrian Bunk wrote:
> On Tue, Jul 10, 2007 at 01:42:48PM -0700, H. Peter Anvin wrote:
>> Segher Boessenkool wrote:
>>> Well at least with -fno-toplevel-reorder it is guaranteed
>>> to work (not the same thing as "is working", heh, but fairly
>>> close).
>>>
>>> It seems to me GCC should grow an option to insert .code16gcc
>>> by itself (-m16 perhaps?)  Or GAS could get a flag to include
>>> a file as a prelude before the main thing.  Neither will help
>>> Linux right now of course.
>> -m16 is the right thing, and it also provides a proper hook for 
>> eventually having a real 16-bit backend (there are at least two 
>> projects for doing that.)
>>
>> For now, I have:
> 
> Can't you use the global CFLAGS and append your specific ones?
> 
>> CFLAGS          := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
> 
> -g ???
> 
>>                    $(cflags-$(ARCH)) \
>>                    -Wall -Wstrict-prototypes \
>>                    -march=i386 -mregparm=3 \
> 
> Why -march=i386 ?

To prevent gcc from using instructions (particularly cmovxx) that not
all processors will understand.

--
				Brian Gerst

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [x86 setup 16/33] String-handling functions for the new x86 setup code.
  2007-07-10 21:14               ` Segher Boessenkool
@ 2007-07-11 12:46                 ` Andi Kleen
  0 siblings, 0 replies; 69+ messages in thread
From: Andi Kleen @ 2007-07-11 12:46 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: H. Peter Anvin, Jan Engelhardt, linux-kernel, linux-arch, andi,
	akpm

> Yes, Linux should definitely be compiled with -ffreestanding,
> it isn't a hosted application after all ;-)

We tried it some time ago and it caused problems so it was dropped
again

-Andi

^ permalink raw reply	[flat|nested] 69+ messages in thread

end of thread, other threads:[~2007-07-11 12:46 UTC | newest]

Thread overview: 69+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-10  2:51 x86 setup code rewrite in C H. Peter Anvin
     [not found] ` <2034f71d414def30de582fb59573295cadbdabb4.1184032748.git.hpa@zytor.com>
2007-07-10  2:51   ` [x86 setup 01/33] x86 setup: MAINTAINERS: formally take responsibility for the i386 boot code H. Peter Anvin
     [not found]   ` <de4df4ebeb6ec1bf47d4adf19f6a388035e2bfec.1184032748.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 02/33] hd.c: remove BIOS/CMOS queries H. Peter Anvin
     [not found]   ` <38825725eb2e4aac1dd8e312460c5c239466b39a.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 03/33] include/asm-i386/boot.h: This is <asm/boot.h>, not <linux/boot.h> H. Peter Anvin
     [not found]   ` <62f9b07039d6bef798882977f3c8986fc2d2c6c6.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 04/33] Unify the CPU features vectors between i386 and x86-64 H. Peter Anvin
     [not found]   ` <8376b111bbf6bf6c8c884fabcb9c1844950737b0.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 05/33] Change CONFIG_X86_MINIMUM_CPU_MODEL to CONFIG_X86_MINIMUM_CPU_FAMILY H. Peter Anvin
     [not found]   ` <06a26dd135e1fc3b7f8b238c5b1bc8404d23acac.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 06/33] Clean up struct screen_info (<linux/screen_info.h>) H. Peter Anvin
     [not found]   ` <32e7eb05f31e6fbff33ecce6580ee4f7bdf38fef.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 07/33] Use a new CPU feature word to cover all Intel features that are spread around H. Peter Anvin
     [not found]   ` <a8e9d4bffc9fa216d32c930606475fd8d1df9405.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 08/33] Define zero-page offset 0x1e4 as a scratch field, and use it H. Peter Anvin
     [not found]   ` <0ff939788c542b0560ec39668550557dcc134afe.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 10/33] Make struct boot_params a real structure, and remove obsolete fields H. Peter Anvin
     [not found]   ` <bbeadd1995da049cf6880ab58794f84ec8785a08.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 11/33] x86-64: add CONFIG_PHYSICAL_ALIGN for consistency with i386 H. Peter Anvin
     [not found]   ` <e3ff2ad47d4610cdafbe24dcabadef42bb3166fb.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 12/33] x86-64: add symbolic constants for the boot segment selectors H. Peter Anvin
     [not found]   ` <96024b4c88d58a8473deb48a8038f6893b8b6b55.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 13/33] Header file to produce 16-bit code with gcc H. Peter Anvin
2007-07-10 14:16       ` Segher Boessenkool
2007-07-10 15:21         ` Andi Kleen
2007-07-10 15:48           ` H. Peter Anvin
2007-07-10 15:53             ` H. Peter Anvin
2007-07-10 20:08             ` Segher Boessenkool
2007-07-10 20:43               ` H. Peter Anvin
2007-07-10 21:08                 ` Pawel Dziepak
2007-07-10 21:20                   ` H. Peter Anvin
2007-07-11  0:26                   ` Brian Gerst
2007-07-10 19:57           ` Segher Boessenkool
2007-07-10 20:42             ` H. Peter Anvin
2007-07-10 21:10               ` Segher Boessenkool
2007-07-10 21:40                 ` H. Peter Anvin
2007-07-10 22:06                   ` Segher Boessenkool
2007-07-10 21:43               ` Adrian Bunk
2007-07-10 21:46                 ` H. Peter Anvin
2007-07-11  0:30                 ` Brian Gerst
     [not found]   ` <a862328acf06a9587458c615848099f96fbab1ce.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 14/33] Top header file for new x86 setup code H. Peter Anvin
     [not found]   ` <899e4acb1fe3e4313dfdca5398431274808d71ef.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 15/33] Simple bitops for the " H. Peter Anvin
     [not found]   ` <d5bd30fc697149284a73e09efe54884ab178de7e.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 16/33] String-handling functions " H. Peter Anvin
2007-07-10 18:25       ` Jan Engelhardt
2007-07-10 18:35         ` H. Peter Anvin
2007-07-10 20:10           ` Segher Boessenkool
2007-07-10 20:44             ` H. Peter Anvin
2007-07-10 21:14               ` Segher Boessenkool
2007-07-11 12:46                 ` Andi Kleen
     [not found]   ` <17db5b2c8a43cf36b2eb36afc142ce9ca0552282.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 17/33] A20 handling code H. Peter Anvin
2007-07-10 18:27       ` Jan Engelhardt
2007-07-10 18:33         ` H. Peter Anvin
2007-07-10 18:36         ` H. Peter Anvin
     [not found]   ` <c488ae7cd0ddd799b666f55652248be3c346a076.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 18/33] APM probing code H. Peter Anvin
     [not found]   ` <3726c75f36dc97c1fce93835e872bbc814857990.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 19/33] Command-line parsing code for the new x86 setup code H. Peter Anvin
     [not found]   ` <bf3e29f3d8c12230b38cae29ef5b476267d40cd1.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 20/33] Console-writing " H. Peter Anvin
2007-07-10 18:35       ` Jan Engelhardt
2007-07-10 18:48         ` H. Peter Anvin
     [not found]   ` <b4eed00df1889f94e8799ca6c0ce081bc5140688.1184032749.git.hpa@zytor.com>
2007-07-10  2:52     ` [x86 setup 21/33] Version string " H. Peter Anvin
     [not found]   ` <f1626ee0c265de9c41725f61eaee8a9017d8c8ff.1184032749.git.hpa@zytor.com>
2007-07-10  2:52     ` [x86 setup 22/33] CPU features verification " H. Peter Anvin
2007-07-10  7:37       ` Sébastien Dugué
     [not found]   ` <b577403d806edfbb1c17ecfec94971fc757a066c.1184032749.git.hpa@zytor.com>
2007-07-10  2:52     ` [x86 setup 23/33] EDD probing code " H. Peter Anvin
     [not found]   ` <77f7b2e92bb1de0f9d423b6537b8156296bcf931.1184032749.git.hpa@zytor.com>
2007-07-10  2:52     ` [x86 setup 24/33] MCA support for " H. Peter Anvin
     [not found]   ` <75642968817648a7816a4782f76138e4f608f1ab.1184032749.git.hpa@zytor.com>
2007-07-10  2:52     ` [x86 setup 25/33] Memory probing support for the " H. Peter Anvin
     [not found]   ` <dd2fade47882935c137f6d2a3c955eac1f6f8ecf.1184032749.git.hpa@zytor.com>
2007-07-10  2:52     ` [x86 setup 26/33] Voyager " H. Peter Anvin
     [not found]   ` <f8afa57a4934b75080449e8dd3a23d178be77a41.1184032749.git.hpa@zytor.com>
2007-07-10  2:52     ` [x86 setup 27/33] Video mode probing " H. Peter Anvin
     [not found]   ` <ae628cbaed0874c2c552ddbd77d61340438f9820.1184032749.git.hpa@zytor.com>
2007-07-10  2:52     ` [x86 setup 28/33] Code for actual protected-mode entry H. Peter Anvin
     [not found]   ` <26d4ebeefed3e0b1593d4fa2357db6912ee944cb.1184032749.git.hpa@zytor.com>
2007-07-10  2:52     ` [x86 setup 29/33] Assembly header and main routine for new x86 setup code H. Peter Anvin
     [not found]   ` <fd5cf379a91de82890893de655876e39e78c1dc9.1184032749.git.hpa@zytor.com>
2007-07-10  2:52     ` [x86 setup 30/33] Linker script for the " H. Peter Anvin
     [not found]   ` <842bbe280e87886e7a1b187434841c7f7334244c.1184032749.git.hpa@zytor.com>
2007-07-10  2:52     ` [x86 setup 31/33] Use the new x86 setup code for i386 H. Peter Anvin
2007-07-10  7:55       ` Tilman Schmidt
     [not found]   ` <0daaab19675363b0c9126a9b98a8325883bbcfea.1184032749.git.hpa@zytor.com>
2007-07-10  2:52     ` [x86 setup 32/33] Use the new x86 setup code for x86-64; unify with i386 H. Peter Anvin
     [not found]   ` <51664bcb2a5a2f1fe130229d34128a642dc81a4c.1184032749.git.hpa@zytor.com>
2007-07-10  2:52     ` [x86 setup 33/33] Remove old i386 setup code H. Peter Anvin
     [not found]   ` <361d0a8b7b7ea9d41d0c25664b3e2b30fd99e329.1184032749.git.hpa@zytor.com>
2007-07-10  2:51     ` [x86 setup 09/33] Make definitions for struct e820entry and struct e820map consistent H. Peter Anvin
2007-07-10 11:48     ` Andi Kleen
2007-07-10  4:24 ` x86 setup code rewrite in C Yinghai Lu
2007-07-10  4:39   ` H. Peter Anvin
2007-07-10  5:25 ` Jeff Garzik
2007-07-10 16:24 ` Jeremy Fitzhardinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).