d73691fb35cc7c944e6fde61de930830506eac8e
[openwrt.git] / target / linux / generic-2.6 / patches-2.6.22 / 014-x86_newsetup.patch
1 GIT 1783e2f0f21444020e3dee1be46b1e34af0ea3e7 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/hpa/linux-2.6-newsetup.git
2
3 commit 1783e2f0f21444020e3dee1be46b1e34af0ea3e7
4 Author: Venki Pallipadi <venkatesh.pallipadi@intel.com>
5 Date:   Wed Jun 20 14:12:39 2007 -0700
6
7     Use a new CPU feature word to cover all Intel features that are spread around
8     
9     in different CPUID leafs like 0x5, 0x6 and 0xA. Make this
10     feature detection code common across i386 and x86_64.
11     
12     Display Intel Dynamic Acceleration feature in /proc/cpuinfo. This feature
13     will be enabled automatically by current acpi-cpufreq driver.
14     
15     Refer to Intel Software Developer's Manual for more details about the feature.
16     
17     Thanks to hpa (H Peter Anvin) for the making the actual code detecting the
18     scattered features data-driven.
19     
20     Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
21     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
22
23 commit cd19eb67cd6636a4e5c9df99631422c7c7286f59
24 Author: H. Peter Anvin <hpa@zytor.com>
25 Date:   Wed Jun 20 14:33:17 2007 -0700
26
27     x86 setup: move __bss_start into the .bss segment
28     
29     Move __bss_start into the .bss segment, and create __bss_end.
30     
31     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
32
33 commit 100327ad6b609cd28970219be57d293847d1261d
34 Author: H. Peter Anvin <hpa@zytor.com>
35 Date:   Wed Jun 6 22:07:01 2007 -0700
36
37     x86 setup: remove TSC as a required feature
38     
39     Remove TSC as a required feature, in anticipation of CONFIG_X86_TSC
40     removal.
41     
42     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
43
44 commit 7c91a172b8af7d4ba087f1f88ed5b155ed459ca3
45 Author: Antonino A. Daplas <adaplas@gmail.com>
46 Date:   Tue Jun 5 19:21:05 2007 +0800
47
48     i386: Set 6-bit DAC channel properties in vesa video setup
49     
50     If the video BIOS is not capable of switching or failed to switch the
51     hardware to 8-bit DAC, the channel properties are not set.  This leads
52     to a blank (all black) display with vesafb at 8 bpp. Fix by defaulting
53     to a 6-bit DAC.
54     
55     Signed-off-by: Antonino Daplas <adaplas@gmail.com>
56     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
57
58 commit 6eac2d442de8d87eac94a4ca8600bd87219fa06b
59 Author: H. Peter Anvin <hpa@zytor.com>
60 Date:   Tue Jun 5 16:19:36 2007 -0700
61
62     x86 setup: arch/i386/boot/cpucheck.c whitespace cleanup
63     
64     Remove stealth whitespace
65     
66     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
67
68 commit f7d89f05a30433034a1b4651143afdbb2a8a9c92
69 Author: H. Peter Anvin <hpa@zytor.com>
70 Date:   Thu May 24 16:56:44 2007 -0700
71
72     hd.c: remove BIOS/CMOS queries
73     
74     An ST-506 disk these days is pretty much someone trying to pull ancient
75     data using an auxilliary controller.  Pulling data from the BIOS or CMOS
76     is just plain wrong, since it's likely to be the primary OS disk... and
77     would be user-entered data anyway.  Instead, require the user enters it
78     on the command line.
79     
80     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
81
82 commit 14c2fdb3bbfd6a9a774980e446c2443150749891
83 Author: H. Peter Anvin <hpa@zytor.com>
84 Date:   Thu May 24 15:25:10 2007 -0700
85
86     x86: add back pbe bit to visible CPUID flags
87     
88     Add pbe back to the visible CPUID flags.  We *do* correctly filter abuses
89     of this bit for 3DNow! in all the appropriate paths.
90     
91     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
92
93 commit e071b068a3b9f318be314f0378e655e2eb50ac89
94 Author: H. Peter Anvin <hpa@zytor.com>
95 Date:   Wed May 23 14:52:34 2007 -0700
96
97     x86 setup: VIA feature mask MSR doesn't just apply to model <= 9
98     
99     The VIA feature mask MSR is known to be present on model 10, and it
100     seems likely it will continue to be supported.  Since we only touch the
101     MSR if we're about to print an error message anyway, go ahead and be
102     aggressive.
103     
104     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
105
106 commit abe0c5aa1827932cda9c754a3842ec22b278d704
107 Author: H. Peter Anvin <hpa@zytor.com>
108 Date:   Tue May 22 17:17:41 2007 -0700
109
110     x86 setup: correct inline assembly constraints in edd.c
111     
112     Fix the inline assembly constraints in edd.c.  In particular, "driveno"
113     was getting clobbered on some (buggy?) BIOSes.
114     
115     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
116
117 commit c2e5887ad275aab90673a3e33344f09946159cf7
118 Author: H. Peter Anvin <hpa@zytor.com>
119 Date:   Fri May 18 10:02:55 2007 -0700
120
121     x86 setup: force the assembler to generate a 2-byte jump in header
122     
123     The jump instruction in the header only has two bytes available, so
124     it *better* be a 2-byte jump!  Unfortunately, the assembler will
125     always generate a 3/5-byte jump when the target is in a different
126     section.  Deal with that by generating the jump instruction
127     explicitly from .byte's, just like we do elsewhere when we need a
128     specific binary representation of a certain instruction.
129     
130     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
131
132 commit ce82e3b93eba48b6852822a03efa73c74e165d4f
133 Author: H. Peter Anvin <hpa@zytor.com>
134 Date:   Thu May 17 15:44:48 2007 -0700
135
136     x86 setup: move the symbol start_of_setup into the proper section.
137     
138     start_of_setup is the beginning of the executable code and should be
139     located in the appropriate section.
140     
141     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
142
143 commit e5f3a529457a5bfaf8f8783fb86013221279a81c
144 Author: H. Peter Anvin <hpa@zytor.com>
145 Date:   Thu May 17 15:43:19 2007 -0700
146
147     x86 setup: add an ASSERT that the header ends up in the right place
148     
149     Just in case we have funnies involving the linker or people putting
150     inappropriate align statements, make the linker abort if the setup
151     header ends up in the wrong place.
152     
153     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
154
155 commit d9dbde725687ab99d1f529f49f14d1e280cc5cac
156 Author: Alexander van Heukelum <heukelum@mailshack.com>
157 Date:   Thu May 17 20:54:25 2007 +0200
158
159     x86 new setup: use appropriate sections for code and data
160     
161     An intermediate elf file is generated for the 16-bit setup code.
162     The generated code can be viewed using objdump -m i8086 -d. As it
163     stands, it also tries to disassemble the bugger_off_msg, which
164     results in garbage. This introduces two new sections to separate
165     the code and the data part of the bootsector stub. It also moves
166     some code from the .header section (a data section) to .inittext.
167     
168     Signed-off-by: Alexander van Heukelum <heukelum@mailshack.com>
169
170 commit 0d7558a81cf61e9fd2332a54897c5fd18df0d7f2
171 Author: H. Peter Anvin <hpa@zytor.com>
172 Date:   Wed May 16 22:03:16 2007 -0700
173
174     x86 setup: use -include code16gcc.h instead of explicit #include
175     
176     Use -include in the Makefile instead of #include to include code16gcc.h.
177     This really is more of a compiler switch than anything else, and is a lot
178     cleaner to do implicitly.
179     
180     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
181
182 commit 017ce54e8a4a9628a76d6b510c7309a7e4e111a8
183 Author: H. Peter Anvin <hpa@zytor.com>
184 Date:   Wed May 16 18:48:06 2007 -0700
185
186     x86 setup: enable features on Centaur (VIA) and Transmeta processors
187     
188     AMD are not the only ones who sometimes mask features which the kernel
189     may very well depend on.  VIA and Transmeta do, too.  Add code to enable
190     these features during checking.
191     
192     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
193
194 commit b794f5f9c5089709f3df38c6d91869fa38a9c1a4
195 Author: H. Peter Anvin <hpa@zytor.com>
196 Date:   Wed May 16 16:37:47 2007 -0700
197
198     x86 setup: in older versions of ld, ASSERT() is an expression
199     
200     Older versions of ld (pre-2.15 or so) need:
201     
202         . = ASSERT(foo, "msg");
203     
204     instead of:
205     
206         ASSERT(foo, "msg")
207     
208     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
209
210 commit 21c2b7c99c417d07015ee8e516a634ec3d98c4ee
211 Author: H. Peter Anvin <hpa@zytor.com>
212 Date:   Wed May 16 10:52:41 2007 -0700
213
214     x86 setup: print a warning message if the bootloader gave us no heap.
215     
216     If the bootloader is so old it doesn't set the CAN_USE_HEAP flag,
217     a lot of functionality will by necessity be disabled, so print a
218     warning message.  This means either a 2.00 protocol bootloader or
219     a buggy bootloader; the Qemu bootloader falls in this category.
220     
221     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
222
223 commit 52ca0431390d389a2a2246f02fe652ea84c1ddd8
224 Author: H. Peter Anvin <hpa@zytor.com>
225 Date:   Wed May 16 10:51:03 2007 -0700
226
227     x86 setup: rely on a compiled-in default for load high/load low
228     
229     When deciding if we should move the kernel from 0x10000 to 0x1000, as
230     is required for a zImage kernel, rely on a compiled-in default since
231     Qemu unconditionally zeroes the loadflags.  This, of course, is a bug
232     in Qemu, but still...
233     
234     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
235
236 commit 4db77a97793104a32e5fb83e62b943fa144b329d
237 Author: H. Peter Anvin <hpa@zytor.com>
238 Date:   Wed May 16 08:45:37 2007 -0700
239
240     x86 setup: correct assembly constraints.
241     
242     Double use of "d" in an asm() constraints; most gcc versions correctly
243     detect and avoid using it, but some version of gcc runs itself into
244     a brick wall instead.  Fix the one "d" which should have been "a".
245     
246     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
247
248 commit 4fbccbc1457d6710d3a9ce55ad70ec6cb0b75fc5
249 Author: H. Peter Anvin <hpa@zytor.com>
250 Date:   Tue May 15 09:16:29 2007 -0700
251
252     x86 setup: include <asm/msr-index.h> not <asm/msr.h>
253     
254     <asm/msr.h> brings in the accessor functions, which may potentially
255     bring in all other kinds of kernel headers which are inappropriate for
256     the setup code.  For the setup code, include <asm/msr-index.h>
257     instead, which only includes the numeric constants.
258     
259     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
260
261 commit 839cafa9c0020e7506722dd2a4fd82a71c2939cc
262 Author: H. Peter Anvin <hpa@zytor.com>
263 Date:   Mon May 14 15:49:01 2007 -0700
264
265     x86 setup: protocol 2.0[01]: base for CL_OFFSET depends on setup_move_size
266     
267     Handle the use of boot protocol 2.00 and 2.01: the base segment for
268     CL_OFFSET depends on the value of setup_move_size.
269     
270     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
271
272 commit d60357ad68a694b03e9b952eadba5ac277c31df0
273 Author: H. Peter Anvin <hpa@zytor.com>
274 Date:   Sat May 12 12:18:53 2007 -0700
275
276     x86 setup: remove unused variable
277     
278     Remove unused variable
279     
280     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
281
282 commit e21a2030b01081612259847321bcce13eae1e883
283 Author: Sam Ravnborg <sam@ravnborg.org>
284 Date:   Sat May 12 12:17:30 2007 -0700
285
286     x86 setup: share i386 Makefile with x86_64
287     
288     The boot Makefile for i386 and x86_64 are equal
289     except for the CFLAGS setting.
290     Teach x86_64 to use the Makefile from i386 and
291     make CFLAGS setting arch dependent in i386 Makefile.
292     
293     Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
294     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
295
296 commit 8618d92339d0d106045f98f34833d863c3235cdb
297 Author: H. Peter Anvin <hpa@zytor.com>
298 Date:   Sat May 12 00:32:12 2007 -0700
299
300     x86 setup: video-bios.c missed the pointer to the set_mode method!
301     
302     We need the actual pointer to the set_mode method (oops!)
303     
304     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
305
306 commit 85dfc374ea9aad33b9e0315f07a4b2722dc11e3e
307 Author: H. Peter Anvin <hpa@zytor.com>
308 Date:   Sat May 12 00:14:43 2007 -0700
309
310     x86 setup: when setting unknown BIOS modes and failing, try to revert
311     
312     If we set an unknown BIOS mode and fail, then explicitly try to revert
313     to the original mode.
314     
315     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
316
317 commit f4f7949f126d2f152b09fa9367b1ec693f2ea818
318 Author: H. Peter Anvin <hpa@zytor.com>
319 Date:   Fri May 11 11:20:59 2007 -0700
320
321     x86 setup: fix typo "video_bios" should be "video-bios"
322     
323     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
324
325 commit 51ba7113ea5b07189b7f8a0534d400a072535197
326 Author: H. Peter Anvin <hpa@zytor.com>
327 Date:   Fri May 11 11:09:55 2007 -0700
328
329     x86 setup: allow setting VESA modes "blind"
330     
331     Apparently, people really do set VESA modes "blind".  As a result, make
332     the framework for settting blind modes more general, to remove some
333     special cases.
334     
335     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
336
337 commit 1b8f73d9b2bf7630a2914ddab606db16fddb509e
338 Author: H. Peter Anvin <hpa@zytor.com>
339 Date:   Thu May 10 22:08:45 2007 -0700
340
341     x86_64: CONFIG_PHYSICAL_ALIGN should be 2 MB
342     
343     It's not actually used yet, but set CONFIG_PHYSICAL_ALIGN to 2 MB
344     as it should be, to prevent conflicts with other works in progress.
345     
346     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
347
348 commit b81f3c88923e4470cd0942d4596fafc0fb1cf4fd
349 Author: H. Peter Anvin <hpa@zytor.com>
350 Date:   Thu May 10 19:11:32 2007 -0700
351
352     x86 setup: remove debugging statements
353     
354     Remove debugging statements in video.c that were not meant for
355     production.
356     
357     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
358
359 commit be58b6d7e9c14e482bce495e8343955999dea77f
360 Author: H. Peter Anvin <hpa@zytor.com>
361 Date:   Thu May 10 18:49:40 2007 -0700
362
363     x86 setup: only restore the screen image when needed
364     
365     Only restore the screen image when needed.  This is how the original
366     code behaves, so it's presumably the desired behaviour.
367     
368     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
369
370 commit 22f6bd8cc23b512af28e34ae7d40036982a0ac63
371 Author: H. Peter Anvin <hpa@zytor.com>
372 Date:   Thu May 10 18:44:08 2007 -0700
373
374     x86 setup: correct the definition of the GDT limit
375     
376     Like all other x86 segment limits, the GDT limit points to the last byte
377     that is *permitted* to access, so it needs to be sizeof(boot_gdt)-1.
378     
379     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
380
381 commit 7f73f1f4aa4c97745bffe07a3ebcf226a4965b00
382 Author: H. Peter Anvin <hpa@zytor.com>
383 Date:   Thu May 10 15:47:48 2007 -0700
384
385     x86 setup: Re-implement scanning for hidden video modes
386     
387     Re-implement scanning for hidden video modes.  Every now and then,
388     apparently, you can find them hidden like easter eggs.
389     
390     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
391
392 commit 6770176714bc12ec92372311ac02c14f0d22776e
393 Author: H. Peter Anvin <hpa@zytor.com>
394 Date:   Thu May 10 15:24:27 2007 -0700
395
396     x86 setup: whitespace cleanup
397     
398     Clean up stealth whitespace.
399     
400     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
401
402 commit ba0480a3537cf471b08bdb99dae6d0780cfb1972
403 Author: H. Peter Anvin <hpa@zytor.com>
404 Date:   Wed May 9 16:54:42 2007 -0700
405
406     x86: sync the CPU feature string arrays
407     
408     With <asm/cpufeature.h> unified, synchronize the CPU feature string
409     arrays.  The whole kernel/cpu directory really needs to be unified.
410     
411     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
412
413 commit ecb53b84efddbad3d9aa49e95598550831324348
414 Author: H. Peter Anvin <hpa@zytor.com>
415 Date:   Tue May 8 22:06:04 2007 -0700
416
417     x86 setup: need to set orig_video_isVGA
418     
419     After detecting a VGA console, we need to set
420     boot_params.screen_info.orig_video_isVGA.
421     
422     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
423
424 commit dc97fc053faff17b984ec962686caea52bd27628
425 Author: H. Peter Anvin <hpa@zytor.com>
426 Date:   Tue May 8 20:51:17 2007 -0700
427
428     x86 setup: boot sector should use ljmp, not jmpl
429     
430     We have an "jmpl" instruction in the boot sector, which was meant
431     to be an "ljmp" instruction.  It worked anyway because gas interpreted
432     a two-argument "jmpl" as an "ljmpl" instruction, however, use plain
433     "ljmp" (i.e. "ljmpw".)
434     
435     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
436
437 commit 7907f05e9692557c53c9ac13647db5e5343c7c76
438 Author: H. Peter Anvin <hpa@zytor.com>
439 Date:   Tue May 8 20:27:10 2007 -0700
440
441     x86 setup: only make VESA graphics modes selectable if CONFIG_FB
442     
443     If we select a VESA graphics mode, we better have framebuffer support
444     or the user will have no console.  Therefore, make these modes
445     non-selectable if CONFIG_FB is not set.
446     
447     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
448
449 commit 8e509f9ebc44f45544d231454e84f10bf78d5772
450 Author: H. Peter Anvin <hpa@zytor.com>
451 Date:   Tue May 8 20:24:11 2007 -0700
452
453     x86 setup: need to probe VESA EDID block 0 only
454     
455     The VESA EDID BIOS call takes the EDID block number in %dx, and may
456     corrupt it by spec.  Pass it in properly.
457     
458     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
459
460 commit 9912b9aed7943773d1fadaa2e2e52f42af395048
461 Author: H. Peter Anvin <hpa@zytor.com>
462 Date:   Mon May 7 18:22:04 2007 -0700
463
464     x86 setup: add missing file "bitops.h" missing from previous checkins
465     
466     The file "bitops.h" was missing from previous checkins.
467     
468     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
469
470 commit 732eb3fac2d772980e6555b8c69902c8107c72aa
471 Author: H. Peter Anvin <hpa@zytor.com>
472 Date:   Mon May 7 14:59:43 2007 -0700
473
474     x86 setup: add -fno-stack-protector; other Makefile fixes
475     
476     Add -fno-stack-protector for the gcc's that need that;
477     Use -ffreestanding consistently;
478     Use $(LINUXINCLUDE);
479     Handle linker scripts consistently with other Makefiles.
480     
481     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
482
483 commit 2d5e47f21202e156fe97aba0a88d158d5c157a33
484 Author: H. Peter Anvin <hpa@zytor.com>
485 Date:   Mon May 7 14:45:25 2007 -0700
486
487     x86 setup: swap cpu.c and cpucheck.c; rename functions
488     
489     Make cpucheck.c the reusable component; the generically-named cpu.c
490     gets to be the wrapper.  Accordingly, rename functions to make it
491     less confusing.
492     
493     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
494
495 commit bf2a428a4e7c1ee3ab9acb23cfafb45e818887a1
496 Author: H. Peter Anvin <hpa@zytor.com>
497 Date:   Mon May 7 14:09:38 2007 -0700
498
499     x86 setup: remove code moved from cpucheck.c -> cpu.c
500     
501     Move all info about requirements into cpu.c.
502     
503     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
504
505 commit 9ea8429fabe5df6aed6393ac3a00d0b64445ba6a
506 Author: H. Peter Anvin <hpa@zytor.com>
507 Date:   Mon May 7 09:42:51 2007 -0700
508
509     x86 setup: remove double nesting of a20_test()
510     
511     a20_test() was invoked as either a20_test() or a20_wait(), where the
512     latter was simply a loop around a loop.  Make the count a parameter
513     instead; this is clearer and saves a couple of bytes.
514     
515     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
516
517 commit 9edc55718f57195c664ee3175514d652f651cfd2
518 Author: H. Peter Anvin <hpa@zytor.com>
519 Date:   Mon May 7 09:30:41 2007 -0700
520
521     x86 setup: compile with -fomit-frame-pointer
522     
523     Compiling with -fomit-frame-pointer reduces the size by about 2%.
524     
525     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
526
527 commit e1003433f2d491bf17c79437cd75268da220dab5
528 Author: H. Peter Anvin <hpa@zytor.com>
529 Date:   Mon May 7 09:30:04 2007 -0700
530
531     x86 setup: be more paranoid about the stack setup in header.S
532     
533     In particular, deal correctly with the stack pointer being zero on entry.
534     While we're at it, align the stack.
535     
536     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
537
538 commit 853499c3dc3fcbeb192a613ac241d150ebc7c5a0
539 Author: H. Peter Anvin <hpa@zytor.com>
540 Date:   Sun May 6 23:25:10 2007 -0700
541
542     x86 setup: Factor out the environment-independent part of the CPU check.
543     
544     Factor out the environment-independent part of the CPU check so it can
545     be invoked from other parts of the kernel as well.
546     
547     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
548
549 commit f235a61f6d6dff57883efad351d746540bcb8caf
550 Author: H. Peter Anvin <hpa@zytor.com>
551 Date:   Sat May 5 22:16:54 2007 -0700
552
553     x86 setup: when watching the setup size, take the stack into account
554     
555     When watching the setup size, we have to take the stack into account.
556     In particular, the stack is used not only by the setup code itself, but
557     by BIOS interrupt handlers and system calls.  Reserve a minimum of
558     512 bytes.
559     
560     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
561
562 commit 0d0e10091be48f7e4c8888e9d5c2836c704994f5
563 Author: H. Peter Anvin <hpa@zytor.com>
564 Date:   Sat May 5 19:25:51 2007 -0700
565
566     x86 setup: actually check the end of the heap.
567     
568     Keep track of where the heap ends and actually watch out for it.
569     
570     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
571
572 commit 47aab0b8f4d012fad3c42b5b0754d3cb87961b37
573 Author: H. Peter Anvin <hpa@zytor.com>
574 Date:   Sat May 5 15:47:58 2007 -0700
575
576     x86 setup: coppyright rPath, Inc.
577     
578     This work was done on the dime of rPath, Inc.; they own the copyright.
579     
580     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
581
582 commit d22571534d7eabf9408f29d9da423e1c6e04445f
583 Author: H. Peter Anvin <hpa@zytor.com>
584 Date:   Sat May 5 15:21:11 2007 -0700
585
586     x86 setup: implement screen contents save/restore
587     
588     The old setup code had screen contents save and restore, so implement
589     it for the new one as well.
590     
591     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
592
593 commit e5145601a752bd998e783d159c187d3017d45d6d
594 Author: H. Peter Anvin <hpa@zytor.com>
595 Date:   Sat May 5 15:20:19 2007 -0700
596
597     x86 setup: whitespace cleanup
598     
599     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
600
601 commit 045ecb52f91a74eecad93ffc8791eefe59cf7fd1
602 Author: H. Peter Anvin <hpa@zytor.com>
603 Date:   Sat May 5 14:22:39 2007 -0700
604
605     x86 setup: allow setting of VESA graphics modes; cleanups
606     
607     - Allow setting of VESA graphics modes (used by vesafb)
608     - Clean up the macros related to the heap
609     - #if 0 copy functions that aren't actually currently being used
610     
611     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
612
613 commit 58c04ed7e2d7d5979e1917a74b49bdc0f3dde211
614 Author: H. Peter Anvin <hpa@zytor.com>
615 Date:   Sat May 5 12:06:14 2007 -0700
616
617     x86 setup: move all VESA-related code into video-vesa.c; add EDID
618     
619     - Move all VESA-related code into video-vesa.c
620     - Add VESA EDID query support
621     - Remove some totally obsolete definitions from video.h
622     
623     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
624
625 commit 07bc3931175fb98256140275c03194426d441b74
626 Author: H. Peter Anvin <hpa@zytor.com>
627 Date:   Sat May 5 12:04:40 2007 -0700
628
629     x86-64: remove -traditional from AFLAGS
630     
631     In arch/x86_64/boot/compressed, remove -traditional from AFLAGS.
632     
633     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
634
635 commit a830f615eeef838d461cbf7bbbee8c1c84708ec8
636 Author: H. Peter Anvin <hpa@zytor.com>
637 Date:   Fri May 4 18:44:38 2007 -0700
638
639     x86 setup: share code between i386 and x86-64
640     
641     Share the boot (setup) code and tools between i386 and x86-64.
642     The compression code is now running in 64-bit mode in order to support
643     relocation, so do *not* share that code.
644     
645     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
646
647 commit 3e159a323bdfa5d5a7be2c1f6be089ca22d598e0
648 Author: H. Peter Anvin <hpa@zytor.com>
649 Date:   Fri May 4 18:43:35 2007 -0700
650
651     x86-64: use 0x1b4 as the scratch area in boot_params, not 0x3c
652     
653     Use 0x1b4 as the scratch area in boot_params rather than 0x3c.
654     
655     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
656
657 commit 4cf4424e7a0f29f251b781f9b5e3655b0645cb7f
658 Author: H. Peter Anvin <hpa@zytor.com>
659 Date:   Fri May 4 18:26:18 2007 -0700
660
661     Revert "x86-64: Make arch/x86-64/boot a symlink to arch/i386/boot"
662     
663     This reverts commit b2ad90f4969226fe8cf3edc5330711ed5fc20105.
664     
665     Restore arch/x86_64/boot as a separate directory hierarchy.
666     
667     Conflicts:
668
669 commit 8ed1ae1d2f94410811b7cca4b1a426e37652457f
670 Author: H. Peter Anvin <hpa@zytor.com>
671 Date:   Fri May 4 17:00:33 2007 -0700
672
673     x86-64: It appears MTRR isn't a required feature after all.
674     
675     MTRR was documented as a required feature, but appears to boot fine
676     without it (tested since Bochs doesn't have MTRR support.)
677     
678     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
679
680 commit 7c616d098579fb790662cdc703f2a0f26ea1668c
681 Author: H. Peter Anvin <hpa@zytor.com>
682 Date:   Fri May 4 16:22:57 2007 -0700
683
684     x86 setup: use 0x1e4 as scratch, instead of 0x3c
685     
686     The compressed relocation needs a 4-byte scratch area to obtain
687     its own address.
688     
689     0x3c is at the end of the video area, which is quite constrained -- it
690     only has 6 bytes left (12 if we recycle the obsolete fields which invade
691     this space.)  Define 0x1e4 as a scratch field, and use it.
692     
693     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
694
695 commit 5bc1019227e94576e4876d05ee920f59195bce90
696 Author: H. Peter Anvin <hpa@zytor.com>
697 Date:   Fri May 4 16:09:15 2007 -0700
698
699     x86 setup: boot_params.e820_map is just the map, not the count; adjust
700     
701     boot_params.e820_map is just a list of entries, whereas
702     "struct e820map" contains a count as well.  Thus, don't use
703     "struct e820map" to describe struct boot_params.
704     
705     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
706
707 commit 0f96b52497f444be2d52d1184ca90be49f713ea3
708 Author: H. Peter Anvin <hpa@zytor.com>
709 Date:   Fri May 4 15:49:03 2007 -0700
710
711     x86 setup: E820MAX is a definitional constant; no need to use sizeof hacks
712     
713     Now when we're using the standard headers for the setup code, we can use
714     E820MAX instead of playing sizeof games.
715     
716     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
717
718 commit 3a23a428b20cbb31fd7ff5516a053b99afc447f7
719 Author: H. Peter Anvin <hpa@zytor.com>
720 Date:   Fri May 4 12:08:46 2007 -0700
721
722     x86: move the bootparam structure definition into include/
723     
724     Move the bootparam structure definition into include/, and make other
725     things use it.  Haven't cleaned up all the macros yet, though.
726     
727     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
728
729 commit e93ec58911995971aa059990f8a91a02b05f6c8f
730 Author: H. Peter Anvin <hpa@zytor.com>
731 Date:   Fri May 4 12:07:50 2007 -0700
732
733     i386: change %lu to %u in arch/i386/kernel/e820.h
734     
735     It's an u32, print it with %u
736     
737     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
738
739 commit 2f47f004f614e2744867c0df274c55d8af2a42d5
740 Author: H. Peter Anvin <hpa@zytor.com>
741 Date:   Fri May 4 12:06:04 2007 -0700
742
743     x86: fix differences between i386 and x86-64 <asm/e820.h>
744     
745     Fix minor differences between i386 and x86-64 <asm/e820.h>
746     
747     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
748
749 commit 56ec52f14e948f430af941052adee98019a617b7
750 Author: H. Peter Anvin <hpa@zytor.com>
751 Date:   Fri May 4 11:45:17 2007 -0700
752
753     x86: fix the definition of struct screen_info
754     
755     Name the fields that aren't really struct screen_info, and declare
756     the structure packed (the "capabilities" field is misaligned.)
757     
758     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
759
760 commit 1d4429eaa564b0085d9ee3aa2de57e87a093a14e
761 Author: H. Peter Anvin <hpa@zytor.com>
762 Date:   Fri May 4 11:43:10 2007 -0700
763
764     x86-64: Make arch/x86-64/boot a symlink to arch/i386/boot
765     
766     Until such time that Kbuild allows for a cleaner solution, make
767     arch/x86-64/boot a symlink to arch/i386/boot.
768     
769     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
770
771 commit 6a85f1b5fd041ea99d8604782559ce0502a60cc0
772 Author: H. Peter Anvin <hpa@zytor.com>
773 Date:   Fri May 4 10:42:06 2007 -0700
774
775     x86-64: rearrange includes due to unifications and inclusion from setup
776     
777     Unification caused a circular dependency between <asm/alternative.h>
778     and <asm/cpufeature.h>; resolve this.
779     
780     Add #ifndef _SETUP in <asm/e820.h> so it can be included from the boot
781     code.
782     
783     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
784
785 commit f6bbdc254bdbd5f7cf7a40c4cd6f9844af90824a
786 Author: H. Peter Anvin <hpa@zytor.com>
787 Date:   Fri May 4 10:40:26 2007 -0700
788
789     x86: Complete <asm/cpufeature.h> with the union of i386 and x86-64
790     
791     Add a feature to <asm/cpufeature.h> which was previously present
792     in x86-64 but missing in i386.
793     
794     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
795
796 commit 1a0819281060489901732914f67869e0aa8f26fd
797 Author: H. Peter Anvin <hpa@zytor.com>
798 Date:   Fri May 4 10:39:32 2007 -0700
799
800     x86: unify <asm/boot.h>
801     
802     Unify <asm/boot.h> between i386 and x86-64
803     
804     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
805
806 commit 8d9c54585f4623e0310f970fb5c6eda7ec1614df
807 Author: H. Peter Anvin <hpa@zytor.com>
808 Date:   Fri May 4 10:38:35 2007 -0700
809
810     x86-64: verify_cpu.S: use new masks
811     
812     Use the <asm/required-features.h> masks.
813     
814     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
815
816 commit 6cf3308646bb7a3210f0f76bcb895b2dea76a93c
817 Author: H. Peter Anvin <hpa@zytor.com>
818 Date:   Fri May 4 10:37:26 2007 -0700
819
820     x86-64: fix compilation errors due to required-features.h change
821     
822     Fix compilation errors induced by required-features.h change.
823     
824     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
825
826 commit 1324201a93ce380b46a3128826ecbd794e617e59
827 Author: H. Peter Anvin <hpa@zytor.com>
828 Date:   Fri May 4 10:35:37 2007 -0700
829
830     x86-64: <asm/segment.h>: add boot segment descriptors
831     
832     Add boot segment descriptors to <asm/segment.h> to match i386.
833     
834     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
835
836 commit a0b15a9e79ed0310813709cd0690d6838917fe82
837 Author: H. Peter Anvin <hpa@zytor.com>
838 Date:   Fri May 4 10:34:37 2007 -0700
839
840     x86-64: add CONFIG_PHYSICAL_ALIGN to match i386
841     
842     Add CONFIG_PHYSICAL_ALIGN to match i386, even though we don't use it.
843     
844     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
845
846 commit 8f5d14d11a7318e257351ae477392c7f7e314602
847 Author: H. Peter Anvin <hpa@zytor.com>
848 Date:   Fri May 4 10:33:54 2007 -0700
849
850     x86 setup: cleanups for compatibility with x86-64
851     
852     These changes are necessary to compile on x86-64.
853     
854     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
855
856 commit a32f68b6d4023c1c6b1e62e8561189516c571ab9
857 Author: H. Peter Anvin <hpa@zytor.com>
858 Date:   Fri May 4 08:40:07 2007 -0700
859
860     x86 setup: add missing linker script
861     
862     Add linker script for the setup code, apparently missing from previous
863     checkins.
864     
865     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
866
867 commit 4f34ca8e926b2d0bf3a7502b99f8dfced8cdba9d
868 Author: H. Peter Anvin <hpa@zytor.com>
869 Date:   Thu May 3 17:42:29 2007 -0700
870
871     x86 setup: paranoia: clear the high half of %esp
872     
873     We're invoked in 16-bit mode from an unknown bootloader.  Make sure
874     we explicitly zero the upper half of %esp to avoid nasty surprises.
875     
876     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
877
878 commit 19eb9b73cc1632a923003a002108b242af7a6080
879 Author: H. Peter Anvin <hpa@zytor.com>
880 Date:   Thu May 3 17:35:41 2007 -0700
881
882     x86 setup: bootlin is *so* dead...
883     
884     Bootlin was never able to load bzImage kernels, so who cares about it.
885     
886     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
887
888 commit 3b9fb73c65151ee043bc74c333d9e3c9b1872125
889 Author: H. Peter Anvin <hpa@zytor.com>
890 Date:   Thu May 3 10:56:40 2007 -0700
891
892     x86 setup: apparently $(src) is insufficient, needs $(srctree)/$(src)
893     
894     For some unfanthomable reason the location of the source tree that
895     corresponds to the current directory has to be written as
896     $(srctree)/$(src) apparently.  There might be a good reason for it,
897     but shorthand would be appreciated, and $(src) really should be the
898     short form.
899     
900     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
901
902 commit a6d01d375a2269be1e3a6b31bcc4d426ad5a473d
903 Author: H. Peter Anvin <hpa@zytor.com>
904 Date:   Thu May 3 10:51:45 2007 -0700
905
906     x86 setup: remove reference to obsolete cpureq.c
907     
908     cpureq.c has been removed; remove it from the Makefile too.
909     
910     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
911
912 commit cbe5b7585d800435080bcbf1b1fd242926982674
913 Author: H. Peter Anvin <hpa@zytor.com>
914 Date:   Thu May 3 10:33:12 2007 -0700
915
916     x86 setup: use the required masks from <asm/required-features.h>
917     
918     Use the now-uniform features from <asm/required-features.h>.
919     
920     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
921
922 commit 99ed30180ecc1bb4e93f6edda5f6bad1adf3e630
923 Author: H. Peter Anvin <hpa@zytor.com>
924 Date:   Thu May 3 10:31:12 2007 -0700
925
926     x86: make the handling of required features consistent
927     
928     Make the handling of required features consistent between i386
929     and x86-64.
930     
931     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
932
933 commit 1120d70a2be8f2deb6bda64047da288d8f86dad3
934 Author: H. Peter Anvin <hpa@zytor.com>
935 Date:   Thu May 3 00:09:53 2007 -0700
936
937     x86: Kconfig.cpu: the minimum CPU model is always 3; WP_WORKS_OK = i486
938     
939     The minimum CPU model number is always 3 (i386), and if we have
940     WP_WORKS_OK it means we need an i486.
941     
942     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
943
944 commit ebc308c204149b86984ae2216f5b9b2e63932028
945 Author: H. Peter Anvin <hpa@zytor.com>
946 Date:   Thu May 3 00:08:48 2007 -0700
947
948     x86 setup: use CONFIG_X86_MINIMUM_CPU_MODEL
949     
950     Use CONFIG_X86_MINIMUM_CPU_MODEL as defined in Kconfig.cpu.
951     
952     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
953
954 commit 8b50b640e015bf5d0f65502437da6fcab46c391b
955 Author: H. Peter Anvin <hpa@zytor.com>
956 Date:   Wed May 2 23:45:42 2007 -0700
957
958     x86 setup: remove bogus "static"
959     
960     Remove invalid "static" declarations in cpu.c
961     
962     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
963
964 commit 35d23b60dfb110da81c24bcbfcda089cfc4fd264
965 Author: H. Peter Anvin <hpa@zytor.com>
966 Date:   Wed May 2 23:37:50 2007 -0700
967
968     x86 setup: cpu detection cleanups
969     
970     - Use <asm/processor-flags.h>
971     - Make sure %cr0 isn't in a dangerous configuration before probing the FPU
972     
973     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
974
975 commit a1150a03247b355d11a4bb696b8aae1f46612992
976 Author: H. Peter Anvin <hpa@zytor.com>
977 Date:   Wed May 2 23:36:55 2007 -0700
978
979     x86 setup: compile with -DSETUP
980     
981     Define SETUP to make it easier to share code with the rest of the kernel.
982     
983     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
984
985 commit 7eb52e8ad1bdf01886023d1a13b3313084cd7db6
986 Author: H. Peter Anvin <hpa@zytor.com>
987 Date:   Wed May 2 23:34:57 2007 -0700
988
989     x86 setup: remove unused verify_cpu.S
990     
991     verify_cpu.S is obsoleted by boot/cpu.c.
992     
993     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
994
995 commit e90317a027c30176968220d18eb18bd6a9d9cc74
996 Author: H. Peter Anvin <hpa@zytor.com>
997 Date:   Wed May 2 20:07:43 2007 -0700
998
999     x86 setup: files missing from previous checkin (cpu.c, cpureq.c)
1000     
1001     These files were missing from a previous checkin; CPU feature-checking
1002     code and the list of CPU features to check for.
1003     
1004     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1005
1006 commit 060f9b3db33c67b5344b2b4110bc823eb776e5cd
1007 Author: H. Peter Anvin <hpa@zytor.com>
1008 Date:   Wed May 2 19:51:34 2007 -0700
1009
1010     x86 setup: whitespace cleanup
1011     
1012     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1013
1014 commit 9f997a5569ec8fceaa15c2e9cf28e728e2ce118d
1015 Author: H. Peter Anvin <hpa@zytor.com>
1016 Date:   Wed May 2 19:07:14 2007 -0700
1017
1018     x86 setup: add CPU feature detect/abort on insufficient featurage
1019     
1020     The x86 setup is the right place to check features and abort if they
1021     are not present, since we can still get a message to the user via the
1022     firmware.
1023     
1024     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1025
1026 commit de4e976376fddec340651ef40b16a45f6189619d
1027 Author: H. Peter Anvin <hpa@zytor.com>
1028 Date:   Wed May 2 19:05:34 2007 -0700
1029
1030     x86 setup: whitespace cleanup
1031     
1032     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1033
1034 commit bcd2d2f8de5d4568b6628aa133fce1ac40ece526
1035 Author: H. Peter Anvin <hpa@zytor.com>
1036 Date:   Wed May 2 16:19:59 2007 -0700
1037
1038     x86 setup: tag functions noreturn; error message on A20 failure
1039     
1040     Tag appropriate functions noreturn.
1041     If the A20 gate fails, output an error message and refuse to boot.
1042     
1043     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1044
1045 commit 752aef90cbfc888084bf11fd83f8f72b6a668fc9
1046 Author: H. Peter Anvin <hpa@zytor.com>
1047 Date:   Wed May 2 15:45:08 2007 -0700
1048
1049     x86 setup: clobber registers in keyboard BIOS call
1050     
1051     Keyboard BIOS call to set repeat rate is known to clobber registers on
1052     "many" BIOSes.
1053     
1054     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1055
1056 commit dde94003e4759aab275732cf9f1834440cd381d0
1057 Author: H. Peter Anvin <hpa@zytor.com>
1058 Date:   Wed May 2 15:44:21 2007 -0700
1059
1060     x86 setup: implement APM BIOS probe
1061     
1062     APM BIOS probe ported from assembly
1063     
1064     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1065
1066 commit 9403917d79e3349184318704476fa080836bd52c
1067 Author: H. Peter Anvin <hpa@zytor.com>
1068 Date:   Wed May 2 15:17:14 2007 -0700
1069
1070     x86 setup: remove references to obsolete probes
1071     
1072     Remove "Hello, World!" as well as references to probes which are no
1073     longer used...
1074     
1075     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1076
1077 commit 712f65ffbd1d4b55b4c55d68b4dcd32406c28fb8
1078 Author: H. Peter Anvin <hpa@zytor.com>
1079 Date:   Wed May 2 12:17:15 2007 -0700
1080
1081     x86 setup: video.c: correct the handling of special mode numbers
1082     
1083     Special mode numbers with the high bit set need to be handled *before*
1084     masking out the high bit.
1085     
1086     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1087
1088 commit 9cf083204fe14cda3b09840eba8d131d2e48ccdf
1089 Author: H. Peter Anvin <hpa@zytor.com>
1090 Date:   Wed May 2 11:44:16 2007 -0700
1091
1092     x86 setup: Modern ATI cards pass the probe but lacks the modes.
1093     
1094     It appears modern ATI cards pass the probe for ATI-ness but lack the
1095     modes.  Kill off the driver as being incorrect.
1096     
1097     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1098
1099 commit 890cbe950589e30af17eac9da800efc76e35e01d
1100 Author: H. Peter Anvin <hpa@zytor.com>
1101 Date:   Wed May 2 11:32:21 2007 -0700
1102
1103     x86 setup: a20.c: make empty_8042() return status
1104     
1105     Make functions which could reasonably return status do so.  It may
1106     be relevant in the future, and it's a lot better if the programmer
1107     doesn't have to figure out where everything should hook in.
1108     
1109     Just on principle.
1110     
1111     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1112
1113 commit 08a44dc655e0086d23fc3c70cb93eb51eaeec259
1114 Author: H. Peter Anvin <hpa@zytor.com>
1115 Date:   Wed May 2 11:31:03 2007 -0700
1116
1117     x86 setup: video.c: clean up unused stuff
1118     
1119     Clean up unused variables that we have no intent on using, as well
1120     as other cruft.
1121     
1122     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1123
1124 commit 57e69acff1f577de430cae1523fd49a5d113e885
1125 Author: H. Peter Anvin <hpa@zytor.com>
1126 Date:   Wed May 2 11:18:13 2007 -0700
1127
1128     x86 setup: drop video mode range checking
1129     
1130     Drop video mode range checking.  If someone really has, say, 12x40 mode
1131     visible through the BIOS then allow them to select it... odds are low
1132     that it will actually conflict with the very sparse allocation we have
1133     anyway.
1134     
1135     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1136
1137 commit c0dda0b90f92d43872d55d295630a71cd357cfa6
1138 Author: H. Peter Anvin <hpa@zytor.com>
1139 Date:   Wed May 2 11:15:53 2007 -0700
1140
1141     x86 setup: if no specific video mode ID is given, generate one
1142     
1143     If we don't specify a certain video mode ID in the driver, then
1144     generate the 0xRRCC mode ID automatically.
1145     
1146     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1147
1148 commit 0db5086e79810e7c5d560006b1c9a7501a02d80c
1149 Author: H. Peter Anvin <hpa@zytor.com>
1150 Date:   Wed May 2 11:10:28 2007 -0700
1151
1152     x86 setup: Sadly, Cirrus removed extended text modes from their BIOS.
1153     
1154     In the later era of the Cirrus 54xx series, Cirrus removed extended text
1155     modes from their BIOS.  Neither Qemu nor Bochs implement them in the BIOS.
1156     If we can find a direct-register-poking method of setting them that
1157     works in Bochs/Qemu it might be worthwhile to resurrect this; the probing
1158     routine *does* work.
1159     
1160     Of course, the Right Thing[TM] would be to submit such a routine to the
1161     Bochs/Qemu BIOS as a VESA text mode.
1162     
1163     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1164
1165 commit 41f3fddeeb764687bf3fb0cf77fd858128571d58
1166 Author: H. Peter Anvin <hpa@zytor.com>
1167 Date:   Wed May 2 10:18:07 2007 -0700
1168
1169     x86 setup: remove assembly implementation of putchar and puts
1170     
1171     Already unused, remove assembly implementation of putchar and puts.
1172     
1173     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1174
1175 commit dfa94cd86aca2c01d2f5e14b6e7c3e8258276195
1176 Author: H. Peter Anvin <hpa@zytor.com>
1177 Date:   Tue May 1 21:41:28 2007 -0700
1178
1179     x86 setup: Call INT 15h AX=E820h properly
1180     
1181     The calling convention for BIOS call 15:E820 was messed up.
1182     
1183     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1184
1185 commit 2487575a36435c0a983febbb4f3751331bd2df7a
1186 Author: H. Peter Anvin <hpa@zytor.com>
1187 Date:   Tue May 1 21:34:12 2007 -0700
1188
1189     x86 setup: advance one e820 descriptor at a time...
1190     
1191     Adding sizeof(foo) to a foo * is not just useless, it's pretty damaging...
1192     
1193     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1194
1195 commit 530d4f4f1732335ae8725c0b8c332a618e63ea1d
1196 Author: H. Peter Anvin <hpa@zytor.com>
1197 Date:   Tue May 1 21:33:28 2007 -0700
1198
1199     x86 setup: fix memcmp_[fg]s()
1200     
1201     Actually return a value from memcmp_[fg]s()...
1202     
1203     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1204
1205 commit 8617cd56ff2e43303147da012b26c9dd46af726e
1206 Author: H. Peter Anvin <hpa@zytor.com>
1207 Date:   Tue May 1 21:32:47 2007 -0700
1208
1209     x86 setup: fix missing semicolon in video-ati.c
1210     
1211     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1212
1213 commit 7bbf7fa3e199b9cef4877c5a56128faff8636cc9
1214 Author: H. Peter Anvin <hpa@zytor.com>
1215 Date:   Tue May 1 21:26:48 2007 -0700
1216
1217     x86 setup: make the video setup code actually do something...
1218     
1219     Basic video setup now works (there is still work to be done, however.)
1220     
1221     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1222
1223 commit 45bcd4406e4b812b32d317d9b3b8db2e5f135a3c
1224 Author: H. Peter Anvin <hpa@zytor.com>
1225 Date:   Tue May 1 21:25:20 2007 -0700
1226
1227     x86 setup: segment descriptors need to be Present
1228     
1229     The segment descriptors were missing the Present bit.
1230     
1231     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1232
1233 commit a39479d4ccf4dceffb623ad2ec7e2d708c38c637
1234 Author: H. Peter Anvin <hpa@zytor.com>
1235 Date:   Tue May 1 21:24:32 2007 -0700
1236
1237     build: setup sectors doesn't include the boot sector
1238     
1239     The "setup sectors" field doesn't include the old boot sector,
1240     even though the two are now one module.
1241     
1242     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1243
1244 commit d8f3d4928ead72e8febe2fcd740d0fee71a61f42
1245 Author: H. Peter Anvin <hpa@zytor.com>
1246 Date:   Tue May 1 21:23:44 2007 -0700
1247
1248     x86 setup: in tty.c, actually tell it what character to print
1249     
1250     putchar() was missing the actual passing of the character code to the
1251     BIOS call, with very silly-looking results.
1252     
1253     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1254
1255 commit 4f1462ed0377e180484a223e622d62432baa64b7
1256 Author: H. Peter Anvin <hpa@zytor.com>
1257 Date:   Tue May 1 21:22:46 2007 -0700
1258
1259     x86 setup: printf.c needs code16gcc.h
1260     
1261     printf.c was missing code16gcc.h, with predictable consequences.
1262     
1263     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1264
1265 commit a5ba7e6df198bd204b0f87fc6e3f68388b9d14c1
1266 Author: H. Peter Anvin <hpa@zytor.com>
1267 Date:   Mon Apr 30 20:56:42 2007 -0700
1268
1269     MAINTAINERS: formally take responsibility for the i386 boot code
1270     
1271     Change MAINTAINERS to formally take responsibility for the i386 boot code.
1272     
1273     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1274
1275 commit 6c821fc005655a99eff6e86c2e4b13654de94dea
1276 Author: H. Peter Anvin <hpa@zytor.com>
1277 Date:   Mon Apr 30 20:54:07 2007 -0700
1278
1279     x86 setup code rewrite: initial development snapshot
1280     
1281     Clean up the setup code and rewrite it in C.
1282     This is an initial development snapshot, not a working tree.
1283     
1284     Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1285 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1286 ---
1287
1288  MAINTAINERS                                 |    4 
1289  arch/i386/Kconfig.cpu                       |    4 
1290  arch/i386/boot/Makefile                     |   45 
1291  arch/i386/boot/a20.c                        |  161 +
1292  arch/i386/boot/apm.c                        |   97 
1293  arch/i386/boot/bitops.h                     |   45 
1294  arch/i386/boot/boot.h                       |  290 ++
1295  arch/i386/boot/bootsect.S                   |   98 
1296  arch/i386/boot/cmdline.c                    |   97 
1297  arch/i386/boot/code16gcc.h                  |    9 
1298  arch/i386/boot/compressed/Makefile          |    7 
1299  arch/i386/boot/compressed/head.S            |    6 
1300  arch/i386/boot/compressed/misc.c            |    3 
1301  arch/i386/boot/copy.S                       |  101 
1302  arch/i386/boot/cpu.c                        |   69 
1303  arch/i386/boot/cpucheck.c                   |  266 ++
1304  arch/i386/boot/edd.S                        |  231 --
1305  arch/i386/boot/edd.c                        |  196 +
1306  arch/i386/boot/header.S                     |  283 ++
1307  arch/i386/boot/main.c                       |  161 +
1308  arch/i386/boot/mca.c                        |   43 
1309  arch/i386/boot/memory.c                     |   99 
1310  arch/i386/boot/pm.c                         |  170 +
1311  arch/i386/boot/pmjump.S                     |   54 
1312  arch/i386/boot/printf.c                     |  331 ++
1313  arch/i386/boot/setup.S                      | 1075 ---------
1314  arch/i386/boot/setup.ld                     |   54 
1315  arch/i386/boot/string.c                     |   34 
1316  arch/i386/boot/tools/build.c                |  156 -
1317  arch/i386/boot/tty.c                        |  112 
1318  arch/i386/boot/version.c                    |   23 
1319  arch/i386/boot/vesa.h                       |   79 
1320  arch/i386/boot/video-bios.c                 |  125 +
1321  arch/i386/boot/video-vesa.c                 |  283 ++
1322  arch/i386/boot/video-vga.c                  |  260 ++
1323  arch/i386/boot/video.S                      | 2043 ------------------
1324  arch/i386/boot/video.c                      |  456 ++++
1325  arch/i386/boot/video.h                      |  145 +
1326  arch/i386/boot/voyager.c                    |   46 
1327  arch/i386/kernel/cpu/addon_cpuid_features.c |   50 
1328  arch/i386/kernel/cpu/common.c               |    2 
1329  arch/i386/kernel/cpu/proc.c                 |   21 
1330  arch/i386/kernel/e820.c                     |    2 
1331  arch/i386/kernel/setup.c                    |   12 
1332  arch/i386/kernel/verify_cpu.S               |   94 
1333  arch/x86_64/Kconfig                         |    4 
1334  arch/x86_64/boot/Makefile                   |  136 -
1335  arch/x86_64/boot/bootsect.S                 |   98 
1336  arch/x86_64/boot/compressed/Makefile        |    9 
1337  arch/x86_64/boot/compressed/head.S          |    6 
1338  arch/x86_64/boot/install.sh                 |    2 
1339  arch/x86_64/boot/mtools.conf.in             |   17 
1340  arch/x86_64/boot/setup.S                    |  826 -------
1341  arch/x86_64/boot/tools/build.c              |  185 -
1342  arch/x86_64/kernel/Makefile                 |    2 
1343  arch/x86_64/kernel/setup.c                  |   21 
1344  arch/x86_64/kernel/verify_cpu.S             |   22 
1345  drivers/ide/legacy/hd.c                     |   73 
1346  include/asm-i386/boot.h                     |    6 
1347  include/asm-i386/bootparam.h                |   85 
1348  include/asm-i386/cpufeature.h               |   26 
1349  include/asm-i386/e820.h                     |   14 
1350  include/asm-i386/processor.h                |    1 
1351  include/asm-i386/required-features.h        |   37 
1352  include/asm-i386/setup.h                    |   10 
1353  include/asm-x86_64/alternative.h            |   68 
1354  include/asm-x86_64/boot.h                   |   16 
1355  include/asm-x86_64/bootparam.h              |    1 
1356  include/asm-x86_64/cpufeature.h             |  115 -
1357  include/asm-x86_64/e820.h                   |    6 
1358  include/asm-x86_64/processor.h              |    3 
1359  include/asm-x86_64/required-features.h      |   46 
1360  include/asm-x86_64/segment.h                |    8 
1361  include/linux/edd.h                         |    4 
1362  include/linux/screen_info.h                 |    9 
1363  75 files changed, 4594 insertions(+), 5204 deletions(-)
1364
1365 diff -puN MAINTAINERS~git-newsetup MAINTAINERS
1366 --- a/MAINTAINERS~git-newsetup
1367 +++ a/MAINTAINERS
1368 @@ -1774,8 +1774,8 @@ T:        http://www.harbaum.org/till/i2c_tiny_
1369  S:     Maintained
1370  
1371  i386 BOOT CODE
1372 -P:     Riley H. Williams
1373 -M:     Riley@Williams.Name
1374 +P:     H. Peter Anvin
1375 +M:     hpa@zytor.com
1376  L:     Linux-Kernel@vger.kernel.org
1377  S:     Maintained
1378  
1379 diff -puN arch/i386/Kconfig.cpu~git-newsetup arch/i386/Kconfig.cpu
1380 --- a/arch/i386/Kconfig.cpu~git-newsetup
1381 +++ a/arch/i386/Kconfig.cpu
1382 @@ -346,6 +346,6 @@ config X86_CMOV
1383  
1384  config X86_MINIMUM_CPU_MODEL
1385         int
1386 -       default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP
1387 -       default "0"
1388 +       default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK
1389 +       default "3"
1390  
1391 diff -puN arch/i386/boot/Makefile~git-newsetup arch/i386/boot/Makefile
1392 --- a/arch/i386/boot/Makefile~git-newsetup
1393 +++ a/arch/i386/boot/Makefile
1394 @@ -25,27 +25,53 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
1395  
1396  #RAMDISK := -DRAMDISK=512
1397  
1398 -targets                := vmlinux.bin bootsect bootsect.o \
1399 -                  setup setup.o zImage bzImage
1400 +targets                := vmlinux.bin setup.bin setup.elf zImage bzImage
1401  subdir-        := compressed
1402  
1403 +setup-y                += a20.o apm.o cmdline.o copy.o cpu.o cpucheck.o edd.o
1404 +setup-y                += header.o main.o mca.o memory.o pm.o pmjump.o
1405 +setup-y                += printf.o string.o tty.o video.o version.o voyager.o
1406 +
1407 +# The link order of the video-*.o modules can matter.  In particular,
1408 +# video-vga.o *must* be listed first, followed by video-vesa.o.
1409 +# Hardware-specific drivers should follow in the order they should be
1410 +# probed, and video-bios.o should typically be last.
1411 +setup-y                += video-vga.o
1412 +setup-y                += video-vesa.o
1413 +setup-y                += video-bios.o
1414 +
1415  hostprogs-y    := tools/build
1416  
1417  HOSTCFLAGS_build.o := $(LINUXINCLUDE)
1418  
1419  # ---------------------------------------------------------------------------
1420  
1421 +# How to compile the 16-bit code.  Note we always compile for -march=i386,
1422 +# that way we can complain to the user if the CPU is insufficient.
1423 +cflags-i386   := 
1424 +cflags-x86_64 := -m32
1425 +CFLAGS         := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
1426 +                  $(cflags-$(ARCH)) \
1427 +                  -Wall -Wstrict-prototypes \
1428 +                  -march=i386 -mregparm=3 \
1429 +                  -include $(srctree)/$(src)/code16gcc.h \
1430 +                  -fno-strict-aliasing -fomit-frame-pointer \
1431 +                  $(call cc-option, -ffreestanding) \
1432 +                  $(call cc-option, -fno-stack-protector)
1433 +AFLAGS         := $(CFLAGS) -D__ASSEMBLY__
1434 +
1435  $(obj)/zImage:  IMAGE_OFFSET := 0x1000
1436  $(obj)/zImage:  EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK)
1437  $(obj)/bzImage: IMAGE_OFFSET := 0x100000
1438 +$(obj)/bzImage: EXTRA_CFLAGS := -D__BIG_KERNEL__
1439  $(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
1440  $(obj)/bzImage: BUILDFLAGS   := -b
1441  
1442  quiet_cmd_image = BUILD   $@
1443 -cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
1444 +cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/setup.bin \
1445             $(obj)/vmlinux.bin $(ROOT_DEV) > $@
1446  
1447 -$(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
1448 +$(obj)/zImage $(obj)/bzImage: $(obj)/setup.bin \
1449                               $(obj)/vmlinux.bin $(obj)/tools/build FORCE
1450         $(call if_changed,image)
1451         @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
1452 @@ -53,12 +79,17 @@ $(obj)/zImage $(obj)/bzImage: $(obj)/boo
1453  $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
1454         $(call if_changed,objcopy)
1455  
1456 -LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
1457 -LDFLAGS_setup   := -Ttext 0x0 -s --oformat binary -e begtext
1458 +SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
1459  
1460 -$(obj)/setup $(obj)/bootsect: %: %.o FORCE
1461 +LDFLAGS_setup.elf      := -T
1462 +$(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
1463         $(call if_changed,ld)
1464  
1465 +OBJCOPYFLAGS_setup.bin := -O binary
1466 +
1467 +$(obj)/setup.bin: $(obj)/setup.elf FORCE
1468 +       $(call if_changed,objcopy)
1469 +
1470  $(obj)/compressed/vmlinux: FORCE
1471         $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
1472  
1473 diff -puN /dev/null arch/i386/boot/a20.c
1474 --- /dev/null
1475 +++ a/arch/i386/boot/a20.c
1476 @@ -0,0 +1,161 @@
1477 +/* -*- linux-c -*- ------------------------------------------------------- *
1478 + *
1479 + *   Copyright (C) 1991, 1992 Linus Torvalds
1480 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
1481 + *
1482 + *   This file is part of the Linux kernel, and is made available under
1483 + *   the terms of the GNU General Public License version 2.
1484 + *
1485 + * ----------------------------------------------------------------------- */
1486 +
1487 +/*
1488 + * arch/i386/boot/a20.c
1489 + *
1490 + * Enable A20 gate (return -1 on failure)
1491 + */
1492 +
1493 +#include "boot.h"
1494 +
1495 +#define MAX_8042_LOOPS 100000
1496 +
1497 +static int empty_8042(void)
1498 +{
1499 +       u8 status;
1500 +       int loops = MAX_8042_LOOPS;
1501 +
1502 +       while (loops--) {
1503 +               io_delay();
1504 +
1505 +               status = inb(0x64);
1506 +               if (status & 1) {
1507 +                       /* Read and discard input data */
1508 +                       io_delay();
1509 +                       (void)inb(0x60);
1510 +               } else if (!(status & 2)) {
1511 +                       /* Buffers empty, finished! */
1512 +                       return 0;
1513 +               }
1514 +       }
1515 +
1516 +       return -1;
1517 +}
1518 +
1519 +/* Returns nonzero if the A20 line is enabled.  The memory address
1520 +   used as a test is the int $0x80 vector, which should be safe. */
1521 +
1522 +#define A20_TEST_ADDR  (4*0x80)
1523 +#define A20_TEST_SHORT  32
1524 +#define A20_TEST_LONG  2097152 /* 2^21 */
1525 +
1526 +static int a20_test(int loops)
1527 +{
1528 +       int ok = 0;
1529 +       int saved, ctr;
1530 +
1531 +       set_fs(0x0000);
1532 +       set_gs(0xffff);
1533 +
1534 +       saved = ctr = rdfs32(A20_TEST_ADDR);
1535 +
1536 +       while (loops--) {
1537 +               wrfs32(++ctr, A20_TEST_ADDR);
1538 +               io_delay();     /* Serialize and make delay constant */
1539 +               ok = rdgs32(A20_TEST_ADDR+0x10) ^ ctr;
1540 +               if (ok)
1541 +                       break;
1542 +       }
1543 +
1544 +       wrfs32(saved, A20_TEST_ADDR);
1545 +       return ok;
1546 +}
1547 +
1548 +/* Quick test to see if A20 is already enabled */
1549 +static int a20_test_short(void)
1550 +{
1551 +       return a20_test(A20_TEST_SHORT);
1552 +}
1553 +
1554 +/* Longer test that actually waits for A20 to come on line; this
1555 +   is useful when dealing with the KBC or other slow external circuitry. */
1556 +static int a20_test_long(void)
1557 +{
1558 +       return a20_test(A20_TEST_LONG);
1559 +}
1560 +
1561 +static void enable_a20_bios(void)
1562 +{
1563 +       asm volatile("pushfl; int $0x15; popfl"
1564 +                    : : "a" ((u16)0x2401));
1565 +}
1566 +
1567 +static void enable_a20_kbc(void)
1568 +{
1569 +       empty_8042();
1570 +
1571 +       outb(0xd1, 0x64);       /* Command write */
1572 +       empty_8042();
1573 +
1574 +       outb(0xdf, 0x60);       /* A20 on */
1575 +       empty_8042();
1576 +}
1577 +
1578 +static void enable_a20_fast(void)
1579 +{
1580 +       u8 port_a;
1581 +
1582 +       port_a = inb(0x92);     /* Configuration port A */
1583 +       port_a |=  0x02;        /* Enable A20 */
1584 +       port_a &= ~0x01;        /* Do not reset machine */
1585 +       outb(port_a, 0x92);
1586 +}
1587 +
1588 +/*
1589 + * Actual routine to enable A20; return 0 on ok, -1 on failure
1590 + */
1591 +
1592 +#define A20_ENABLE_LOOPS 255   /* Number of times to try */
1593 +
1594 +int enable_a20(void)
1595 +{
1596 +       int loops = A20_ENABLE_LOOPS;
1597 +
1598 +#if defined(CONFIG_X86_ELAN)
1599 +       /* Elan croaks if we try to touch the KBC */
1600 +       enable_a20_fast();
1601 +       while (!a20_test_long())
1602 +               ;
1603 +       return 0;
1604 +#elif defined(CONFIG_X86_VOYAGER)
1605 +       /* On Voyager, a20_test() is unsafe? */
1606 +       enable_a20_kbc();
1607 +       return 0;
1608 +#else
1609 +       while (loops--) {
1610 +               /* First, check to see if A20 is already enabled
1611 +                  (legacy free, etc.) */
1612 +               if (a20_test_short())
1613 +                       return 0;
1614 +
1615 +               /* Next, try the BIOS (INT 0x15, AX=0x2401) */
1616 +               enable_a20_bios();
1617 +               if (a20_test_short())
1618 +                       return 0;
1619 +
1620 +               /* Try enabling A20 through the keyboard controller */
1621 +               empty_8042();
1622 +               if (a20_test_short())
1623 +                       return 0; /* BIOS worked, but with delayed reaction */
1624 +
1625 +               enable_a20_kbc();
1626 +               if (a20_test_long())
1627 +                       return 0;
1628 +
1629 +               /* Finally, try enabling the "fast A20 gate" */
1630 +               enable_a20_fast();
1631 +               if (a20_test_long())
1632 +                       return 0;
1633 +       }
1634 +
1635 +       return -1;
1636 +#endif
1637 +}
1638 diff -puN /dev/null arch/i386/boot/apm.c
1639 --- /dev/null
1640 +++ a/arch/i386/boot/apm.c
1641 @@ -0,0 +1,97 @@
1642 +/* -*- linux-c -*- ------------------------------------------------------- *
1643 + *
1644 + *   Copyright (C) 1991, 1992 Linus Torvalds
1645 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
1646 + *
1647 + *   Original APM BIOS checking by Stephen Rothwell, May 1994
1648 + *   (sfr@canb.auug.org.au)
1649 + *
1650 + *   This file is part of the Linux kernel, and is made available under
1651 + *   the terms of the GNU General Public License version 2.
1652 + *
1653 + * ----------------------------------------------------------------------- */
1654 +
1655 +/*
1656 + * arch/i386/boot/apm.c
1657 + *
1658 + * Get APM BIOS information
1659 + */
1660 +
1661 +#include "boot.h"
1662 +
1663 +#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
1664 +
1665 +int query_apm_bios(void)
1666 +{
1667 +       u16 ax, bx, cx, dx, di;
1668 +       u32 ebx, esi;
1669 +       u8 err;
1670 +
1671 +       /* APM BIOS installation check */
1672 +       ax = 0x5300;
1673 +       bx = cx = 0;
1674 +       asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
1675 +                    : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
1676 +                    : : "esi", "edi");
1677 +
1678 +       if (err)
1679 +               return -1;              /* No APM BIOS */
1680 +
1681 +       if (bx != 0x504d)       /* "PM" signature */
1682 +               return -1;
1683 +
1684 +       if (cx & 0x02)          /* 32 bits supported? */
1685 +               return -1;
1686 +
1687 +       /* Disconnect first, just in case */
1688 +       ax = 0x5304;
1689 +       asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
1690 +                    : "+a" (ax)
1691 +                    : : "ebx", "ecx", "edx", "esi", "edi");
1692 +
1693 +       /* Paranoia */
1694 +       ebx = esi = 0;
1695 +       cx = dx = di = 0;
1696 +
1697 +       /* 32-bit connect */
1698 +       asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6"
1699 +                    : "=a" (ax), "+b" (ebx), "+c" (cx), "+d" (dx),
1700 +                      "+S" (esi), "+D" (di), "=m" (err)
1701 +                    : "a" (0x5303));
1702 +
1703 +       boot_params.apm_bios_info.cseg = ax;
1704 +       boot_params.apm_bios_info.offset = ebx;
1705 +       boot_params.apm_bios_info.cseg_16 = cx;
1706 +       boot_params.apm_bios_info.dseg = dx;
1707 +       boot_params.apm_bios_info.cseg_len = (u16)esi;
1708 +       boot_params.apm_bios_info.cseg_16_len = esi >> 16;
1709 +       boot_params.apm_bios_info.dseg_len = di;
1710 +
1711 +       if (err)
1712 +               return -1;
1713 +
1714 +       /* Redo the installation check as the 32-bit connect;
1715 +          some BIOSes return different flags this way... */
1716 +
1717 +       ax = 0x5300;
1718 +       bx = cx = 0;
1719 +       asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
1720 +                    : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
1721 +                    : : "esi", "edi");
1722 +
1723 +       if (err || bx != 0x504d) {
1724 +               /* Failure with 32-bit connect, try to disconect and ignore */
1725 +               ax = 0x5304;
1726 +               bx = 0;
1727 +               asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
1728 +                            : "+a" (ax), "+b" (bx)
1729 +                            : : "ecx", "edx", "esi", "edi");
1730 +               return -1;
1731 +       }
1732 +
1733 +       boot_params.apm_bios_info.version = ax;
1734 +       boot_params.apm_bios_info.flags = cx;
1735 +       return 0;
1736 +}
1737 +
1738 +#endif
1739 diff -puN /dev/null arch/i386/boot/bitops.h
1740 --- /dev/null
1741 +++ a/arch/i386/boot/bitops.h
1742 @@ -0,0 +1,45 @@
1743 +/* -*- linux-c -*- ------------------------------------------------------- *
1744 + *
1745 + *   Copyright (C) 1991, 1992 Linus Torvalds
1746 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
1747 + *
1748 + *   This file is part of the Linux kernel, and is made available under
1749 + *   the terms of the GNU General Public License version 2.
1750 + *
1751 + * ----------------------------------------------------------------------- */
1752 +
1753 +/*
1754 + * arch/i386/boot/bitops.h
1755 + *
1756 + * Very simple bitops for the boot code.
1757 + */
1758 +
1759 +#ifndef BOOT_BITOPS_H
1760 +#define BOOT_BITOPS_H
1761 +#define _LINUX_BITOPS_H                /* Inhibit inclusion of <linux/bitops.h> */
1762 +
1763 +static inline int constant_test_bit(int nr, const void *addr)
1764 +{
1765 +       const u32 *p = (const u32 *)addr;
1766 +       return ((1UL << (nr & 31)) & (p[nr >> 5])) != 0;
1767 +}
1768 +static inline int variable_test_bit(int nr, const void *addr)
1769 +{
1770 +       u8 v;
1771 +       const u32 *p = (const u32 *)addr;
1772 +
1773 +       asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
1774 +       return v;
1775 +}
1776 +
1777 +#define test_bit(nr,addr) \
1778 +(__builtin_constant_p(nr) ? \
1779 + constant_test_bit((nr),(addr)) : \
1780 + variable_test_bit((nr),(addr)))
1781 +
1782 +static inline void set_bit(int nr, void *addr)
1783 +{
1784 +       asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
1785 +}
1786 +
1787 +#endif /* BOOT_BITOPS_H */
1788 diff -puN /dev/null arch/i386/boot/boot.h
1789 --- /dev/null
1790 +++ a/arch/i386/boot/boot.h
1791 @@ -0,0 +1,290 @@
1792 +/* -*- linux-c -*- ------------------------------------------------------- *
1793 + *
1794 + *   Copyright (C) 1991, 1992 Linus Torvalds
1795 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
1796 + *
1797 + *   This file is part of the Linux kernel, and is made available under
1798 + *   the terms of the GNU General Public License version 2.
1799 + *
1800 + * ----------------------------------------------------------------------- */
1801 +
1802 +/*
1803 + * arch/i386/boot/boot.h
1804 + *
1805 + * Header file for the real-mode kernel code
1806 + */
1807 +
1808 +#ifndef BOOT_BOOT_H
1809 +#define BOOT_BOOT_H
1810 +
1811 +#ifndef __ASSEMBLY__
1812 +
1813 +#include <stdarg.h>
1814 +#include <linux/types.h>
1815 +#include <linux/edd.h>
1816 +#include <asm/boot.h>
1817 +#include <asm/bootparam.h>
1818 +
1819 +/* Useful macros */
1820 +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
1821 +
1822 +extern struct setup_header hdr;
1823 +extern struct boot_params boot_params;
1824 +
1825 +/* Basic port I/O */
1826 +static inline void outb(u8 v, u16 port)
1827 +{
1828 +       asm volatile("outb %0,%1" : : "a" (v), "dN" (port));
1829 +}
1830 +static inline u8 inb(u16 port)
1831 +{
1832 +       u8 v;
1833 +       asm volatile("inb %1,%0" : "=a" (v) : "dN" (port));
1834 +       return v;
1835 +}
1836 +
1837 +static inline void outw(u16 v, u16 port)
1838 +{
1839 +       asm volatile("outw %0,%1" : : "a" (v), "dN" (port));
1840 +}
1841 +static inline u16 inw(u16 port)
1842 +{
1843 +       u16 v;
1844 +       asm volatile("inw %1,%0" : "=a" (v) : "dN" (port));
1845 +       return v;
1846 +}
1847 +
1848 +static inline void outl(u32 v, u16 port)
1849 +{
1850 +       asm volatile("outl %0,%1" : : "a" (v), "dn" (port));
1851 +}
1852 +static inline u32 inl(u32 port)
1853 +{
1854 +       u32 v;
1855 +       asm volatile("inl %1,%0" : "=a" (v) : "dN" (port));
1856 +       return v;
1857 +}
1858 +
1859 +static inline void io_delay(void)
1860 +{
1861 +       const u16 DELAY_PORT = 0x80;
1862 +       asm volatile("outb %%al,%0" : : "dN" (DELAY_PORT));
1863 +}
1864 +
1865 +/* These functions are used to reference data in other segments. */
1866 +
1867 +static inline u16 ds(void)
1868 +{
1869 +       u16 seg;
1870 +       asm("movw %%ds,%0" : "=rm" (seg));
1871 +       return seg;
1872 +}
1873 +
1874 +static inline void set_fs(u16 seg)
1875 +{
1876 +       asm volatile("movw %0,%%fs" : : "rm" (seg));
1877 +}
1878 +static inline u16 fs(void)
1879 +{
1880 +       u16 seg;
1881 +       asm("movw %%fs,%0" : "=rm" (seg));
1882 +       return seg;
1883 +}
1884 +
1885 +static inline void set_gs(u16 seg)
1886 +{
1887 +       asm volatile("movw %0,%%gs" : : "rm" (seg));
1888 +}
1889 +static inline u16 gs(void)
1890 +{
1891 +       u16 seg;
1892 +       asm("movw %%gs,%0" : "=rm" (seg));
1893 +       return seg;
1894 +}
1895 +
1896 +typedef unsigned int addr_t;
1897 +
1898 +static inline u8 rdfs8(addr_t addr)
1899 +{
1900 +       u8 v;
1901 +       asm("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
1902 +       return v;
1903 +}
1904 +static inline u16 rdfs16(addr_t addr)
1905 +{
1906 +       u16 v;
1907 +       asm("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
1908 +       return v;
1909 +}
1910 +static inline u32 rdfs32(addr_t addr)
1911 +{
1912 +       u32 v;
1913 +       asm("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
1914 +       return v;
1915 +}
1916 +
1917 +static inline void wrfs8(u8 v, addr_t addr)
1918 +{
1919 +       asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "r" (v));
1920 +}
1921 +static inline void wrfs16(u16 v, addr_t addr)
1922 +{
1923 +       asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "r" (v));
1924 +}
1925 +static inline void wrfs32(u32 v, addr_t addr)
1926 +{
1927 +       asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "r" (v));
1928 +}
1929 +
1930 +static inline u8 rdgs8(addr_t addr)
1931 +{
1932 +       u8 v;
1933 +       asm("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
1934 +       return v;
1935 +}
1936 +static inline u16 rdgs16(addr_t addr)
1937 +{
1938 +       u16 v;
1939 +       asm("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
1940 +       return v;
1941 +}
1942 +static inline u32 rdgs32(addr_t addr)
1943 +{
1944 +       u32 v;
1945 +       asm("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
1946 +       return v;
1947 +}
1948 +
1949 +static inline void wrgs8(u8 v, addr_t addr)
1950 +{
1951 +       asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "r" (v));
1952 +}
1953 +static inline void wrgs16(u16 v, addr_t addr)
1954 +{
1955 +       asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "r" (v));
1956 +}
1957 +static inline void wrgs32(u32 v, addr_t addr)
1958 +{
1959 +       asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "r" (v));
1960 +}
1961 +
1962 +/* Note: these only return true/false, not a signed return value! */
1963 +static inline int memcmp(const void *s1, const void *s2, size_t len)
1964 +{
1965 +       u8 diff;
1966 +       asm("repe; cmpsb; setnz %0"
1967 +           : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
1968 +       return diff;
1969 +}
1970 +
1971 +static inline int memcmp_fs(const void *s1, addr_t s2, size_t len)
1972 +{
1973 +       u8 diff;
1974 +       asm("fs; repe; cmpsb; setnz %0"
1975 +           : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
1976 +       return diff;
1977 +}
1978 +static inline int memcmp_gs(const void *s1, addr_t s2, size_t len)
1979 +{
1980 +       u8 diff;
1981 +       asm("gs; repe; cmpsb; setnz %0"
1982 +           : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
1983 +       return diff;
1984 +}
1985 +
1986 +/* Heap -- available for dynamic lists. */
1987 +#define STACK_SIZE     512     /* Minimum number of bytes for stack */
1988 +
1989 +extern char _end[];
1990 +extern char *HEAP;
1991 +extern char *heap_end;
1992 +#define RESET_HEAP() ((void *)( HEAP = _end ))
1993 +static inline char *__get_heap(size_t s, size_t a, size_t n)
1994 +{
1995 +       char *tmp;
1996 +
1997 +       HEAP = (char *)(((size_t)HEAP+(a-1)) & ~(a-1));
1998 +       tmp = HEAP;
1999 +       HEAP += s*n;
2000 +       return tmp;
2001 +}
2002 +#define GET_HEAP(type, n) \
2003 +       ((type *)__get_heap(sizeof(type),__alignof__(type),(n)))
2004 +
2005 +static inline int heap_free(void)
2006 +{
2007 +       return heap_end-HEAP;
2008 +}
2009 +
2010 +/* copy.S */
2011 +
2012 +void copy_to_fs(addr_t dst, void *src, size_t len);
2013 +void *copy_from_fs(void *dst, addr_t src, size_t len);
2014 +void copy_to_gs(addr_t dst, void *src, size_t len);
2015 +void *copy_from_gs(void *dst, addr_t src, size_t len);
2016 +void *memcpy(void *dst, void *src, size_t len);
2017 +void *memset(void *dst, int c, size_t len);
2018 +
2019 +#define memcpy(d,s,l) __builtin_memcpy(d,s,l)
2020 +#define memset(d,c,l) __builtin_memset(d,c,l)
2021 +
2022 +/* a20.c */
2023 +int enable_a20(void);
2024 +
2025 +/* apm.c */
2026 +int query_apm_bios(void);
2027 +
2028 +/* cmdline.c */
2029 +int cmdline_find_option(const char *option, char *buffer, int bufsize);
2030 +
2031 +/* cpu.c, cpucheck.c */
2032 +int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
2033 +int validate_cpu(void);
2034 +
2035 +/* edd.c */
2036 +void query_edd(void);
2037 +
2038 +/* header.S */
2039 +void __attribute__((noreturn)) die(void);
2040 +
2041 +/* mca.c */
2042 +int query_mca(void);
2043 +
2044 +/* memory.c */
2045 +int detect_memory(void);
2046 +
2047 +/* pm.c */
2048 +void __attribute__((noreturn)) go_to_protected_mode(void);
2049 +
2050 +/* pmjump.S */
2051 +void __attribute__((noreturn))
2052 +       protected_mode_jump(u32 entrypoint, u32 bootparams);
2053 +
2054 +/* printf.c */
2055 +unsigned int atou(const char *s);
2056 +int sprintf(char *buf, const char *fmt, ...);
2057 +int vsprintf(char *buf, const char *fmt, va_list args);
2058 +int printf(const char *fmt, ...);
2059 +
2060 +/* string.c */
2061 +int strcmp(const char *str1, const char *str2);
2062 +
2063 +/* tty.c */
2064 +void puts(const char *);
2065 +void putchar(int);
2066 +int getchar(void);
2067 +void kbd_flush(void);
2068 +int getchar_timeout(void);
2069 +
2070 +/* video.c */
2071 +void set_video(void);
2072 +
2073 +/* video-vesa.c */
2074 +void vesa_store_edid(void);
2075 +
2076 +/* voyager.c */
2077 +int query_voyager(void);
2078 +
2079 +#endif /* __ASSEMBLY__ */
2080 +
2081 +#endif /* BOOT_BOOT_H */
2082 diff -puN arch/i386/boot/bootsect.S~git-newsetup /dev/null
2083 --- a/arch/i386/boot/bootsect.S
2084 +++ /dev/null
2085 @@ -1,98 +0,0 @@
2086 -/*
2087 - *     bootsect.S              Copyright (C) 1991, 1992 Linus Torvalds
2088 - *
2089 - *     modified by Drew Eckhardt
2090 - *     modified by Bruce Evans (bde)
2091 - *     modified by Chris Noe (May 1999) (as86 -> gas)
2092 - *     gutted by H. Peter Anvin (Jan 2003)
2093 - *
2094 - * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
2095 - * addresses must be multiplied by 16 to obtain their respective linear
2096 - * addresses. To avoid confusion, linear addresses are written using leading
2097 - * hex while segment addresses are written as segment:offset.
2098 - *
2099 - */
2100 -
2101 -#include <asm/boot.h>
2102 -
2103 -SETUPSECTS     = 4                     /* default nr of setup-sectors */
2104 -BOOTSEG                = 0x07C0                /* original address of boot-sector */
2105 -INITSEG                = DEF_INITSEG           /* we move boot here - out of the way */
2106 -SETUPSEG       = DEF_SETUPSEG          /* setup starts here */
2107 -SYSSEG         = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
2108 -SYSSIZE                = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
2109 -                                       /* to be loaded */
2110 -ROOT_DEV       = 0                     /* ROOT_DEV is now written by "build" */
2111 -SWAP_DEV       = 0                     /* SWAP_DEV is now written by "build" */
2112 -
2113 -#ifndef SVGA_MODE
2114 -#define SVGA_MODE ASK_VGA
2115 -#endif
2116 -
2117 -#ifndef RAMDISK
2118 -#define RAMDISK 0
2119 -#endif
2120 -
2121 -#ifndef ROOT_RDONLY
2122 -#define ROOT_RDONLY 1
2123 -#endif
2124 -
2125 -.code16
2126 -.text
2127 -
2128 -.global _start
2129 -_start:
2130 -
2131 -       # Normalize the start address
2132 -       jmpl    $BOOTSEG, $start2
2133 -
2134 -start2:
2135 -       movw    %cs, %ax
2136 -       movw    %ax, %ds
2137 -       movw    %ax, %es
2138 -       movw    %ax, %ss
2139 -       movw    $0x7c00, %sp
2140 -       sti
2141 -       cld
2142 -
2143 -       movw    $bugger_off_msg, %si
2144 -
2145 -msg_loop:
2146 -       lodsb
2147 -       andb    %al, %al
2148 -       jz      die
2149 -       movb    $0xe, %ah
2150 -       movw    $7, %bx
2151 -       int     $0x10
2152 -       jmp     msg_loop
2153 -
2154 -die:
2155 -       # Allow the user to press a key, then reboot
2156 -       xorw    %ax, %ax
2157 -       int     $0x16
2158 -       int     $0x19
2159 -
2160 -       # int 0x19 should never return.  In case it does anyway,
2161 -       # invoke the BIOS reset code...
2162 -       ljmp    $0xf000,$0xfff0
2163 -
2164 -
2165 -bugger_off_msg:
2166 -       .ascii  "Direct booting from floppy is no longer supported.\r\n"
2167 -       .ascii  "Please use a boot loader program instead.\r\n"
2168 -       .ascii  "\n"
2169 -       .ascii  "Remove disk and press any key to reboot . . .\r\n"
2170 -       .byte   0
2171 -
2172 -
2173 -       # Kernel attributes; used by setup
2174 -
2175 -       .org 497
2176 -setup_sects:   .byte SETUPSECTS
2177 -root_flags:    .word ROOT_RDONLY
2178 -syssize:       .word SYSSIZE
2179 -swap_dev:      .word SWAP_DEV
2180 -ram_size:      .word RAMDISK
2181 -vid_mode:      .word SVGA_MODE
2182 -root_dev:      .word ROOT_DEV
2183 -boot_flag:     .word 0xAA55
2184 diff -puN /dev/null arch/i386/boot/cmdline.c
2185 --- /dev/null
2186 +++ a/arch/i386/boot/cmdline.c
2187 @@ -0,0 +1,97 @@
2188 +/* -*- linux-c -*- ------------------------------------------------------- *
2189 + *
2190 + *   Copyright (C) 1991, 1992 Linus Torvalds
2191 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
2192 + *
2193 + *   This file is part of the Linux kernel, and is made available under
2194 + *   the terms of the GNU General Public License version 2.
2195 + *
2196 + * ----------------------------------------------------------------------- */
2197 +
2198 +/*
2199 + * arch/i386/boot/cmdline.c
2200 + *
2201 + * Simple command-line parser for early boot.
2202 + */
2203 +
2204 +#include "boot.h"
2205 +
2206 +static inline int myisspace(u8 c)
2207 +{
2208 +       return c <= ' ';        /* Close enough approximation */
2209 +}
2210 +
2211 +/*
2212 + * Find a non-boolean option, that is, "option=argument".  In accordance
2213 + * with standard Linux practice, if this option is repeated, this returns
2214 + * the last instance on the command line.
2215 + *
2216 + * Returns the length of the argument (regardless of if it was
2217 + * truncated to fit in the buffer), or -1 on not found.
2218 + */
2219 +int cmdline_find_option(const char *option, char *buffer, int bufsize)
2220 +{
2221 +       u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr;
2222 +       addr_t cptr;
2223 +       char c;
2224 +       int len = -1;
2225 +       const char *opptr = NULL;
2226 +       char *bufptr = buffer;
2227 +       enum {
2228 +               st_wordstart,   /* Start of word/after whitespace */
2229 +               st_wordcmp,     /* Comparing this word */
2230 +               st_wordskip,    /* Miscompare, skip */
2231 +               st_bufcpy       /* Copying this to buffer */
2232 +       } state = st_wordstart;
2233 +
2234 +       if (!cmdline_ptr || cmdline_ptr >= 0x100000)
2235 +               return -1;      /* No command line, or inaccessible */
2236 +
2237 +       cptr = cmdline_ptr & 0xf;
2238 +       set_fs(cmdline_ptr >> 4);
2239 +
2240 +       while (cptr < 0x10000 && (c = rdfs8(cptr++))) {
2241 +               switch (state) {
2242 +               case st_wordstart:
2243 +                       if (myisspace(c))
2244 +                               break;
2245 +
2246 +                       /* else */
2247 +                       state = st_wordcmp;
2248 +                       opptr = option;
2249 +                       /* fall through */
2250 +
2251 +               case st_wordcmp:
2252 +                       if (c == '=' && !*opptr) {
2253 +                               len = 0;
2254 +                               bufptr = buffer;
2255 +                               state = st_bufcpy;
2256 +                       } else if (myisspace(c)) {
2257 +                               state = st_wordstart;
2258 +                       } else if (c != *opptr++) {
2259 +                               state = st_wordskip;
2260 +                       }
2261 +                       break;
2262 +
2263 +               case st_wordskip:
2264 +                       if (myisspace(c))
2265 +                               state = st_wordstart;
2266 +                       break;
2267 +
2268 +               case st_bufcpy:
2269 +                       if (myisspace(c)) {
2270 +                               state = st_wordstart;
2271 +                       } else {
2272 +                               if (len < bufsize-1)
2273 +                                       *bufptr++ = c;
2274 +                               len++;
2275 +                       }
2276 +                       break;
2277 +               }
2278 +       }
2279 +
2280 +       if (bufsize)
2281 +               *bufptr = '\0';
2282 +
2283 +       return len;
2284 +}
2285 diff -puN /dev/null arch/i386/boot/code16gcc.h
2286 --- /dev/null
2287 +++ a/arch/i386/boot/code16gcc.h
2288 @@ -0,0 +1,9 @@
2289 +/*
2290 + * code16gcc.h
2291 + *
2292 + * This file is -include'd when compiling 16-bit C code.
2293 + */
2294 +
2295 +#ifndef __ASSEMBLY__
2296 +asm(".code16gcc");
2297 +#endif
2298 diff -puN arch/i386/boot/compressed/Makefile~git-newsetup arch/i386/boot/compressed/Makefile
2299 --- a/arch/i386/boot/compressed/Makefile~git-newsetup
2300 +++ a/arch/i386/boot/compressed/Makefile
2301 @@ -9,9 +9,14 @@ targets                := vmlinux vmlinux.bin vmlinux.
2302  EXTRA_AFLAGS   := -traditional
2303  
2304  LDFLAGS_vmlinux := -T
2305 -CFLAGS_misc.o += -fPIC
2306  hostprogs-y    := relocs
2307  
2308 +CFLAGS  := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
2309 +          -fno-strict-aliasing -fPIC \
2310 +          $(call cc-option,-ffreestanding) \
2311 +          $(call cc-option,-fno-stack-protector)
2312 +LDFLAGS := -m elf_i386
2313 +
2314  $(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
2315         $(call if_changed,ld)
2316         @:
2317 diff -puN arch/i386/boot/compressed/head.S~git-newsetup arch/i386/boot/compressed/head.S
2318 --- a/arch/i386/boot/compressed/head.S~git-newsetup
2319 +++ a/arch/i386/boot/compressed/head.S
2320 @@ -45,10 +45,10 @@ startup_32:
2321   * at and where we were actually loaded at.  This can only be done
2322   * with a short local call on x86.  Nothing  else will tell us what
2323   * address we are running at.  The reserved chunk of the real-mode
2324 - * data at 0x34-0x3f are used as the stack for this calculation.
2325 - * Only 4 bytes are needed.
2326 + * data at 0x1e4 (defined as a scratch field) are used as the stack
2327 + * for this calculation. Only 4 bytes are needed.
2328   */
2329 -       leal 0x40(%esi), %esp
2330 +       leal (0x1e4+4)(%esi), %esp
2331         call 1f
2332  1:     popl %ebp
2333         subl $1b, %ebp
2334 diff -puN arch/i386/boot/compressed/misc.c~git-newsetup arch/i386/boot/compressed/misc.c
2335 --- a/arch/i386/boot/compressed/misc.c~git-newsetup
2336 +++ a/arch/i386/boot/compressed/misc.c
2337 @@ -11,7 +11,6 @@
2338  
2339  #undef CONFIG_PARAVIRT
2340  #include <linux/linkage.h>
2341 -#include <linux/vmalloc.h>
2342  #include <linux/screen_info.h>
2343  #include <asm/io.h>
2344  #include <asm/page.h>
2345 @@ -364,8 +363,10 @@ asmlinkage void decompress_kernel(void *
2346  
2347         if ((u32)output & (CONFIG_PHYSICAL_ALIGN -1))
2348                 error("Destination address not CONFIG_PHYSICAL_ALIGN aligned");
2349 +#ifndef CONFIG_X86_64
2350         if (end > ((-__PAGE_OFFSET-(512 <<20)-1) & 0x7fffffff))
2351                 error("Destination address too large");
2352 +#endif
2353  #ifndef CONFIG_RELOCATABLE
2354         if ((u32)output != LOAD_PHYSICAL_ADDR)
2355                 error("Wrong destination address");
2356 diff -puN /dev/null arch/i386/boot/copy.S
2357 --- /dev/null
2358 +++ a/arch/i386/boot/copy.S
2359 @@ -0,0 +1,101 @@
2360 +/* ----------------------------------------------------------------------- *
2361 + *
2362 + *   Copyright (C) 1991, 1992 Linus Torvalds
2363 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
2364 + *
2365 + *   This file is part of the Linux kernel, and is made available under
2366 + *   the terms of the GNU General Public License version 2.
2367 + *
2368 + * ----------------------------------------------------------------------- */
2369 +
2370 +/*
2371 + * arch/i386/boot/copy.S
2372 + *
2373 + * Memory copy routines
2374 + */
2375 +
2376 +       .code16gcc
2377 +       .text
2378 +
2379 +       .globl  memcpy
2380 +       .type   memcpy, @function
2381 +memcpy:
2382 +       pushw   %si
2383 +       pushw   %di
2384 +       movw    %ax, %di
2385 +       movw    %dx, %si
2386 +       pushw   %cx
2387 +       shrw    $2, %cx
2388 +       rep; movsl
2389 +       popw    %cx
2390 +       andw    $3, %cx
2391 +       rep; movsb
2392 +       popw    %di
2393 +       popw    %si
2394 +       ret
2395 +       .size   memcpy, .-memcpy
2396 +
2397 +       .globl  memset
2398 +       .type   memset, @function
2399 +memset:
2400 +       pushw   %di
2401 +       movw    %ax, %di
2402 +       movzbl  %dl, %eax
2403 +       imull   $0x01010101,%eax
2404 +       pushw   %cx
2405 +       shrw    $2, %cx
2406 +       rep; stosl
2407 +       popw    %cx
2408 +       andw    $3, %cx
2409 +       rep; stosb
2410 +       popw    %di
2411 +       ret
2412 +       .size   memset, .-memset
2413 +
2414 +       .globl  copy_from_fs
2415 +       .type   copy_from_fs, @function
2416 +copy_from_fs:
2417 +       pushw   %ds
2418 +       pushw   %fs
2419 +       popw    %ds
2420 +       call    memcpy
2421 +       popw    %ds
2422 +       ret
2423 +       .size   copy_from_fs, .-copy_from_fs
2424 +
2425 +       .globl  copy_to_fs
2426 +       .type   copy_to_fs, @function
2427 +copy_to_fs:
2428 +       pushw   %es
2429 +       pushw   %fs
2430 +       popw    %es
2431 +       call    memcpy
2432 +       popw    %es
2433 +       ret
2434 +       .size   copy_to_fs, .-copy_to_fs
2435 +
2436 +#if 0 /* Not currently used, but can be enabled as needed */
2437 +
2438 +       .globl  copy_from_gs
2439 +       .type   copy_from_gs, @function
2440 +copy_from_gs:
2441 +       pushw   %ds
2442 +       pushw   %gs
2443 +       popw    %ds
2444 +       call    memcpy
2445 +       popw    %ds
2446 +       ret
2447 +       .size   copy_from_gs, .-copy_from_gs
2448 +       .globl  copy_to_gs
2449 +
2450 +       .type   copy_to_gs, @function
2451 +copy_to_gs:
2452 +       pushw   %es
2453 +       pushw   %gs
2454 +       popw    %es
2455 +       call    memcpy
2456 +       popw    %es
2457 +       ret
2458 +       .size   copy_to_gs, .-copy_to_gs
2459 +
2460 +#endif
2461 diff -puN /dev/null arch/i386/boot/cpu.c
2462 --- /dev/null
2463 +++ a/arch/i386/boot/cpu.c
2464 @@ -0,0 +1,69 @@
2465 +/* -*- linux-c -*- ------------------------------------------------------- *
2466 + *
2467 + *   Copyright (C) 1991, 1992 Linus Torvalds
2468 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
2469 + *
2470 + *   This file is part of the Linux kernel, and is made available under
2471 + *   the terms of the GNU General Public License version 2.
2472 + *
2473 + * ----------------------------------------------------------------------- */
2474 +
2475 +/*
2476 + * arch/i386/boot/cpucheck.c
2477 + *
2478 + * Check for obligatory CPU features and abort if the features are not
2479 + * present.
2480 + */
2481 +
2482 +#include "boot.h"
2483 +#include "bitops.h"
2484 +#include <asm/cpufeature.h>
2485 +
2486 +static char *cpu_name(int level)
2487 +{
2488 +       static char buf[6];
2489 +
2490 +       if (level == 64) {
2491 +               return "x86-64";
2492 +       } else {
2493 +               sprintf(buf, "i%d86", level);
2494 +               return buf;
2495 +       }
2496 +}
2497 +
2498 +int validate_cpu(void)
2499 +{
2500 +       u32 *err_flags;
2501 +       int cpu_level, req_level;
2502 +
2503 +       check_cpu(&cpu_level, &req_level, &err_flags);
2504 +
2505 +       if (cpu_level < req_level) {
2506 +               printf("This kernel requires an %s CPU, ",
2507 +                      cpu_name(req_level));
2508 +               printf("but only detected an %s CPU.\n",
2509 +                      cpu_name(cpu_level));
2510 +               return -1;
2511 +       }
2512 +
2513 +       if (err_flags) {
2514 +               int i, j;
2515 +               puts("This kernel requires the following features "
2516 +                    "not present on the CPU:\n");
2517 +
2518 +               for (i = 0; i < NCAPINTS; i++) {
2519 +                       u32 e = err_flags[i];
2520 +
2521 +                       for (j = 0; j < 32; j++) {
2522 +                               if (e & 1)
2523 +                                       printf("%d:%d ", i, j);
2524 +
2525 +                               e >>= 1;
2526 +                       }
2527 +               }
2528 +               putchar('\n');
2529 +               return -1;
2530 +       } else {
2531 +               return 0;
2532 +       }
2533 +}
2534 diff -puN /dev/null arch/i386/boot/cpucheck.c
2535 --- /dev/null
2536 +++ a/arch/i386/boot/cpucheck.c
2537 @@ -0,0 +1,266 @@
2538 +/* -*- linux-c -*- ------------------------------------------------------- *
2539 + *
2540 + *   Copyright (C) 1991, 1992 Linus Torvalds
2541 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
2542 + *
2543 + *   This file is part of the Linux kernel, and is made available under
2544 + *   the terms of the GNU General Public License version 2.
2545 + *
2546 + * ----------------------------------------------------------------------- */
2547 +
2548 +/*
2549 + * arch/i386/boot/cpu.c
2550 + *
2551 + * Check for obligatory CPU features and abort if the features are not
2552 + * present.  This code should be compilable as 16-, 32- or 64-bit
2553 + * code, so be very careful with types and inline assembly.
2554 + *
2555 + * This code should not contain any messages; that requires an
2556 + * additional wrapper.
2557 + *
2558 + * As written, this code is not safe for inclusion into the kernel
2559 + * proper (after FPU initialization, in particular).
2560 + */
2561 +
2562 +#ifdef _SETUP
2563 +# include "boot.h"
2564 +# include "bitops.h"
2565 +#endif
2566 +#include <linux/types.h>
2567 +#include <asm/cpufeature.h>
2568 +#include <asm/processor-flags.h>
2569 +#include <asm/required-features.h>
2570 +#include <asm/msr-index.h>
2571 +
2572 +struct cpu_features {
2573 +       int level;
2574 +       int model;
2575 +       u32 flags[NCAPINTS];
2576 +};
2577 +
2578 +static struct cpu_features cpu;
2579 +static u32 cpu_vendor[3];
2580 +static u32 err_flags[NCAPINTS];
2581 +
2582 +#ifdef CONFIG_X86_64
2583 +static const int req_level = 64;
2584 +#elif defined(CONFIG_X86_MINIMUM_CPU_MODEL)
2585 +static const int req_level = CONFIG_X86_MINIMUM_CPU_MODEL;
2586 +#else
2587 +static const int req_level = 3;
2588 +#endif
2589 +
2590 +static const u32 req_flags[NCAPINTS] =
2591 +{
2592 +       REQUIRED_MASK0,
2593 +       REQUIRED_MASK1,
2594 +       REQUIRED_MASK2,
2595 +       REQUIRED_MASK3,
2596 +       REQUIRED_MASK4,
2597 +       REQUIRED_MASK5,
2598 +       REQUIRED_MASK6,
2599 +};
2600 +
2601 +#define A32(a,b,c,d) (((d) << 24)+((c) << 16)+((b) << 8)+(a))
2602 +
2603 +static int is_amd(void)
2604 +{
2605 +       return cpu_vendor[0] == A32('A','u','t','h') &&
2606 +              cpu_vendor[1] == A32('e','n','t','i') &&
2607 +              cpu_vendor[2] == A32('c','A','M','D');
2608 +}
2609 +
2610 +static int is_centaur(void)
2611 +{
2612 +       return cpu_vendor[0] == A32('C','e','n','t') &&
2613 +              cpu_vendor[1] == A32('a','u','r','H') &&
2614 +              cpu_vendor[2] == A32('a','u','l','s');
2615 +}
2616 +
2617 +static int is_transmeta(void)
2618 +{
2619 +       return cpu_vendor[0] == A32('G','e','n','u') &&
2620 +              cpu_vendor[1] == A32('i','n','e','T') &&
2621 +              cpu_vendor[2] == A32('M','x','8','6');
2622 +}
2623 +
2624 +static int has_fpu(void)
2625 +{
2626 +       u16 fcw = -1, fsw = -1;
2627 +       u32 cr0;
2628 +
2629 +       asm("movl %%cr0,%0" : "=r" (cr0));
2630 +       if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
2631 +               cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
2632 +               asm volatile("movl %0,%%cr0" : : "r" (cr0));
2633 +       }
2634 +
2635 +       asm("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw));
2636 +
2637 +       return fsw == 0 && (fcw & 0x103f) == 0x003f;
2638 +}
2639 +
2640 +static int has_eflag(u32 mask)
2641 +{
2642 +       u32 f0, f1;
2643 +
2644 +       asm("pushfl ; "
2645 +           "pushfl ; "
2646 +           "popl %0 ; "
2647 +           "movl %0,%1 ; "
2648 +           "xorl %2,%1 ; "
2649 +           "pushl %1 ; "
2650 +           "popfl ; "
2651 +           "pushfl ; "
2652 +           "popl %1 ; "
2653 +           "popfl"
2654 +           : "=r" (f0), "=r" (f1)
2655 +           : "g" (mask));
2656 +
2657 +       return !!((f0^f1) & mask);
2658 +}
2659 +
2660 +static void get_flags(void)
2661 +{
2662 +       u32 max_intel_level, max_amd_level;
2663 +       u32 tfms;
2664 +
2665 +       if (has_fpu())
2666 +               set_bit(X86_FEATURE_FPU, cpu.flags);
2667 +
2668 +       if (has_eflag(X86_EFLAGS_ID)) {
2669 +               asm("cpuid"
2670 +                   : "=a" (max_intel_level),
2671 +                     "=b" (cpu_vendor[0]),
2672 +                     "=d" (cpu_vendor[1]),
2673 +                     "=c" (cpu_vendor[2])
2674 +                   : "a" (0));
2675 +
2676 +               if (max_intel_level >= 0x00000001 &&
2677 +                   max_intel_level <= 0x0000ffff) {
2678 +                       asm("cpuid"
2679 +                           : "=a" (tfms),
2680 +                             "=c" (cpu.flags[4]),
2681 +                             "=d" (cpu.flags[0])
2682 +                           : "a" (0x00000001)
2683 +                           : "ebx");
2684 +                       cpu.level = (tfms >> 8) & 15;
2685 +                       cpu.model = (tfms >> 4) & 15;
2686 +                       if (cpu.level >= 6)
2687 +                               cpu.model += ((tfms >> 16) & 0xf) << 4;
2688 +               }
2689 +
2690 +               asm("cpuid"
2691 +                   : "=a" (max_amd_level)
2692 +                   : "a" (0x80000000)
2693 +                   : "ebx", "ecx", "edx");
2694 +
2695 +               if (max_amd_level >= 0x80000001 &&
2696 +                   max_amd_level <= 0x8000ffff) {
2697 +                       u32 eax = 0x80000001;
2698 +                       asm("cpuid"
2699 +                           : "+a" (eax),
2700 +                             "=c" (cpu.flags[6]),
2701 +                             "=d" (cpu.flags[1])
2702 +                           : : "ebx");
2703 +               }
2704 +       }
2705 +}
2706 +
2707 +/* Returns a bitmask of which words we have error bits in */
2708 +static int check_flags(void)
2709 +{
2710 +       u32 err;
2711 +       int i;
2712 +
2713 +       err = 0;
2714 +       for (i = 0; i < NCAPINTS; i++) {
2715 +               err_flags[i] = req_flags[i] & ~cpu.flags[i];
2716 +               if (err_flags[i])
2717 +                       err |= 1 << i;
2718 +       }
2719 +
2720 +       return err;
2721 +}
2722 +
2723 +/*
2724 + * Returns -1 on error.
2725 + *
2726 + * *cpu_level is set to the current CPU level; *req_level to the required
2727 + * level.  x86-64 is considered level 64 for this purpose.
2728 + *
2729 + * *err_flags_ptr is set to the flags error array if there are flags missing.
2730 + */
2731 +int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
2732 +{
2733 +       int err;
2734 +
2735 +       memset(&cpu.flags, 0, sizeof cpu.flags);
2736 +       cpu.level = 3;
2737 +
2738 +       if (has_eflag(X86_EFLAGS_AC))
2739 +               cpu.level = 4;
2740 +
2741 +       get_flags();
2742 +       err = check_flags();
2743 +
2744 +       if (test_bit(X86_FEATURE_LM, cpu.flags))
2745 +               cpu.level = 64;
2746 +
2747 +       if (err == 0x01 &&
2748 +           !(err_flags[0] &
2749 +             ~((1 << X86_FEATURE_XMM)|(1 << X86_FEATURE_XMM2))) &&
2750 +           is_amd()) {
2751 +               /* If this is an AMD and we're only missing SSE+SSE2, try to
2752 +                  turn them on */
2753 +
2754 +               u32 ecx = MSR_K7_HWCR;
2755 +               u32 eax, edx;
2756 +
2757 +               asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
2758 +               eax &= ~(1 << 15);
2759 +               asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
2760 +
2761 +               get_flags();    /* Make sure it really did something */
2762 +               err = check_flags();
2763 +       } else if (err == 0x01 &&
2764 +                  !(err_flags[0] & ~(1 << X86_FEATURE_CX8)) &&
2765 +                  is_centaur() && cpu.model >= 6) {
2766 +               /* If this is a VIA C3, we might have to enable CX8
2767 +                  explicitly */
2768 +
2769 +               u32 ecx = MSR_VIA_FCR;
2770 +               u32 eax, edx;
2771 +
2772 +               asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
2773 +               eax |= (1<<1)|(1<<7);
2774 +               asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
2775 +
2776 +               set_bit(X86_FEATURE_CX8, cpu.flags);
2777 +               err = check_flags();
2778 +       } else if (err == 0x01 && is_transmeta()) {
2779 +               /* Transmeta might have masked feature bits in word 0 */
2780 +
2781 +               u32 ecx = 0x80860004;
2782 +               u32 eax, edx;
2783 +               u32 level = 1;
2784 +
2785 +               asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
2786 +               asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
2787 +               asm("cpuid"
2788 +                   : "+a" (level), "=d" (cpu.flags[0])
2789 +                   : : "ecx", "ebx");
2790 +               asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
2791 +
2792 +               err = check_flags();
2793 +       }
2794 +
2795 +       if (err_flags_ptr)
2796 +               *err_flags_ptr = err ? err_flags : NULL;
2797 +       if (cpu_level_ptr)
2798 +               *cpu_level_ptr = cpu.level;
2799 +       if (req_level_ptr)
2800 +               *req_level_ptr = req_level;
2801 +
2802 +       return (cpu.level < req_level || err) ? -1 : 0;
2803 +}
2804 diff -puN arch/i386/boot/edd.S~git-newsetup /dev/null
2805 --- a/arch/i386/boot/edd.S
2806 +++ /dev/null
2807 @@ -1,231 +0,0 @@
2808 -/*
2809 - * BIOS Enhanced Disk Drive support
2810 - * Copyright (C) 2002, 2003, 2004 Dell, Inc.
2811 - * by Matt Domsch <Matt_Domsch@dell.com> October 2002
2812 - * conformant to T13 Committee www.t13.org
2813 - *   projects 1572D, 1484D, 1386D, 1226DT
2814 - * disk signature read by Matt Domsch <Matt_Domsch@dell.com>
2815 - *     and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004
2816 - * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net>
2817 - *      March 2004
2818 - * Command line option parsing, Matt Domsch, November 2004
2819 - */
2820 -
2821 -#include <linux/edd.h>
2822 -#include <asm/setup.h>
2823 -
2824 -#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
2825 -
2826 -# It is assumed that %ds == INITSEG here
2827 -
2828 -       movb    $0, (EDD_MBR_SIG_NR_BUF)
2829 -       movb    $0, (EDDNR)
2830 -
2831 -# Check the command line for options:
2832 -# edd=of  disables EDD completely  (edd=off)
2833 -# edd=sk  skips the MBR test    (edd=skipmbr)
2834 -# edd=on  re-enables EDD (edd=on)
2835 -
2836 -       pushl   %esi
2837 -       movw    $edd_mbr_sig_start, %di # Default to edd=on
2838 -
2839 -       movl    %cs:(cmd_line_ptr), %esi
2840 -       andl    %esi, %esi
2841 -       jz      old_cl                  # Old boot protocol?
2842 -
2843 -# Convert to a real-mode pointer in fs:si
2844 -       movl    %esi, %eax
2845 -       shrl    $4, %eax
2846 -       movw    %ax, %fs
2847 -       andw    $0xf, %si
2848 -       jmp     have_cl_pointer
2849 -
2850 -# Old-style boot protocol?
2851 -old_cl:
2852 -       push    %ds                     # aka INITSEG
2853 -       pop     %fs
2854 -
2855 -       cmpw    $0xa33f, (0x20)
2856 -       jne     done_cl                 # No command line at all?
2857 -       movw    (0x22), %si             # Pointer relative to INITSEG
2858 -
2859 -# fs:si has the pointer to the command line now
2860 -have_cl_pointer:
2861 -
2862 -# Loop through kernel command line one byte at a time.  Just in
2863 -# case the loader is buggy and failed to null-terminate the command line
2864 -# terminate if we get close enough to the end of the segment that we
2865 -# cannot fit "edd=XX"...
2866 -cl_atspace:
2867 -       cmpw    $-5, %si                # Watch for segment wraparound
2868 -       jae     done_cl
2869 -       movl    %fs:(%si), %eax
2870 -       andb    %al, %al                # End of line?
2871 -       jz      done_cl
2872 -       cmpl    $EDD_CL_EQUALS, %eax
2873 -       jz      found_edd_equals
2874 -       cmpb    $0x20, %al              # <= space consider whitespace
2875 -       ja      cl_skipword
2876 -       incw    %si
2877 -       jmp     cl_atspace
2878 -
2879 -cl_skipword:
2880 -       cmpw    $-5, %si                # Watch for segment wraparound
2881 -       jae     done_cl
2882 -       movb    %fs:(%si), %al          # End of string?
2883 -       andb    %al, %al
2884 -       jz      done_cl
2885 -       cmpb    $0x20, %al
2886 -       jbe     cl_atspace
2887 -       incw    %si
2888 -       jmp     cl_skipword
2889 -
2890 -found_edd_equals:
2891 -# only looking at first two characters after equals
2892 -# late overrides early on the command line, so keep going after finding something
2893 -       movw    %fs:4(%si), %ax
2894 -       cmpw    $EDD_CL_OFF, %ax        # edd=of
2895 -       je      do_edd_off
2896 -       cmpw    $EDD_CL_SKIP, %ax       # edd=sk
2897 -       je      do_edd_skipmbr
2898 -       cmpw    $EDD_CL_ON, %ax         # edd=on
2899 -       je      do_edd_on
2900 -       jmp     cl_skipword
2901 -do_edd_skipmbr:
2902 -       movw    $edd_start, %di
2903 -       jmp     cl_skipword
2904 -do_edd_off:
2905 -       movw    $edd_done, %di
2906 -       jmp     cl_skipword
2907 -do_edd_on:
2908 -       movw    $edd_mbr_sig_start, %di
2909 -       jmp     cl_skipword
2910 -
2911 -done_cl:
2912 -       popl    %esi
2913 -       jmpw    *%di
2914 -
2915 -# Read the first sector of each BIOS disk device and store the 4-byte signature
2916 -edd_mbr_sig_start:
2917 -       movb    $0x80, %dl                      # from device 80
2918 -       movw    $EDD_MBR_SIG_BUF, %bx           # store buffer ptr in bx
2919 -edd_mbr_sig_read:
2920 -       movl    $0xFFFFFFFF, %eax
2921 -       movl    %eax, (%bx)                     # assume failure
2922 -       pushw   %bx
2923 -       movb    $READ_SECTORS, %ah
2924 -       movb    $1, %al                         # read 1 sector
2925 -       movb    $0, %dh                         # at head 0
2926 -       movw    $1, %cx                         # cylinder 0, sector 0
2927 -       pushw   %es
2928 -       pushw   %ds
2929 -       popw    %es
2930 -       movw    $EDDBUF, %bx                    # disk's data goes into EDDBUF
2931 -       pushw   %dx             # work around buggy BIOSes
2932 -       stc                     # work around buggy BIOSes
2933 -       int     $0x13
2934 -       sti                     # work around buggy BIOSes
2935 -       popw    %dx
2936 -       popw    %es
2937 -       popw    %bx
2938 -       jc      edd_mbr_sig_done                # on failure, we're done.
2939 -       cmpb    $0, %ah         # some BIOSes do not set CF
2940 -       jne     edd_mbr_sig_done                # on failure, we're done.
2941 -       movl    (EDDBUF+EDD_MBR_SIG_OFFSET), %eax # read sig out of the MBR
2942 -       movl    %eax, (%bx)                     # store success
2943 -       incb    (EDD_MBR_SIG_NR_BUF)            # note that we stored something
2944 -       incb    %dl                             # increment to next device
2945 -       addw    $4, %bx                         # increment sig buffer ptr
2946 -       cmpb    $EDD_MBR_SIG_MAX, (EDD_MBR_SIG_NR_BUF)  # Out of space?
2947 -       jb      edd_mbr_sig_read                # keep looping
2948 -edd_mbr_sig_done:
2949 -
2950 -# Do the BIOS Enhanced Disk Drive calls
2951 -# This consists of two calls:
2952 -#    int 13h ah=41h "Check Extensions Present"
2953 -#    int 13h ah=48h "Get Device Parameters"
2954 -#    int 13h ah=08h "Legacy Get Device Parameters"
2955 -#
2956 -# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use
2957 -# in the boot_params at EDDBUF.  The first four bytes of which are
2958 -# used to store the device number, interface support map and version
2959 -# results from fn41.  The next four bytes are used to store the legacy
2960 -# cylinders, heads, and sectors from fn08. The following 74 bytes are used to
2961 -# store the results from fn48.  Starting from device 80h, fn41, then fn48
2962 -# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE).
2963 -# Then the pointer is incremented to store the data for the next call.
2964 -# This repeats until either a device doesn't exist, or until EDDMAXNR
2965 -# devices have been stored.
2966 -# The one tricky part is that ds:si always points EDDEXTSIZE bytes into
2967 -# the structure, and the fn41 and fn08 results are stored at offsets
2968 -# from there.  This removes the need to increment the pointer for
2969 -# every store, and leaves it ready for the fn48 call.
2970 -# A second one-byte buffer, EDDNR, in the boot_params stores
2971 -# the number of BIOS devices which exist, up to EDDMAXNR.
2972 -# In setup.c, copy_edd() stores both boot_params buffers away
2973 -# for later use, as they would get overwritten otherwise.
2974 -# This code is sensitive to the size of the structs in edd.h
2975 -edd_start:
2976 -                                               # %ds points to the bootsector
2977 -                                                       # result buffer for fn48
2978 -       movw    $EDDBUF+EDDEXTSIZE, %si         # in ds:si, fn41 results
2979 -                                               # kept just before that
2980 -       movb    $0x80, %dl                      # BIOS device 0x80
2981 -
2982 -edd_check_ext:
2983 -       movb    $CHECKEXTENSIONSPRESENT, %ah    # Function 41
2984 -       movw    $EDDMAGIC1, %bx                 # magic
2985 -       int     $0x13                           # make the call
2986 -       jc      edd_done                        # no more BIOS devices
2987 -
2988 -       cmpw    $EDDMAGIC2, %bx                 # is magic right?
2989 -       jne     edd_next                        # nope, next...
2990 -
2991 -       movb    %dl, %ds:-8(%si)                # store device number
2992 -       movb    %ah, %ds:-7(%si)                # store version
2993 -       movw    %cx, %ds:-6(%si)                # store extensions
2994 -       incb    (EDDNR)                         # note that we stored something
2995 -
2996 -edd_get_device_params:
2997 -       movw    $EDDPARMSIZE, %ds:(%si)         # put size
2998 -       movw    $0x0, %ds:2(%si)                # work around buggy BIOSes
2999 -       movb    $GETDEVICEPARAMETERS, %ah       # Function 48
3000 -       int     $0x13                           # make the call
3001 -                                               # Don't check for fail return
3002 -                                               # it doesn't matter.
3003 -edd_get_legacy_chs:
3004 -       xorw    %ax, %ax
3005 -       movw    %ax, %ds:-4(%si)
3006 -       movw    %ax, %ds:-2(%si)
3007 -        # Ralf Brown's Interrupt List says to set ES:DI to
3008 -       # 0000h:0000h "to guard against BIOS bugs"
3009 -       pushw   %es
3010 -       movw    %ax, %es
3011 -       movw    %ax, %di
3012 -       pushw   %dx                             # legacy call clobbers %dl
3013 -       movb    $LEGACYGETDEVICEPARAMETERS, %ah # Function 08
3014 -       int     $0x13                           # make the call
3015 -       jc      edd_legacy_done                 # failed
3016 -       movb    %cl, %al                        # Low 6 bits are max
3017 -       andb    $0x3F, %al                      #   sector number
3018 -       movb    %al, %ds:-1(%si)                # Record max sect
3019 -       movb    %dh, %ds:-2(%si)                # Record max head number
3020 -       movb    %ch, %al                        # Low 8 bits of max cyl
3021 -       shr     $6, %cl
3022 -       movb    %cl, %ah                        # High 2 bits of max cyl
3023 -       movw    %ax, %ds:-4(%si)
3024 -
3025 -edd_legacy_done:
3026 -       popw    %dx
3027 -       popw    %es
3028 -       movw    %si, %ax                        # increment si
3029 -       addw    $EDDPARMSIZE+EDDEXTSIZE, %ax
3030 -       movw    %ax, %si
3031 -
3032 -edd_next:
3033 -       incb    %dl                             # increment to next device
3034 -       cmpb    $EDDMAXNR, (EDDNR)              # Out of space?
3035 -       jb      edd_check_ext                   # keep looping
3036 -
3037 -edd_done:
3038 -#endif
3039 diff -puN /dev/null arch/i386/boot/edd.c
3040 --- /dev/null
3041 +++ a/arch/i386/boot/edd.c
3042 @@ -0,0 +1,196 @@
3043 +/* -*- linux-c -*- ------------------------------------------------------- *
3044 + *
3045 + *   Copyright (C) 1991, 1992 Linus Torvalds
3046 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
3047 + *
3048 + *   This file is part of the Linux kernel, and is made available under
3049 + *   the terms of the GNU General Public License version 2.
3050 + *
3051 + * ----------------------------------------------------------------------- */
3052 +
3053 +/*
3054 + * arch/i386/boot/edd.c
3055 + *
3056 + * Get EDD BIOS disk information
3057 + */
3058 +
3059 +#include "boot.h"
3060 +#include <linux/edd.h>
3061 +
3062 +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
3063 +
3064 +struct edd_dapa {
3065 +       u8      pkt_size;
3066 +       u8      rsvd;
3067 +       u16     sector_cnt;
3068 +       u16     buf_off, buf_seg;
3069 +       u64     lba;
3070 +       u64     buf_lin_addr;
3071 +};
3072 +
3073 +/*
3074 + * Note: this uses the heap to hold the loaded sector.
3075 + */
3076 +static int read_sector(u8 devno, u64 lba, void *buf)
3077 +{
3078 +       struct edd_dapa dapa;
3079 +       u16 ax, bx, cx, dx, si;
3080 +
3081 +       memset(&dapa, 0, sizeof dapa);
3082 +       dapa.pkt_size = sizeof(dapa);
3083 +       dapa.sector_cnt = 1;
3084 +       dapa.buf_off = (size_t)buf;
3085 +       dapa.buf_seg = ds();
3086 +       dapa.lba = lba;
3087 +
3088 +       ax = 0x4200;            /* Extended Read */
3089 +       si = (size_t)&dapa;
3090 +       dx = devno;
3091 +       asm("pushfl; stc; int $0x13; setc %%al; popfl"
3092 +           : "+a" (ax), "+S" (si), "+d" (dx)
3093 +           : "m" (dapa)
3094 +           : "ebx", "ecx", "edi", "memory");
3095 +
3096 +       if (!(u8)ax)
3097 +               return 0;       /* OK */
3098 +
3099 +       ax = 0x0201;            /* Legacy Read, one sector */
3100 +       cx = 0x0001;            /* Sector 0-0-1 */
3101 +       dx = devno;
3102 +       bx = (size_t)buf;
3103 +       asm("pushfl; stc; int $0x13; setc %%al; popfl"
3104 +           : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
3105 +           : : "esi", "edi", "memory");
3106 +
3107 +       return -(u8)ax;         /* 0 or -1 */
3108 +}
3109 +
3110 +static u32 read_mbr_sig(u8 devno, struct edd_info *ei)
3111 +{
3112 +       int sector_size;
3113 +       char *mbrbuf_ptr, *mbrbuf_end;
3114 +       u32 mbrsig;
3115 +       u32 buf_base, mbr_base;
3116 +       extern char _end[];
3117 +       static char mbr_buf[1024];
3118 +
3119 +       sector_size = ei->params.bytes_per_sector;
3120 +       if (!sector_size)
3121 +               sector_size = 512; /* Best available guess */
3122 +
3123 +       buf_base = (ds() << 4) + (u32)&_end;
3124 +       mbr_base = (buf_base+sector_size-1) & ~(sector_size-1);
3125 +       mbrbuf_ptr = mbr_buf + (mbr_base-buf_base);
3126 +       mbrbuf_end = mbrbuf_ptr + sector_size;
3127 +
3128 +       if (!(boot_params.hdr.loadflags & CAN_USE_HEAP))
3129 +               return 0;
3130 +       if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr)
3131 +               return 0;
3132 +
3133 +       if (read_sector(devno, 0, mbrbuf_ptr))
3134 +               return 0;
3135 +
3136 +       mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET];
3137 +       return mbrsig;
3138 +}
3139 +
3140 +static int get_edd_info(u8 devno, struct edd_info *ei)
3141 +{
3142 +       u16 ax, bx, cx, dx, di;
3143 +
3144 +       memset(ei, 0, sizeof *ei);
3145 +
3146 +       /* Check Extensions Present */
3147 +
3148 +       ax = 0x4100;
3149 +       bx = EDDMAGIC1;
3150 +       dx = devno;
3151 +       asm("pushfl; stc; int $0x13; setc %%al; popfl"
3152 +           : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
3153 +           : : "esi", "edi");
3154 +
3155 +       if ((u8)ax)
3156 +               return -1;      /* No extended information */
3157 +
3158 +       if (bx != EDDMAGIC2)
3159 +               return -1;
3160 +
3161 +       ei->device  = devno;
3162 +       ei->version = ax >> 8;  /* EDD version number */
3163 +       ei->interface_support = cx; /* EDD functionality subsets */
3164 +
3165 +       /* Extended Get Device Parameters */
3166 +
3167 +       ei->params.length = sizeof(ei->params);
3168 +       ax = 0x4800;
3169 +       dx = devno;
3170 +       asm("pushfl; int $0x13; popfl"
3171 +           : "+a" (ax), "+d" (dx)
3172 +           : "S" (&ei->params)
3173 +           : "ebx", "ecx", "edi");
3174 +
3175 +       /* Get legacy CHS parameters */
3176 +
3177 +       /* Ralf Brown recommends setting ES:DI to 0:0 */
3178 +       ax = 0x0800;
3179 +       dx = devno;
3180 +       di = 0;
3181 +       asm("pushw %%es; "
3182 +           "movw %%di,%%es; "
3183 +           "pushfl; stc; int $0x13; setc %%al; popfl; "
3184 +           "popw %%es"
3185 +           : "+a" (ax), "=b" (bx), "=c" (cx), "+d" (dx), "+D" (di)
3186 +           : : "esi");
3187 +
3188 +       if ((u8)ax == 0) {
3189 +               ei->legacy_max_cylinder = (cx >> 8) + ((cx & 0xc0) << 2);
3190 +               ei->legacy_max_head = dx >> 8;
3191 +               ei->legacy_sectors_per_track = cx & 0x3f;
3192 +       }
3193 +
3194 +       return 0;
3195 +}
3196 +
3197 +void query_edd(void)
3198 +{
3199 +       char eddarg[8];
3200 +       int do_mbr = 1;
3201 +       int do_edd = 1;
3202 +       int devno;
3203 +       struct edd_info ei, *edp;
3204 +
3205 +       if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) {
3206 +               if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip"))
3207 +                       do_mbr = 0;
3208 +               else if (!strcmp(eddarg, "off"))
3209 +                       do_edd = 0;
3210 +       }
3211 +
3212 +       edp = (struct edd_info *)boot_params.eddbuf;
3213 +
3214 +       if (!do_edd)
3215 +               return;
3216 +
3217 +       for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
3218 +               /*
3219 +                * Scan the BIOS-supported hard disks and query EDD
3220 +                * information...
3221 +                */
3222 +               get_edd_info(devno, &ei);
3223 +
3224 +               if (boot_params.eddbuf_entries < EDDMAXNR) {
3225 +                       memcpy(edp, &ei, sizeof ei);
3226 +                       edp++;
3227 +                       boot_params.eddbuf_entries++;
3228 +               }
3229 +
3230 +               if (do_mbr) {
3231 +                       u32 mbr_sig;
3232 +                       mbr_sig = read_mbr_sig(devno, &ei);
3233 +                       boot_params.edd_mbr_sig_buffer[devno-0x80] = mbr_sig;
3234 +               }
3235 +       }
3236 +}
3237 +
3238 +#endif
3239 diff -puN /dev/null arch/i386/boot/header.S
3240 --- /dev/null
3241 +++ a/arch/i386/boot/header.S
3242 @@ -0,0 +1,283 @@
3243 +/*
3244 + *     header.S
3245 + *
3246 + *     Copyright (C) 1991, 1992 Linus Torvalds
3247 + *
3248 + *     Based on bootsect.S and setup.S
3249 + *     modified by more people than can be counted
3250 + *
3251 + *     Rewritten as a common file by H. Peter Anvin (Apr 2007)
3252 + *
3253 + * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
3254 + * addresses must be multiplied by 16 to obtain their respective linear
3255 + * addresses. To avoid confusion, linear addresses are written using leading
3256 + * hex while segment addresses are written as segment:offset.
3257 + *
3258 + */
3259 +
3260 +#include <asm/segment.h>
3261 +#include <linux/utsrelease.h>
3262 +#include <asm/boot.h>
3263 +#include <asm/e820.h>
3264 +#include <asm/page.h>
3265 +#include <asm/setup.h>
3266 +#include "boot.h"
3267 +
3268 +SETUPSECTS     = 4                     /* default nr of setup-sectors */
3269 +BOOTSEG                = 0x07C0                /* original address of boot-sector */
3270 +SYSSEG         = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
3271 +SYSSIZE                = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
3272 +                                       /* to be loaded */
3273 +ROOT_DEV       = 0                     /* ROOT_DEV is now written by "build" */
3274 +SWAP_DEV       = 0                     /* SWAP_DEV is now written by "build" */
3275 +
3276 +#ifndef SVGA_MODE
3277 +#define SVGA_MODE ASK_VGA
3278 +#endif
3279 +
3280 +#ifndef RAMDISK
3281 +#define RAMDISK 0
3282 +#endif
3283 +
3284 +#ifndef ROOT_RDONLY
3285 +#define ROOT_RDONLY 1
3286 +#endif
3287 +
3288 +       .code16
3289 +       .section ".bstext", "ax"
3290 +
3291 +       .global bootsect_start
3292 +bootsect_start:
3293 +
3294 +       # Normalize the start address
3295 +       ljmp    $BOOTSEG, $start2
3296 +
3297 +start2:
3298 +       movw    %cs, %ax
3299 +       movw    %ax, %ds
3300 +       movw    %ax, %es
3301 +       movw    %ax, %ss
3302 +       xorw    %sp, %sp
3303 +       sti
3304 +       cld
3305 +
3306 +       movw    $bugger_off_msg, %si
3307 +
3308 +msg_loop:
3309 +       lodsb
3310 +       andb    %al, %al
3311 +       jz      bs_die
3312 +       movb    $0xe, %ah
3313 +       movw    $7, %bx
3314 +       int     $0x10
3315 +       jmp     msg_loop
3316 +
3317 +bs_die:
3318 +       # Allow the user to press a key, then reboot
3319 +       xorw    %ax, %ax
3320 +       int     $0x16
3321 +       int     $0x19
3322 +
3323 +       # int 0x19 should never return.  In case it does anyway,
3324 +       # invoke the BIOS reset code...
3325 +       ljmp    $0xf000,$0xfff0
3326 +
3327 +       .section ".bsdata", "a"
3328 +bugger_off_msg:
3329 +       .ascii  "Direct booting from floppy is no longer supported.\r\n"
3330 +       .ascii  "Please use a boot loader program instead.\r\n"
3331 +       .ascii  "\n"
3332 +       .ascii  "Remove disk and press any key to reboot . . .\r\n"
3333 +       .byte   0
3334 +
3335 +
3336 +       # Kernel attributes; used by setup.  This is part 1 of the
3337 +       # header, from the old boot sector.
3338 +
3339 +       .section ".header", "a"
3340 +       .globl  hdr
3341 +hdr:
3342 +setup_sects:   .byte SETUPSECTS
3343 +root_flags:    .word ROOT_RDONLY
3344 +syssize:       .long SYSSIZE
3345 +ram_size:      .word RAMDISK
3346 +vid_mode:      .word SVGA_MODE
3347 +root_dev:      .word ROOT_DEV
3348 +boot_flag:     .word 0xAA55
3349 +
3350 +       # offset 512, entry point
3351 +
3352 +       .globl  _start
3353 +_start:
3354 +               # Explicitly enter this as bytes, or the assembler
3355 +               # tries to generate a 3-byte jump here, which causes
3356 +               # everything else to push off to the wrong offset.
3357 +               .byte   0xeb            # short (2-byte) jump
3358 +               .byte   start_of_setup-1f
3359 +1:
3360 +
3361 +       # Part 2 of the header, from the old setup.S
3362 +
3363 +               .ascii  "HdrS"          # header signature
3364 +               .word   0x0206          # header version number (>= 0x0105)
3365 +                                       # or else old loadlin-1.5 will fail)
3366 +               .globl realmode_swtch
3367 +realmode_swtch:        .word   0, 0            # default_switch, SETUPSEG
3368 +start_sys_seg: .word   SYSSEG
3369 +               .word   kernel_version-512 # pointing to kernel version string
3370 +                                       # above section of header is compatible
3371 +                                       # with loadlin-1.5 (header v1.5). Don't
3372 +                                       # change it.
3373 +
3374 +type_of_loader:        .byte   0               # = 0, old one (LILO, Loadlin,
3375 +                                       #      Bootlin, SYSLX, bootsect...)
3376 +                                       # See Documentation/i386/boot.txt for
3377 +                                       # assigned ids
3378 +
3379 +# flags, unused bits must be zero (RFU) bit within loadflags
3380 +loadflags:
3381 +LOADED_HIGH    = 1                     # If set, the kernel is loaded high
3382 +CAN_USE_HEAP   = 0x80                  # If set, the loader also has set
3383 +                                       # heap_end_ptr to tell how much
3384 +                                       # space behind setup.S can be used for
3385 +                                       # heap purposes.
3386 +                                       # Only the loader knows what is free
3387 +#ifndef __BIG_KERNEL__
3388 +               .byte   0
3389 +#else
3390 +               .byte   LOADED_HIGH
3391 +#endif
3392 +
3393 +setup_move_size: .word  0x8000         # size to move, when setup is not
3394 +                                       # loaded at 0x90000. We will move setup
3395 +                                       # to 0x90000 then just before jumping
3396 +                                       # into the kernel. However, only the
3397 +                                       # loader knows how much data behind
3398 +                                       # us also needs to be loaded.
3399 +
3400 +code32_start:                          # here loaders can put a different
3401 +                                       # start address for 32-bit code.
3402 +#ifndef __BIG_KERNEL__
3403 +               .long   0x1000          #   0x1000 = default for zImage
3404 +#else
3405 +               .long   0x100000        # 0x100000 = default for big kernel
3406 +#endif
3407 +
3408 +ramdisk_image: .long   0               # address of loaded ramdisk image
3409 +                                       # Here the loader puts the 32-bit
3410 +                                       # address where it loaded the image.
3411 +                                       # This only will be read by the kernel.
3412 +
3413 +ramdisk_size:  .long   0               # its size in bytes
3414 +
3415 +bootsect_kludge:
3416 +               .long   0               # obsolete
3417 +
3418 +heap_end_ptr:  .word   _end+1024       # (Header version 0x0201 or later)
3419 +                                       # space from here (exclusive) down to
3420 +                                       # end of setup code can be used by setup
3421 +                                       # for local heap purposes.
3422 +
3423 +pad1:          .word   0
3424 +cmd_line_ptr:  .long   0               # (Header version 0x0202 or later)
3425 +                                       # If nonzero, a 32-bit pointer
3426 +                                       # to the kernel command line.
3427 +                                       # The command line should be
3428 +                                       # located between the start of
3429 +                                       # setup and the end of low
3430 +                                       # memory (0xa0000), or it may
3431 +                                       # get overwritten before it
3432 +                                       # gets read.  If this field is
3433 +                                       # used, there is no longer
3434 +                                       # anything magical about the
3435 +                                       # 0x90000 segment; the setup
3436 +                                       # can be located anywhere in
3437 +                                       # low memory 0x10000 or higher.
3438 +
3439 +ramdisk_max:   .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
3440 +                                       # (Header version 0x0203 or later)
3441 +                                       # The highest safe address for
3442 +                                       # the contents of an initrd
3443 +
3444 +kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN #physical addr alignment
3445 +                                               #required for protected mode
3446 +                                               #kernel
3447 +#ifdef CONFIG_RELOCATABLE
3448 +relocatable_kernel:    .byte 1
3449 +#else
3450 +relocatable_kernel:    .byte 0
3451 +#endif
3452 +pad2:                  .byte 0
3453 +pad3:                  .word 0
3454 +
3455 +cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
3456 +                                                #added with boot protocol
3457 +                                                #version 2.06
3458 +
3459 +# End of setup header #####################################################
3460 +
3461 +       .section ".inittext", "ax"
3462 +start_of_setup:
3463 +#ifdef SAFE_RESET_DISK_CONTROLLER
3464 +# Reset the disk controller.
3465 +       movw    $0x0000, %ax            # Reset disk controller
3466 +       movb    $0x80, %dl              # All disks
3467 +       int     $0x13
3468 +#endif
3469 +
3470 +# We will have entired with %cs = %ds+0x20, normalize %cs so
3471 +# it is on par with the other segments.
3472 +       pushw   %ds
3473 +       pushw   $setup2
3474 +       lretw
3475 +
3476 +setup2:
3477 +# Force %es = %ds
3478 +       movw    %ds, %ax
3479 +       movw    %ax, %es
3480 +       cld
3481 +
3482 +# Stack paranoia: align the stack and make sure it is good
3483 +# for both 16- and 32-bit references.  In particular, if we
3484 +# were meant to have been using the full 16-bit segment, the
3485 +# caller might have set %sp to zero, which breaks %esp-based
3486 +# references.
3487 +       andw    $~3, %sp        # dword align (might as well...)
3488 +       jnz     1f
3489 +       movw    $0xfffc, %sp    # Make sure we're not zero
3490 +1:     movzwl  %sp, %esp       # Clear upper half of %esp
3491 +       sti
3492 +
3493 +# Check signature at end of setup
3494 +       cmpl    $0x5a5aaa55, setup_sig
3495 +       jne     setup_bad
3496 +
3497 +# Zero the bss
3498 +       movw    $__bss_start, %di
3499 +       movw    $_end+3, %cx
3500 +       xorl    %eax, %eax
3501 +       subw    %di, %cx
3502 +       shrw    $2, %cx
3503 +       rep; stosl
3504 +
3505 +# Jump to C code (should not return)
3506 +       calll   main
3507 +
3508 +# Setup corrupt somehow...
3509 +setup_bad:
3510 +       movl    $setup_corrupt, %eax
3511 +       calll   puts
3512 +       # Fall through...
3513 +
3514 +       .globl  die
3515 +       .type   die, @function
3516 +die:
3517 +       hlt
3518 +       jmp     die
3519 +
3520 +       .size   die, .-due
3521 +
3522 +       .section ".initdata", "a"
3523 +setup_corrupt:
3524 +       .byte   7
3525 +       .string "No setup signature found..."
3526 diff -puN /dev/null arch/i386/boot/main.c
3527 --- /dev/null
3528 +++ a/arch/i386/boot/main.c
3529 @@ -0,0 +1,161 @@
3530 +/* -*- linux-c -*- ------------------------------------------------------- *
3531 + *
3532 + *   Copyright (C) 1991, 1992 Linus Torvalds
3533 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
3534 + *
3535 + *   This file is part of the Linux kernel, and is made available under
3536 + *   the terms of the GNU General Public License version 2.
3537 + *
3538 + * ----------------------------------------------------------------------- */
3539 +
3540 +/*
3541 + * arch/i386/boot/main.c
3542 + *
3543 + * Main module for the real-mode kernel code
3544 + */
3545 +
3546 +#include "boot.h"
3547 +
3548 +struct boot_params boot_params __attribute__((aligned(16)));
3549 +
3550 +char *HEAP = _end;
3551 +char *heap_end = _end;         /* Default end of heap = no heap */
3552 +
3553 +/*
3554 + * Copy the header into the boot parameter block.  Since this
3555 + * screws up the old-style command line protocol, adjust by
3556 + * filling in the new-style command line pointer instead.
3557 + */
3558 +#define OLD_CL_MAGIC   0xA33F
3559 +#define OLD_CL_ADDRESS 0x20
3560 +
3561 +static void copy_boot_params(void)
3562 +{
3563 +       struct old_cmdline {
3564 +               u16 cl_magic;
3565 +               u16 cl_offset;
3566 +       };
3567 +       const struct old_cmdline * const oldcmd =
3568 +               (const struct old_cmdline *)OLD_CL_ADDRESS;
3569 +
3570 +       BUILD_BUG_ON(sizeof boot_params != 4096);
3571 +       memcpy(&boot_params.hdr, &hdr, sizeof hdr);
3572 +
3573 +       if (!boot_params.hdr.cmd_line_ptr &&
3574 +           oldcmd->cl_magic == OLD_CL_MAGIC) {
3575 +               /* Old-style command line protocol. */
3576 +               u16 cmdline_seg;
3577 +
3578 +               /* Figure out if the command line falls in the region
3579 +                  of memory that an old kernel would have copied up
3580 +                  to 0x90000... */
3581 +               if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
3582 +                       cmdline_seg = ds();
3583 +               else
3584 +                       cmdline_seg = 0x9000;
3585 +
3586 +               boot_params.hdr.cmd_line_ptr =
3587 +                       (cmdline_seg << 4) + oldcmd->cl_offset;
3588 +       }
3589 +}
3590 +
3591 +/*
3592 + * Set the keyboard repeat rate to maximum.  Unclear why this
3593 + * is done here; this might be possible to kill off as stale code.
3594 + */
3595 +static void keyboard_set_repeat(void)
3596 +{
3597 +       u16 ax = 0x0305;
3598 +       u16 bx = 0;
3599 +       asm volatile("int $0x16"
3600 +                    : "+a" (ax), "+b" (bx)
3601 +                    : : "ecx", "edx", "esi", "edi");
3602 +}
3603 +
3604 +/*
3605 + * Get Intel SpeedStep IST information.
3606 + */
3607 +static void query_speedstep_ist(void)
3608 +{
3609 +       asm("int $0x15"
3610 +           : "=a" (boot_params.speedstep_info[0]),
3611 +             "=b" (boot_params.speedstep_info[1]),
3612 +             "=c" (boot_params.speedstep_info[2]),
3613 +             "=d" (boot_params.speedstep_info[3])
3614 +           : "a" (0x0000e980),  /* IST Support */
3615 +             "d" (0x47534943)); /* Request value */
3616 +}
3617 +
3618 +/*
3619 + * Tell the BIOS what CPU mode we intend to run in.
3620 + */
3621 +static void set_bios_mode(void)
3622 +{
3623 +#ifdef CONFIG_X86_64
3624 +       u32 eax, ebx;
3625 +
3626 +       eax = 0xec00;
3627 +       ebx = 2;
3628 +       asm volatile("int $0x15"
3629 +                    : "+a" (eax), "+b" (ebx)
3630 +                    : : "ecx", "edx", "esi", "edi");
3631 +#endif
3632 +}
3633 +
3634 +void main(void)
3635 +{
3636 +       /* First, copy the boot header into the "zeropage" */
3637 +       copy_boot_params();
3638 +
3639 +       /* End of heap check */
3640 +       if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
3641 +               heap_end = (char *)(boot_params.hdr.heap_end_ptr
3642 +                                   +0x200-STACK_SIZE);
3643 +       } else {
3644 +               /* Boot protocol 2.00 only, no heap available */
3645 +               puts("WARNING: Ancient bootloader, some functionality "
3646 +                    "may be limited!\n");
3647 +       }
3648 +
3649 +       /* Make sure we have all the proper CPU support */
3650 +       if (validate_cpu()) {
3651 +               puts("Unable to boot - please use a kernel appropriate "
3652 +                    "for your CPU.\n");
3653 +               die();
3654 +       }
3655 +
3656 +       /* Tell the BIOS what CPU mode we intend to run in. */
3657 +       set_bios_mode();
3658 +
3659 +       /* Detect memory layout */
3660 +       detect_memory();
3661 +
3662 +       /* Set keyboard repeat rate (why?) */
3663 +       keyboard_set_repeat();
3664 +
3665 +       /* Set the video mode */
3666 +       set_video();
3667 +
3668 +       /* Query MCA information */
3669 +       query_mca();
3670 +
3671 +       /* Voyager */
3672 +#ifdef CONFIG_X86_VOYAGER
3673 +       query_voyager();
3674 +#endif
3675 +
3676 +       /* Query SpeedStep IST information */
3677 +       query_speedstep_ist();
3678 +
3679 +       /* Query APM information */
3680 +#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
3681 +       query_apm_bios();
3682 +#endif
3683 +
3684 +       /* Query EDD information */
3685 +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
3686 +       query_edd();
3687 +#endif
3688 +       /* Do the last things and invoke protected mode */
3689 +       go_to_protected_mode();
3690 +}
3691 diff -puN /dev/null arch/i386/boot/mca.c
3692 --- /dev/null
3693 +++ a/arch/i386/boot/mca.c
3694 @@ -0,0 +1,43 @@
3695 +/* -*- linux-c -*- ------------------------------------------------------- *
3696 + *
3697 + *   Copyright (C) 1991, 1992 Linus Torvalds
3698 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
3699 + *
3700 + *   This file is part of the Linux kernel, and is made available under
3701 + *   the terms of the GNU General Public License version 2.
3702 + *
3703 + * ----------------------------------------------------------------------- */
3704 +
3705 +/*
3706 + * arch/i386/boot/mca.c
3707 + *
3708 + * Get the MCA system description table
3709 + */
3710 +
3711 +#include "boot.h"
3712 +
3713 +int query_mca(void)
3714 +{
3715 +       u8 err;
3716 +       u16 es, bx, len;
3717 +
3718 +       asm("pushw %%es ; "
3719 +           "int $0x15 ; "
3720 +           "setc %0 ; "
3721 +           "movw %%es, %1 ; "
3722 +           "popw %%es"
3723 +           : "=acdSDm" (err), "=acdSDm" (es), "=b" (bx)
3724 +           : "a" (0xc000));
3725 +
3726 +       if (err)
3727 +               return -1;      /* No MCA present */
3728 +
3729 +       set_fs(es);
3730 +       len = rdfs16(bx);
3731 +
3732 +       if (len > sizeof(boot_params.sys_desc_table))
3733 +               len = sizeof(boot_params.sys_desc_table);
3734 +
3735 +       copy_from_fs(&boot_params.sys_desc_table, bx, len);
3736 +       return 0;
3737 +}
3738 diff -puN /dev/null arch/i386/boot/memory.c
3739 --- /dev/null
3740 +++ a/arch/i386/boot/memory.c
3741 @@ -0,0 +1,99 @@
3742 +/* -*- linux-c -*- ------------------------------------------------------- *
3743 + *
3744 + *   Copyright (C) 1991, 1992 Linus Torvalds
3745 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
3746 + *
3747 + *   This file is part of the Linux kernel, and is made available under
3748 + *   the terms of the GNU General Public License version 2.
3749 + *
3750 + * ----------------------------------------------------------------------- */
3751 +
3752 +/*
3753 + * arch/i386/boot/memory.c
3754 + *
3755 + * Memory detection code
3756 + */
3757 +
3758 +#include "boot.h"
3759 +
3760 +#define SMAP   0x534d4150      /* ASCII "SMAP" */
3761 +
3762 +static int detect_memory_e820(void)
3763 +{
3764 +       u32 next = 0;
3765 +       u32 size, id;
3766 +       u8 err;
3767 +       struct e820entry *desc = boot_params.e820_map;
3768 +
3769 +       do {
3770 +               size = sizeof(struct e820entry);
3771 +               id = SMAP;
3772 +               asm("int $0x15; setc %0"
3773 +                   : "=am" (err), "+b" (next), "+d" (id), "+c" (size),
3774 +                     "=m" (*desc)
3775 +                   : "D" (desc), "a" (0xe820));
3776 +
3777 +               if (err || id != SMAP)
3778 +                       break;
3779 +
3780 +               boot_params.e820_entries++;
3781 +               desc++;
3782 +       } while (next && boot_params.e820_entries < E820MAX);
3783 +
3784 +       return boot_params.e820_entries;
3785 +}
3786 +
3787 +static int detect_memory_e801(void)
3788 +{
3789 +       u16 ax, bx, cx, dx;
3790 +       u8 err;
3791 +
3792 +       bx = cx = dx = 0;
3793 +       ax = 0xe801;
3794 +       asm("stc; int $0x15; setc %0"
3795 +           : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
3796 +
3797 +       if (err)
3798 +               return -1;
3799 +
3800 +       /* Do we really need to do this? */
3801 +       if (cx || dx) {
3802 +               ax = cx;
3803 +               bx = dx;
3804 +       }
3805 +
3806 +       if (ax > 15*1024)
3807 +               return -1;      /* Bogus! */
3808 +
3809 +       /* This ignores memory above 16MB if we have a memory hole
3810 +          there.  If someone actually finds a machine with a memory
3811 +          hole at 16MB and no support for 0E820h they should probably
3812 +          generate a fake e820 map. */
3813 +       boot_params.alt_mem_k = (ax == 15*1024) ? (dx << 6)+ax : ax;
3814 +
3815 +       return 0;
3816 +}
3817 +
3818 +static int detect_memory_88(void)
3819 +{
3820 +       u16 ax;
3821 +       u8 err;
3822 +
3823 +       ax = 0x8800;
3824 +       asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3825 +
3826 +       boot_params.screen_info.ext_mem_k = ax;
3827 +
3828 +       return -err;
3829 +}
3830 +
3831 +int detect_memory(void)
3832 +{
3833 +       if (detect_memory_e820() > 0)
3834 +               return 0;
3835 +
3836 +       if (!detect_memory_e801())
3837 +               return 0;
3838 +
3839 +       return detect_memory_88();
3840 +}
3841 diff -puN /dev/null arch/i386/boot/pm.c
3842 --- /dev/null
3843 +++ a/arch/i386/boot/pm.c
3844 @@ -0,0 +1,170 @@
3845 +/* -*- linux-c -*- ------------------------------------------------------- *
3846 + *
3847 + *   Copyright (C) 1991, 1992 Linus Torvalds
3848 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
3849 + *
3850 + *   This file is part of the Linux kernel, and is made available under
3851 + *   the terms of the GNU General Public License version 2.
3852 + *
3853 + * ----------------------------------------------------------------------- */
3854 +
3855 +/*
3856 + * arch/i386/boot/pm.c
3857 + *
3858 + * Prepare the machine for transition to protected mode.
3859 + */
3860 +
3861 +#include "boot.h"
3862 +#include <asm/segment.h>
3863 +
3864 +/*
3865 + * Invoke the realmode switch hook if present; otherwise
3866 + * disable all interrupts.
3867 + */
3868 +static void realmode_switch_hook(void)
3869 +{
3870 +       if (boot_params.hdr.realmode_swtch) {
3871 +               asm volatile("lcallw *%0"
3872 +                            : : "m" (boot_params.hdr.realmode_swtch)
3873 +                            : "eax", "ebx", "ecx", "edx");
3874 +       } else {
3875 +               asm volatile("cli");
3876 +               outb(0x80, 0x70); /* Disable NMI */
3877 +               io_delay();
3878 +       }
3879 +}
3880 +
3881 +/*
3882 + * A zImage kernel is loaded at 0x10000 but wants to run at 0x1000.
3883 + * A bzImage kernel is loaded and runs at 0x100000.
3884 + */
3885 +static void move_kernel_around(void)
3886 +{
3887 +       /* Note: rely on the compile-time option here rather than
3888 +          the LOADED_HIGH flag.  The Qemu kernel loader unconditionally
3889 +          sets the loadflags to zero. */
3890 +#ifndef __BIG_KERNEL__
3891 +       u16 dst_seg, src_seg;
3892 +       u32 syssize;
3893 +
3894 +       dst_seg =  0x1000 >> 4;
3895 +       src_seg = 0x10000 >> 4;
3896 +       syssize = boot_params.hdr.syssize; /* Size in 16-byte paragraps */
3897 +
3898 +       while (syssize) {
3899 +               int paras  = (syssize >= 0x1000) ? 0x1000 : syssize;
3900 +               int dwords = paras << 2;
3901 +
3902 +               asm volatile("pushw %%es ; "
3903 +                            "pushw %%ds ; "
3904 +                            "movw %1,%%es ; "
3905 +                            "movw %2,%%ds ; "
3906 +                            "xorw %%di,%%di ; "
3907 +                            "xorw %%si,%%si ; "
3908 +                            "rep;movsl ; "
3909 +                            "popw %%ds ; "
3910 +                            "popw %%es"
3911 +                            : "+c" (dwords)
3912 +                            : "rm" (dst_seg), "rm" (src_seg)
3913 +                            : "esi", "edi");
3914 +
3915 +               syssize -= paras;
3916 +               dst_seg += paras;
3917 +               src_seg += paras;
3918 +       }
3919 +#endif
3920 +}
3921 +
3922 +/*
3923 + * Disable all interrupts at the legacy PIC.
3924 + */
3925 +static void mask_all_interrupts(void)
3926 +{
3927 +       outb(0xff, 0xa1);       /* Mask all interrupts on the seconday PIC */
3928 +       io_delay();
3929 +       outb(0xfb, 0x21);       /* Mask all but cascade on the primary PIC */
3930 +       io_delay();
3931 +}
3932 +
3933 +/*
3934 + * Reset IGNNE# if asserted in the FPU.
3935 + */
3936 +static void reset_coprocessor(void)
3937 +{
3938 +       outb(0, 0xf0);
3939 +       io_delay();
3940 +       outb(0, 0xf1);
3941 +       io_delay();
3942 +}
3943 +
3944 +/*
3945 + * Set up the GDT
3946 + */
3947 +#define GDT_ENTRY(flags,base,limit)            \
3948 +       (((u64)(base & 0xff000000) << 32) |     \
3949 +        ((u64)flags << 40) |                   \
3950 +        ((u64)(limit & 0x00ff0000) << 32) |    \
3951 +        ((u64)(base & 0x00ffff00) << 16) |     \
3952 +        ((u64)(limit & 0x0000ffff)))
3953 +
3954 +struct gdt_ptr {
3955 +       u16 len;
3956 +       u32 ptr;
3957 +} __attribute__((packed));
3958 +
3959 +static void setup_gdt(void)
3960 +{
3961 +       /* There are machines which are known to not boot with the GDT
3962 +          being 8-byte unaligned.  Intel recommends 16 byte alignment. */
3963 +       static const u64 boot_gdt[] __attribute__((aligned(16))) = {
3964 +               /* CS: code, read/execute, 4 GB, base 0 */
3965 +               [GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
3966 +               /* DS: data, read/write, 4 GB, base 0 */
3967 +               [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
3968 +       };
3969 +       struct gdt_ptr gdt;
3970 +
3971 +       gdt.len = sizeof(boot_gdt)-1;
3972 +       gdt.ptr = (u32)&boot_gdt + (ds() << 4);
3973 +
3974 +       asm volatile("lgdtl %0" : : "m" (gdt));
3975 +}
3976 +
3977 +/*
3978 + * Set up the IDT
3979 + */
3980 +static void setup_idt(void)
3981 +{
3982 +       static const struct gdt_ptr null_idt = {0, 0};
3983 +       asm volatile("lidtl %0" : : "m" (null_idt));
3984 +}
3985 +
3986 +/*
3987 + * Actual invocation sequence
3988 + */
3989 +void go_to_protected_mode(void)
3990 +{
3991 +       /* Hook before leaving real mode, also disables interrupts */
3992 +       realmode_switch_hook();
3993 +
3994 +       /* Move the kernel/setup to their final resting places */
3995 +       move_kernel_around();
3996 +
3997 +       /* Enable the A20 gate */
3998 +       if (enable_a20()) {
3999 +               puts("A20 gate not responding, unable to boot...\n");
4000 +               die();
4001 +       }
4002 +
4003 +       /* Reset coprocessor (IGNNE#) */
4004 +       reset_coprocessor();
4005 +
4006 +       /* Mask all interrupts in the PIC */
4007 +       mask_all_interrupts();
4008 +
4009 +       /* Actual transition to protected mode... */
4010 +       setup_idt();
4011 +       setup_gdt();
4012 +       protected_mode_jump(boot_params.hdr.code32_start,
4013 +                           (u32)&boot_params + (ds() << 4));
4014 +}
4015 diff -puN /dev/null arch/i386/boot/pmjump.S
4016 --- /dev/null
4017 +++ a/arch/i386/boot/pmjump.S
4018 @@ -0,0 +1,54 @@
4019 +/* ----------------------------------------------------------------------- *
4020 + *
4021 + *   Copyright (C) 1991, 1992 Linus Torvalds
4022 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
4023 + *
4024 + *   This file is part of the Linux kernel, and is made available under
4025 + *   the terms of the GNU General Public License version 2.
4026 + *
4027 + * ----------------------------------------------------------------------- */
4028 +
4029 +/*
4030 + * arch/i386/boot/pmjump.S
4031 + *
4032 + * The actual transition into protected mode
4033 + */
4034 +
4035 +#include <asm/boot.h>
4036 +#include <asm/segment.h>
4037 +
4038 +       .text
4039 +
4040 +       .globl  protected_mode_jump
4041 +       .type   protected_mode_jump, @function
4042 +
4043 +       .code16
4044 +
4045 +/*
4046 + * void protected_mode_jump(u32 entrypoint, u32 bootparams);
4047 + */
4048 +protected_mode_jump:
4049 +       xorl    %ebx, %ebx              # Flag to indicate this is a boot
4050 +       movl    %edx, %esi              # Pointer to boot_params table
4051 +       movl    %eax, 2f                # Patch ljmpl instruction
4052 +       jmp     1f                      # Short jump to flush instruction q.
4053 +
4054 +1:
4055 +       movw    $__BOOT_DS, %cx
4056 +
4057 +       movl    %cr0, %edx
4058 +       orb     $1, %dl                 # Protected mode (PE) bit
4059 +       movl    %edx, %cr0
4060 +
4061 +       movw    %cx, %ds
4062 +       movw    %cx, %es
4063 +       movw    %cx, %fs
4064 +       movw    %cx, %gs
4065 +       movw    %cx, %ss
4066 +
4067 +       # Jump to the 32-bit entrypoint
4068 +       .byte   0x66, 0xea              # ljmpl opcode
4069 +2:     .long   0                       # offset
4070 +       .word   __BOOT_CS               # segment
4071 +
4072 +       .size   protected_mode_jump, .-protected_mode_jump
4073 diff -puN /dev/null arch/i386/boot/printf.c
4074 --- /dev/null
4075 +++ a/arch/i386/boot/printf.c
4076 @@ -0,0 +1,331 @@
4077 +/* -*- linux-c -*- ------------------------------------------------------- *
4078 + *
4079 + *   Copyright (C) 1991, 1992 Linus Torvalds
4080 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
4081 + *
4082 + *   This file is part of the Linux kernel, and is made available under
4083 + *   the terms of the GNU General Public License version 2.
4084 + *
4085 + * ----------------------------------------------------------------------- */
4086 +
4087 +/*
4088 + * arch/i386/boot/printf.c
4089 + *
4090 + * Oh, it's a waste of space, but oh-so-yummy for debugging.  This
4091 + * version of printf() does not include 64-bit support.  "Live with
4092 + * it."
4093 + *
4094 + */
4095 +
4096 +#include "boot.h"
4097 +
4098 +static inline int isdigit(int ch)
4099 +{
4100 +       return (ch >= '0') && (ch <= '9');
4101 +}
4102 +
4103 +static int skip_atoi(const char **s)
4104 +{
4105 +       int i = 0;
4106 +
4107 +       while (isdigit(**s))
4108 +               i = i * 10 + *((*s)++) - '0';
4109 +       return i;
4110 +}
4111 +
4112 +unsigned int atou(const char *s)
4113 +{
4114 +       unsigned int i = 0;
4115 +       while (isdigit(*s))
4116 +               i = i * 10 + (*s++ - '0');
4117 +       return i;
4118 +}
4119 +
4120 +static int strnlen(const char *s, int maxlen)
4121 +{
4122 +       const char *es = s;
4123 +       while (*es && maxlen) {
4124 +               es++;
4125 +               maxlen--;
4126 +       }
4127 +
4128 +       return (es - s);
4129 +}
4130 +
4131 +#define ZEROPAD        1               /* pad with zero */
4132 +#define SIGN   2               /* unsigned/signed long */
4133 +#define PLUS   4               /* show plus */
4134 +#define SPACE  8               /* space if plus */
4135 +#define LEFT   16              /* left justified */
4136 +#define SPECIAL        32              /* 0x */
4137 +#define LARGE  64              /* use 'ABCDEF' instead of 'abcdef' */
4138 +
4139 +#define do_div(n,base) ({ \
4140 +int __res; \
4141 +__res = ((unsigned long) n) % (unsigned) base; \
4142 +n = ((unsigned long) n) / (unsigned) base; \
4143 +__res; })
4144 +
4145 +static char *number(char *str, long num, int base, int size, int precision,
4146 +                   int type)
4147 +{
4148 +       char c, sign, tmp[66];
4149 +       const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
4150 +       int i;
4151 +
4152 +       if (type & LARGE)
4153 +               digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
4154 +       if (type & LEFT)
4155 +               type &= ~ZEROPAD;
4156 +       if (base < 2 || base > 36)
4157 +               return 0;
4158 +       c = (type & ZEROPAD) ? '0' : ' ';
4159 +       sign = 0;
4160 +       if (type & SIGN) {
4161 +               if (num < 0) {
4162 +                       sign = '-';
4163 +                       num = -num;
4164 +                       size--;
4165 +               } else if (type & PLUS) {
4166 +                       sign = '+';
4167 +                       size--;
4168 +               } else if (type & SPACE) {
4169 +                       sign = ' ';
4170 +                       size--;
4171 +               }
4172 +       }
4173 +       if (type & SPECIAL) {
4174 +               if (base == 16)
4175 +                       size -= 2;
4176 +               else if (base == 8)
4177 +                       size--;
4178 +       }
4179 +       i = 0;
4180 +       if (num == 0)
4181 +               tmp[i++] = '0';
4182 +       else
4183 +               while (num != 0)
4184 +                       tmp[i++] = digits[do_div(num, base)];
4185 +       if (i > precision)
4186 +               precision = i;
4187 +       size -= precision;
4188 +       if (!(type & (ZEROPAD + LEFT)))
4189 +               while (size-- > 0)
4190 +                       *str++ = ' ';
4191 +       if (sign)
4192 +               *str++ = sign;
4193 +       if (type & SPECIAL) {
4194 +               if (base == 8)
4195 +                       *str++ = '0';
4196 +               else if (base == 16) {
4197 +                       *str++ = '0';
4198 +                       *str++ = digits[33];
4199 +               }
4200 +       }
4201 +       if (!(type & LEFT))
4202 +               while (size-- > 0)
4203 +                       *str++ = c;
4204 +       while (i < precision--)
4205 +               *str++ = '0';
4206 +       while (i-- > 0)
4207 +               *str++ = tmp[i];
4208 +       while (size-- > 0)
4209 +               *str++ = ' ';
4210 +       return str;
4211 +}
4212 +
4213 +int vsprintf(char *buf, const char *fmt, va_list args)
4214 +{
4215 +       int len;
4216 +       unsigned long num;
4217 +       int i, base;
4218 +       char *str;
4219 +       const char *s;
4220 +
4221 +       int flags;              /* flags to number() */
4222 +
4223 +       int field_width;        /* width of output field */
4224 +       int precision;          /* min. # of digits for integers; max
4225 +                                  number of chars for from string */
4226 +       int qualifier;          /* 'h', 'l', or 'L' for integer fields */
4227 +
4228 +       for (str = buf; *fmt; ++fmt) {
4229 +               if (*fmt != '%') {
4230 +                       *str++ = *fmt;
4231 +                       continue;
4232 +               }
4233 +
4234 +               /* process flags */
4235 +               flags = 0;
4236 +             repeat:
4237 +               ++fmt;          /* this also skips first '%' */
4238 +               switch (*fmt) {
4239 +               case '-':
4240 +                       flags |= LEFT;
4241 +                       goto repeat;
4242 +               case '+':
4243 +                       flags |= PLUS;
4244 +                       goto repeat;
4245 +               case ' ':
4246 +                       flags |= SPACE;
4247 +                       goto repeat;
4248 +               case '#':
4249 +                       flags |= SPECIAL;
4250 +                       goto repeat;
4251 +               case '0':
4252 +                       flags |= ZEROPAD;
4253 +                       goto repeat;
4254 +               }
4255 +
4256 +               /* get field width */
4257 +               field_width = -1;
4258 +               if (isdigit(*fmt))
4259 +                       field_width = skip_atoi(&fmt);
4260 +               else if (*fmt == '*') {
4261 +                       ++fmt;
4262 +                       /* it's the next argument */
4263 +                       field_width = va_arg(args, int);
4264 +                       if (field_width < 0) {
4265 +                               field_width = -field_width;
4266 +                               flags |= LEFT;
4267 +                       }
4268 +               }
4269 +
4270 +               /* get the precision */
4271 +               precision = -1;
4272 +               if (*fmt == '.') {
4273 +                       ++fmt;
4274 +                       if (isdigit(*fmt))
4275 +                               precision = skip_atoi(&fmt);
4276 +                       else if (*fmt == '*') {
4277 +                               ++fmt;
4278 +                               /* it's the next argument */
4279 +                               precision = va_arg(args, int);
4280 +                       }
4281 +                       if (precision < 0)
4282 +                               precision = 0;
4283 +               }
4284 +
4285 +               /* get the conversion qualifier */
4286 +               qualifier = -1;
4287 +               if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
4288 +                       qualifier = *fmt;
4289 +                       ++fmt;
4290 +               }
4291 +
4292 +               /* default base */
4293 +               base = 10;
4294 +
4295 +               switch (*fmt) {
4296 +               case 'c':
4297 +                       if (!(flags & LEFT))
4298 +                               while (--field_width > 0)
4299 +                                       *str++ = ' ';
4300 +                       *str++ = (unsigned char)va_arg(args, int);
4301 +                       while (--field_width > 0)
4302 +                               *str++ = ' ';
4303 +                       continue;
4304 +
4305 +               case 's':
4306 +                       s = va_arg(args, char *);
4307 +                       len = strnlen(s, precision);
4308 +
4309 +                       if (!(flags & LEFT))
4310 +                               while (len < field_width--)
4311 +                                       *str++ = ' ';
4312 +                       for (i = 0; i < len; ++i)
4313 +                               *str++ = *s++;
4314 +                       while (len < field_width--)
4315 +                               *str++ = ' ';
4316 +                       continue;
4317 +
4318 +               case 'p':
4319 +                       if (field_width == -1) {
4320 +                               field_width = 2 * sizeof(void *);
4321 +                               flags |= ZEROPAD;
4322 +                       }
4323 +                       str = number(str,
4324 +                                    (unsigned long)va_arg(args, void *), 16,
4325 +                                    field_width, precision, flags);
4326 +                       continue;
4327 +
4328 +               case 'n':
4329 +                       if (qualifier == 'l') {
4330 +                               long *ip = va_arg(args, long *);
4331 +                               *ip = (str - buf);
4332 +                       } else {
4333 +                               int *ip = va_arg(args, int *);
4334 +                               *ip = (str - buf);
4335 +                       }
4336 +                       continue;
4337 +
4338 +               case '%':
4339 +                       *str++ = '%';
4340 +                       continue;
4341 +
4342 +                       /* integer number formats - set up the flags and "break" */
4343 +               case 'o':
4344 +                       base = 8;
4345 +                       break;
4346 +
4347 +               case 'X':
4348 +                       flags |= LARGE;
4349 +               case 'x':
4350 +                       base = 16;
4351 +                       break;
4352 +
4353 +               case 'd':
4354 +               case 'i':
4355 +                       flags |= SIGN;
4356 +               case 'u':
4357 +                       break;
4358 +
4359 +               default:
4360 +                       *str++ = '%';
4361 +                       if (*fmt)
4362 +                               *str++ = *fmt;
4363 +                       else
4364 +                               --fmt;
4365 +                       continue;
4366 +               }
4367 +               if (qualifier == 'l')
4368 +                       num = va_arg(args, unsigned long);
4369 +               else if (qualifier == 'h') {
4370 +                       num = (unsigned short)va_arg(args, int);
4371 +                       if (flags & SIGN)
4372 +                               num = (short)num;
4373 +               } else if (flags & SIGN)
4374 +                       num = va_arg(args, int);
4375 +               else
4376 +                       num = va_arg(args, unsigned int);
4377 +               str = number(str, num, base, field_width, precision, flags);
4378 +       }
4379 +       *str = '\0';
4380 +       return str - buf;
4381 +}
4382 +
4383 +int sprintf(char *buf, const char *fmt, ...)
4384 +{
4385 +       va_list args;
4386 +       int i;
4387 +
4388 +       va_start(args, fmt);
4389 +       i = vsprintf(buf, fmt, args);
4390 +       va_end(args);
4391 +       return i;
4392 +}
4393 +
4394 +int printf(const char *fmt, ...)
4395 +{
4396 +       char printf_buf[1024];
4397 +       va_list args;
4398 +       int printed;
4399 +
4400 +       va_start(args, fmt);
4401 +       printed = vsprintf(printf_buf, fmt, args);
4402 +       va_end(args);
4403 +
4404 +       puts(printf_buf);
4405 +
4406 +       return printed;
4407 +}
4408 diff -puN arch/i386/boot/setup.S~git-newsetup /dev/null
4409 --- a/arch/i386/boot/setup.S
4410 +++ /dev/null
4411 @@ -1,1075 +0,0 @@
4412 -/*
4413 - *     setup.S         Copyright (C) 1991, 1992 Linus Torvalds
4414 - *
4415 - * setup.s is responsible for getting the system data from the BIOS,
4416 - * and putting them into the appropriate places in system memory.
4417 - * both setup.s and system has been loaded by the bootblock.
4418 - *
4419 - * This code asks the bios for memory/disk/other parameters, and
4420 - * puts them in a "safe" place: 0x90000-0x901FF, ie where the
4421 - * boot-block used to be. It is then up to the protected mode
4422 - * system to read them from there before the area is overwritten
4423 - * for buffer-blocks.
4424 - *
4425 - * Move PS/2 aux init code to psaux.c
4426 - * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
4427 - *
4428 - * some changes and additional features by Christoph Niemann,
4429 - * March 1993/June 1994 (Christoph.Niemann@linux.org)
4430 - *
4431 - * add APM BIOS checking by Stephen Rothwell, May 1994
4432 - * (sfr@canb.auug.org.au)
4433 - *
4434 - * High load stuff, initrd support and position independency
4435 - * by Hans Lermen & Werner Almesberger, February 1996
4436 - * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
4437 - *
4438 - * Video handling moved to video.S by Martin Mares, March 1996
4439 - * <mj@k332.feld.cvut.cz>
4440 - *
4441 - * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
4442 - * parsons) to avoid loadlin confusion, July 1997
4443 - *
4444 - * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
4445 - * <stiker@northlink.com>
4446 - *
4447 - * Fix to work around buggy BIOSes which don't use carry bit correctly
4448 - * and/or report extended memory in CX/DX for e801h memory size detection 
4449 - * call.  As a result the kernel got wrong figures.  The int15/e801h docs
4450 - * from Ralf Brown interrupt list seem to indicate AX/BX should be used
4451 - * anyway.  So to avoid breaking many machines (presumably there was a reason
4452 - * to orginally use CX/DX instead of AX/BX), we do a kludge to see
4453 - * if CX/DX have been changed in the e801 call and if so use AX/BX .
4454 - * Michael Miller, April 2001 <michaelm@mjmm.org>
4455 - *
4456 - * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes
4457 - * by Robert Schwebel, December 2001 <robert@schwebel.de>
4458 - */
4459 -
4460 -#include <asm/segment.h>
4461 -#include <linux/utsrelease.h>
4462 -#include <linux/compile.h>
4463 -#include <asm/boot.h>
4464 -#include <asm/e820.h>
4465 -#include <asm/page.h>
4466 -#include <asm/setup.h>
4467 -       
4468 -/* Signature words to ensure LILO loaded us right */
4469 -#define SIG1   0xAA55
4470 -#define SIG2   0x5A5A
4471 -
4472 -INITSEG  = DEF_INITSEG         # 0x9000, we move boot here, out of the way
4473 -SYSSEG   = DEF_SYSSEG          # 0x1000, system loaded at 0x10000 (65536).
4474 -SETUPSEG = DEF_SETUPSEG                # 0x9020, this is the current segment
4475 -                               # ... and the former contents of CS
4476 -
4477 -DELTA_INITSEG = SETUPSEG - INITSEG     # 0x0020
4478 -
4479 -.code16
4480 -.globl begtext, begdata, begbss, endtext, enddata, endbss
4481 -
4482 -.text
4483 -begtext:
4484 -.data
4485 -begdata:
4486 -.bss
4487 -begbss:
4488 -.text
4489 -
4490 -start:
4491 -       jmp     trampoline
4492 -
4493 -# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
4494 -
4495 -               .ascii  "HdrS"          # header signature
4496 -               .word   0x0206          # header version number (>= 0x0105)
4497 -                                       # or else old loadlin-1.5 will fail)
4498 -realmode_swtch:        .word   0, 0            # default_switch, SETUPSEG
4499 -start_sys_seg: .word   SYSSEG
4500 -               .word   kernel_version  # pointing to kernel version string
4501 -                                       # above section of header is compatible
4502 -                                       # with loadlin-1.5 (header v1.5). Don't
4503 -                                       # change it.
4504 -
4505 -type_of_loader:        .byte   0               # = 0, old one (LILO, Loadlin,
4506 -                                       #      Bootlin, SYSLX, bootsect...)
4507 -                                       # See Documentation/i386/boot.txt for
4508 -                                       # assigned ids
4509 -       
4510 -# flags, unused bits must be zero (RFU) bit within loadflags
4511 -loadflags:
4512 -LOADED_HIGH    = 1                     # If set, the kernel is loaded high
4513 -CAN_USE_HEAP   = 0x80                  # If set, the loader also has set
4514 -                                       # heap_end_ptr to tell how much
4515 -                                       # space behind setup.S can be used for
4516 -                                       # heap purposes.
4517 -                                       # Only the loader knows what is free
4518 -#ifndef __BIG_KERNEL__
4519 -               .byte   0
4520 -#else
4521 -               .byte   LOADED_HIGH
4522 -#endif
4523 -
4524 -setup_move_size: .word  0x8000         # size to move, when setup is not
4525 -                                       # loaded at 0x90000. We will move setup 
4526 -                                       # to 0x90000 then just before jumping
4527 -                                       # into the kernel. However, only the
4528 -                                       # loader knows how much data behind
4529 -                                       # us also needs to be loaded.
4530 -
4531 -code32_start:                          # here loaders can put a different
4532 -                                       # start address for 32-bit code.
4533 -#ifndef __BIG_KERNEL__
4534 -               .long   0x1000          #   0x1000 = default for zImage
4535 -#else
4536 -               .long   0x100000        # 0x100000 = default for big kernel
4537 -#endif
4538 -
4539 -ramdisk_image: .long   0               # address of loaded ramdisk image
4540 -                                       # Here the loader puts the 32-bit
4541 -                                       # address where it loaded the image.
4542 -                                       # This only will be read by the kernel.
4543 -
4544 -ramdisk_size:  .long   0               # its size in bytes
4545 -
4546 -bootsect_kludge:
4547 -               .long   0               # obsolete
4548 -
4549 -heap_end_ptr:  .word   modelist+1024   # (Header version 0x0201 or later)
4550 -                                       # space from here (exclusive) down to
4551 -                                       # end of setup code can be used by setup
4552 -                                       # for local heap purposes.
4553 -
4554 -pad1:          .word   0
4555 -cmd_line_ptr:  .long 0                 # (Header version 0x0202 or later)
4556 -                                       # If nonzero, a 32-bit pointer
4557 -                                       # to the kernel command line.
4558 -                                       # The command line should be
4559 -                                       # located between the start of
4560 -                                       # setup and the end of low
4561 -                                       # memory (0xa0000), or it may
4562 -                                       # get overwritten before it
4563 -                                       # gets read.  If this field is
4564 -                                       # used, there is no longer
4565 -                                       # anything magical about the
4566 -                                       # 0x90000 segment; the setup
4567 -                                       # can be located anywhere in
4568 -                                       # low memory 0x10000 or higher.
4569 -
4570 -ramdisk_max:   .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
4571 -                                       # (Header version 0x0203 or later)
4572 -                                       # The highest safe address for
4573 -                                       # the contents of an initrd
4574 -
4575 -kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN         #physical addr alignment
4576 -                                               #required for protected mode
4577 -                                               #kernel
4578 -#ifdef CONFIG_RELOCATABLE
4579 -relocatable_kernel:    .byte 1
4580 -#else
4581 -relocatable_kernel:    .byte 0
4582 -#endif
4583 -pad2:                  .byte 0
4584 -pad3:                  .word 0
4585 -
4586 -cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
4587 -                                                #added with boot protocol
4588 -                                                #version 2.06
4589 -
4590 -trampoline:    call    start_of_setup
4591 -               .align 16
4592 -                                       # The offset at this point is 0x240
4593 -               .space  (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
4594 -# End of setup header #####################################################
4595 -
4596 -start_of_setup:
4597 -# Bootlin depends on this being done early
4598 -       movw    $0x01500, %ax
4599 -       movb    $0x81, %dl
4600 -       int     $0x13
4601 -
4602 -#ifdef SAFE_RESET_DISK_CONTROLLER
4603 -# Reset the disk controller.
4604 -       movw    $0x0000, %ax
4605 -       movb    $0x80, %dl
4606 -       int     $0x13
4607 -#endif
4608 -
4609 -# Set %ds = %cs, we know that SETUPSEG = %cs at this point
4610 -       movw    %cs, %ax                # aka SETUPSEG
4611 -       movw    %ax, %ds
4612 -# Check signature at end of setup
4613 -       cmpw    $SIG1, setup_sig1
4614 -       jne     bad_sig
4615 -
4616 -       cmpw    $SIG2, setup_sig2
4617 -       jne     bad_sig
4618 -
4619 -       jmp     good_sig1
4620 -
4621 -# Routine to print asciiz string at ds:si
4622 -prtstr:
4623 -       lodsb
4624 -       andb    %al, %al
4625 -       jz      fin
4626 -
4627 -       call    prtchr
4628 -       jmp     prtstr
4629 -
4630 -fin:   ret
4631 -
4632 -# Space printing
4633 -prtsp2:        call    prtspc          # Print double space
4634 -prtspc:        movb    $0x20, %al      # Print single space (note: fall-thru)
4635 -
4636 -# Part of above routine, this one just prints ascii al
4637 -prtchr:        pushw   %ax
4638 -       pushw   %cx
4639 -       movw    $7,%bx
4640 -       movw    $0x01, %cx
4641 -       movb    $0x0e, %ah
4642 -       int     $0x10
4643 -       popw    %cx
4644 -       popw    %ax
4645 -       ret
4646 -
4647 -beep:  movb    $0x07, %al
4648 -       jmp     prtchr
4649 -       
4650 -no_sig_mess: .string   "No setup signature found ..."
4651 -
4652 -good_sig1:
4653 -       jmp     good_sig
4654 -
4655 -# We now have to find the rest of the setup code/data
4656 -bad_sig:
4657 -       movw    %cs, %ax                        # SETUPSEG
4658 -       subw    $DELTA_INITSEG, %ax             # INITSEG
4659 -       movw    %ax, %ds
4660 -       xorb    %bh, %bh
4661 -       movb    (497), %bl                      # get setup sect from bootsect
4662 -       subw    $4, %bx                         # LILO loads 4 sectors of setup
4663 -       shlw    $8, %bx                         # convert to words (1sect=2^8 words)
4664 -       movw    %bx, %cx
4665 -       shrw    $3, %bx                         # convert to segment
4666 -       addw    $SYSSEG, %bx
4667 -       movw    %bx, %cs:start_sys_seg
4668 -# Move rest of setup code/data to here
4669 -       movw    $2048, %di                      # four sectors loaded by LILO
4670 -       subw    %si, %si
4671 -       pushw   %cs
4672 -       popw    %es
4673 -       movw    $SYSSEG, %ax
4674 -       movw    %ax, %ds
4675 -       rep
4676 -       movsw
4677 -       movw    %cs, %ax                        # aka SETUPSEG
4678 -       movw    %ax, %ds
4679 -       cmpw    $SIG1, setup_sig1
4680 -       jne     no_sig
4681 -
4682 -       cmpw    $SIG2, setup_sig2
4683 -       jne     no_sig
4684 -
4685 -       jmp     good_sig
4686 -
4687 -no_sig:
4688 -       lea     no_sig_mess, %si
4689 -       call    prtstr
4690 -
4691 -no_sig_loop:
4692 -       hlt
4693 -       jmp     no_sig_loop
4694 -
4695 -good_sig:
4696 -       movw    %cs, %ax                        # aka SETUPSEG
4697 -       subw    $DELTA_INITSEG, %ax             # aka INITSEG
4698 -       movw    %ax, %ds
4699 -# Check if an old loader tries to load a big-kernel
4700 -       testb   $LOADED_HIGH, %cs:loadflags     # Do we have a big kernel?
4701 -       jz      loader_ok                       # No, no danger for old loaders.
4702 -
4703 -       cmpb    $0, %cs:type_of_loader          # Do we have a loader that
4704 -                                               # can deal with us?
4705 -       jnz     loader_ok                       # Yes, continue.
4706 -
4707 -       pushw   %cs                             # No, we have an old loader,
4708 -       popw    %ds                             # die. 
4709 -       lea     loader_panic_mess, %si
4710 -       call    prtstr
4711 -
4712 -       jmp     no_sig_loop
4713 -
4714 -loader_panic_mess: .string "Wrong loader, giving up..."
4715 -
4716 -# check minimum cpuid
4717 -# we do this here because it is the last place we can actually
4718 -# show a user visible error message. Later the video modus
4719 -# might be already messed up.
4720 -loader_ok:
4721 -       call verify_cpu
4722 -       testl  %eax,%eax
4723 -       jz      cpu_ok
4724 -       movw    %cs,%ax         # aka SETUPSEG
4725 -       movw    %ax,%ds
4726 -       lea     cpu_panic_mess,%si
4727 -       call    prtstr
4728 -1:     jmp     1b
4729 -
4730 -cpu_panic_mess:
4731 -       .asciz  "PANIC: CPU too old for this kernel."
4732 -
4733 -#include "../kernel/verify_cpu.S"
4734 -
4735 -cpu_ok:
4736 -# Get memory size (extended mem, kB)
4737 -
4738 -       xorl    %eax, %eax
4739 -       movl    %eax, (0x1e0)
4740 -#ifndef STANDARD_MEMORY_BIOS_CALL
4741 -       movb    %al, (E820NR)
4742 -# Try three different memory detection schemes.  First, try
4743 -# e820h, which lets us assemble a memory map, then try e801h,
4744 -# which returns a 32-bit memory size, and finally 88h, which
4745 -# returns 0-64m
4746 -
4747 -# method E820H:
4748 -# the memory map from hell.  e820h returns memory classified into
4749 -# a whole bunch of different types, and allows memory holes and
4750 -# everything.  We scan through this memory map and build a list
4751 -# of the first 32 memory areas, which we return at [E820MAP].
4752 -# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
4753 -
4754 -#define SMAP  0x534d4150
4755 -
4756 -meme820:
4757 -       xorl    %ebx, %ebx                      # continuation counter
4758 -       movw    $E820MAP, %di                   # point into the whitelist
4759 -                                               # so we can have the bios
4760 -                                               # directly write into it.
4761 -
4762 -jmpe820:
4763 -       movl    $0x0000e820, %eax               # e820, upper word zeroed
4764 -       movl    $SMAP, %edx                     # ascii 'SMAP'
4765 -       movl    $20, %ecx                       # size of the e820rec
4766 -       pushw   %ds                             # data record.
4767 -       popw    %es
4768 -       int     $0x15                           # make the call
4769 -       jc      bail820                         # fall to e801 if it fails
4770 -
4771 -       cmpl    $SMAP, %eax                     # check the return is `SMAP'
4772 -       jne     bail820                         # fall to e801 if it fails
4773 -
4774 -#      cmpl    $1, 16(%di)                     # is this usable memory?
4775 -#      jne     again820
4776 -
4777 -       # If this is usable memory, we save it by simply advancing %di by
4778 -       # sizeof(e820rec).
4779 -       #
4780 -good820:
4781 -       movb    (E820NR), %al                   # up to 128 entries
4782 -       cmpb    $E820MAX, %al
4783 -       jae     bail820
4784 -
4785 -       incb    (E820NR)
4786 -       movw    %di, %ax
4787 -       addw    $20, %ax
4788 -       movw    %ax, %di
4789 -again820:
4790 -       cmpl    $0, %ebx                        # check to see if
4791 -       jne     jmpe820                         # %ebx is set to EOF
4792 -bail820:
4793 -
4794 -
4795 -# method E801H:
4796 -# memory size is in 1k chunksizes, to avoid confusing loadlin.
4797 -# we store the 0xe801 memory size in a completely different place,
4798 -# because it will most likely be longer than 16 bits.
4799 -# (use 1e0 because that's what Larry Augustine uses in his
4800 -# alternative new memory detection scheme, and it's sensible
4801 -# to write everything into the same place.)
4802 -
4803 -meme801:
4804 -       stc                                     # fix to work around buggy
4805 -       xorw    %cx,%cx                         # BIOSes which don't clear/set
4806 -       xorw    %dx,%dx                         # carry on pass/error of
4807 -                                               # e801h memory size call
4808 -                                               # or merely pass cx,dx though
4809 -                                               # without changing them.
4810 -       movw    $0xe801, %ax
4811 -       int     $0x15
4812 -       jc      mem88
4813 -
4814 -       cmpw    $0x0, %cx                       # Kludge to handle BIOSes
4815 -       jne     e801usecxdx                     # which report their extended
4816 -       cmpw    $0x0, %dx                       # memory in AX/BX rather than
4817 -       jne     e801usecxdx                     # CX/DX.  The spec I have read
4818 -       movw    %ax, %cx                        # seems to indicate AX/BX 
4819 -       movw    %bx, %dx                        # are more reasonable anyway...
4820 -
4821 -e801usecxdx:
4822 -       andl    $0xffff, %edx                   # clear sign extend
4823 -       shll    $6, %edx                        # and go from 64k to 1k chunks
4824 -       movl    %edx, (0x1e0)                   # store extended memory size
4825 -       andl    $0xffff, %ecx                   # clear sign extend
4826 -       addl    %ecx, (0x1e0)                   # and add lower memory into
4827 -                                               # total size.
4828 -
4829 -# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
4830 -# 64mb, depending on the bios) in ax.
4831 -mem88:
4832 -
4833 -#endif
4834 -       movb    $0x88, %ah
4835 -       int     $0x15
4836 -       movw    %ax, (2)
4837 -
4838 -# Set the keyboard repeat rate to the max
4839 -       movw    $0x0305, %ax
4840 -       xorw    %bx, %bx
4841 -       int     $0x16
4842 -
4843 -# Check for video adapter and its parameters and allow the
4844 -# user to browse video modes.
4845 -       call    video                           # NOTE: we need %ds pointing
4846 -                                               # to bootsector
4847 -
4848 -# Get hd0 data...
4849 -       xorw    %ax, %ax
4850 -       movw    %ax, %ds
4851 -       ldsw    (4 * 0x41), %si
4852 -       movw    %cs, %ax                        # aka SETUPSEG
4853 -       subw    $DELTA_INITSEG, %ax             # aka INITSEG
4854 -       pushw   %ax
4855 -       movw    %ax, %es
4856 -       movw    $0x0080, %di
4857 -       movw    $0x10, %cx
4858 -       pushw   %cx
4859 -       cld
4860 -       rep
4861 -       movsb
4862 -# Get hd1 data...
4863 -       xorw    %ax, %ax
4864 -       movw    %ax, %ds
4865 -       ldsw    (4 * 0x46), %si
4866 -       popw    %cx
4867 -       popw    %es
4868 -       movw    $0x0090, %di
4869 -       rep
4870 -       movsb
4871 -# Check that there IS a hd1 :-)
4872 -       movw    $0x01500, %ax
4873 -       movb    $0x81, %dl
4874 -       int     $0x13
4875 -       jc      no_disk1
4876 -       
4877 -       cmpb    $3, %ah
4878 -       je      is_disk1
4879 -
4880 -no_disk1:
4881 -       movw    %cs, %ax                        # aka SETUPSEG
4882 -       subw    $DELTA_INITSEG, %ax             # aka INITSEG
4883 -       movw    %ax, %es
4884 -       movw    $0x0090, %di
4885 -       movw    $0x10, %cx
4886 -       xorw    %ax, %ax
4887 -       cld
4888 -       rep
4889 -       stosb
4890 -is_disk1:
4891 -# check for Micro Channel (MCA) bus
4892 -       movw    %cs, %ax                        # aka SETUPSEG
4893 -       subw    $DELTA_INITSEG, %ax             # aka INITSEG
4894 -       movw    %ax, %ds
4895 -       xorw    %ax, %ax
4896 -       movw    %ax, (0xa0)                     # set table length to 0
4897 -       movb    $0xc0, %ah
4898 -       stc
4899 -       int     $0x15                           # moves feature table to es:bx
4900 -       jc      no_mca
4901 -
4902 -       pushw   %ds
4903 -       movw    %es, %ax
4904 -       movw    %ax, %ds
4905 -       movw    %cs, %ax                        # aka SETUPSEG
4906 -       subw    $DELTA_INITSEG, %ax             # aka INITSEG
4907 -       movw    %ax, %es
4908 -       movw    %bx, %si
4909 -       movw    $0xa0, %di
4910 -       movw    (%si), %cx
4911 -       addw    $2, %cx                         # table length is a short
4912 -       cmpw    $0x10, %cx
4913 -       jc      sysdesc_ok
4914 -
4915 -       movw    $0x10, %cx                      # we keep only first 16 bytes
4916 -sysdesc_ok:
4917 -       rep
4918 -       movsb
4919 -       popw    %ds
4920 -no_mca:
4921 -#ifdef CONFIG_X86_VOYAGER
4922 -       movb    $0xff, 0x40     # flag on config found
4923 -       movb    $0xc0, %al
4924 -       mov     $0xff, %ah
4925 -       int     $0x15           # put voyager config info at es:di
4926 -       jc      no_voyager
4927 -       movw    $0x40, %si      # place voyager info in apm table
4928 -       cld
4929 -       movw    $7, %cx
4930 -voyager_rep:
4931 -       movb    %es:(%di), %al
4932 -       movb    %al,(%si)
4933 -       incw    %di
4934 -       incw    %si
4935 -       decw    %cx
4936 -       jnz     voyager_rep
4937 -no_voyager:    
4938 -#endif
4939 -# Check for PS/2 pointing device
4940 -       movw    %cs, %ax                        # aka SETUPSEG
4941 -       subw    $DELTA_INITSEG, %ax             # aka INITSEG
4942 -       movw    %ax, %ds
4943 -       movb    $0, (0x1ff)                     # default is no pointing device
4944 -       int     $0x11                           # int 0x11: equipment list
4945 -       testb   $0x04, %al                      # check if mouse installed
4946 -       jz      no_psmouse
4947 -
4948 -       movb    $0xAA, (0x1ff)                  # device present
4949 -no_psmouse:
4950 -
4951 -#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
4952 -       movl    $0x0000E980, %eax               # IST Support 
4953 -       movl    $0x47534943, %edx               # Request value
4954 -       int     $0x15
4955 -
4956 -       movl    %eax, (96)
4957 -       movl    %ebx, (100)
4958 -       movl    %ecx, (104)
4959 -       movl    %edx, (108)
4960 -#endif
4961 -
4962 -#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
4963 -# Then check for an APM BIOS...
4964 -                                               # %ds points to the bootsector
4965 -       movw    $0, 0x40                        # version = 0 means no APM BIOS
4966 -       movw    $0x05300, %ax                   # APM BIOS installation check
4967 -       xorw    %bx, %bx
4968 -       int     $0x15
4969 -       jc      done_apm_bios                   # Nope, no APM BIOS
4970 -       
4971 -       cmpw    $0x0504d, %bx                   # Check for "PM" signature
4972 -       jne     done_apm_bios                   # No signature, no APM BIOS
4973 -
4974 -       andw    $0x02, %cx                      # Is 32 bit supported?
4975 -       je      done_apm_bios                   # No 32-bit, no (good) APM BIOS
4976 -
4977 -       movw    $0x05304, %ax                   # Disconnect first just in case
4978 -       xorw    %bx, %bx
4979 -       int     $0x15                           # ignore return code
4980 -       movw    $0x05303, %ax                   # 32 bit connect
4981 -       xorl    %ebx, %ebx
4982 -       xorw    %cx, %cx                        # paranoia :-)
4983 -       xorw    %dx, %dx                        #   ...
4984 -       xorl    %esi, %esi                      #   ...
4985 -       xorw    %di, %di                        #   ...
4986 -       int     $0x15
4987 -       jc      no_32_apm_bios                  # Ack, error. 
4988 -
4989 -       movw    %ax,  (66)                      # BIOS code segment
4990 -       movl    %ebx, (68)                      # BIOS entry point offset
4991 -       movw    %cx,  (72)                      # BIOS 16 bit code segment
4992 -       movw    %dx,  (74)                      # BIOS data segment
4993 -       movl    %esi, (78)                      # BIOS code segment lengths
4994 -       movw    %di,  (82)                      # BIOS data segment length
4995 -# Redo the installation check as the 32 bit connect
4996 -# modifies the flags returned on some BIOSs
4997 -       movw    $0x05300, %ax                   # APM BIOS installation check
4998 -       xorw    %bx, %bx
4999 -       xorw    %cx, %cx                        # paranoia
5000 -       int     $0x15
5001 -       jc      apm_disconnect                  # error -> shouldn't happen
5002 -
5003 -       cmpw    $0x0504d, %bx                   # check for "PM" signature
5004 -       jne     apm_disconnect                  # no sig -> shouldn't happen
5005 -
5006 -       movw    %ax, (64)                       # record the APM BIOS version
5007 -       movw    %cx, (76)                       # and flags
5008 -       jmp     done_apm_bios
5009 -
5010 -apm_disconnect:                                        # Tidy up
5011 -       movw    $0x05304, %ax                   # Disconnect
5012 -       xorw    %bx, %bx
5013 -       int     $0x15                           # ignore return code
5014 -
5015 -       jmp     done_apm_bios
5016 -
5017 -no_32_apm_bios:
5018 -       andw    $0xfffd, (76)                   # remove 32 bit support bit
5019 -done_apm_bios:
5020 -#endif
5021 -
5022 -#include "edd.S"
5023 -
5024 -# Now we want to move to protected mode ...
5025 -       cmpw    $0, %cs:realmode_swtch
5026 -       jz      rmodeswtch_normal
5027 -
5028 -       lcall   *%cs:realmode_swtch
5029 -
5030 -       jmp     rmodeswtch_end
5031 -
5032 -rmodeswtch_normal:
5033 -        pushw  %cs
5034 -       call    default_switch
5035 -
5036 -rmodeswtch_end:
5037 -# Now we move the system to its rightful place ... but we check if we have a
5038 -# big-kernel. In that case we *must* not move it ...
5039 -       testb   $LOADED_HIGH, %cs:loadflags
5040 -       jz      do_move0                        # .. then we have a normal low
5041 -                                               # loaded zImage
5042 -                                               # .. or else we have a high
5043 -                                               # loaded bzImage
5044 -       jmp     end_move                        # ... and we skip moving
5045 -
5046 -do_move0:
5047 -       movw    $0x100, %ax                     # start of destination segment
5048 -       movw    %cs, %bp                        # aka SETUPSEG
5049 -       subw    $DELTA_INITSEG, %bp             # aka INITSEG
5050 -       movw    %cs:start_sys_seg, %bx          # start of source segment
5051 -       cld
5052 -do_move:
5053 -       movw    %ax, %es                        # destination segment
5054 -       incb    %ah                             # instead of add ax,#0x100
5055 -       movw    %bx, %ds                        # source segment
5056 -       addw    $0x100, %bx
5057 -       subw    %di, %di
5058 -       subw    %si, %si
5059 -       movw    $0x800, %cx
5060 -       rep
5061 -       movsw
5062 -       cmpw    %bp, %bx                        # assume start_sys_seg > 0x200,
5063 -                                               # so we will perhaps read one
5064 -                                               # page more than needed, but
5065 -                                               # never overwrite INITSEG
5066 -                                               # because destination is a
5067 -                                               # minimum one page below source
5068 -       jb      do_move
5069 -
5070 -end_move:
5071 -# then we load the segment descriptors
5072 -       movw    %cs, %ax                        # aka SETUPSEG
5073 -       movw    %ax, %ds
5074 -               
5075 -# Check whether we need to be downward compatible with version <=201
5076 -       cmpl    $0, cmd_line_ptr
5077 -       jne     end_move_self           # loader uses version >=202 features
5078 -       cmpb    $0x20, type_of_loader
5079 -       je      end_move_self           # bootsect loader, we know of it
5080 -
5081 -# Boot loader doesnt support boot protocol version 2.02.
5082 -# If we have our code not at 0x90000, we need to move it there now.
5083 -# We also then need to move the params behind it (commandline)
5084 -# Because we would overwrite the code on the current IP, we move
5085 -# it in two steps, jumping high after the first one.
5086 -       movw    %cs, %ax
5087 -       cmpw    $SETUPSEG, %ax
5088 -       je      end_move_self
5089 -
5090 -       cli                                     # make sure we really have
5091 -                                               # interrupts disabled !
5092 -                                               # because after this the stack
5093 -                                               # should not be used
5094 -       subw    $DELTA_INITSEG, %ax             # aka INITSEG
5095 -       movw    %ss, %dx
5096 -       cmpw    %ax, %dx
5097 -       jb      move_self_1
5098 -
5099 -       addw    $INITSEG, %dx
5100 -       subw    %ax, %dx                        # this will go into %ss after
5101 -                                               # the move
5102 -move_self_1:
5103 -       movw    %ax, %ds
5104 -       movw    $INITSEG, %ax                   # real INITSEG
5105 -       movw    %ax, %es
5106 -       movw    %cs:setup_move_size, %cx
5107 -       std                                     # we have to move up, so we use
5108 -                                               # direction down because the
5109 -                                               # areas may overlap
5110 -       movw    %cx, %di
5111 -       decw    %di
5112 -       movw    %di, %si
5113 -       subw    $move_self_here+0x200, %cx
5114 -       rep
5115 -       movsb
5116 -       ljmp    $SETUPSEG, $move_self_here
5117 -
5118 -move_self_here:
5119 -       movw    $move_self_here+0x200, %cx
5120 -       rep
5121 -       movsb
5122 -       movw    $SETUPSEG, %ax
5123 -       movw    %ax, %ds
5124 -       movw    %dx, %ss
5125 -end_move_self:                                 # now we are at the right place
5126 -
5127 -#
5128 -# Enable A20.  This is at the very best an annoying procedure.
5129 -# A20 code ported from SYSLINUX 1.52-1.63 by H. Peter Anvin.
5130 -# AMD Elan bug fix by Robert Schwebel.
5131 -#
5132 -
5133 -#if defined(CONFIG_X86_ELAN)
5134 -       movb $0x02, %al                 # alternate A20 gate
5135 -       outb %al, $0x92                 # this works on SC410/SC520
5136 -a20_elan_wait:
5137 -       call a20_test
5138 -       jz a20_elan_wait
5139 -       jmp a20_done
5140 -#endif
5141 -
5142 -
5143 -A20_TEST_LOOPS         =  32           # Iterations per wait
5144 -A20_ENABLE_LOOPS       = 255           # Total loops to try            
5145 -
5146 -
5147 -#ifndef CONFIG_X86_VOYAGER
5148 -a20_try_loop:
5149 -
5150 -       # First, see if we are on a system with no A20 gate.
5151 -a20_none:
5152 -       call    a20_test
5153 -       jnz     a20_done
5154 -
5155 -       # Next, try the BIOS (INT 0x15, AX=0x2401)
5156 -a20_bios:
5157 -       movw    $0x2401, %ax
5158 -       pushfl                                  # Be paranoid about flags
5159 -       int     $0x15
5160 -       popfl
5161 -
5162 -       call    a20_test
5163 -       jnz     a20_done
5164 -
5165 -       # Try enabling A20 through the keyboard controller
5166 -#endif /* CONFIG_X86_VOYAGER */
5167 -a20_kbc:
5168 -       call    empty_8042
5169 -
5170 -#ifndef CONFIG_X86_VOYAGER
5171 -       call    a20_test                        # Just in case the BIOS worked
5172 -       jnz     a20_done                        # but had a delayed reaction.
5173 -#endif
5174 -
5175 -       movb    $0xD1, %al                      # command write
5176 -       outb    %al, $0x64
5177 -       call    empty_8042
5178 -
5179 -       movb    $0xDF, %al                      # A20 on
5180 -       outb    %al, $0x60
5181 -       call    empty_8042
5182 -
5183 -#ifndef CONFIG_X86_VOYAGER
5184 -       # Wait until a20 really *is* enabled; it can take a fair amount of
5185 -       # time on certain systems; Toshiba Tecras are known to have this
5186 -       # problem.
5187 -a20_kbc_wait:
5188 -       xorw    %cx, %cx
5189 -a20_kbc_wait_loop:
5190 -       call    a20_test
5191 -       jnz     a20_done
5192 -       loop    a20_kbc_wait_loop
5193 -
5194 -       # Final attempt: use "configuration port A"
5195 -a20_fast:
5196 -       inb     $0x92, %al                      # Configuration Port A
5197 -       orb     $0x02, %al                      # "fast A20" version
5198 -       andb    $0xFE, %al                      # don't accidentally reset
5199 -       outb    %al, $0x92
5200 -
5201 -       # Wait for configuration port A to take effect
5202 -a20_fast_wait:
5203 -       xorw    %cx, %cx
5204 -a20_fast_wait_loop:
5205 -       call    a20_test
5206 -       jnz     a20_done
5207 -       loop    a20_fast_wait_loop
5208 -
5209 -       # A20 is still not responding.  Try frobbing it again.
5210 -       # 
5211 -       decb    (a20_tries)
5212 -       jnz     a20_try_loop
5213 -       
5214 -       movw    $a20_err_msg, %si
5215 -       call    prtstr
5216 -
5217 -a20_die:
5218 -       hlt
5219 -       jmp     a20_die
5220 -
5221 -a20_tries:
5222 -       .byte   A20_ENABLE_LOOPS
5223 -
5224 -a20_err_msg:
5225 -       .ascii  "linux: fatal error: A20 gate not responding!"
5226 -       .byte   13, 10, 0
5227 -
5228 -       # If we get here, all is good
5229 -a20_done:
5230 -
5231 -#endif /* CONFIG_X86_VOYAGER */
5232 -# set up gdt and idt and 32bit start address
5233 -       lidt    idt_48                          # load idt with 0,0
5234 -       xorl    %eax, %eax                      # Compute gdt_base
5235 -       movw    %ds, %ax                        # (Convert %ds:gdt to a linear ptr)
5236 -       shll    $4, %eax
5237 -       addl    %eax, code32
5238 -       addl    $gdt, %eax
5239 -       movl    %eax, (gdt_48+2)
5240 -       lgdt    gdt_48                          # load gdt with whatever is
5241 -                                               # appropriate
5242 -
5243 -# make sure any possible coprocessor is properly reset..
5244 -       xorw    %ax, %ax
5245 -       outb    %al, $0xf0
5246 -       call    delay
5247 -
5248 -       outb    %al, $0xf1
5249 -       call    delay
5250 -
5251 -# well, that went ok, I hope. Now we mask all interrupts - the rest
5252 -# is done in init_IRQ().
5253 -       movb    $0xFF, %al                      # mask all interrupts for now
5254 -       outb    %al, $0xA1
5255 -       call    delay
5256 -       
5257 -       movb    $0xFB, %al                      # mask all irq's but irq2 which
5258 -       outb    %al, $0x21                      # is cascaded
5259 -
5260 -# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
5261 -# need no steenking BIOS anyway (except for the initial loading :-).
5262 -# The BIOS-routine wants lots of unnecessary data, and it's less
5263 -# "interesting" anyway. This is how REAL programmers do it.
5264 -#
5265 -# Well, now's the time to actually move into protected mode. To make
5266 -# things as simple as possible, we do no register set-up or anything,
5267 -# we let the gnu-compiled 32-bit programs do that. We just jump to
5268 -# absolute address 0x1000 (or the loader supplied one),
5269 -# in 32-bit protected mode.
5270 -#
5271 -# Note that the short jump isn't strictly needed, although there are
5272 -# reasons why it might be a good idea. It won't hurt in any case.
5273 -       movw    $1, %ax                         # protected mode (PE) bit
5274 -       lmsw    %ax                             # This is it!
5275 -       jmp     flush_instr
5276 -
5277 -flush_instr:
5278 -       xorw    %bx, %bx                        # Flag to indicate a boot
5279 -       xorl    %esi, %esi                      # Pointer to real-mode code
5280 -       movw    %cs, %si
5281 -       subw    $DELTA_INITSEG, %si
5282 -       shll    $4, %esi                        # Convert to 32-bit pointer
5283 -
5284 -# jump to startup_32 in arch/i386/boot/compressed/head.S
5285 -#      
5286 -# NOTE: For high loaded big kernels we need a
5287 -#      jmpi    0x100000,__BOOT_CS
5288 -#
5289 -#      but we yet haven't reloaded the CS register, so the default size 
5290 -#      of the target offset still is 16 bit.
5291 -#      However, using an operand prefix (0x66), the CPU will properly
5292 -#      take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
5293 -#      Manual, Mixing 16-bit and 32-bit code, page 16-6)
5294 -
5295 -       .byte 0x66, 0xea                        # prefix + jmpi-opcode
5296 -code32:        .long   startup_32                      # will be set to %cs+startup_32
5297 -       .word   __BOOT_CS
5298 -.code32
5299 -startup_32:
5300 -       movl $(__BOOT_DS), %eax
5301 -       movl %eax, %ds
5302 -       movl %eax, %es
5303 -       movl %eax, %fs
5304 -       movl %eax, %gs
5305 -       movl %eax, %ss
5306 -
5307 -       xorl %eax, %eax
5308 -1:     incl %eax                               # check that A20 really IS enabled
5309 -       movl %eax, 0x00000000                   # loop forever if it isn't
5310 -       cmpl %eax, 0x00100000
5311 -       je 1b
5312 -
5313 -       # Jump to the 32bit entry point
5314 -       jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi)
5315 -.code16
5316 -
5317 -# Here's a bunch of information about your current kernel..
5318 -kernel_version:        .ascii  UTS_RELEASE
5319 -               .ascii  " ("
5320 -               .ascii  LINUX_COMPILE_BY
5321 -               .ascii  "@"
5322 -               .ascii  LINUX_COMPILE_HOST
5323 -               .ascii  ") "
5324 -               .ascii  UTS_VERSION
5325 -               .byte   0
5326 -
5327 -# This is the default real mode switch routine.
5328 -# to be called just before protected mode transition
5329 -default_switch:
5330 -       cli                                     # no interrupts allowed !
5331 -       movb    $0x80, %al                      # disable NMI for bootup
5332 -                                               # sequence
5333 -       outb    %al, $0x70
5334 -       lret
5335 -
5336 -
5337 -#ifndef CONFIG_X86_VOYAGER
5338 -# This routine tests whether or not A20 is enabled.  If so, it
5339 -# exits with zf = 0.
5340 -#
5341 -# The memory address used, 0x200, is the int $0x80 vector, which
5342 -# should be safe.
5343 -
5344 -A20_TEST_ADDR = 4*0x80
5345 -
5346 -a20_test:
5347 -       pushw   %cx
5348 -       pushw   %ax
5349 -       xorw    %cx, %cx
5350 -       movw    %cx, %fs                        # Low memory
5351 -       decw    %cx
5352 -       movw    %cx, %gs                        # High memory area
5353 -       movw    $A20_TEST_LOOPS, %cx
5354 -       movw    %fs:(A20_TEST_ADDR), %ax
5355 -       pushw   %ax
5356 -a20_test_wait:
5357 -       incw    %ax
5358 -       movw    %ax, %fs:(A20_TEST_ADDR)
5359 -       call    delay                           # Serialize and make delay constant
5360 -       cmpw    %gs:(A20_TEST_ADDR+0x10), %ax
5361 -       loope   a20_test_wait
5362 -
5363 -       popw    %fs:(A20_TEST_ADDR)
5364 -       popw    %ax
5365 -       popw    %cx
5366 -       ret     
5367 -
5368 -#endif /* CONFIG_X86_VOYAGER */
5369 -
5370 -# This routine checks that the keyboard command queue is empty
5371 -# (after emptying the output buffers)
5372 -#
5373 -# Some machines have delusions that the keyboard buffer is always full
5374 -# with no keyboard attached...
5375 -#
5376 -# If there is no keyboard controller, we will usually get 0xff
5377 -# to all the reads.  With each IO taking a microsecond and
5378 -# a timeout of 100,000 iterations, this can take about half a
5379 -# second ("delay" == outb to port 0x80). That should be ok,
5380 -# and should also be plenty of time for a real keyboard controller
5381 -# to empty.
5382 -#
5383 -
5384 -empty_8042:
5385 -       pushl   %ecx
5386 -       movl    $100000, %ecx
5387 -
5388 -empty_8042_loop:
5389 -       decl    %ecx
5390 -       jz      empty_8042_end_loop
5391 -
5392 -       call    delay
5393 -
5394 -       inb     $0x64, %al                      # 8042 status port
5395 -       testb   $1, %al                         # output buffer?
5396 -       jz      no_output
5397 -
5398 -       call    delay
5399 -       inb     $0x60, %al                      # read it
5400 -       jmp     empty_8042_loop
5401 -
5402 -no_output:
5403 -       testb   $2, %al                         # is input buffer full?
5404 -       jnz     empty_8042_loop                 # yes - loop
5405 -empty_8042_end_loop:
5406 -       popl    %ecx
5407 -       ret
5408 -
5409 -# Read the cmos clock. Return the seconds in al
5410 -gettime:
5411 -       pushw   %cx
5412 -       movb    $0x02, %ah
5413 -       int     $0x1a
5414 -       movb    %dh, %al                        # %dh contains the seconds
5415 -       andb    $0x0f, %al
5416 -       movb    %dh, %ah
5417 -       movb    $0x04, %cl
5418 -       shrb    %cl, %ah
5419 -       aad
5420 -       popw    %cx
5421 -       ret
5422 -
5423 -# Delay is needed after doing I/O
5424 -delay:
5425 -       outb    %al,$0x80
5426 -       ret
5427 -
5428 -# Descriptor tables
5429 -#
5430 -# NOTE: The intel manual says gdt should be sixteen bytes aligned for
5431 -# efficiency reasons.  However, there are machines which are known not
5432 -# to boot with misaligned GDTs, so alter this at your peril!  If you alter
5433 -# GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two
5434 -# empty GDT entries (one for NULL and one reserved).
5435 -#
5436 -# NOTE:        On some CPUs, the GDT must be 8 byte aligned.  This is
5437 -# true for the Voyager Quad CPU card which will not boot without
5438 -# This directive.  16 byte aligment is recommended by intel.
5439 -#
5440 -       .align 16
5441 -gdt:
5442 -       .fill GDT_ENTRY_BOOT_CS,8,0
5443 -
5444 -       .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
5445 -       .word   0                               # base address = 0
5446 -       .word   0x9A00                          # code read/exec
5447 -       .word   0x00CF                          # granularity = 4096, 386
5448 -                                               #  (+5th nibble of limit)
5449 -
5450 -       .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
5451 -       .word   0                               # base address = 0
5452 -       .word   0x9200                          # data read/write
5453 -       .word   0x00CF                          # granularity = 4096, 386
5454 -                                               #  (+5th nibble of limit)
5455 -gdt_end:
5456 -       .align  4
5457 -       
5458 -       .word   0                               # alignment byte
5459 -idt_48:
5460 -       .word   0                               # idt limit = 0
5461 -       .word   0, 0                            # idt base = 0L
5462 -
5463 -       .word   0                               # alignment byte
5464 -gdt_48:
5465 -       .word   gdt_end - gdt - 1               # gdt limit
5466 -       .word   0, 0                            # gdt base (filled in later)
5467 -
5468 -# Include video setup & detection code
5469 -
5470 -#include "video.S"
5471 -
5472 -# Setup signature -- must be last
5473 -setup_sig1:    .word   SIG1
5474 -setup_sig2:    .word   SIG2
5475 -
5476 -# After this point, there is some free space which is used by the video mode
5477 -# handling code to store the temporary mode table (not used by the kernel).
5478 -
5479 -modelist:
5480 -
5481 -.text
5482 -endtext:
5483 -.data
5484 -enddata:
5485 -.bss
5486 -endbss:
5487 diff -puN /dev/null arch/i386/boot/setup.ld
5488 --- /dev/null
5489 +++ a/arch/i386/boot/setup.ld
5490 @@ -0,0 +1,54 @@
5491 +/*
5492 + * setup.ld
5493 + *
5494 + * Linker script for the i386 setup code
5495 + */
5496 +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
5497 +OUTPUT_ARCH(i386)
5498 +ENTRY(_start)
5499 +
5500 +SECTIONS
5501 +{
5502 +       . = 0;
5503 +       .bstext         : { *(.bstext) }
5504 +       .bsdata         : { *(.bsdata) }
5505 +
5506 +       . = 497;
5507 +       .header         : { *(.header) }
5508 +       .inittext       : { *(.inittext) }
5509 +       .initdata       : { *(.initdata) }
5510 +       .text           : { *(.text*) }
5511 +
5512 +       . = ALIGN(16);
5513 +       .rodata         : { *(.rodata*) }
5514 +
5515 +       .videocards     : {
5516 +               video_cards = .;
5517 +               *(.videocards)
5518 +               video_cards_end = .;
5519 +       }
5520 +
5521 +       . = ALIGN(16);
5522 +       .data           : { *(.data*) }
5523 +
5524 +       .signature      : {
5525 +               setup_sig = .;
5526 +               LONG(0x5a5aaa55)
5527 +       }
5528 +
5529 +
5530 +       . = ALIGN(16);
5531 +       .bss            :
5532 +       {
5533 +               __bss_start = .;
5534 +               *(.bss)
5535 +               __bss_end = .;
5536 +       }
5537 +       . = ALIGN(16);
5538 +       _end = .;
5539 +
5540 +       /DISCARD/ : { *(.note*) }
5541 +
5542 +       . = ASSERT(_end <= 0x8000, "Setup too big!");
5543 +       . = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
5544 +}
5545 diff -puN /dev/null arch/i386/boot/string.c
5546 --- /dev/null
5547 +++ a/arch/i386/boot/string.c
5548 @@ -0,0 +1,34 @@
5549 +/* -*- linux-c -*- ------------------------------------------------------- *
5550 + *
5551 + *   Copyright (C) 1991, 1992 Linus Torvalds
5552 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
5553 + *
5554 + *   This file is part of the Linux kernel, and is made available under
5555 + *   the terms of the GNU General Public License version 2.
5556 + *
5557 + * ----------------------------------------------------------------------- */
5558 +
5559 +/*
5560 + * arch/i386/boot/string.c
5561 + *
5562 + * Very basic string functions
5563 + */
5564 +
5565 +#include "boot.h"
5566 +#include <linux/edd.h>
5567 +
5568 +int strcmp(const char *str1, const char *str2)
5569 +{
5570 +       const unsigned char *s1 = (const unsigned char *)str1;
5571 +       const unsigned char *s2 = (const unsigned char *)str2;
5572 +       int delta = 0;
5573 +
5574 +       while (*s1 || *s2) {
5575 +               delta = *s2 - *s1;
5576 +               if (delta)
5577 +                       return delta;
5578 +               s1++;
5579 +               s2++;
5580 +       }
5581 +       return 0;
5582 +}
5583 diff -puN arch/i386/boot/tools/build.c~git-newsetup arch/i386/boot/tools/build.c
5584 --- a/arch/i386/boot/tools/build.c~git-newsetup
5585 +++ a/arch/i386/boot/tools/build.c
5586 @@ -1,13 +1,12 @@
5587  /*
5588   *  Copyright (C) 1991, 1992  Linus Torvalds
5589   *  Copyright (C) 1997 Martin Mares
5590 + *  Copyright (C) 2007 H. Peter Anvin
5591   */
5592  
5593  /*
5594   * This file builds a disk-image from three different files:
5595   *
5596 - * - bootsect: compatibility mbr which prints an error message if
5597 - *             someone tries to boot the kernel directly.
5598   * - setup: 8086 machine code, sets up system parm
5599   * - system: 80386 code for actual system
5600   *
5601 @@ -21,6 +20,7 @@
5602   * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
5603   * Cross compiling fixes by Gertjan van Wingerde, July 1996
5604   * Rewritten by Martin Mares, April 1997
5605 + * Substantially overhauled by H. Peter Anvin, April 2007
5606   */
5607  
5608  #include <stdio.h>
5609 @@ -32,23 +32,25 @@
5610  #include <sys/sysmacros.h>
5611  #include <unistd.h>
5612  #include <fcntl.h>
5613 +#include <sys/mman.h>
5614  #include <asm/boot.h>
5615  
5616 -typedef unsigned char byte;
5617 -typedef unsigned short word;
5618 -typedef unsigned long u32;
5619 +typedef unsigned char  u8;
5620 +typedef unsigned short u16;
5621 +typedef unsigned long  u32;
5622  
5623  #define DEFAULT_MAJOR_ROOT 0
5624  #define DEFAULT_MINOR_ROOT 0
5625  
5626 -/* Minimal number of setup sectors (see also bootsect.S) */
5627 -#define SETUP_SECTS 4
5628 +/* Minimal number of setup sectors */
5629 +#define SETUP_SECT_MIN 5
5630 +#define SETUP_SECT_MAX 64
5631  
5632 -byte buf[1024];
5633 -int fd;
5634 +/* This must be large enough to hold the entire setup */
5635 +u8 buf[SETUP_SECT_MAX*512];
5636  int is_big_kernel;
5637  
5638 -void die(const char * str, ...)
5639 +static void die(const char * str, ...)
5640  {
5641         va_list args;
5642         va_start(args, str);
5643 @@ -57,15 +59,9 @@ void die(const char * str, ...)
5644         exit(1);
5645  }
5646  
5647 -void file_open(const char *name)
5648 +static void usage(void)
5649  {
5650 -       if ((fd = open(name, O_RDONLY, 0)) < 0)
5651 -               die("Unable to open `%s': %m", name);
5652 -}
5653 -
5654 -void usage(void)
5655 -{
5656 -       die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
5657 +       die("Usage: build [-b] setup system [rootdev] [> image]");
5658  }
5659  
5660  int main(int argc, char ** argv)
5661 @@ -73,27 +69,30 @@ int main(int argc, char ** argv)
5662         unsigned int i, sz, setup_sectors;
5663         int c;
5664         u32 sys_size;
5665 -       byte major_root, minor_root;
5666 +       u8 major_root, minor_root;
5667         struct stat sb;
5668 +       FILE *file;
5669 +       int fd;
5670 +       void *kernel;
5671  
5672         if (argc > 2 && !strcmp(argv[1], "-b"))
5673           {
5674             is_big_kernel = 1;
5675             argc--, argv++;
5676           }
5677 -       if ((argc < 4) || (argc > 5))
5678 +       if ((argc < 3) || (argc > 4))
5679                 usage();
5680 -       if (argc > 4) {
5681 -               if (!strcmp(argv[4], "CURRENT")) {
5682 +       if (argc > 3) {
5683 +               if (!strcmp(argv[3], "CURRENT")) {
5684                         if (stat("/", &sb)) {
5685                                 perror("/");
5686                                 die("Couldn't stat /");
5687                         }
5688                         major_root = major(sb.st_dev);
5689                         minor_root = minor(sb.st_dev);
5690 -               } else if (strcmp(argv[4], "FLOPPY")) {
5691 -                       if (stat(argv[4], &sb)) {
5692 -                               perror(argv[4]);
5693 +               } else if (strcmp(argv[3], "FLOPPY")) {
5694 +                       if (stat(argv[3], &sb)) {
5695 +                               perror(argv[3]);
5696                                 die("Couldn't stat root device.");
5697                         }
5698                         major_root = major(sb.st_rdev);
5699 @@ -108,79 +107,62 @@ int main(int argc, char ** argv)
5700         }
5701         fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
5702  
5703 -       file_open(argv[1]);
5704 -       i = read(fd, buf, sizeof(buf));
5705 -       fprintf(stderr,"Boot sector %d bytes.\n",i);
5706 -       if (i != 512)
5707 -               die("Boot block must be exactly 512 bytes");
5708 +       /* Copy the setup code */
5709 +       file = fopen(argv[1], "r");
5710 +       if (!file)
5711 +               die("Unable to open `%s': %m", argv[1]);
5712 +       c = fread(buf, 1, sizeof(buf), file);
5713 +       if (ferror(file))
5714 +               die("read-error on `setup'");
5715 +       if (c < 1024)
5716 +               die("The setup must be at least 1024 bytes");
5717         if (buf[510] != 0x55 || buf[511] != 0xaa)
5718                 die("Boot block hasn't got boot flag (0xAA55)");
5719 +       fclose(file);
5720 +
5721 +       /* Pad unused space with zeros */
5722 +       setup_sectors = (c + 511) / 512;
5723 +       if (setup_sectors < SETUP_SECT_MIN)
5724 +               setup_sectors = SETUP_SECT_MIN;
5725 +       i = setup_sectors*512;
5726 +       memset(buf+c, 0, i-c);
5727 +
5728 +       /* Set the default root device */
5729         buf[508] = minor_root;
5730         buf[509] = major_root;
5731 -       if (write(1, buf, 512) != 512)
5732 -               die("Write call failed");
5733 -       close (fd);
5734 -
5735 -       file_open(argv[2]);                                 /* Copy the setup code */
5736 -       for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
5737 -               if (write(1, buf, c) != c)
5738 -                       die("Write call failed");
5739 -       if (c != 0)
5740 -               die("read-error on `setup'");
5741 -       close (fd);
5742  
5743 -       setup_sectors = (i + 511) / 512;        /* Pad unused space with zeros */
5744 -       /* for compatibility with ancient versions of LILO. */
5745 -       if (setup_sectors < SETUP_SECTS)
5746 -               setup_sectors = SETUP_SECTS;
5747 -       fprintf(stderr, "Setup is %d bytes.\n", i);
5748 -       memset(buf, 0, sizeof(buf));
5749 -       while (i < setup_sectors * 512) {
5750 -               c = setup_sectors * 512 - i;
5751 -               if (c > sizeof(buf))
5752 -                       c = sizeof(buf);
5753 -               if (write(1, buf, c) != c)
5754 -                       die("Write call failed");
5755 -               i += c;
5756 -       }
5757 +       fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
5758  
5759 -       file_open(argv[3]);
5760 -       if (fstat (fd, &sb))
5761 -               die("Unable to stat `%s': %m", argv[3]);
5762 +       /* Open and stat the kernel file */
5763 +       fd = open(argv[2], O_RDONLY);
5764 +       if (fd < 0)
5765 +               die("Unable to open `%s': %m", argv[2]);
5766 +       if (fstat(fd, &sb))
5767 +               die("Unable to stat `%s': %m", argv[2]);
5768         sz = sb.st_size;
5769 -       fprintf (stderr, "System is %d kB\n", sz/1024);
5770 +       fprintf (stderr, "System is %d kB\n", (sz+1023)/1024);
5771 +       kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
5772 +       if (kernel == MAP_FAILED)
5773 +               die("Unable to mmap '%s': %m", argv[2]);
5774         sys_size = (sz + 15) / 16;
5775         if (!is_big_kernel && sys_size > DEF_SYSSIZE)
5776                 die("System is too big. Try using bzImage or modules.");
5777 -       while (sz > 0) {
5778 -               int l, n;
5779  
5780 -               l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
5781 -               if ((n=read(fd, buf, l)) != l) {
5782 -                       if (n < 0)
5783 -                               die("Error reading %s: %m", argv[3]);
5784 -                       else
5785 -                               die("%s: Unexpected EOF", argv[3]);
5786 -               }
5787 -               if (write(1, buf, l) != l)
5788 -                       die("Write failed");
5789 -               sz -= l;
5790 -       }
5791 +       /* Patch the setup code with the appropriate size parameters */
5792 +       buf[0x1f1] = setup_sectors-1;
5793 +       buf[0x1f4] = sys_size;
5794 +       buf[0x1f5] = sys_size >> 8;
5795 +       buf[0x1f6] = sys_size >> 16;
5796 +       buf[0x1f7] = sys_size >> 24;
5797 +
5798 +       if (fwrite(buf, 1, i, stdout) != i)
5799 +               die("Writing setup failed");
5800 +
5801 +       /* Copy the kernel code */
5802 +       if (fwrite(kernel, 1, sz, stdout) != sz)
5803 +               die("Writing kernel failed");
5804         close(fd);
5805  
5806 -       if (lseek(1, 497, SEEK_SET) != 497)                 /* Write sizes to the bootsector */
5807 -               die("Output: seek failed");
5808 -       buf[0] = setup_sectors;
5809 -       if (write(1, buf, 1) != 1)
5810 -               die("Write of setup sector count failed");
5811 -       if (lseek(1, 500, SEEK_SET) != 500)
5812 -               die("Output: seek failed");
5813 -       buf[0] = (sys_size & 0xff);
5814 -       buf[1] = ((sys_size >> 8) & 0xff);
5815 -       buf[2] = ((sys_size >> 16) & 0xff);
5816 -       buf[3] = ((sys_size >> 24) & 0xff);
5817 -       if (write(1, buf, 4) != 4)
5818 -               die("Write of image length failed");
5819 -
5820 -       return 0;                                           /* Everything is OK */
5821 +       /* Everything is OK */
5822 +       return 0;
5823  }
5824 diff -puN /dev/null arch/i386/boot/tty.c
5825 --- /dev/null
5826 +++ a/arch/i386/boot/tty.c
5827 @@ -0,0 +1,112 @@
5828 +/* -*- linux-c -*- ------------------------------------------------------- *
5829 + *
5830 + *   Copyright (C) 1991, 1992 Linus Torvalds
5831 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
5832 + *
5833 + *   This file is part of the Linux kernel, and is made available under
5834 + *   the terms of the GNU General Public License version 2.
5835 + *
5836 + * ----------------------------------------------------------------------- */
5837 +
5838 +/*
5839 + * arch/i386/boot/tty.c
5840 + *
5841 + * Very simple screen I/O
5842 + * XXX: Probably should add very simple serial I/O?
5843 + */
5844 +
5845 +#include "boot.h"
5846 +
5847 +/*
5848 + * These functions are in .inittext so they can be used to signal
5849 + * error during initialization.
5850 + */
5851 +
5852 +void __attribute__((section(".inittext"))) putchar(int ch)
5853 +{
5854 +       unsigned char c = ch;
5855 +
5856 +       if (c == '\n')
5857 +               putchar('\r');  /* \n -> \r\n */
5858 +
5859 +       /* int $0x10 is known to have bugs involving touching registers
5860 +          it shouldn't.  Be extra conservative... */
5861 +       asm volatile("pushal; int $0x10; popal"
5862 +                    : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
5863 +}
5864 +
5865 +void __attribute__((section(".inittext"))) puts(const char *str)
5866 +{
5867 +       int n = 0;
5868 +       while (*str) {
5869 +               putchar(*str++);
5870 +               n++;
5871 +       }
5872 +}
5873 +
5874 +/*
5875 + * Read the CMOS clock through the BIOS, and return the
5876 + * seconds in BCD.
5877 + */
5878 +
5879 +static u8 gettime(void)
5880 +{
5881 +       u16 ax = 0x0200;
5882 +       u16 cx, dx;
5883 +
5884 +       asm("int $0x1a"
5885 +           : "+a" (ax), "=c" (cx), "=d" (dx)
5886 +           : : "ebx", "esi", "edi");
5887 +
5888 +       return dx >> 8;
5889 +}
5890 +
5891 +/*
5892 + * Read from the keyboard
5893 + */
5894 +int getchar(void)
5895 +{
5896 +       u16 ax = 0;
5897 +       asm("int $0x16" : "+a" (ax));
5898 +
5899 +       return ax & 0xff;
5900 +}
5901 +
5902 +static int kbd_pending(void)
5903 +{
5904 +       u8 pending;
5905 +       asm("int $0x16; setnz %0"
5906 +           : "=rm" (pending)
5907 +           : "a" (0x0100));
5908 +       return pending;
5909 +}
5910 +
5911 +void kbd_flush(void)
5912 +{
5913 +       for (;;) {
5914 +               if (!kbd_pending())
5915 +                       break;
5916 +               getchar();
5917 +       }
5918 +}
5919 +
5920 +int getchar_timeout(void)
5921 +{
5922 +       int cnt = 30;
5923 +       int t0, t1;
5924 +
5925 +       t0 = gettime();
5926 +
5927 +       while (cnt) {
5928 +               if (kbd_pending())
5929 +                       return getchar();
5930 +
5931 +               t1 = gettime();
5932 +               if (t0 != t1) {
5933 +                       cnt--;
5934 +                       t0 = t1;
5935 +               }
5936 +       }
5937 +
5938 +       return 0;               /* Timeout! */
5939 +}
5940 diff -puN /dev/null arch/i386/boot/version.c
5941 --- /dev/null
5942 +++ a/arch/i386/boot/version.c
5943 @@ -0,0 +1,23 @@
5944 +/* -*- linux-c -*- ------------------------------------------------------- *
5945 + *
5946 + *   Copyright (C) 1991, 1992 Linus Torvalds
5947 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
5948 + *
5949 + *   This file is part of the Linux kernel, and is made available under
5950 + *   the terms of the GNU General Public License version 2.
5951 + *
5952 + * ----------------------------------------------------------------------- */
5953 +
5954 +/*
5955 + * arch/i386/boot/version.c
5956 + *
5957 + * Kernel version string
5958 + */
5959 +
5960 +#include "boot.h"
5961 +#include <linux/utsrelease.h>
5962 +#include <linux/compile.h>
5963 +
5964 +const char kernel_version[] =
5965 +       UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") "
5966 +       UTS_VERSION;
5967 diff -puN /dev/null arch/i386/boot/vesa.h
5968 --- /dev/null
5969 +++ a/arch/i386/boot/vesa.h
5970 @@ -0,0 +1,79 @@
5971 +/* ----------------------------------------------------------------------- *
5972 + *
5973 + *   Copyright 1999-2007 H. Peter Anvin - All Rights Reserved
5974 + *
5975 + *   This program is free software; you can redistribute it and/or modify
5976 + *   it under the terms of the GNU General Public License as published by
5977 + *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
5978 + *   Boston MA 02111-1307, USA; either version 2 of the License, or
5979 + *   (at your option) any later version; incorporated herein by reference.
5980 + *
5981 + * ----------------------------------------------------------------------- */
5982 +
5983 +#ifndef BOOT_VESA_H
5984 +#define BOOT_VESA_H
5985 +
5986 +typedef struct {
5987 +       u16 off, seg;
5988 +} far_ptr;
5989 +
5990 +/* VESA General Information table */
5991 +struct vesa_general_info {
5992 +  u32    signature;            /* 0 Magic number = "VESA" */
5993 +  u16    version;              /* 4 */
5994 +  far_ptr vendor_string;       /* 6 */
5995 +  u32    capabilities;         /* 10 */
5996 +  far_ptr video_mode_ptr;      /* 14 */
5997 +  u16     total_memory;                /* 18 */
5998 +
5999 +  u16     oem_software_rev;    /* 20 */
6000 +  far_ptr oem_vendor_name_ptr; /* 22 */
6001 +  far_ptr oem_product_name_ptr;        /* 26 */
6002 +  far_ptr oem_product_rev_ptr; /* 30 */
6003 +
6004 +  u8      reserved[222];       /* 34 */
6005 +  u8      oem_data[256];       /* 256 */
6006 +} __attribute__((packed));
6007 +
6008 +#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
6009 +#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24))
6010 +
6011 +struct vesa_mode_info {
6012 +  u16     mode_attr;           /* 0 */
6013 +  u8      win_attr[2];         /* 2 */
6014 +  u16     win_grain;           /* 4 */
6015 +  u16     win_size;            /* 6 */
6016 +  u16     win_seg[2];          /* 8 */
6017 +  far_ptr win_scheme;          /* 12 */
6018 +  u16     logical_scan;                /* 16 */
6019 +
6020 +  u16     h_res;               /* 18 */
6021 +  u16     v_res;               /* 20 */
6022 +  u8      char_width;          /* 22 */
6023 +  u8      char_height;         /* 23 */
6024 +  u8      memory_planes;       /* 24 */
6025 +  u8      bpp;                 /* 25 */
6026 +  u8      banks;               /* 26 */
6027 +  u8      memory_layout;       /* 27 */
6028 +  u8      bank_size;           /* 28 */
6029 +  u8      image_planes;                /* 29 */
6030 +  u8      page_function;       /* 30 */
6031 +
6032 +  u8      rmask;               /* 31 */
6033 +  u8      rpos;                        /* 32 */
6034 +  u8      gmask;               /* 33 */
6035 +  u8      gpos;                        /* 34 */
6036 +  u8      bmask;               /* 35 */
6037 +  u8      bpos;                        /* 36 */
6038 +  u8      resv_mask;           /* 37 */
6039 +  u8      resv_pos;            /* 38 */
6040 +  u8      dcm_info;            /* 39 */
6041 +
6042 +  u32     lfb_ptr;             /* 40 Linear frame buffer address */
6043 +  u32     offscreen_ptr;       /* 44 Offscreen memory address */
6044 +  u16     offscreen_size;      /* 48 */
6045 +
6046 +  u8      reserved[206];       /* 50 */
6047 +} __attribute__((packed));
6048 +
6049 +#endif /* LIB_SYS_VESA_H */
6050 diff -puN /dev/null arch/i386/boot/video-bios.c
6051 --- /dev/null
6052 +++ a/arch/i386/boot/video-bios.c
6053 @@ -0,0 +1,125 @@
6054 +/* -*- linux-c -*- ------------------------------------------------------- *
6055 + *
6056 + *   Copyright (C) 1991, 1992 Linus Torvalds
6057 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
6058 + *
6059 + *   This file is part of the Linux kernel, and is made available under
6060 + *   the terms of the GNU General Public License version 2.
6061 + *
6062 + * ----------------------------------------------------------------------- */
6063 +
6064 +/*
6065 + * arch/i386/boot/video-bios.c
6066 + *
6067 + * Standard video BIOS modes
6068 + *
6069 + * We have two options for this; silent and scanned.
6070 + */
6071 +
6072 +#include "boot.h"
6073 +#include "video.h"
6074 +
6075 +__videocard video_bios;
6076 +
6077 +/* Set a conventional BIOS mode */
6078 +static int set_bios_mode(u8 mode);
6079 +
6080 +static int bios_set_mode(struct mode_info *mi)
6081 +{
6082 +       return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS);
6083 +}
6084 +
6085 +static int set_bios_mode(u8 mode)
6086 +{
6087 +       u16 ax;
6088 +       u8 new_mode;
6089 +
6090 +       ax = mode;              /* AH=0x00 Set Video Mode */
6091 +       asm volatile(INT10
6092 +                    : "+a" (ax)
6093 +                    : : "ebx", "ecx", "edx", "esi", "edi");
6094 +
6095 +       ax = 0x0f00;            /* Get Current Video Mode */
6096 +       asm volatile(INT10
6097 +                    : "+a" (ax)
6098 +                    : : "ebx", "ecx", "edx", "esi", "edi");
6099 +
6100 +       do_restore = 1;         /* Assume video contents was lost */
6101 +       new_mode = ax & 0x7f;   /* Not all BIOSes are clean with the top bit */
6102 +
6103 +       if (new_mode == mode)
6104 +               return 0;       /* Mode change OK */
6105 +
6106 +       if (new_mode != boot_params.screen_info.orig_video_mode) {
6107 +               /* Mode setting failed, but we didn't end up where we
6108 +                  started.  That's bad.  Try to revert to the original
6109 +                  video mode. */
6110 +               ax = boot_params.screen_info.orig_video_mode;
6111 +               asm volatile(INT10
6112 +                            : "+a" (ax)
6113 +                            : : "ebx", "ecx", "edx", "esi", "edi");
6114 +       }
6115 +       return -1;
6116 +}
6117 +
6118 +static int bios_probe(void)
6119 +{
6120 +       u8 mode;
6121 +       u8 saved_mode = boot_params.screen_info.orig_video_mode;
6122 +       u16 crtc;
6123 +       struct mode_info *mi;
6124 +       int nmodes = 0;
6125 +
6126 +       if (adapter != ADAPTER_EGA && adapter != ADAPTER_VGA)
6127 +               return 0;
6128 +
6129 +       set_fs(0);
6130 +       crtc = vga_crtc();
6131 +
6132 +       video_bios.modes = GET_HEAP(struct mode_info, 0);
6133 +
6134 +       for (mode = 0x14; mode <= 0x7f; mode++) {
6135 +               if (heap_free() < sizeof(struct mode_info))
6136 +                       break;
6137 +
6138 +               if (mode_defined(VIDEO_FIRST_BIOS+mode))
6139 +                       continue;
6140 +
6141 +               if (set_bios_mode(mode))
6142 +                       continue;
6143 +
6144 +               /* Try to verify that it's a text mode. */
6145 +
6146 +               /* Attribute Controller: make graphics controller disabled */
6147 +               if (in_idx(0x3c0, 0x10) & 0x01)
6148 +                       continue;
6149 +
6150 +               /* Graphics Controller: verify Alpha addressing enabled */
6151 +               if (in_idx(0x3ce, 0x06) & 0x01)
6152 +                       continue;
6153 +
6154 +               /* CRTC cursor location low should be zero(?) */
6155 +               if (in_idx(crtc, 0x0f))
6156 +                       continue;
6157 +
6158 +               mi = GET_HEAP(struct mode_info, 1);
6159 +               mi->mode = VIDEO_FIRST_BIOS+mode;
6160 +               mi->x = rdfs16(0x44a);
6161 +               mi->y = rdfs8(0x484)+1;
6162 +               nmodes++;
6163 +       }
6164 +
6165 +       set_bios_mode(saved_mode);
6166 +
6167 +       return nmodes;
6168 +}
6169 +
6170 +__videocard video_bios =
6171 +{
6172 +       .card_name      = "BIOS (scanned)",
6173 +       .probe          = bios_probe,
6174 +       .set_mode       = bios_set_mode,
6175 +       .unsafe         = 1,
6176 +       .xmode_first    = VIDEO_FIRST_BIOS,
6177 +       .xmode_n        = 0x80,
6178 +};
6179 diff -puN /dev/null arch/i386/boot/video-vesa.c
6180 --- /dev/null
6181 +++ a/arch/i386/boot/video-vesa.c
6182 @@ -0,0 +1,283 @@
6183 +/* -*- linux-c -*- ------------------------------------------------------- *
6184 + *
6185 + *   Copyright (C) 1991, 1992 Linus Torvalds
6186 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
6187 + *
6188 + *   This file is part of the Linux kernel, and is made available under
6189 + *   the terms of the GNU General Public License version 2.
6190 + *
6191 + * ----------------------------------------------------------------------- */
6192 +
6193 +/*
6194 + * arch/i386/boot/video-vesa.c
6195 + *
6196 + * VESA text modes
6197 + */
6198 +
6199 +#include "boot.h"
6200 +#include "video.h"
6201 +#include "vesa.h"
6202 +
6203 +/* VESA information */
6204 +static struct vesa_general_info vginfo;
6205 +static struct vesa_mode_info vminfo;
6206 +
6207 +__videocard video_vesa;
6208 +
6209 +static void vesa_store_mode_params_graphics(void);
6210 +
6211 +static int vesa_probe(void)
6212 +{
6213 +#ifdef CONFIG_VIDEO_VESA
6214 +       u16 ax;
6215 +       u16 mode;
6216 +       addr_t mode_ptr;
6217 +       struct mode_info *mi;
6218 +       int nmodes = 0;
6219 +
6220 +       video_vesa.modes = GET_HEAP(struct mode_info, 0);
6221 +
6222 +       vginfo.signature = VBE2_MAGIC;
6223 +
6224 +       /* Optimistically assume a VESA BIOS is register-clean... */
6225 +       ax = 0x4f00;
6226 +       asm("int $0x10" : "+a" (ax), "=m" (vginfo) : "D" (&vginfo));
6227 +
6228 +       if (ax != 0x004f ||
6229 +           vginfo.signature != VESA_MAGIC ||
6230 +           vginfo.version < 0x0102)
6231 +               return 0;       /* Not present */
6232 +
6233 +       set_fs(vginfo.video_mode_ptr.seg);
6234 +       mode_ptr = vginfo.video_mode_ptr.off;
6235 +
6236 +       while ((mode = rdfs16(mode_ptr)) != 0xffff) {
6237 +               mode_ptr += 2;
6238 +
6239 +               if (heap_free() < sizeof(struct mode_info))
6240 +                       break;  /* Heap full, can't save mode info */
6241 +
6242 +               if (mode & ~0x1ff)
6243 +                       continue;
6244 +
6245 +               memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
6246 +
6247 +               ax = 0x4f01;
6248 +               asm("int $0x10"
6249 +                   : "+a" (ax), "=m" (vminfo)
6250 +                   : "c" (mode), "D" (&vminfo));
6251 +
6252 +               if (ax != 0x004f)
6253 +                       continue;
6254 +
6255 +               if ((vminfo.mode_attr & 0x15) == 0x05) {
6256 +                       /* Text Mode, TTY BIOS supported,
6257 +                          supported by hardware */
6258 +                       mi = GET_HEAP(struct mode_info, 1);
6259 +                       mi->mode = mode + VIDEO_FIRST_VESA;
6260 +                       mi->x    = vminfo.h_res;
6261 +                       mi->y    = vminfo.v_res;
6262 +                       nmodes++;
6263 +               } else if ((vminfo.mode_attr & 0x99) == 0x99) {
6264 +#ifdef CONFIG_FB
6265 +                       /* Graphics mode, color, linear frame buffer
6266 +                          supported -- register the mode but hide from
6267 +                          the menu.  Only do this if framebuffer is
6268 +                          configured, however, otherwise the user will
6269 +                          be left without a screen. */
6270 +                       mi = GET_HEAP(struct mode_info, 1);
6271 +                       mi->mode = mode + VIDEO_FIRST_VESA;
6272 +                       mi->x = mi->y = 0;
6273 +                       nmodes++;
6274 +#endif
6275 +               }
6276 +       }
6277 +
6278 +       return nmodes;
6279 +#else
6280 +       return 0;
6281 +#endif
6282 +}
6283 +
6284 +static int vesa_set_mode(struct mode_info *mode)
6285 +{
6286 +       u16 ax;
6287 +       int is_graphic;
6288 +       u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;
6289 +
6290 +       memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
6291 +
6292 +       ax = 0x4f01;
6293 +       asm("int $0x10"
6294 +           : "+a" (ax), "=m" (vminfo)
6295 +           : "c" (vesa_mode), "D" (&vminfo));
6296 +
6297 +       if (ax != 0x004f)
6298 +               return -1;
6299 +
6300 +       if ((vminfo.mode_attr & 0x15) == 0x05) {
6301 +               /* It's a supported text mode */
6302 +               is_graphic = 0;
6303 +       } else if ((vminfo.mode_attr & 0x99) == 0x99) {
6304 +               /* It's a graphics mode with linear frame buffer */
6305 +               is_graphic = 1;
6306 +               vesa_mode |= 0x4000; /* Request linear frame buffer */
6307 +       } else {
6308 +               return -1;      /* Invalid mode */
6309 +       }
6310 +
6311 +
6312 +       ax = 0x4f02;
6313 +       asm volatile("int $0x10"
6314 +                    : "+a" (ax)
6315 +                    : "b" (vesa_mode), "D" (0));
6316 +
6317 +       if (ax != 0x004f)
6318 +               return -1;
6319 +
6320 +       graphic_mode = is_graphic;
6321 +       if (!is_graphic) {
6322 +               /* Text mode */
6323 +               force_x = mode->x;
6324 +               force_y = mode->y;
6325 +               do_restore = 1;
6326 +       } else {
6327 +               /* Graphics mode */
6328 +               vesa_store_mode_params_graphics();
6329 +       }
6330 +
6331 +       return 0;
6332 +}
6333 +
6334 +
6335 +/* Switch DAC to 8-bit mode */
6336 +static void vesa_dac_set_8bits(void)
6337 +{
6338 +       u8 dac_size = 6;
6339 +
6340 +       /* If possible, switch the DAC to 8-bit mode */
6341 +       if (vginfo.capabilities & 1) {
6342 +               u16 ax, bx;
6343 +
6344 +               ax = 0x4f08;
6345 +               bx = 0x0800;
6346 +               asm volatile(INT10
6347 +                            : "+a" (ax), "+b" (bx)
6348 +                            : : "ecx", "edx", "esi", "edi");
6349 +
6350 +               if (ax == 0x004f)
6351 +                       dac_size = bx >> 8;
6352 +       }
6353 +
6354 +       /* Set the color sizes to the DAC size, and offsets to 0 */
6355 +       boot_params.screen_info.red_size = dac_size;
6356 +       boot_params.screen_info.green_size = dac_size;
6357 +       boot_params.screen_info.blue_size = dac_size;
6358 +       boot_params.screen_info.rsvd_size = dac_size;
6359 +
6360 +       boot_params.screen_info.red_pos = 0;
6361 +       boot_params.screen_info.green_pos = 0;
6362 +       boot_params.screen_info.blue_pos = 0;
6363 +       boot_params.screen_info.rsvd_pos = 0;
6364 +}
6365 +
6366 +/* Save the VESA protected mode info */
6367 +static void vesa_store_pm_info(void)
6368 +{
6369 +       u16 ax, bx, di, es;
6370 +
6371 +       ax = 0x4f0a;
6372 +       bx = di = 0;
6373 +       asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
6374 +           : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
6375 +           : : "ecx", "esi");
6376 +
6377 +       if (ax != 0x004f)
6378 +               return;
6379 +
6380 +       boot_params.screen_info.vesapm_seg = es;
6381 +       boot_params.screen_info.vesapm_off = di;
6382 +}
6383 +
6384 +/*
6385 + * Save video mode parameters for graphics mode
6386 + */
6387 +static void vesa_store_mode_params_graphics(void)
6388 +{
6389 +       /* Tell the kernel we're in VESA graphics mode */
6390 +       boot_params.screen_info.orig_video_isVGA = 0x23;
6391 +
6392 +       /* Mode parameters */
6393 +       boot_params.screen_info.vesa_attributes = vminfo.mode_attr;
6394 +       boot_params.screen_info.lfb_linelength = vminfo.logical_scan;
6395 +       boot_params.screen_info.lfb_width = vminfo.h_res;
6396 +       boot_params.screen_info.lfb_height = vminfo.v_res;
6397 +       boot_params.screen_info.lfb_depth = vminfo.bpp;
6398 +       boot_params.screen_info.pages = vminfo.image_planes;
6399 +       boot_params.screen_info.lfb_base = vminfo.lfb_ptr;
6400 +       memcpy(&boot_params.screen_info.red_size,
6401 +              &vminfo.rmask, 8);
6402 +
6403 +       /* General parameters */
6404 +       boot_params.screen_info.lfb_size = vginfo.total_memory;
6405 +
6406 +       if (vminfo.bpp <= 8)
6407 +               vesa_dac_set_8bits();
6408 +
6409 +       vesa_store_pm_info();
6410 +}
6411 +
6412 +/*
6413 + * Save EDID information for the kernel; this is invoked, separately,
6414 + * after mode-setting.
6415 + */
6416 +void vesa_store_edid(void)
6417 +{
6418 +#ifdef CONFIG_FIRMWARE_EDID
6419 +       u16 ax, bx, cx, dx, di;
6420 +
6421 +       /* Apparently used as a nonsense token... */
6422 +       memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info);
6423 +
6424 +       if (vginfo.version < 0x0200)
6425 +               return;         /* EDID requires VBE 2.0+ */
6426 +
6427 +       ax = 0x4f15;            /* VBE DDC */
6428 +       bx = 0x0000;            /* Report DDC capabilities */
6429 +       cx = 0;                 /* Controller 0 */
6430 +       di = 0;                 /* ES:DI must be 0 by spec */
6431 +
6432 +       /* Note: The VBE DDC spec is different from the main VESA spec;
6433 +          we genuinely have to assume all registers are destroyed here. */
6434 +
6435 +       asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
6436 +           : "+a" (ax), "+b" (bx)
6437 +           :  "c" (cx), "D" (di)
6438 +           : "esi");
6439 +
6440 +       if (ax != 0x004f)
6441 +               return;         /* No EDID */
6442 +
6443 +       /* BH = time in seconds to transfer EDD information */
6444 +       /* BL = DDC level supported */
6445 +
6446 +       ax = 0x4f15;            /* VBE DDC */
6447 +       bx = 0x0001;            /* Read EDID */
6448 +       cx = 0;                 /* Controller 0 */
6449 +       dx = 0;                 /* EDID block number */
6450 +       di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
6451 +       asm(INT10
6452 +           : "+a" (ax), "+b" (bx), "+d" (dx)
6453 +           : "c" (cx), "D" (di)
6454 +           : "esi");
6455 +#endif /* CONFIG_FIRMWARE_EDID */
6456 +}
6457 +
6458 +__videocard video_vesa =
6459 +{
6460 +       .card_name      = "VESA",
6461 +       .probe          = vesa_probe,
6462 +       .set_mode       = vesa_set_mode,
6463 +       .xmode_first    = VIDEO_FIRST_VESA,
6464 +       .xmode_n        = 0x200,
6465 +};
6466 diff -puN /dev/null arch/i386/boot/video-vga.c
6467 --- /dev/null
6468 +++ a/arch/i386/boot/video-vga.c
6469 @@ -0,0 +1,260 @@
6470 +/* -*- linux-c -*- ------------------------------------------------------- *
6471 + *
6472 + *   Copyright (C) 1991, 1992 Linus Torvalds
6473 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
6474 + *
6475 + *   This file is part of the Linux kernel, and is made available under
6476 + *   the terms of the GNU General Public License version 2.
6477 + *
6478 + * ----------------------------------------------------------------------- */
6479 +
6480 +/*
6481 + * arch/i386/boot/video-vga.c
6482 + *
6483 + * Common all-VGA modes
6484 + */
6485 +
6486 +#include "boot.h"
6487 +#include "video.h"
6488 +
6489 +static struct mode_info vga_modes[] = {
6490 +       { VIDEO_80x25,  80, 25 },
6491 +       { VIDEO_8POINT, 80, 50 },
6492 +       { VIDEO_80x43,  80, 43 },
6493 +       { VIDEO_80x28,  80, 28 },
6494 +       { VIDEO_80x30,  80, 30 },
6495 +       { VIDEO_80x34,  80, 34 },
6496 +       { VIDEO_80x60,  80, 60 },
6497 +};
6498 +
6499 +static struct mode_info ega_modes[] = {
6500 +       { VIDEO_80x25,  80, 25 },
6501 +       { VIDEO_8POINT, 80, 43 },
6502 +};
6503 +
6504 +static struct mode_info cga_modes[] = {
6505 +       { VIDEO_80x25,  80, 25 },
6506 +};
6507 +
6508 +__videocard video_vga;
6509 +
6510 +/* Set basic 80x25 mode */
6511 +static u8 vga_set_basic_mode(void)
6512 +{
6513 +       u16 ax;
6514 +       u8 rows;
6515 +       u8 mode;
6516 +
6517 +#ifdef CONFIG_VIDEO_400_HACK
6518 +       if (adapter >= ADAPTER_VGA) {
6519 +               asm(INT10
6520 +                   : : "a" (0x1202), "b" (0x0030)
6521 +                   : "ecx", "edx", "esi", "edi");
6522 +       }
6523 +#endif
6524 +
6525 +       ax = 0x0f00;
6526 +       asm(INT10
6527 +           : "+a" (ax)
6528 +           : : "ebx", "ecx", "edx", "esi", "edi");
6529 +
6530 +       mode = (u8)ax;
6531 +
6532 +       set_fs(0);
6533 +       rows = rdfs8(0x484);    /* rows minus one */
6534 +
6535 +#ifndef CONFIG_VIDEO_400_HACK
6536 +       if ((ax == 0x5003 || ax == 0x5007) &&
6537 +           (rows == 0 || rows == 24))
6538 +               return mode;
6539 +#endif
6540 +
6541 +       if (mode != 3 && mode != 7)
6542 +               mode = 3;
6543 +
6544 +       /* Set the mode */
6545 +       asm volatile(INT10
6546 +                    : : "a" (mode)
6547 +                    : "ebx", "ecx", "edx", "esi", "edi");
6548 +       do_restore = 1;
6549 +       return mode;
6550 +}
6551 +
6552 +static void vga_set_8font(void)
6553 +{
6554 +       /* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
6555 +
6556 +       /* Set 8x8 font */
6557 +       asm volatile(INT10 : : "a" (0x1112), "b" (0));
6558 +
6559 +       /* Use alternate print screen */
6560 +       asm volatile(INT10 : : "a" (0x1200), "b" (0x20));
6561 +
6562 +       /* Turn off cursor emulation */
6563 +       asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
6564 +
6565 +       /* Cursor is scan lines 6-7 */
6566 +       asm volatile(INT10 : : "a" (0x0100), "c" (0x0607));
6567 +}
6568 +
6569 +static void vga_set_14font(void)
6570 +{
6571 +       /* Set 9x14 font - 80x28 on VGA */
6572 +
6573 +       /* Set 9x14 font */
6574 +       asm volatile(INT10 : : "a" (0x1111), "b" (0));
6575 +
6576 +       /* Turn off cursor emulation */
6577 +       asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
6578 +
6579 +       /* Cursor is scan lines 11-12 */
6580 +       asm volatile(INT10 : : "a" (0x0100), "c" (0x0b0c));
6581 +}
6582 +
6583 +static void vga_set_80x43(void)
6584 +{
6585 +       /* Set 80x43 mode on VGA (not EGA) */
6586 +
6587 +       /* Set 350 scans */
6588 +       asm volatile(INT10 : : "a" (0x1201), "b" (0x30));
6589 +
6590 +       /* Reset video mode */
6591 +       asm volatile(INT10 : : "a" (0x0003));
6592 +
6593 +       vga_set_8font();
6594 +}
6595 +
6596 +/* I/O address of the VGA CRTC */
6597 +u16 vga_crtc(void)
6598 +{
6599 +       return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
6600 +}
6601 +
6602 +static void vga_set_480_scanlines(int end)
6603 +{
6604 +       u16 crtc;
6605 +       u8  csel;
6606 +
6607 +       crtc = vga_crtc();
6608 +
6609 +       out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */
6610 +       out_idx(0x0b, crtc, 0x06); /* Vertical total */
6611 +       out_idx(0x3e, crtc, 0x07); /* Vertical overflow */
6612 +       out_idx(0xea, crtc, 0x10); /* Vertical sync start */
6613 +       out_idx(end, crtc, 0x12); /* Vertical display end */
6614 +       out_idx(0xe7, crtc, 0x15); /* Vertical blank start */
6615 +       out_idx(0x04, crtc, 0x16); /* Vertical blank end */
6616 +       csel = inb(0x3cc);
6617 +       csel &= 0x0d;
6618 +       csel |= 0xe2;
6619 +       outb(csel, 0x3cc);
6620 +}
6621 +
6622 +static void vga_set_80x30(void)
6623 +{
6624 +       vga_set_480_scanlines(0xdf);
6625 +}
6626 +
6627 +static void vga_set_80x34(void)
6628 +{
6629 +       vga_set_14font();
6630 +       vga_set_480_scanlines(0xdb);
6631 +}
6632 +
6633 +static void vga_set_80x60(void)
6634 +{
6635 +       vga_set_8font();
6636 +       vga_set_480_scanlines(0xdf);
6637 +}
6638 +
6639 +static int vga_set_mode(struct mode_info *mode)
6640 +{
6641 +       /* Set the basic mode */
6642 +       vga_set_basic_mode();
6643 +
6644 +       /* Override a possibly broken BIOS */
6645 +       force_x = mode->x;
6646 +       force_y = mode->y;
6647 +
6648 +       switch (mode->mode) {
6649 +       case VIDEO_80x25:
6650 +               break;
6651 +       case VIDEO_8POINT:
6652 +               vga_set_8font();
6653 +               break;
6654 +       case VIDEO_80x43:
6655 +               vga_set_80x43();
6656 +               break;
6657 +       case VIDEO_80x28:
6658 +               vga_set_14font();
6659 +               break;
6660 +       case VIDEO_80x30:
6661 +               vga_set_80x30();
6662 +               break;
6663 +       case VIDEO_80x34:
6664 +               vga_set_80x34();
6665 +               break;
6666 +       case VIDEO_80x60:
6667 +               vga_set_80x60();
6668 +               break;
6669 +       }
6670 +
6671 +       return 0;
6672 +}
6673 +
6674 +/*
6675 + * Note: this probe includes basic information required by all
6676 + * systems.  It should be executed first, by making sure
6677 + * video-vga.c is listed first in the Makefile.
6678 + */
6679 +static int vga_probe(void)
6680 +{
6681 +       static const char *card_name[] = {
6682 +               "CGA/MDA/HGC", "EGA", "VGA"
6683 +       };
6684 +       static struct mode_info *mode_lists[] = {
6685 +               cga_modes,
6686 +               ega_modes,
6687 +               vga_modes,
6688 +       };
6689 +       static int mode_count[] = {
6690 +               sizeof(cga_modes)/sizeof(struct mode_info),
6691 +               sizeof(ega_modes)/sizeof(struct mode_info),
6692 +               sizeof(vga_modes)/sizeof(struct mode_info),
6693 +       };
6694 +       u8 vga_flag;
6695 +
6696 +       asm(INT10
6697 +           : "=b" (boot_params.screen_info.orig_video_ega_bx)
6698 +           : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
6699 +           : "ecx", "edx", "esi", "edi");
6700 +
6701 +       /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
6702 +       if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
6703 +               /* EGA/VGA */
6704 +               asm(INT10
6705 +                   : "=a" (vga_flag)
6706 +                   : "a" (0x1a00)
6707 +                   : "ebx", "ecx", "edx", "esi", "edi");
6708 +
6709 +               if (vga_flag == 0x1a) {
6710 +                       adapter = ADAPTER_VGA;
6711 +                       boot_params.screen_info.orig_video_isVGA = 1;
6712 +               } else {
6713 +                       adapter = ADAPTER_EGA;
6714 +               }
6715 +       } else {
6716 +               adapter = ADAPTER_CGA;
6717 +       }
6718 +
6719 +       video_vga.modes = mode_lists[adapter];
6720 +       video_vga.card_name = card_name[adapter];
6721 +       return mode_count[adapter];
6722 +}
6723 +
6724 +__videocard video_vga =
6725 +{
6726 +       .card_name      = "VGA",
6727 +       .probe          = vga_probe,
6728 +       .set_mode       = vga_set_mode,
6729 +};
6730 diff -puN arch/i386/boot/video.S~git-newsetup /dev/null
6731 --- a/arch/i386/boot/video.S
6732 +++ /dev/null
6733 @@ -1,2043 +0,0 @@
6734 -/*     video.S
6735 - *
6736 - *     Display adapter & video mode setup, version 2.13 (14-May-99)
6737 - *
6738 - *     Copyright (C) 1995 -- 1998 Martin Mares <mj@ucw.cz>
6739 - *     Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
6740 - *
6741 - *     Rewritten to use GNU 'as' by Chris Noe <stiker@northlink.com> May 1999
6742 - *
6743 - *     For further information, look at Documentation/svga.txt.
6744 - *
6745 - */
6746 -
6747 -/* Enable autodetection of SVGA adapters and modes. */
6748 -#undef CONFIG_VIDEO_SVGA
6749 -
6750 -/* Enable autodetection of VESA modes */
6751 -#define CONFIG_VIDEO_VESA
6752 -
6753 -/* Enable compacting of mode table */
6754 -#define CONFIG_VIDEO_COMPACT
6755 -
6756 -/* Retain screen contents when switching modes */
6757 -#define CONFIG_VIDEO_RETAIN
6758 -
6759 -/* Enable local mode list */
6760 -#undef CONFIG_VIDEO_LOCAL
6761 -
6762 -/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
6763 -#undef CONFIG_VIDEO_400_HACK
6764 -
6765 -/* Hack that lets you force specific BIOS mode ID and specific dimensions */
6766 -#undef CONFIG_VIDEO_GFX_HACK
6767 -#define VIDEO_GFX_BIOS_AX 0x4f02       /* 800x600 on ThinkPad */
6768 -#define VIDEO_GFX_BIOS_BX 0x0102
6769 -#define VIDEO_GFX_DUMMY_RESOLUTION 0x6425      /* 100x37 */
6770 -
6771 -/* This code uses an extended set of video mode numbers. These include:
6772 - * Aliases for standard modes
6773 - *     NORMAL_VGA (-1)
6774 - *     EXTENDED_VGA (-2)
6775 - *     ASK_VGA (-3)
6776 - * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
6777 - * of compatibility when extending the table. These are between 0x00 and 0xff.
6778 - */
6779 -#define VIDEO_FIRST_MENU 0x0000
6780 -
6781 -/* Standard BIOS video modes (BIOS number + 0x0100) */
6782 -#define VIDEO_FIRST_BIOS 0x0100
6783 -
6784 -/* VESA BIOS video modes (VESA number + 0x0200) */
6785 -#define VIDEO_FIRST_VESA 0x0200
6786 -
6787 -/* Video7 special modes (BIOS number + 0x0900) */
6788 -#define VIDEO_FIRST_V7 0x0900
6789 -
6790 -/* Special video modes */
6791 -#define VIDEO_FIRST_SPECIAL 0x0f00
6792 -#define VIDEO_80x25 0x0f00
6793 -#define VIDEO_8POINT 0x0f01
6794 -#define VIDEO_80x43 0x0f02
6795 -#define VIDEO_80x28 0x0f03
6796 -#define VIDEO_CURRENT_MODE 0x0f04
6797 -#define VIDEO_80x30 0x0f05
6798 -#define VIDEO_80x34 0x0f06
6799 -#define VIDEO_80x60 0x0f07
6800 -#define VIDEO_GFX_HACK 0x0f08
6801 -#define VIDEO_LAST_SPECIAL 0x0f09
6802 -
6803 -/* Video modes given by resolution */
6804 -#define VIDEO_FIRST_RESOLUTION 0x1000
6805 -
6806 -/* The "recalculate timings" flag */
6807 -#define VIDEO_RECALC 0x8000
6808 -
6809 -/* Positions of various video parameters passed to the kernel */
6810 -/* (see also include/linux/tty.h) */
6811 -#define PARAM_CURSOR_POS       0x00
6812 -#define PARAM_VIDEO_PAGE       0x04
6813 -#define PARAM_VIDEO_MODE       0x06
6814 -#define PARAM_VIDEO_COLS       0x07
6815 -#define PARAM_VIDEO_EGA_BX     0x0a
6816 -#define PARAM_VIDEO_LINES      0x0e
6817 -#define PARAM_HAVE_VGA         0x0f
6818 -#define PARAM_FONT_POINTS      0x10
6819 -
6820 -#define PARAM_LFB_WIDTH                0x12
6821 -#define PARAM_LFB_HEIGHT       0x14
6822 -#define PARAM_LFB_DEPTH                0x16
6823 -#define PARAM_LFB_BASE         0x18
6824 -#define PARAM_LFB_SIZE         0x1c
6825 -#define PARAM_LFB_LINELENGTH   0x24
6826 -#define PARAM_LFB_COLORS       0x26
6827 -#define PARAM_VESAPM_SEG       0x2e
6828 -#define PARAM_VESAPM_OFF       0x30
6829 -#define PARAM_LFB_PAGES                0x32
6830 -#define PARAM_VESA_ATTRIB      0x34
6831 -#define PARAM_CAPABILITIES     0x36
6832 -
6833 -/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
6834 -#ifdef CONFIG_VIDEO_RETAIN
6835 -#define DO_STORE call store_screen
6836 -#else
6837 -#define DO_STORE
6838 -#endif /* CONFIG_VIDEO_RETAIN */
6839 -
6840 -# This is the main entry point called by setup.S
6841 -# %ds *must* be pointing to the bootsector
6842 -video: pushw   %ds             # We use different segments
6843 -       pushw   %ds             # FS contains original DS
6844 -       popw    %fs
6845 -       pushw   %cs             # DS is equal to CS
6846 -       popw    %ds
6847 -       pushw   %cs             # ES is equal to CS
6848 -       popw    %es
6849 -       xorw    %ax, %ax
6850 -       movw    %ax, %gs        # GS is zero
6851 -       cld
6852 -       call    basic_detect    # Basic adapter type testing (EGA/VGA/MDA/CGA)
6853 -#ifdef CONFIG_VIDEO_SELECT
6854 -       movw    %fs:(0x01fa), %ax               # User selected video mode
6855 -       cmpw    $ASK_VGA, %ax                   # Bring up the menu
6856 -       jz      vid2
6857 -
6858 -       call    mode_set                        # Set the mode
6859 -       jc      vid1
6860 -
6861 -       leaw    badmdt, %si                     # Invalid mode ID
6862 -       call    prtstr
6863 -vid2:  call    mode_menu
6864 -vid1:
6865 -#ifdef CONFIG_VIDEO_RETAIN
6866 -       call    restore_screen                  # Restore screen contents
6867 -#endif /* CONFIG_VIDEO_RETAIN */
6868 -       call    store_edid
6869 -#endif /* CONFIG_VIDEO_SELECT */
6870 -       call    mode_params                     # Store mode parameters
6871 -       popw    %ds                             # Restore original DS
6872 -       ret
6873 -
6874 -# Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel.
6875 -basic_detect:
6876 -       movb    $0, %fs:(PARAM_HAVE_VGA)
6877 -       movb    $0x12, %ah      # Check EGA/VGA
6878 -       movb    $0x10, %bl
6879 -       int     $0x10
6880 -       movw    %bx, %fs:(PARAM_VIDEO_EGA_BX)   # Identifies EGA to the kernel
6881 -       cmpb    $0x10, %bl                      # No, it's a CGA/MDA/HGA card.
6882 -       je      basret
6883 -
6884 -       incb    adapter
6885 -       movw    $0x1a00, %ax                    # Check EGA or VGA?
6886 -       int     $0x10
6887 -       cmpb    $0x1a, %al                      # 1a means VGA...
6888 -       jne     basret                          # anything else is EGA.
6889 -       
6890 -       incb    %fs:(PARAM_HAVE_VGA)            # We've detected a VGA
6891 -       incb    adapter
6892 -basret:        ret
6893 -
6894 -# Store the video mode parameters for later usage by the kernel.
6895 -# This is done by asking the BIOS except for the rows/columns
6896 -# parameters in the default 80x25 mode -- these are set directly,
6897 -# because some very obscure BIOSes supply insane values.
6898 -mode_params:
6899 -#ifdef CONFIG_VIDEO_SELECT
6900 -       cmpb    $0, graphic_mode
6901 -       jnz     mopar_gr
6902 -#endif
6903 -       movb    $0x03, %ah                      # Read cursor position
6904 -       xorb    %bh, %bh
6905 -       int     $0x10
6906 -       movw    %dx, %fs:(PARAM_CURSOR_POS)
6907 -       movb    $0x0f, %ah                      # Read page/mode/width
6908 -       int     $0x10
6909 -       movw    %bx, %fs:(PARAM_VIDEO_PAGE)
6910 -       movw    %ax, %fs:(PARAM_VIDEO_MODE)     # Video mode and screen width
6911 -       cmpb    $0x7, %al                       # MDA/HGA => segment differs
6912 -       jnz     mopar0
6913 -
6914 -       movw    $0xb000, video_segment
6915 -mopar0: movw   %gs:(0x485), %ax                # Font size
6916 -       movw    %ax, %fs:(PARAM_FONT_POINTS)    # (valid only on EGA/VGA)
6917 -       movw    force_size, %ax                 # Forced size?
6918 -       orw     %ax, %ax
6919 -       jz      mopar1
6920 -
6921 -       movb    %ah, %fs:(PARAM_VIDEO_COLS)
6922 -       movb    %al, %fs:(PARAM_VIDEO_LINES)
6923 -       ret
6924 -
6925 -mopar1:        movb    $25, %al
6926 -       cmpb    $0, adapter                     # If we are on CGA/MDA/HGA, the
6927 -       jz      mopar2                          # screen must have 25 lines.
6928 -
6929 -       movb    %gs:(0x484), %al                # On EGA/VGA, use the EGA+ BIOS
6930 -       incb    %al                             # location of max lines.
6931 -mopar2: movb   %al, %fs:(PARAM_VIDEO_LINES)
6932 -       ret
6933 -
6934 -#ifdef CONFIG_VIDEO_SELECT
6935 -# Fetching of VESA frame buffer parameters
6936 -mopar_gr:
6937 -       leaw    modelist+1024, %di
6938 -       movb    $0x23, %fs:(PARAM_HAVE_VGA)
6939 -       movw    16(%di), %ax
6940 -       movw    %ax, %fs:(PARAM_LFB_LINELENGTH)
6941 -       movw    18(%di), %ax
6942 -       movw    %ax, %fs:(PARAM_LFB_WIDTH)
6943 -       movw    20(%di), %ax
6944 -       movw    %ax, %fs:(PARAM_LFB_HEIGHT)
6945 -       movb    25(%di), %al
6946 -       movb    $0, %ah
6947 -       movw    %ax, %fs:(PARAM_LFB_DEPTH)
6948 -       movb    29(%di), %al    
6949 -       movb    $0, %ah
6950 -       movw    %ax, %fs:(PARAM_LFB_PAGES)
6951 -       movl    40(%di), %eax
6952 -       movl    %eax, %fs:(PARAM_LFB_BASE)
6953 -       movl    31(%di), %eax
6954 -       movl    %eax, %fs:(PARAM_LFB_COLORS)
6955 -       movl    35(%di), %eax
6956 -       movl    %eax, %fs:(PARAM_LFB_COLORS+4)
6957 -       movw    0(%di), %ax
6958 -       movw    %ax, %fs:(PARAM_VESA_ATTRIB)
6959 -
6960 -# get video mem size
6961 -       leaw    modelist+1024, %di
6962 -       movw    $0x4f00, %ax
6963 -       int     $0x10
6964 -       xorl    %eax, %eax
6965 -       movw    18(%di), %ax
6966 -       movl    %eax, %fs:(PARAM_LFB_SIZE)
6967 -
6968 -# store mode capabilities
6969 -       movl 10(%di), %eax
6970 -       movl %eax, %fs:(PARAM_CAPABILITIES)
6971 -
6972 -# switching the DAC to 8-bit is for <= 8 bpp only
6973 -       movw    %fs:(PARAM_LFB_DEPTH), %ax
6974 -       cmpw    $8, %ax
6975 -       jg      dac_done
6976 -
6977 -# get DAC switching capability
6978 -       xorl    %eax, %eax
6979 -       movb    10(%di), %al
6980 -       testb   $1, %al
6981 -       jz      dac_set
6982 -
6983 -# attempt to switch DAC to 8-bit
6984 -       movw    $0x4f08, %ax
6985 -       movw    $0x0800, %bx
6986 -       int     $0x10
6987 -       cmpw    $0x004f, %ax
6988 -       jne     dac_set
6989 -       movb    %bh, dac_size           # store actual DAC size
6990 -
6991 -dac_set:
6992 -# set color size to DAC size
6993 -       movb    dac_size, %al
6994 -       movb    %al, %fs:(PARAM_LFB_COLORS+0)
6995 -       movb    %al, %fs:(PARAM_LFB_COLORS+2)
6996 -       movb    %al, %fs:(PARAM_LFB_COLORS+4)
6997 -       movb    %al, %fs:(PARAM_LFB_COLORS+6)
6998 -
6999 -# set color offsets to 0
7000 -       movb    $0, %fs:(PARAM_LFB_COLORS+1)
7001 -       movb    $0, %fs:(PARAM_LFB_COLORS+3)
7002 -       movb    $0, %fs:(PARAM_LFB_COLORS+5)
7003 -       movb    $0, %fs:(PARAM_LFB_COLORS+7)
7004 -
7005 -dac_done:
7006 -# get protected mode interface informations
7007 -       movw    $0x4f0a, %ax
7008 -       xorw    %bx, %bx
7009 -       xorw    %di, %di
7010 -       int     $0x10
7011 -       cmp     $0x004f, %ax
7012 -       jnz     no_pm
7013 -
7014 -       movw    %es, %fs:(PARAM_VESAPM_SEG)
7015 -       movw    %di, %fs:(PARAM_VESAPM_OFF)
7016 -no_pm: ret
7017 -
7018 -# The video mode menu
7019 -mode_menu:
7020 -       leaw    keymsg, %si                     # "Return/Space/Timeout" message
7021 -       call    prtstr
7022 -       call    flush
7023 -nokey: call    getkt
7024 -
7025 -       cmpb    $0x0d, %al                      # ENTER ?
7026 -       je      listm                           # yes - manual mode selection
7027 -
7028 -       cmpb    $0x20, %al                      # SPACE ?
7029 -       je      defmd1                          # no - repeat
7030 -
7031 -       call    beep
7032 -       jmp     nokey
7033 -
7034 -defmd1:        ret                                     # No mode chosen? Default 80x25
7035 -
7036 -listm: call    mode_table                      # List mode table
7037 -listm0:        leaw    name_bann, %si                  # Print adapter name
7038 -       call    prtstr
7039 -       movw    card_name, %si
7040 -       orw     %si, %si
7041 -       jnz     an2
7042 -
7043 -       movb    adapter, %al
7044 -       leaw    old_name, %si
7045 -       orb     %al, %al
7046 -       jz      an1
7047 -
7048 -       leaw    ega_name, %si
7049 -       decb    %al
7050 -       jz      an1
7051 -
7052 -       leaw    vga_name, %si
7053 -       jmp     an1
7054 -
7055 -an2:   call    prtstr
7056 -       leaw    svga_name, %si
7057 -an1:   call    prtstr
7058 -       leaw    listhdr, %si                    # Table header
7059 -       call    prtstr
7060 -       movb    $0x30, %dl                      # DL holds mode number
7061 -       leaw    modelist, %si
7062 -lm1:   cmpw    $ASK_VGA, (%si)                 # End?
7063 -       jz      lm2
7064 -
7065 -       movb    %dl, %al                        # Menu selection number
7066 -       call    prtchr
7067 -       call    prtsp2
7068 -       lodsw
7069 -       call    prthw                           # Mode ID
7070 -       call    prtsp2
7071 -       movb    0x1(%si), %al
7072 -       call    prtdec                          # Rows
7073 -       movb    $0x78, %al                      # the letter 'x'
7074 -       call    prtchr
7075 -       lodsw
7076 -       call    prtdec                          # Columns
7077 -       movb    $0x0d, %al                      # New line
7078 -       call    prtchr
7079 -       movb    $0x0a, %al
7080 -       call    prtchr
7081 -       incb    %dl                             # Next character
7082 -       cmpb    $0x3a, %dl
7083 -       jnz     lm1
7084 -
7085 -       movb    $0x61, %dl
7086 -       jmp     lm1
7087 -
7088 -lm2:   leaw    prompt, %si                     # Mode prompt
7089 -       call    prtstr
7090 -       leaw    edit_buf, %di                   # Editor buffer
7091 -lm3:   call    getkey
7092 -       cmpb    $0x0d, %al                      # Enter?
7093 -       jz      lment
7094 -
7095 -       cmpb    $0x08, %al                      # Backspace?
7096 -       jz      lmbs
7097 -
7098 -       cmpb    $0x20, %al                      # Printable?
7099 -       jc      lm3
7100 -
7101 -       cmpw    $edit_buf+4, %di                # Enough space?
7102 -       jz      lm3
7103 -
7104 -       stosb
7105 -       call    prtchr
7106 -       jmp     lm3
7107 -
7108 -lmbs:  cmpw    $edit_buf, %di                  # Backspace
7109 -       jz      lm3
7110 -
7111 -       decw    %di
7112 -       movb    $0x08, %al
7113 -       call    prtchr
7114 -       call    prtspc
7115 -       movb    $0x08, %al
7116 -       call    prtchr
7117 -       jmp     lm3
7118 -       
7119 -lment: movb    $0, (%di)
7120 -       leaw    crlft, %si
7121 -       call    prtstr
7122 -       leaw    edit_buf, %si
7123 -       cmpb    $0, (%si)                       # Empty string = default mode
7124 -       jz      lmdef
7125 -
7126 -       cmpb    $0, 1(%si)                      # One character = menu selection
7127 -       jz      mnusel
7128 -
7129 -       cmpw    $0x6373, (%si)                  # "scan" => mode scanning
7130 -       jnz     lmhx
7131 -
7132 -       cmpw    $0x6e61, 2(%si)
7133 -       jz      lmscan
7134 -
7135 -lmhx:  xorw    %bx, %bx                        # Else => mode ID in hex
7136 -lmhex: lodsb
7137 -       orb     %al, %al
7138 -       jz      lmuse1
7139 -
7140 -       subb    $0x30, %al
7141 -       jc      lmbad
7142 -
7143 -       cmpb    $10, %al
7144 -       jc      lmhx1
7145 -
7146 -       subb    $7, %al
7147 -       andb    $0xdf, %al
7148 -       cmpb    $10, %al
7149 -       jc      lmbad
7150 -
7151 -       cmpb    $16, %al
7152 -       jnc     lmbad
7153 -
7154 -lmhx1: shlw    $4, %bx
7155 -       orb     %al, %bl
7156 -       jmp     lmhex
7157 -
7158 -lmuse1:        movw    %bx, %ax
7159 -       jmp     lmuse
7160 -
7161 -mnusel:        lodsb                                   # Menu selection
7162 -       xorb    %ah, %ah
7163 -       subb    $0x30, %al
7164 -       jc      lmbad
7165 -
7166 -       cmpb    $10, %al
7167 -       jc      lmuse
7168 -       
7169 -       cmpb    $0x61-0x30, %al
7170 -       jc      lmbad
7171 -       
7172 -       subb    $0x61-0x30-10, %al
7173 -       cmpb    $36, %al
7174 -       jnc     lmbad
7175 -
7176 -lmuse: call    mode_set
7177 -       jc      lmdef
7178 -
7179 -lmbad: leaw    unknt, %si
7180 -       call    prtstr
7181 -       jmp     lm2
7182 -lmscan:        cmpb    $0, adapter                     # Scanning only on EGA/VGA
7183 -       jz      lmbad
7184 -
7185 -       movw    $0, mt_end                      # Scanning of modes is
7186 -       movb    $1, scanning                    # done as new autodetection.
7187 -       call    mode_table
7188 -       jmp     listm0
7189 -lmdef: ret
7190 -
7191 -# Additional parts of mode_set... (relative jumps, you know)
7192 -setv7:                                         # Video7 extended modes
7193 -       DO_STORE
7194 -       subb    $VIDEO_FIRST_V7>>8, %bh
7195 -       movw    $0x6f05, %ax
7196 -       int     $0x10
7197 -       stc
7198 -       ret
7199 -
7200 -_setrec:       jmp     setrec                  # Ugly...
7201 -_set_80x25:    jmp     set_80x25
7202 -
7203 -# Aliases for backward compatibility.
7204 -setalias:
7205 -       movw    $VIDEO_80x25, %ax
7206 -       incw    %bx
7207 -       jz      mode_set
7208 -
7209 -       movb    $VIDEO_8POINT-VIDEO_FIRST_SPECIAL, %al
7210 -       incw    %bx
7211 -       jnz     setbad                          # Fall-through!
7212 -
7213 -# Setting of user mode (AX=mode ID) => CF=success
7214 -mode_set:
7215 -       movw    %ax, %fs:(0x01fa)               # Store mode for use in acpi_wakeup.S
7216 -       movw    %ax, %bx
7217 -       cmpb    $0xff, %ah
7218 -       jz      setalias
7219 -
7220 -       testb   $VIDEO_RECALC>>8, %ah
7221 -       jnz     _setrec
7222 -
7223 -       cmpb    $VIDEO_FIRST_RESOLUTION>>8, %ah
7224 -       jnc     setres
7225 -       
7226 -       cmpb    $VIDEO_FIRST_SPECIAL>>8, %ah
7227 -       jz      setspc
7228 -       
7229 -       cmpb    $VIDEO_FIRST_V7>>8, %ah
7230 -       jz      setv7
7231 -       
7232 -       cmpb    $VIDEO_FIRST_VESA>>8, %ah
7233 -       jnc     check_vesa
7234 -       
7235 -       orb     %ah, %ah
7236 -       jz      setmenu
7237 -       
7238 -       decb    %ah
7239 -       jz      setbios
7240 -
7241 -setbad:        clc
7242 -       movb    $0, do_restore                  # The screen needn't be restored
7243 -       ret
7244 -
7245 -setvesa:
7246 -       DO_STORE
7247 -       subb    $VIDEO_FIRST_VESA>>8, %bh
7248 -       movw    $0x4f02, %ax                    # VESA BIOS mode set call
7249 -       int     $0x10
7250 -       cmpw    $0x004f, %ax                    # AL=4f if implemented
7251 -       jnz     setbad                          # AH=0 if OK
7252 -
7253 -       stc
7254 -       ret
7255 -
7256 -setbios:
7257 -       DO_STORE
7258 -       int     $0x10                           # Standard BIOS mode set call
7259 -       pushw   %bx
7260 -       movb    $0x0f, %ah                      # Check if really set
7261 -       int     $0x10
7262 -       popw    %bx
7263 -       cmpb    %bl, %al
7264 -       jnz     setbad
7265 -       
7266 -       stc
7267 -       ret
7268 -
7269 -setspc:        xorb    %bh, %bh                        # Set special mode
7270 -       cmpb    $VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl
7271 -       jnc     setbad
7272 -       
7273 -       addw    %bx, %bx
7274 -       jmp     *spec_inits(%bx)
7275 -
7276 -setmenu:
7277 -       orb     %al, %al                        # 80x25 is an exception
7278 -       jz      _set_80x25
7279 -       
7280 -       pushw   %bx                             # Set mode chosen from menu
7281 -       call    mode_table                      # Build the mode table
7282 -       popw    %ax
7283 -       shlw    $2, %ax
7284 -       addw    %ax, %si
7285 -       cmpw    %di, %si
7286 -       jnc     setbad
7287 -       
7288 -       movw    (%si), %ax                      # Fetch mode ID
7289 -_m_s:  jmp     mode_set
7290 -
7291 -setres:        pushw   %bx                             # Set mode chosen by resolution
7292 -       call    mode_table
7293 -       popw    %bx
7294 -       xchgb   %bl, %bh
7295 -setr1: lodsw
7296 -       cmpw    $ASK_VGA, %ax                   # End of the list?
7297 -       jz      setbad
7298 -       
7299 -       lodsw
7300 -       cmpw    %bx, %ax
7301 -       jnz     setr1
7302 -       
7303 -       movw    -4(%si), %ax                    # Fetch mode ID
7304 -       jmp     _m_s
7305 -
7306 -check_vesa:
7307 -#ifdef CONFIG_FIRMWARE_EDID
7308 -       leaw    modelist+1024, %di
7309 -       movw    $0x4f00, %ax
7310 -       int     $0x10
7311 -       cmpw    $0x004f, %ax
7312 -       jnz     setbad
7313 -
7314 -       movw    4(%di), %ax
7315 -       movw    %ax, vbe_version
7316 -#endif
7317 -       leaw    modelist+1024, %di
7318 -       subb    $VIDEO_FIRST_VESA>>8, %bh
7319 -       movw    %bx, %cx                        # Get mode information structure
7320 -       movw    $0x4f01, %ax
7321 -       int     $0x10
7322 -       addb    $VIDEO_FIRST_VESA>>8, %bh
7323 -       cmpw    $0x004f, %ax
7324 -       jnz     setbad
7325 -
7326 -       movb    (%di), %al                      # Check capabilities.
7327 -       andb    $0x19, %al
7328 -       cmpb    $0x09, %al
7329 -       jz      setvesa                         # This is a text mode
7330 -
7331 -       movb    (%di), %al                      # Check capabilities.
7332 -       andb    $0x99, %al
7333 -       cmpb    $0x99, %al
7334 -       jnz     _setbad                         # Doh! No linear frame buffer.
7335 -
7336 -       subb    $VIDEO_FIRST_VESA>>8, %bh
7337 -       orw     $0x4000, %bx                    # Use linear frame buffer
7338 -       movw    $0x4f02, %ax                    # VESA BIOS mode set call
7339 -       int     $0x10
7340 -       cmpw    $0x004f, %ax                    # AL=4f if implemented
7341 -       jnz     _setbad                         # AH=0 if OK
7342 -
7343 -       movb    $1, graphic_mode                # flag graphic mode
7344 -       movb    $0, do_restore                  # no screen restore
7345 -       stc
7346 -       ret
7347 -
7348 -_setbad:       jmp     setbad                  # Ugly...
7349 -
7350 -# Recalculate vertical display end registers -- this fixes various
7351 -# inconsistencies of extended modes on many adapters. Called when
7352 -# the VIDEO_RECALC flag is set in the mode ID.
7353 -
7354 -setrec:        subb    $VIDEO_RECALC>>8, %ah           # Set the base mode
7355 -       call    mode_set
7356 -       jnc     rct3
7357 -
7358 -       movw    %gs:(0x485), %ax                # Font size in pixels
7359 -       movb    %gs:(0x484), %bl                # Number of rows
7360 -       incb    %bl
7361 -       mulb    %bl                             # Number of visible
7362 -       decw    %ax                             # scan lines - 1
7363 -       movw    $0x3d4, %dx
7364 -       movw    %ax, %bx
7365 -       movb    $0x12, %al                      # Lower 8 bits
7366 -       movb    %bl, %ah
7367 -       outw    %ax, %dx
7368 -       movb    $0x07, %al              # Bits 8 and 9 in the overflow register
7369 -       call    inidx
7370 -       xchgb   %al, %ah
7371 -       andb    $0xbd, %ah
7372 -       shrb    %bh
7373 -       jnc     rct1
7374 -       orb     $0x02, %ah
7375 -rct1:  shrb    %bh
7376 -       jnc     rct2
7377 -       orb     $0x40, %ah
7378 -rct2:  movb    $0x07, %al
7379 -       outw    %ax, %dx
7380 -       stc
7381 -rct3:  ret
7382 -
7383 -# Table of routines for setting of the special modes.
7384 -spec_inits:
7385 -       .word   set_80x25
7386 -       .word   set_8pixel
7387 -       .word   set_80x43
7388 -       .word   set_80x28
7389 -       .word   set_current
7390 -       .word   set_80x30
7391 -       .word   set_80x34
7392 -       .word   set_80x60
7393 -       .word   set_gfx
7394 -
7395 -# Set the 80x25 mode. If already set, do nothing.
7396 -set_80x25:
7397 -       movw    $0x5019, force_size             # Override possibly broken BIOS
7398 -use_80x25:
7399 -#ifdef CONFIG_VIDEO_400_HACK
7400 -       movw    $0x1202, %ax                    # Force 400 scan lines
7401 -       movb    $0x30, %bl
7402 -       int     $0x10
7403 -#else
7404 -       movb    $0x0f, %ah                      # Get current mode ID
7405 -       int     $0x10
7406 -       cmpw    $0x5007, %ax    # Mode 7 (80x25 mono) is the only one available
7407 -       jz      st80            # on CGA/MDA/HGA and is also available on EGAM
7408 -
7409 -       cmpw    $0x5003, %ax    # Unknown mode, force 80x25 color
7410 -       jnz     force3
7411 -
7412 -st80:  cmpb    $0, adapter     # CGA/MDA/HGA => mode 3/7 is always 80x25
7413 -       jz      set80
7414 -
7415 -       movb    %gs:(0x0484), %al       # This is EGA+ -- beware of 80x50 etc.
7416 -       orb     %al, %al                # Some buggy BIOS'es set 0 rows
7417 -       jz      set80
7418 -       
7419 -       cmpb    $24, %al                # It's hopefully correct
7420 -       jz      set80
7421 -#endif /* CONFIG_VIDEO_400_HACK */
7422 -force3:        DO_STORE
7423 -       movw    $0x0003, %ax                    # Forced set
7424 -       int     $0x10
7425 -set80: stc
7426 -       ret
7427 -
7428 -# Set the 80x50/80x43 8-pixel mode. Simple BIOS calls.
7429 -set_8pixel:
7430 -       DO_STORE
7431 -       call    use_80x25                       # The base is 80x25
7432 -set_8pt:
7433 -       movw    $0x1112, %ax                    # Use 8x8 font
7434 -       xorb    %bl, %bl
7435 -       int     $0x10
7436 -       movw    $0x1200, %ax                    # Use alternate print screen
7437 -       movb    $0x20, %bl
7438 -       int     $0x10
7439 -       movw    $0x1201, %ax                    # Turn off cursor emulation
7440 -       movb    $0x34, %bl
7441 -       int     $0x10
7442 -       movb    $0x01, %ah                      # Define cursor scan lines 6-7
7443 -       movw    $0x0607, %cx
7444 -       int     $0x10
7445 -set_current:
7446 -       stc
7447 -       ret
7448 -
7449 -# Set the 80x28 mode. This mode works on all VGA's, because it's a standard
7450 -# 80x25 mode with 14-point fonts instead of 16-point.
7451 -set_80x28:
7452 -       DO_STORE
7453 -       call    use_80x25                       # The base is 80x25
7454 -set14: movw    $0x1111, %ax                    # Use 9x14 font
7455 -       xorb    %bl, %bl
7456 -       int     $0x10
7457 -       movb    $0x01, %ah                      # Define cursor scan lines 11-12
7458 -       movw    $0x0b0c, %cx
7459 -       int     $0x10
7460 -       stc
7461 -       ret
7462 -
7463 -# Set the 80x43 mode. This mode is works on all VGA's.
7464 -# It's a 350-scanline mode with 8-pixel font.
7465 -set_80x43:
7466 -       DO_STORE
7467 -       movw    $0x1201, %ax                    # Set 350 scans
7468 -       movb    $0x30, %bl
7469 -       int     $0x10
7470 -       movw    $0x0003, %ax                    # Reset video mode
7471 -       int     $0x10
7472 -       jmp     set_8pt                         # Use 8-pixel font
7473 -
7474 -# Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font.
7475 -set_80x30:
7476 -       call    use_80x25                       # Start with real 80x25
7477 -       DO_STORE
7478 -       movw    $0x3cc, %dx                     # Get CRTC port
7479 -       inb     %dx, %al
7480 -       movb    $0xd4, %dl
7481 -       rorb    %al                             # Mono or color?
7482 -       jc      set48a
7483 -
7484 -       movb    $0xb4, %dl
7485 -set48a:        movw    $0x0c11, %ax            # Vertical sync end (also unlocks CR0-7)
7486 -       call    outidx
7487 -       movw    $0x0b06, %ax                    # Vertical total
7488 -       call    outidx
7489 -       movw    $0x3e07, %ax                    # (Vertical) overflow
7490 -       call    outidx
7491 -       movw    $0xea10, %ax                    # Vertical sync start
7492 -       call    outidx
7493 -       movw    $0xdf12, %ax                    # Vertical display end
7494 -       call    outidx
7495 -       movw    $0xe715, %ax                    # Vertical blank start
7496 -       call    outidx
7497 -       movw    $0x0416, %ax                    # Vertical blank end
7498 -       call    outidx
7499 -       pushw   %dx
7500 -       movb    $0xcc, %dl                      # Misc output register (read)
7501 -       inb     %dx, %al
7502 -       movb    $0xc2, %dl                      # (write)
7503 -       andb    $0x0d, %al      # Preserve clock select bits and color bit
7504 -       orb     $0xe2, %al                      # Set correct sync polarity
7505 -       outb    %al, %dx
7506 -       popw    %dx
7507 -       movw    $0x501e, force_size
7508 -       stc                                     # That's all.
7509 -       ret
7510 -
7511 -# Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font.
7512 -set_80x34:
7513 -       call    set_80x30                       # Set 480 scans
7514 -       call    set14                           # And 14-pt font
7515 -       movw    $0xdb12, %ax                    # VGA vertical display end
7516 -       movw    $0x5022, force_size
7517 -setvde:        call    outidx
7518 -       stc
7519 -       ret
7520 -
7521 -# Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font.
7522 -set_80x60:
7523 -       call    set_80x30                       # Set 480 scans
7524 -       call    set_8pt                         # And 8-pt font
7525 -       movw    $0xdf12, %ax                    # VGA vertical display end
7526 -       movw    $0x503c, force_size
7527 -       jmp     setvde
7528 -
7529 -# Special hack for ThinkPad graphics
7530 -set_gfx:
7531 -#ifdef CONFIG_VIDEO_GFX_HACK
7532 -       movw    $VIDEO_GFX_BIOS_AX, %ax
7533 -       movw    $VIDEO_GFX_BIOS_BX, %bx
7534 -       int     $0x10
7535 -       movw    $VIDEO_GFX_DUMMY_RESOLUTION, force_size
7536 -       stc
7537 -#endif
7538 -       ret
7539 -
7540 -#ifdef CONFIG_VIDEO_RETAIN
7541 -
7542 -# Store screen contents to temporary buffer.
7543 -store_screen:
7544 -       cmpb    $0, do_restore                  # Already stored?
7545 -       jnz     stsr
7546 -
7547 -       testb   $CAN_USE_HEAP, loadflags        # Have we space for storing?
7548 -       jz      stsr
7549 -       
7550 -       pushw   %ax
7551 -       pushw   %bx
7552 -       pushw   force_size                      # Don't force specific size
7553 -       movw    $0, force_size
7554 -       call    mode_params                     # Obtain params of current mode
7555 -       popw    force_size
7556 -       movb    %fs:(PARAM_VIDEO_LINES), %ah
7557 -       movb    %fs:(PARAM_VIDEO_COLS), %al
7558 -       movw    %ax, %bx                        # BX=dimensions
7559 -       mulb    %ah
7560 -       movw    %ax, %cx                        # CX=number of characters
7561 -       addw    %ax, %ax                        # Calculate image size
7562 -       addw    $modelist+1024+4, %ax
7563 -       cmpw    heap_end_ptr, %ax
7564 -       jnc     sts1                            # Unfortunately, out of memory
7565 -
7566 -       movw    %fs:(PARAM_CURSOR_POS), %ax     # Store mode params
7567 -       leaw    modelist+1024, %di
7568 -       stosw
7569 -       movw    %bx, %ax
7570 -       stosw
7571 -       pushw   %ds                             # Store the screen
7572 -       movw    video_segment, %ds
7573 -       xorw    %si, %si
7574 -       rep
7575 -       movsw
7576 -       popw    %ds
7577 -       incb    do_restore                      # Screen will be restored later
7578 -sts1:  popw    %bx
7579 -       popw    %ax
7580 -stsr:  ret
7581 -
7582 -# Restore screen contents from temporary buffer.
7583 -restore_screen:
7584 -       cmpb    $0, do_restore                  # Has the screen been stored?
7585 -       jz      res1
7586 -
7587 -       call    mode_params                     # Get parameters of current mode
7588 -       movb    %fs:(PARAM_VIDEO_LINES), %cl
7589 -       movb    %fs:(PARAM_VIDEO_COLS), %ch
7590 -       leaw    modelist+1024, %si              # Screen buffer
7591 -       lodsw                                   # Set cursor position
7592 -       movw    %ax, %dx
7593 -       cmpb    %cl, %dh
7594 -       jc      res2
7595 -       
7596 -       movb    %cl, %dh
7597 -       decb    %dh
7598 -res2:  cmpb    %ch, %dl
7599 -       jc      res3
7600 -       
7601 -       movb    %ch, %dl
7602 -       decb    %dl
7603 -res3:  movb    $0x02, %ah
7604 -       movb    $0x00, %bh
7605 -       int     $0x10
7606 -       lodsw                                   # Display size
7607 -       movb    %ah, %dl                        # DL=number of lines
7608 -       movb    $0, %ah                         # BX=phys. length of orig. line
7609 -       movw    %ax, %bx
7610 -       cmpb    %cl, %dl                        # Too many?
7611 -       jc      res4
7612 -
7613 -       pushw   %ax
7614 -       movb    %dl, %al
7615 -       subb    %cl, %al
7616 -       mulb    %bl
7617 -       addw    %ax, %si
7618 -       addw    %ax, %si
7619 -       popw    %ax
7620 -       movb    %cl, %dl
7621 -res4:  cmpb    %ch, %al                        # Too wide?
7622 -       jc      res5
7623 -       
7624 -       movb    %ch, %al                        # AX=width of src. line
7625 -res5:  movb    $0, %cl
7626 -       xchgb   %ch, %cl
7627 -       movw    %cx, %bp                        # BP=width of dest. line
7628 -       pushw   %es
7629 -       movw    video_segment, %es
7630 -       xorw    %di, %di                        # Move the data
7631 -       addw    %bx, %bx                        # Convert BX and BP to _bytes_
7632 -       addw    %bp, %bp
7633 -res6:  pushw   %si
7634 -       pushw   %di
7635 -       movw    %ax, %cx
7636 -       rep
7637 -       movsw
7638 -       popw    %di
7639 -       popw    %si
7640 -       addw    %bp, %di
7641 -       addw    %bx, %si
7642 -       decb    %dl
7643 -       jnz     res6
7644 -       
7645 -       popw    %es                             # Done
7646 -res1:  ret
7647 -#endif /* CONFIG_VIDEO_RETAIN */
7648 -
7649 -# Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)
7650 -outidx:        outb    %al, %dx
7651 -       pushw   %ax
7652 -       movb    %ah, %al
7653 -       incw    %dx
7654 -       outb    %al, %dx
7655 -       decw    %dx
7656 -       popw    %ax
7657 -       ret
7658 -
7659 -# Build the table of video modes (stored after the setup.S code at the
7660 -# `modelist' label. Each video mode record looks like:
7661 -#      .word   MODE-ID         (our special mode ID (see above))
7662 -#      .byte   rows            (number of rows)
7663 -#      .byte   columns         (number of columns)
7664 -# Returns address of the end of the table in DI, the end is marked
7665 -# with a ASK_VGA ID.
7666 -mode_table:
7667 -       movw    mt_end, %di                     # Already filled?
7668 -       orw     %di, %di
7669 -       jnz     mtab1x
7670 -       
7671 -       leaw    modelist, %di                   # Store standard modes:
7672 -       movl    $VIDEO_80x25 + 0x50190000, %eax # The 80x25 mode (ALL)
7673 -       stosl
7674 -       movb    adapter, %al                    # CGA/MDA/HGA -- no more modes
7675 -       orb     %al, %al
7676 -       jz      mtabe
7677 -       
7678 -       decb    %al
7679 -       jnz     mtabv
7680 -       
7681 -       movl    $VIDEO_8POINT + 0x502b0000, %eax        # The 80x43 EGA mode
7682 -       stosl
7683 -       jmp     mtabe
7684 -
7685 -mtab1x:        jmp     mtab1
7686 -
7687 -mtabv: leaw    vga_modes, %si                  # All modes for std VGA
7688 -       movw    $vga_modes_end-vga_modes, %cx
7689 -       rep     # I'm unable to use movsw as I don't know how to store a half
7690 -       movsb   # of the expression above to cx without using explicit shr.
7691 -
7692 -       cmpb    $0, scanning                    # Mode scan requested?
7693 -       jz      mscan1
7694 -       
7695 -       call    mode_scan
7696 -mscan1:
7697 -
7698 -#ifdef CONFIG_VIDEO_LOCAL
7699 -       call    local_modes
7700 -#endif /* CONFIG_VIDEO_LOCAL */
7701 -
7702 -#ifdef CONFIG_VIDEO_VESA
7703 -       call    vesa_modes                      # Detect VESA VGA modes
7704 -#endif /* CONFIG_VIDEO_VESA */
7705 -
7706 -#ifdef CONFIG_VIDEO_SVGA
7707 -       cmpb    $0, scanning                    # Bypass when scanning
7708 -       jnz     mscan2
7709 -       
7710 -       call    svga_modes                      # Detect SVGA cards & modes
7711 -mscan2:
7712 -#endif /* CONFIG_VIDEO_SVGA */
7713 -
7714 -mtabe:
7715 -
7716 -#ifdef CONFIG_VIDEO_COMPACT
7717 -       leaw    modelist, %si
7718 -       movw    %di, %dx
7719 -       movw    %si, %di
7720 -cmt1:  cmpw    %dx, %si                        # Scan all modes
7721 -       jz      cmt2
7722 -
7723 -       leaw    modelist, %bx                   # Find in previous entries
7724 -       movw    2(%si), %cx
7725 -cmt3:  cmpw    %bx, %si
7726 -       jz      cmt4
7727 -
7728 -       cmpw    2(%bx), %cx                     # Found => don't copy this entry
7729 -       jz      cmt5
7730 -
7731 -       addw    $4, %bx
7732 -       jmp     cmt3
7733 -
7734 -cmt4:  movsl                                   # Copy entry
7735 -       jmp     cmt1
7736 -
7737 -cmt5:  addw    $4, %si                         # Skip entry
7738 -       jmp     cmt1
7739 -
7740 -cmt2:
7741 -#endif /* CONFIG_VIDEO_COMPACT */
7742 -
7743 -       movw    $ASK_VGA, (%di)                 # End marker
7744 -       movw    %di, mt_end
7745 -mtab1: leaw    modelist, %si                   # SI=mode list, DI=list end
7746 -ret0:  ret
7747 -
7748 -# Modes usable on all standard VGAs
7749 -vga_modes:
7750 -       .word   VIDEO_8POINT
7751 -       .word   0x5032                          # 80x50
7752 -       .word   VIDEO_80x43
7753 -       .word   0x502b                          # 80x43
7754 -       .word   VIDEO_80x28
7755 -       .word   0x501c                          # 80x28
7756 -       .word   VIDEO_80x30
7757 -       .word   0x501e                          # 80x30
7758 -       .word   VIDEO_80x34
7759 -       .word   0x5022                          # 80x34
7760 -       .word   VIDEO_80x60
7761 -       .word   0x503c                          # 80x60
7762 -#ifdef CONFIG_VIDEO_GFX_HACK
7763 -       .word   VIDEO_GFX_HACK
7764 -       .word   VIDEO_GFX_DUMMY_RESOLUTION
7765 -#endif
7766 -
7767 -vga_modes_end:
7768 -# Detect VESA modes.
7769 -
7770 -#ifdef CONFIG_VIDEO_VESA
7771 -vesa_modes:
7772 -       cmpb    $2, adapter                     # VGA only
7773 -       jnz     ret0
7774 -
7775 -       movw    %di, %bp                        # BP=original mode table end
7776 -       addw    $0x200, %di                     # Buffer space
7777 -       movw    $0x4f00, %ax                    # VESA Get card info call
7778 -       int     $0x10
7779 -       movw    %bp, %di
7780 -       cmpw    $0x004f, %ax                    # Successful?
7781 -       jnz     ret0
7782 -       
7783 -       cmpw    $0x4556, 0x200(%di)
7784 -       jnz     ret0
7785 -       
7786 -       cmpw    $0x4153, 0x202(%di)
7787 -       jnz     ret0
7788 -       
7789 -       movw    $vesa_name, card_name           # Set name to "VESA VGA"
7790 -       pushw   %gs
7791 -       lgsw    0x20e(%di), %si                 # GS:SI=mode list
7792 -       movw    $128, %cx                       # Iteration limit
7793 -vesa1:
7794 -# gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst.
7795 -# XXX: lodsw   %gs:(%si), %ax                  # Get next mode in the list
7796 -       gs; lodsw
7797 -       cmpw    $0xffff, %ax                    # End of the table?
7798 -       jz      vesar
7799 -       
7800 -       cmpw    $0x0080, %ax                    # Check validity of mode ID
7801 -       jc      vesa2
7802 -       
7803 -       orb     %ah, %ah                # Valid IDs: 0x0000-0x007f/0x0100-0x07ff
7804 -       jz      vesan                   # Certain BIOSes report 0x80-0xff!
7805 -
7806 -       cmpw    $0x0800, %ax
7807 -       jnc     vesae
7808 -
7809 -vesa2: pushw   %cx
7810 -       movw    %ax, %cx                        # Get mode information structure
7811 -       movw    $0x4f01, %ax
7812 -       int     $0x10
7813 -       movw    %cx, %bx                        # BX=mode number
7814 -       addb    $VIDEO_FIRST_VESA>>8, %bh
7815 -       popw    %cx
7816 -       cmpw    $0x004f, %ax
7817 -       jnz     vesan                   # Don't report errors (buggy BIOSES)
7818 -
7819 -       movb    (%di), %al                      # Check capabilities. We require
7820 -       andb    $0x19, %al                      # a color text mode.
7821 -       cmpb    $0x09, %al
7822 -       jnz     vesan
7823 -       
7824 -       cmpw    $0xb800, 8(%di)         # Standard video memory address required
7825 -       jnz     vesan
7826 -
7827 -       testb   $2, (%di)                       # Mode characteristics supplied?
7828 -       movw    %bx, (%di)                      # Store mode number
7829 -       jz      vesa3
7830 -       
7831 -       xorw    %dx, %dx
7832 -       movw    0x12(%di), %bx                  # Width
7833 -       orb     %bh, %bh
7834 -       jnz     vesan
7835 -       
7836 -       movb    %bl, 0x3(%di)
7837 -       movw    0x14(%di), %ax                  # Height
7838 -       orb     %ah, %ah
7839 -       jnz     vesan
7840 -       
7841 -       movb    %al, 2(%di)
7842 -       mulb    %bl
7843 -       cmpw    $8193, %ax              # Small enough for Linux console driver?
7844 -       jnc     vesan
7845 -
7846 -       jmp     vesaok
7847 -
7848 -vesa3: subw    $0x8108, %bx    # This mode has no detailed info specified,
7849 -       jc      vesan           # so it must be a standard VESA mode.
7850 -
7851 -       cmpw    $5, %bx
7852 -       jnc     vesan
7853 -
7854 -       movw    vesa_text_mode_table(%bx), %ax
7855 -       movw    %ax, 2(%di)
7856 -vesaok:        addw    $4, %di                         # The mode is valid. Store it.
7857 -vesan: loop    vesa1                   # Next mode. Limit exceeded => error
7858 -vesae: leaw    vesaer, %si
7859 -       call    prtstr
7860 -       movw    %bp, %di                        # Discard already found modes.
7861 -vesar: popw    %gs
7862 -       ret
7863 -
7864 -# Dimensions of standard VESA text modes
7865 -vesa_text_mode_table:
7866 -       .byte   60, 80                          # 0108
7867 -       .byte   25, 132                         # 0109
7868 -       .byte   43, 132                         # 010A
7869 -       .byte   50, 132                         # 010B
7870 -       .byte   60, 132                         # 010C
7871 -#endif /* CONFIG_VIDEO_VESA */
7872 -
7873 -# Scan for video modes. A bit dirty, but should work.
7874 -mode_scan:
7875 -       movw    $0x0100, %cx                    # Start with mode 0
7876 -scm1:  movb    $0, %ah                         # Test the mode
7877 -       movb    %cl, %al
7878 -       int     $0x10
7879 -       movb    $0x0f, %ah
7880 -       int     $0x10
7881 -       cmpb    %cl, %al
7882 -       jnz     scm2                            # Mode not set
7883 -
7884 -       movw    $0x3c0, %dx                     # Test if it's a text mode
7885 -       movb    $0x10, %al                      # Mode bits
7886 -       call    inidx
7887 -       andb    $0x03, %al
7888 -       jnz     scm2
7889 -       
7890 -       movb    $0xce, %dl                      # Another set of mode bits
7891 -       movb    $0x06, %al
7892 -       call    inidx
7893 -       shrb    %al
7894 -       jc      scm2
7895 -       
7896 -       movb    $0xd4, %dl                      # Cursor location
7897 -       movb    $0x0f, %al
7898 -       call    inidx
7899 -       orb     %al, %al
7900 -       jnz     scm2
7901 -       
7902 -       movw    %cx, %ax                        # Ok, store the mode
7903 -       stosw
7904 -       movb    %gs:(0x484), %al                # Number of rows
7905 -       incb    %al
7906 -       stosb
7907 -       movw    %gs:(0x44a), %ax                # Number of columns
7908 -       stosb
7909 -scm2:  incb    %cl
7910 -       jns     scm1
7911 -       
7912 -       movw    $0x0003, %ax                    # Return back to mode 3
7913 -       int     $0x10
7914 -       ret
7915 -
7916 -tstidx:        outw    %ax, %dx                        # OUT DX,AX and inidx
7917 -inidx: outb    %al, %dx                        # Read from indexed VGA register
7918 -       incw    %dx                     # AL=index, DX=index reg port -> AL=data
7919 -       inb     %dx, %al
7920 -       decw    %dx
7921 -       ret
7922 -
7923 -# Try to detect type of SVGA card and supply (usually approximate) video
7924 -# mode table for it.
7925 -
7926 -#ifdef CONFIG_VIDEO_SVGA
7927 -svga_modes:
7928 -       leaw    svga_table, %si                 # Test all known SVGA adapters
7929 -dosvga:        lodsw
7930 -       movw    %ax, %bp                        # Default mode table
7931 -       orw     %ax, %ax
7932 -       jz      didsv1
7933 -
7934 -       lodsw                                   # Pointer to test routine
7935 -       pushw   %si
7936 -       pushw   %di
7937 -       pushw   %es
7938 -       movw    $0xc000, %bx
7939 -       movw    %bx, %es
7940 -       call    *%ax                            # Call test routine
7941 -       popw    %es
7942 -       popw    %di
7943 -       popw    %si
7944 -       orw     %bp, %bp
7945 -       jz      dosvga
7946 -       
7947 -       movw    %bp, %si                        # Found, copy the modes
7948 -       movb    svga_prefix, %ah
7949 -cpsvga:        lodsb
7950 -       orb     %al, %al
7951 -       jz      didsv
7952 -       
7953 -       stosw
7954 -       movsw
7955 -       jmp     cpsvga
7956 -
7957 -didsv: movw    %si, card_name                  # Store pointer to card name
7958 -didsv1:        ret
7959 -
7960 -# Table of all known SVGA cards. For each card, we store a pointer to
7961 -# a table of video modes supported by the card and a pointer to a routine
7962 -# used for testing of presence of the card. The video mode table is always
7963 -# followed by the name of the card or the chipset.
7964 -svga_table:
7965 -       .word   ati_md, ati_test
7966 -       .word   oak_md, oak_test
7967 -       .word   paradise_md, paradise_test
7968 -       .word   realtek_md, realtek_test
7969 -       .word   s3_md, s3_test
7970 -       .word   chips_md, chips_test
7971 -       .word   video7_md, video7_test
7972 -       .word   cirrus5_md, cirrus5_test
7973 -       .word   cirrus6_md, cirrus6_test
7974 -       .word   cirrus1_md, cirrus1_test
7975 -       .word   ahead_md, ahead_test
7976 -       .word   everex_md, everex_test
7977 -       .word   genoa_md, genoa_test
7978 -       .word   trident_md, trident_test
7979 -       .word   tseng_md, tseng_test
7980 -       .word   0
7981 -
7982 -# Test routines and mode tables:
7983 -
7984 -# S3 - The test algorithm was taken from the SuperProbe package
7985 -# for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org
7986 -s3_test:
7987 -       movw    $0x0f35, %cx    # we store some constants in cl/ch
7988 -       movw    $0x03d4, %dx
7989 -       movb    $0x38, %al
7990 -       call    inidx
7991 -       movb    %al, %bh        # store current CRT-register 0x38
7992 -       movw    $0x0038, %ax
7993 -       call    outidx          # disable writing to special regs
7994 -       movb    %cl, %al        # check whether we can write special reg 0x35
7995 -       call    inidx
7996 -       movb    %al, %bl        # save the current value of CRT reg 0x35
7997 -       andb    $0xf0, %al      # clear bits 0-3
7998 -       movb    %al, %ah
7999 -       movb    %cl, %al        # and write it to CRT reg 0x35
8000 -       call    outidx
8001 -       call    inidx           # now read it back
8002 -       andb    %ch, %al        # clear the upper 4 bits
8003 -       jz      s3_2            # the first test failed. But we have a
8004 -
8005 -       movb    %bl, %ah        # second chance
8006 -       movb    %cl, %al
8007 -       call    outidx
8008 -       jmp     s3_1            # do the other tests
8009 -
8010 -s3_2:  movw    %cx, %ax        # load ah with 0xf and al with 0x35
8011 -       orb     %bl, %ah        # set the upper 4 bits of ah with the orig value
8012 -       call    outidx          # write ...
8013 -       call    inidx           # ... and reread 
8014 -       andb    %cl, %al        # turn off the upper 4 bits
8015 -       pushw   %ax
8016 -       movb    %bl, %ah        # restore old value in register 0x35
8017 -       movb    %cl, %al
8018 -       call    outidx
8019 -       popw    %ax
8020 -       cmpb    %ch, %al        # setting lower 4 bits was successful => bad
8021 -       je      no_s3           # writing is allowed => this is not an S3
8022 -
8023 -s3_1:  movw    $0x4838, %ax    # allow writing to special regs by putting
8024 -       call    outidx          # magic number into CRT-register 0x38
8025 -       movb    %cl, %al        # check whether we can write special reg 0x35
8026 -       call    inidx
8027 -       movb    %al, %bl
8028 -       andb    $0xf0, %al
8029 -       movb    %al, %ah
8030 -       movb    %cl, %al
8031 -       call    outidx
8032 -       call    inidx
8033 -       andb    %ch, %al
8034 -       jnz     no_s3           # no, we can't write => no S3
8035 -
8036 -       movw    %cx, %ax
8037 -       orb     %bl, %ah
8038 -       call    outidx
8039 -       call    inidx
8040 -       andb    %ch, %al
8041 -       pushw   %ax
8042 -       movb    %bl, %ah        # restore old value in register 0x35
8043 -       movb    %cl, %al
8044 -       call    outidx
8045 -       popw    %ax
8046 -       cmpb    %ch, %al
8047 -       jne     no_s31          # writing not possible => no S3
8048 -       movb    $0x30, %al
8049 -       call    inidx           # now get the S3 id ...
8050 -       leaw    idS3, %di
8051 -       movw    $0x10, %cx
8052 -       repne
8053 -       scasb
8054 -       je      no_s31
8055 -
8056 -       movb    %bh, %ah
8057 -       movb    $0x38, %al
8058 -       jmp     s3rest
8059 -
8060 -no_s3: movb    $0x35, %al      # restore CRT register 0x35
8061 -       movb    %bl, %ah
8062 -       call    outidx
8063 -no_s31:        xorw    %bp, %bp        # Detection failed
8064 -s3rest:        movb    %bh, %ah
8065 -       movb    $0x38, %al      # restore old value of CRT register 0x38
8066 -       jmp     outidx
8067 -
8068 -idS3:  .byte   0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
8069 -       .byte   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
8070 -
8071 -s3_md: .byte   0x54, 0x2b, 0x84
8072 -       .byte   0x55, 0x19, 0x84
8073 -       .byte   0
8074 -       .ascii  "S3"
8075 -       .byte   0
8076 -
8077 -# ATI cards.
8078 -ati_test:
8079 -       leaw    idati, %si
8080 -       movw    $0x31, %di
8081 -       movw    $0x09, %cx
8082 -       repe
8083 -       cmpsb
8084 -       je      atiok
8085 -
8086 -       xorw    %bp, %bp
8087 -atiok: ret
8088 -
8089 -idati: .ascii  "761295520"
8090 -
8091 -ati_md:        .byte   0x23, 0x19, 0x84
8092 -       .byte   0x33, 0x2c, 0x84
8093 -       .byte   0x22, 0x1e, 0x64
8094 -       .byte   0x21, 0x19, 0x64
8095 -       .byte   0x58, 0x21, 0x50
8096 -       .byte   0x5b, 0x1e, 0x50
8097 -       .byte   0
8098 -       .ascii  "ATI"
8099 -       .byte   0
8100 -
8101 -# AHEAD
8102 -ahead_test:
8103 -       movw    $0x200f, %ax
8104 -       movw    $0x3ce, %dx
8105 -       outw    %ax, %dx
8106 -       incw    %dx
8107 -       inb     %dx, %al
8108 -       cmpb    $0x20, %al
8109 -       je      isahed
8110 -
8111 -       cmpb    $0x21, %al
8112 -       je      isahed
8113 -       
8114 -       xorw    %bp, %bp
8115 -isahed:        ret
8116 -
8117 -ahead_md:
8118 -       .byte   0x22, 0x2c, 0x84
8119 -       .byte   0x23, 0x19, 0x84
8120 -       .byte   0x24, 0x1c, 0x84
8121 -       .byte   0x2f, 0x32, 0xa0
8122 -       .byte   0x32, 0x22, 0x50
8123 -       .byte   0x34, 0x42, 0x50
8124 -       .byte   0
8125 -       .ascii  "Ahead"
8126 -       .byte   0
8127 -
8128 -# Chips & Tech.
8129 -chips_test:
8130 -       movw    $0x3c3, %dx
8131 -       inb     %dx, %al
8132 -       orb     $0x10, %al
8133 -       outb    %al, %dx
8134 -       movw    $0x104, %dx
8135 -       inb     %dx, %al
8136 -       movb    %al, %bl
8137 -       movw    $0x3c3, %dx
8138 -       inb     %dx, %al
8139 -       andb    $0xef, %al
8140 -       outb    %al, %dx
8141 -       cmpb    $0xa5, %bl
8142 -       je      cantok
8143 -       
8144 -       xorw    %bp, %bp
8145 -cantok:        ret
8146 -
8147 -chips_md:
8148 -       .byte   0x60, 0x19, 0x84
8149 -       .byte   0x61, 0x32, 0x84
8150 -       .byte   0
8151 -       .ascii  "Chips & Technologies"
8152 -       .byte   0
8153 -
8154 -# Cirrus Logic 5X0
8155 -cirrus1_test:
8156 -       movw    $0x3d4, %dx
8157 -       movb    $0x0c, %al
8158 -       outb    %al, %dx
8159 -       incw    %dx
8160 -       inb     %dx, %al
8161 -       movb    %al, %bl
8162 -       xorb    %al, %al
8163 -       outb    %al, %dx
8164 -       decw    %dx
8165 -       movb    $0x1f, %al
8166 -       outb    %al, %dx
8167 -       incw    %dx
8168 -       inb     %dx, %al
8169 -       movb    %al, %bh
8170 -       xorb    %ah, %ah
8171 -       shlb    $4, %al
8172 -       movw    %ax, %cx
8173 -       movb    %bh, %al
8174 -       shrb    $4, %al
8175 -       addw    %ax, %cx
8176 -       shlw    $8, %cx
8177 -       addw    $6, %cx
8178 -       movw    %cx, %ax
8179 -       movw    $0x3c4, %dx
8180 -       outw    %ax, %dx
8181 -       incw    %dx
8182 -       inb     %dx, %al
8183 -       andb    %al, %al
8184 -       jnz     nocirr
8185 -       
8186 -       movb    %bh, %al
8187 -       outb    %al, %dx
8188 -       inb     %dx, %al
8189 -       cmpb    $0x01, %al
8190 -       je      iscirr
8191 -
8192 -nocirr:        xorw    %bp, %bp
8193 -iscirr: movw   $0x3d4, %dx
8194 -       movb    %bl, %al
8195 -       xorb    %ah, %ah
8196 -       shlw    $8, %ax
8197 -       addw    $0x0c, %ax
8198 -       outw    %ax, %dx
8199 -       ret
8200 -
8201 -cirrus1_md:
8202 -       .byte   0x1f, 0x19, 0x84
8203 -       .byte   0x20, 0x2c, 0x84
8204 -       .byte   0x22, 0x1e, 0x84
8205 -       .byte   0x31, 0x25, 0x64
8206 -       .byte   0
8207 -       .ascii  "Cirrus Logic 5X0"
8208 -       .byte   0
8209 -
8210 -# Cirrus Logic 54XX
8211 -cirrus5_test:
8212 -       movw    $0x3c4, %dx
8213 -       movb    $6, %al
8214 -       call    inidx
8215 -       movb    %al, %bl                        # BL=backup
8216 -       movw    $6, %ax
8217 -       call    tstidx
8218 -       cmpb    $0x0f, %al
8219 -       jne     c5fail
8220 -       
8221 -       movw    $0x1206, %ax
8222 -       call    tstidx
8223 -       cmpb    $0x12, %al
8224 -       jne     c5fail
8225 -       
8226 -       movb    $0x1e, %al
8227 -       call    inidx
8228 -       movb    %al, %bh
8229 -       movb    %bh, %ah
8230 -       andb    $0xc0, %ah
8231 -       movb    $0x1e, %al
8232 -       call    tstidx
8233 -       andb    $0x3f, %al
8234 -       jne     c5xx
8235 -       
8236 -       movb    $0x1e, %al
8237 -       movb    %bh, %ah
8238 -       orb     $0x3f, %ah
8239 -       call    tstidx
8240 -       xorb    $0x3f, %al
8241 -       andb    $0x3f, %al
8242 -c5xx:  pushf
8243 -       movb    $0x1e, %al
8244 -       movb    %bh, %ah
8245 -       outw    %ax, %dx
8246 -       popf
8247 -       je      c5done
8248 -
8249 -c5fail:        xorw    %bp, %bp
8250 -c5done:        movb    $6, %al
8251 -       movb    %bl, %ah
8252 -       outw    %ax, %dx
8253 -       ret
8254 -
8255 -cirrus5_md:
8256 -       .byte   0x14, 0x19, 0x84
8257 -       .byte   0x54, 0x2b, 0x84
8258 -       .byte   0
8259 -       .ascii  "Cirrus Logic 54XX"
8260 -       .byte   0
8261 -
8262 -# Cirrus Logic 64XX -- no known extra modes, but must be identified, because
8263 -# it's misidentified by the Ahead test.
8264 -cirrus6_test:
8265 -       movw    $0x3ce, %dx
8266 -       movb    $0x0a, %al
8267 -       call    inidx
8268 -       movb    %al, %bl        # BL=backup
8269 -       movw    $0xce0a, %ax
8270 -       call    tstidx
8271 -       orb     %al, %al
8272 -       jne     c2fail
8273 -       
8274 -       movw    $0xec0a, %ax
8275 -       call    tstidx
8276 -       cmpb    $0x01, %al
8277 -       jne     c2fail
8278 -       
8279 -       movb    $0xaa, %al
8280 -       call    inidx           # 4X, 5X, 7X and 8X are valid 64XX chip ID's. 
8281 -       shrb    $4, %al
8282 -       subb    $4, %al
8283 -       jz      c6done
8284 -       
8285 -       decb    %al
8286 -       jz      c6done
8287 -       
8288 -       subb    $2, %al
8289 -       jz      c6done
8290 -       
8291 -       decb    %al
8292 -       jz      c6done
8293 -       
8294 -c2fail:        xorw    %bp, %bp
8295 -c6done:        movb    $0x0a, %al
8296 -       movb    %bl, %ah
8297 -       outw    %ax, %dx
8298 -       ret
8299 -
8300 -cirrus6_md:
8301 -       .byte   0
8302 -       .ascii  "Cirrus Logic 64XX"
8303 -       .byte   0
8304 -
8305 -# Everex / Trident
8306 -everex_test:
8307 -       movw    $0x7000, %ax
8308 -       xorw    %bx, %bx
8309 -       int     $0x10
8310 -       cmpb    $0x70, %al
8311 -       jne     noevrx
8312 -       
8313 -       shrw    $4, %dx
8314 -       cmpw    $0x678, %dx
8315 -       je      evtrid
8316 -       
8317 -       cmpw    $0x236, %dx
8318 -       jne     evrxok
8319 -
8320 -evtrid:        leaw    trident_md, %bp
8321 -evrxok:        ret
8322 -
8323 -noevrx:        xorw    %bp, %bp
8324 -       ret
8325 -
8326 -everex_md:
8327 -       .byte   0x03, 0x22, 0x50
8328 -       .byte   0x04, 0x3c, 0x50
8329 -       .byte   0x07, 0x2b, 0x64
8330 -       .byte   0x08, 0x4b, 0x64
8331 -       .byte   0x0a, 0x19, 0x84
8332 -       .byte   0x0b, 0x2c, 0x84
8333 -       .byte   0x16, 0x1e, 0x50
8334 -       .byte   0x18, 0x1b, 0x64
8335 -       .byte   0x21, 0x40, 0xa0
8336 -       .byte   0x40, 0x1e, 0x84
8337 -       .byte   0
8338 -       .ascii  "Everex/Trident"
8339 -       .byte   0
8340 -
8341 -# Genoa.
8342 -genoa_test:
8343 -       leaw    idgenoa, %si                    # Check Genoa 'clues'
8344 -       xorw    %ax, %ax
8345 -       movb    %es:(0x37), %al
8346 -       movw    %ax, %di
8347 -       movw    $0x04, %cx
8348 -       decw    %si
8349 -       decw    %di
8350 -l1:    incw    %si
8351 -       incw    %di
8352 -       movb    (%si), %al
8353 -       testb   %al, %al
8354 -       jz      l2
8355 -
8356 -       cmpb    %es:(%di), %al
8357 -l2:    loope   l1
8358 -       orw     %cx, %cx
8359 -       je      isgen
8360 -       
8361 -       xorw    %bp, %bp
8362 -isgen: ret
8363 -
8364 -idgenoa: .byte 0x77, 0x00, 0x99, 0x66
8365 -
8366 -genoa_md:
8367 -       .byte   0x58, 0x20, 0x50
8368 -       .byte   0x5a, 0x2a, 0x64
8369 -       .byte   0x60, 0x19, 0x84
8370 -       .byte   0x61, 0x1d, 0x84
8371 -       .byte   0x62, 0x20, 0x84
8372 -       .byte   0x63, 0x2c, 0x84
8373 -       .byte   0x64, 0x3c, 0x84
8374 -       .byte   0x6b, 0x4f, 0x64
8375 -       .byte   0x72, 0x3c, 0x50
8376 -       .byte   0x74, 0x42, 0x50
8377 -       .byte   0x78, 0x4b, 0x64
8378 -       .byte   0
8379 -       .ascii  "Genoa"
8380 -       .byte   0
8381 -
8382 -# OAK
8383 -oak_test:
8384 -       leaw    idoakvga, %si
8385 -       movw    $0x08, %di
8386 -       movw    $0x08, %cx
8387 -       repe
8388 -       cmpsb
8389 -       je      isoak
8390 -       
8391 -       xorw    %bp, %bp
8392 -isoak: ret
8393 -
8394 -idoakvga: .ascii  "OAK VGA "
8395 -
8396 -oak_md: .byte  0x4e, 0x3c, 0x50
8397 -       .byte   0x4f, 0x3c, 0x84
8398 -       .byte   0x50, 0x19, 0x84
8399 -       .byte   0x51, 0x2b, 0x84
8400 -       .byte   0
8401 -       .ascii  "OAK"
8402 -       .byte   0
8403 -
8404 -# WD Paradise.
8405 -paradise_test:
8406 -       leaw    idparadise, %si
8407 -       movw    $0x7d, %di
8408 -       movw    $0x04, %cx
8409 -       repe
8410 -       cmpsb
8411 -       je      ispara
8412 -       
8413 -       xorw    %bp, %bp
8414 -ispara:        ret
8415 -
8416 -idparadise:    .ascii  "VGA="
8417 -
8418 -paradise_md:
8419 -       .byte   0x41, 0x22, 0x50
8420 -       .byte   0x47, 0x1c, 0x84
8421 -       .byte   0x55, 0x19, 0x84
8422 -       .byte   0x54, 0x2c, 0x84
8423 -       .byte   0
8424 -       .ascii  "Paradise"
8425 -       .byte   0
8426 -
8427 -# Trident.
8428 -trident_test:
8429 -       movw    $0x3c4, %dx
8430 -       movb    $0x0e, %al
8431 -       outb    %al, %dx
8432 -       incw    %dx
8433 -       inb     %dx, %al
8434 -       xchgb   %al, %ah
8435 -       xorb    %al, %al
8436 -       outb    %al, %dx
8437 -       inb     %dx, %al
8438 -       xchgb   %ah, %al
8439 -       movb    %al, %bl        # Strange thing ... in the book this wasn't
8440 -       andb    $0x02, %bl      # necessary but it worked on my card which
8441 -       jz      setb2           # is a trident. Without it the screen goes
8442 -                               # blurred ...
8443 -       andb    $0xfd, %al
8444 -       jmp     clrb2           
8445 -
8446 -setb2: orb     $0x02, %al      
8447 -clrb2: outb    %al, %dx
8448 -       andb    $0x0f, %ah
8449 -       cmpb    $0x02, %ah
8450 -       je      istrid
8451 -
8452 -       xorw    %bp, %bp
8453 -istrid:        ret
8454 -
8455 -trident_md:
8456 -       .byte   0x50, 0x1e, 0x50
8457 -       .byte   0x51, 0x2b, 0x50
8458 -       .byte   0x52, 0x3c, 0x50
8459 -       .byte   0x57, 0x19, 0x84
8460 -       .byte   0x58, 0x1e, 0x84
8461 -       .byte   0x59, 0x2b, 0x84
8462 -       .byte   0x5a, 0x3c, 0x84
8463 -       .byte   0
8464 -       .ascii  "Trident"
8465 -       .byte   0
8466 -
8467 -# Tseng.
8468 -tseng_test:
8469 -       movw    $0x3cd, %dx
8470 -       inb     %dx, %al        # Could things be this simple ! :-)
8471 -       movb    %al, %bl
8472 -       movb    $0x55, %al
8473 -       outb    %al, %dx
8474 -       inb     %dx, %al
8475 -       movb    %al, %ah
8476 -       movb    %bl, %al
8477 -       outb    %al, %dx
8478 -       cmpb    $0x55, %ah
8479 -       je      istsen
8480 -
8481 -isnot: xorw    %bp, %bp
8482 -istsen:        ret
8483 -
8484 -tseng_md:
8485 -       .byte   0x26, 0x3c, 0x50
8486 -       .byte   0x2a, 0x28, 0x64
8487 -       .byte   0x23, 0x19, 0x84
8488 -       .byte   0x24, 0x1c, 0x84
8489 -       .byte   0x22, 0x2c, 0x84
8490 -       .byte   0x21, 0x3c, 0x84
8491 -       .byte   0
8492 -       .ascii  "Tseng"
8493 -       .byte   0
8494 -
8495 -# Video7.
8496 -video7_test:
8497 -       movw    $0x3cc, %dx
8498 -       inb     %dx, %al
8499 -       movw    $0x3b4, %dx
8500 -       andb    $0x01, %al
8501 -       jz      even7
8502 -
8503 -       movw    $0x3d4, %dx
8504 -even7: movb    $0x0c, %al
8505 -       outb    %al, %dx
8506 -       incw    %dx
8507 -       inb     %dx, %al
8508 -       movb    %al, %bl
8509 -       movb    $0x55, %al
8510 -       outb    %al, %dx
8511 -       inb     %dx, %al
8512 -       decw    %dx
8513 -       movb    $0x1f, %al
8514 -       outb    %al, %dx
8515 -       incw    %dx
8516 -       inb     %dx, %al
8517 -       movb    %al, %bh
8518 -       decw    %dx
8519 -       movb    $0x0c, %al
8520 -       outb    %al, %dx
8521 -       incw    %dx
8522 -       movb    %bl, %al
8523 -       outb    %al, %dx
8524 -       movb    $0x55, %al
8525 -       xorb    $0xea, %al
8526 -       cmpb    %bh, %al
8527 -       jne     isnot
8528 -       
8529 -       movb    $VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching
8530 -       ret
8531 -
8532 -video7_md:
8533 -       .byte   0x40, 0x2b, 0x50
8534 -       .byte   0x43, 0x3c, 0x50
8535 -       .byte   0x44, 0x3c, 0x64
8536 -       .byte   0x41, 0x19, 0x84
8537 -       .byte   0x42, 0x2c, 0x84
8538 -       .byte   0x45, 0x1c, 0x84
8539 -       .byte   0
8540 -       .ascii  "Video 7"
8541 -       .byte   0
8542 -
8543 -# Realtek VGA
8544 -realtek_test:
8545 -       leaw    idrtvga, %si
8546 -       movw    $0x45, %di
8547 -       movw    $0x0b, %cx
8548 -       repe
8549 -       cmpsb
8550 -       je      isrt
8551 -       
8552 -       xorw    %bp, %bp
8553 -isrt:  ret
8554 -
8555 -idrtvga:       .ascii  "REALTEK VGA"
8556 -
8557 -realtek_md:
8558 -       .byte   0x1a, 0x3c, 0x50
8559 -       .byte   0x1b, 0x19, 0x84
8560 -       .byte   0x1c, 0x1e, 0x84
8561 -       .byte   0x1d, 0x2b, 0x84
8562 -       .byte   0x1e, 0x3c, 0x84
8563 -       .byte   0
8564 -       .ascii  "REALTEK"
8565 -       .byte   0
8566 -
8567 -#endif /* CONFIG_VIDEO_SVGA */
8568 -
8569 -# User-defined local mode table (VGA only)
8570 -#ifdef CONFIG_VIDEO_LOCAL
8571 -local_modes:
8572 -       leaw    local_mode_table, %si
8573 -locm1: lodsw
8574 -       orw     %ax, %ax
8575 -       jz      locm2
8576 -       
8577 -       stosw
8578 -       movsw
8579 -       jmp     locm1
8580 -
8581 -locm2: ret
8582 -
8583 -# This is the table of local video modes which can be supplied manually
8584 -# by the user. Each entry consists of mode ID (word) and dimensions
8585 -# (byte for column count and another byte for row count). These modes
8586 -# are placed before all SVGA and VESA modes and override them if table
8587 -# compacting is enabled. The table must end with a zero word followed
8588 -# by NUL-terminated video adapter name.
8589 -local_mode_table:
8590 -       .word   0x0100                          # Example: 40x25
8591 -       .byte   25,40
8592 -       .word   0
8593 -       .ascii  "Local"
8594 -       .byte   0
8595 -#endif /* CONFIG_VIDEO_LOCAL */
8596 -
8597 -# Read a key and return the ASCII code in al, scan code in ah
8598 -getkey:        xorb    %ah, %ah
8599 -       int     $0x16
8600 -       ret
8601 -
8602 -# Read a key with a timeout of 30 seconds.
8603 -# The hardware clock is used to get the time.
8604 -getkt: call    gettime
8605 -       addb    $30, %al                        # Wait 30 seconds
8606 -       cmpb    $60, %al
8607 -       jl      lminute
8608 -
8609 -       subb    $60, %al
8610 -lminute:
8611 -       movb    %al, %cl
8612 -again: movb    $0x01, %ah
8613 -       int     $0x16
8614 -       jnz     getkey                          # key pressed, so get it
8615 -
8616 -       call    gettime
8617 -       cmpb    %cl, %al
8618 -       jne     again
8619 -
8620 -       movb    $0x20, %al                      # timeout, return `space'
8621 -       ret
8622 -
8623 -# Flush the keyboard buffer
8624 -flush: movb    $0x01, %ah
8625 -       int     $0x16
8626 -       jz      empty
8627 -       
8628 -       xorb    %ah, %ah
8629 -       int     $0x16
8630 -       jmp     flush
8631 -
8632 -empty: ret
8633 -
8634 -# Print hexadecimal number.
8635 -prthw: pushw   %ax
8636 -       movb    %ah, %al
8637 -       call    prthb
8638 -       popw    %ax
8639 -prthb: pushw   %ax
8640 -       shrb    $4, %al
8641 -       call    prthn
8642 -       popw    %ax
8643 -       andb    $0x0f, %al
8644 -prthn: cmpb    $0x0a, %al
8645 -       jc      prth1
8646 -
8647 -       addb    $0x07, %al
8648 -prth1: addb    $0x30, %al
8649 -       jmp     prtchr
8650 -
8651 -# Print decimal number in al
8652 -prtdec:        pushw   %ax
8653 -       pushw   %cx
8654 -       xorb    %ah, %ah
8655 -       movb    $0x0a, %cl
8656 -       idivb   %cl
8657 -       cmpb    $0x09, %al
8658 -       jbe     lt100
8659 -
8660 -       call    prtdec
8661 -       jmp     skip10
8662 -
8663 -lt100: addb    $0x30, %al
8664 -       call    prtchr
8665 -skip10:        movb    %ah, %al
8666 -       addb    $0x30, %al
8667 -       call    prtchr  
8668 -       popw    %cx
8669 -       popw    %ax
8670 -       ret
8671 -
8672 -store_edid:
8673 -#ifdef CONFIG_FIRMWARE_EDID
8674 -       pushw   %es                             # just save all registers
8675 -       pushw   %ax
8676 -       pushw   %bx
8677 -       pushw   %cx
8678 -       pushw   %dx
8679 -       pushw   %di
8680 -
8681 -       pushw   %fs
8682 -       popw    %es
8683 -
8684 -       movl    $0x13131313, %eax               # memset block with 0x13
8685 -       movw    $32, %cx
8686 -       movw    $0x140, %di
8687 -       cld
8688 -       rep
8689 -       stosl
8690 -
8691 -       cmpw    $0x0200, vbe_version            # only do EDID on >= VBE2.0
8692 -       jl      no_edid
8693 -
8694 -       pushw   %es                             # save ES
8695 -       xorw    %di, %di                        # Report Capability
8696 -       pushw   %di
8697 -       popw    %es                             # ES:DI must be 0:0
8698 -       movw    $0x4f15, %ax
8699 -       xorw    %bx, %bx
8700 -       xorw    %cx, %cx
8701 -       int     $0x10
8702 -       popw    %es                             # restore ES
8703 -
8704 -       cmpb    $0x00, %ah                      # call successful
8705 -       jne     no_edid
8706 -
8707 -       cmpb    $0x4f, %al                      # function supported
8708 -       jne     no_edid
8709 -
8710 -       movw    $0x4f15, %ax                    # do VBE/DDC
8711 -       movw    $0x01, %bx
8712 -       movw    $0x00, %cx
8713 -       movw    $0x00, %dx
8714 -       movw    $0x140, %di
8715 -       int     $0x10
8716 -
8717 -no_edid:
8718 -       popw    %di                             # restore all registers
8719 -       popw    %dx
8720 -       popw    %cx
8721 -       popw    %bx
8722 -       popw    %ax
8723 -       popw    %es
8724 -#endif
8725 -       ret
8726 -
8727 -# VIDEO_SELECT-only variables
8728 -mt_end:                .word   0       # End of video mode table if built
8729 -edit_buf:      .space  6       # Line editor buffer
8730 -card_name:     .word   0       # Pointer to adapter name
8731 -scanning:      .byte   0       # Performing mode scan
8732 -do_restore:    .byte   0       # Screen contents altered during mode change
8733 -svga_prefix:   .byte   VIDEO_FIRST_BIOS>>8     # Default prefix for BIOS modes
8734 -graphic_mode:  .byte   0       # Graphic mode with a linear frame buffer
8735 -dac_size:      .byte   6       # DAC bit depth
8736 -vbe_version:   .word   0       # VBE bios version
8737 -
8738 -# Status messages
8739 -keymsg:                .ascii  "Press <RETURN> to see video modes available, "
8740 -               .ascii  "<SPACE> to continue or wait 30 secs"
8741 -               .byte   0x0d, 0x0a, 0
8742 -
8743 -listhdr:       .byte   0x0d, 0x0a
8744 -               .ascii  "Mode:    COLSxROWS:"
8745 -
8746 -crlft:         .byte   0x0d, 0x0a, 0
8747 -
8748 -prompt:                .byte   0x0d, 0x0a
8749 -               .asciz  "Enter mode number or `scan': "
8750 -
8751 -unknt:         .asciz  "Unknown mode ID. Try again."
8752 -
8753 -badmdt:                .ascii  "You passed an undefined mode number."
8754 -               .byte   0x0d, 0x0a, 0
8755 -
8756 -vesaer:                .ascii  "Error: Scanning of VESA modes failed. Please "
8757 -               .ascii  "report to <mj@ucw.cz>."
8758 -               .byte   0x0d, 0x0a, 0
8759 -
8760 -old_name:      .asciz  "CGA/MDA/HGA"
8761 -
8762 -ega_name:      .asciz  "EGA"
8763 -
8764 -svga_name:     .ascii  " "
8765 -
8766 -vga_name:      .asciz  "VGA"
8767 -
8768 -vesa_name:     .asciz  "VESA"
8769 -
8770 -name_bann:     .asciz  "Video adapter: "
8771 -#endif /* CONFIG_VIDEO_SELECT */
8772 -
8773 -# Other variables:
8774 -adapter:       .byte   0       # Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA
8775 -video_segment: .word   0xb800  # Video memory segment
8776 -force_size:    .word   0       # Use this size instead of the one in BIOS vars
8777 diff -puN /dev/null arch/i386/boot/video.c
8778 --- /dev/null
8779 +++ a/arch/i386/boot/video.c
8780 @@ -0,0 +1,456 @@
8781 +/* -*- linux-c -*- ------------------------------------------------------- *
8782 + *
8783 + *   Copyright (C) 1991, 1992 Linus Torvalds
8784 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
8785 + *
8786 + *   This file is part of the Linux kernel, and is made available under
8787 + *   the terms of the GNU General Public License version 2.
8788 + *
8789 + * ----------------------------------------------------------------------- */
8790 +
8791 +/*
8792 + * arch/i386/boot/video.c
8793 + *
8794 + * Select video mode
8795 + */
8796 +
8797 +#include "boot.h"
8798 +#include "video.h"
8799 +#include "vesa.h"
8800 +
8801 +/*
8802 + * Mode list variables
8803 + */
8804 +static struct card_info cards[];    /* List of cards to probe for */
8805 +
8806 +/*
8807 + * Common variables
8808 + */
8809 +int adapter;                   /* 0=CGA/MDA/HGC, 1=EGA, 2=VGA+ */
8810 +u16 video_segment;
8811 +int force_x, force_y;  /* Don't query the BIOS for cols/rows */
8812 +
8813 +int do_restore = 0;    /* Screen contents changed during mode flip */
8814 +int graphic_mode;      /* Graphic mode with linear frame buffer */
8815 +
8816 +static void store_cursor_position(void)
8817 +{
8818 +       u16 curpos;
8819 +       u16 ax, bx;
8820 +
8821 +       ax = 0x0300;
8822 +       bx = 0;
8823 +       asm(INT10
8824 +           : "=d" (curpos), "+a" (ax), "+b" (bx)
8825 +           : : "ecx", "esi", "edi");
8826 +
8827 +       boot_params.screen_info.orig_x = curpos;
8828 +       boot_params.screen_info.orig_y = curpos >> 8;
8829 +}
8830 +
8831 +static void store_video_mode(void)
8832 +{
8833 +       u16 ax, page;
8834 +
8835 +       /* N.B.: the saving of the video page here is a bit silly,
8836 +          since we pretty much assume page 0 everywhere. */
8837 +       ax = 0x0f00;
8838 +       asm(INT10
8839 +           : "+a" (ax), "=b" (page)
8840 +           : : "ecx", "edx", "esi", "edi");
8841 +
8842 +       /* Not all BIOSes are clean with respect to the top bit */
8843 +       boot_params.screen_info.orig_video_mode = ax & 0x7f;
8844 +       boot_params.screen_info.orig_video_page = page;
8845 +}
8846 +
8847 +/*
8848 + * Store the video mode parameters for later usage by the kernel.
8849 + * This is done by asking the BIOS except for the rows/columns
8850 + * parameters in the default 80x25 mode -- these are set directly,
8851 + * because some very obscure BIOSes supply insane values.
8852 + */
8853 +static void store_mode_params(void)
8854 +{
8855 +       u16 font_size;
8856 +       int x, y;
8857 +
8858 +       /* For graphics mode, it is up to the mode-setting driver
8859 +          (currently only video-vesa.c) to store the parameters */
8860 +       if (graphic_mode)
8861 +               return;
8862 +
8863 +       store_cursor_position();
8864 +       store_video_mode();
8865 +
8866 +       if (boot_params.screen_info.orig_video_mode == 0x07) {
8867 +               /* MDA, HGC, or VGA in monochrome mode */
8868 +               video_segment = 0xb000;
8869 +       } else {
8870 +               /* CGA, EGA, VGA and so forth */
8871 +               video_segment = 0xb800;
8872 +       }
8873 +
8874 +       set_fs(0);
8875 +       font_size = rdfs16(0x485); /* Font size, BIOS area */
8876 +       boot_params.screen_info.orig_video_points = font_size;
8877 +
8878 +       x = rdfs16(0x44a);
8879 +       y = (adapter == ADAPTER_CGA) ? 25 : rdfs8(0x484)+1;
8880 +
8881 +       if (force_x)
8882 +               x = force_x;
8883 +       if (force_y)
8884 +               y = force_y;
8885 +
8886 +       boot_params.screen_info.orig_video_cols  = x;
8887 +       boot_params.screen_info.orig_video_lines = y;
8888 +}
8889 +
8890 +/* Probe the video drivers and have them generate their mode lists. */
8891 +static void probe_cards(int unsafe)
8892 +{
8893 +       struct card_info *card;
8894 +       static u8 probed[2];
8895 +
8896 +       if (probed[unsafe])
8897 +               return;
8898 +
8899 +       probed[unsafe] = 1;
8900 +
8901 +       for (card = video_cards; card < video_cards_end; card++) {
8902 +               if (card->unsafe == unsafe) {
8903 +                       if (card->probe)
8904 +                               card->nmodes = card->probe();
8905 +                       else
8906 +                               card->nmodes = 0;
8907 +               }
8908 +       }
8909 +}
8910 +
8911 +/* Test if a mode is defined */
8912 +int mode_defined(u16 mode)
8913 +{
8914 +       struct card_info *card;
8915 +       struct mode_info *mi;
8916 +       int i;
8917 +
8918 +       for (card = video_cards; card < video_cards_end; card++) {
8919 +               mi = card->modes;
8920 +               for (i = 0; i < card->nmodes; i++, mi++) {
8921 +                       if (mi->mode == mode)
8922 +                               return 1;
8923 +               }
8924 +       }
8925 +
8926 +       return 0;
8927 +}
8928 +
8929 +/* Set mode (without recalc) */
8930 +static int raw_set_mode(u16 mode)
8931 +{
8932 +       int nmode, i;
8933 +       struct card_info *card;
8934 +       struct mode_info *mi;
8935 +
8936 +       /* Drop the recalc bit if set */
8937 +       mode &= ~VIDEO_RECALC;
8938 +
8939 +       /* Scan for mode based on fixed ID, position, or resolution */
8940 +       nmode = 0;
8941 +       for (card = video_cards; card < video_cards_end; card++) {
8942 +               mi = card->modes;
8943 +               for (i = 0; i < card->nmodes; i++, mi++) {
8944 +                       int visible = mi->x || mi->y;
8945 +
8946 +                       if ((mode == nmode && visible) ||
8947 +                           mode == mi->mode ||
8948 +                           mode == (mi->y << 8)+mi->x)
8949 +                               return card->set_mode(mi);
8950 +
8951 +                       if (visible)
8952 +                               nmode++;
8953 +               }
8954 +       }
8955 +
8956 +       /* Nothing found?  Is it an "exceptional" (unprobed) mode? */
8957 +       for (card = video_cards; card < video_cards_end; card++) {
8958 +               if (mode >= card->xmode_first &&
8959 +                   mode < card->xmode_first+card->xmode_n) {
8960 +                       struct mode_info mix;
8961 +                       mix.mode = mode;
8962 +                       mix.x = mix.y = 0;
8963 +                       return card->set_mode(&mix);
8964 +               }
8965 +       }
8966 +
8967 +       /* Otherwise, failure... */
8968 +       return -1;
8969 +}
8970 +
8971 +/*
8972 + * Recalculate the vertical video cutoff (hack!)
8973 + */
8974 +static void vga_recalc_vertical(void)
8975 +{
8976 +       unsigned int font_size, rows;
8977 +       u16 crtc;
8978 +       u8 ov;
8979 +
8980 +       set_fs(0);
8981 +       font_size = rdfs8(0x485); /* BIOS: font size (pixels) */
8982 +       rows = force_y ? force_y : rdfs8(0x484)+1; /* Text rows */
8983 +
8984 +       rows *= font_size;      /* Visible scan lines */
8985 +       rows--;                 /* ... minus one */
8986 +
8987 +       crtc = vga_crtc();
8988 +
8989 +       out_idx((u8)rows, crtc, 0x12); /* Lower height register */
8990 +       ov = in_idx(crtc, 0x07); /* Overflow register */
8991 +       ov &= 0xbd;
8992 +       ov |= (rows >> (8-1)) & 0x02;
8993 +       ov |= (rows >> (9-6)) & 0x40;
8994 +       out_idx(ov, crtc, 0x07);
8995 +}
8996 +
8997 +/* Set mode (with recalc if specified) */
8998 +static int set_mode(u16 mode)
8999 +{
9000 +       int rv;
9001 +
9002 +       /* Very special mode numbers... */
9003 +       if (mode == VIDEO_CURRENT_MODE)
9004 +               return 0;       /* Nothing to do... */
9005 +       else if (mode == NORMAL_VGA)
9006 +               mode = VIDEO_80x25;
9007 +       else if (mode == EXTENDED_VGA)
9008 +               mode = VIDEO_8POINT;
9009 +
9010 +       rv = raw_set_mode(mode);
9011 +       if (rv)
9012 +               return rv;
9013 +
9014 +       if (mode & VIDEO_RECALC)
9015 +               vga_recalc_vertical();
9016 +
9017 +       return 0;
9018 +}
9019 +
9020 +static unsigned int get_entry(void)
9021 +{
9022 +       char entry_buf[4];
9023 +       int i, len = 0;
9024 +       int key;
9025 +       unsigned int v;
9026 +
9027 +       do {
9028 +               key = getchar();
9029 +
9030 +               if (key == '\b') {
9031 +                       if (len > 0) {
9032 +                               puts("\b \b");
9033 +                               len--;
9034 +                       }
9035 +               } else if ((key >= '0' && key <= '9') ||
9036 +                          (key >= 'A' && key <= 'Z') ||
9037 +                          (key >= 'a' && key <= 'z')) {
9038 +                       if (len < sizeof entry_buf) {
9039 +                               entry_buf[len++] = key;
9040 +                               putchar(key);
9041 +                       }
9042 +               }
9043 +       } while (key != '\r');
9044 +       putchar('\n');
9045 +
9046 +       if (len == 0)
9047 +               return VIDEO_CURRENT_MODE; /* Default */
9048 +
9049 +       v = 0;
9050 +       for (i = 0; i < len; i++) {
9051 +               v <<= 4;
9052 +               key = entry_buf[i] | 0x20;
9053 +               v += (key > '9') ? key-'a'+10 : key-'0';
9054 +       }
9055 +
9056 +       return v;
9057 +}
9058 +
9059 +static void display_menu(void)
9060 +{
9061 +       struct card_info *card;
9062 +       struct mode_info *mi;
9063 +       char ch;
9064 +       int i;
9065 +
9066 +       puts("Mode:    COLSxROWS:\n");
9067 +
9068 +       ch = '0';
9069 +       for (card = video_cards; card < video_cards_end; card++) {
9070 +               mi = card->modes;
9071 +               for (i = 0; i < card->nmodes; i++, mi++) {
9072 +                       int visible = mi->x && mi->y;
9073 +                       u16 mode_id = mi->mode ? mi->mode :
9074 +                               (mi->y << 8)+mi->x;
9075 +
9076 +                       if (!visible)
9077 +                               continue; /* Hidden mode */
9078 +
9079 +                       printf("%c  %04X  %3dx%-3d  %s\n",
9080 +                              ch, mode_id, mi->x, mi->y, card->card_name);
9081 +
9082 +                       if (ch == '9')
9083 +                               ch = 'a';
9084 +                       else if (ch == 'z' || ch == ' ')
9085 +                               ch = ' '; /* Out of keys... */
9086 +                       else
9087 +                               ch++;
9088 +               }
9089 +       }
9090 +}
9091 +
9092 +#define H(x)   ((x)-'a'+10)
9093 +#define SCAN   ((H('s')<<12)+(H('c')<<8)+(H('a')<<4)+H('n'))
9094 +
9095 +static unsigned int mode_menu(void)
9096 +{
9097 +       int key;
9098 +       unsigned int sel;
9099 +
9100 +       puts("Press <ENTER> to see video modes available, "
9101 +            "<SPACE> to continue, or wait 30 sec\n");
9102 +
9103 +       kbd_flush();
9104 +       while (1) {
9105 +               key = getchar_timeout();
9106 +               if (key == ' ' || key == 0)
9107 +                       return VIDEO_CURRENT_MODE; /* Default */
9108 +               if (key == '\r')
9109 +                       break;
9110 +               putchar('\a');  /* Beep! */
9111 +       }
9112 +
9113 +
9114 +       for (;;) {
9115 +               display_menu();
9116 +
9117 +               puts("Enter a video mode or \"scan\" to scan for "
9118 +                    "additional modes: ");
9119 +               sel = get_entry();
9120 +               if (sel != SCAN)
9121 +                       return sel;
9122 +
9123 +               probe_cards(1);
9124 +       }
9125 +}
9126 +
9127 +#ifdef CONFIG_VIDEO_RETAIN
9128 +/* Save screen content to the heap */
9129 +struct saved_screen {
9130 +       int x, y;
9131 +       int curx, cury;
9132 +       u16 *data;
9133 +} saved;
9134 +
9135 +static void save_screen(void)
9136 +{
9137 +       /* Should be called after store_mode_params() */
9138 +       saved.x = boot_params.screen_info.orig_video_cols;
9139 +       saved.y = boot_params.screen_info.orig_video_lines;
9140 +       saved.curx = boot_params.screen_info.orig_x;
9141 +       saved.cury = boot_params.screen_info.orig_y;
9142 +
9143 +       if (heap_free() < saved.x*saved.y*sizeof(u16)+512)
9144 +               return;         /* Not enough heap to save the screen */
9145 +
9146 +       saved.data = GET_HEAP(u16, saved.x*saved.y);
9147 +
9148 +       set_fs(video_segment);
9149 +       copy_from_fs(saved.data, 0, saved.x*saved.y*sizeof(u16));
9150 +}
9151 +
9152 +static void restore_screen(void)
9153 +{
9154 +       /* Should be called after store_mode_params() */
9155 +       int xs = boot_params.screen_info.orig_video_cols;
9156 +       int ys = boot_params.screen_info.orig_video_lines;
9157 +       int y;
9158 +       addr_t dst = 0;
9159 +       u16 *src = saved.data;
9160 +       u16 ax, bx, dx;
9161 +
9162 +       if (graphic_mode)
9163 +               return;         /* Can't restore onto a graphic mode */
9164 +
9165 +       if (!src)
9166 +               return;         /* No saved screen contents */
9167 +
9168 +       /* Restore screen contents */
9169 +
9170 +       set_fs(video_segment);
9171 +       for (y = 0; y < ys; y++) {
9172 +               int npad;
9173 +
9174 +               if (y < saved.y) {
9175 +                       int copy = (xs < saved.x) ? xs : saved.x;
9176 +                       copy_to_fs(dst, src, copy*sizeof(u16));
9177 +                       dst += copy*sizeof(u16);
9178 +                       src += saved.x;
9179 +                       npad = (xs < saved.x) ? 0 : xs-saved.x;
9180 +               } else {
9181 +                       npad = xs;
9182 +               }
9183 +
9184 +               /* Writes "npad" blank characters to
9185 +                  video_segment:dst and advances dst */
9186 +               asm volatile("pushw %%es ; "
9187 +                            "movw %2,%%es ; "
9188 +                            "shrw %%cx ; "
9189 +                            "jnc 1f ; "
9190 +                            "stosw \n\t"
9191 +                            "1: rep;stosl ; "
9192 +                            "popw %%es"
9193 +                            : "+D" (dst), "+c" (npad)
9194 +                            : "bdSm" (video_segment),
9195 +                              "a" (0x07200720));
9196 +       }
9197 +
9198 +       /* Restore cursor position */
9199 +       ax = 0x0200;            /* Set cursor position */
9200 +       bx = 0;                 /* Page number (<< 8) */
9201 +       dx = (saved.cury << 8)+saved.curx;
9202 +       asm volatile(INT10
9203 +                    : "+a" (ax), "+b" (bx), "+d" (dx)
9204 +                    : : "ecx", "esi", "edi");
9205 +}
9206 +#else
9207 +#define save_screen()          ((void)0)
9208 +#define restore_screen()       ((void)0)
9209 +#endif
9210 +
9211 +void set_video(void)
9212 +{
9213 +       u16 mode = boot_params.hdr.vid_mode;
9214 +
9215 +       RESET_HEAP();
9216 +
9217 +       store_mode_params();
9218 +       save_screen();
9219 +       probe_cards(0);
9220 +
9221 +       for (;;) {
9222 +               if (mode == ASK_VGA)
9223 +                       mode = mode_menu();
9224 +
9225 +               if (!set_mode(mode))
9226 +                       break;
9227 +
9228 +               printf("Undefined video mode number: %x\n", mode);
9229 +               mode = ASK_VGA;
9230 +       }
9231 +       vesa_store_edid();
9232 +       store_mode_params();
9233 +
9234 +       if (do_restore)
9235 +               restore_screen();
9236 +}
9237 diff -puN /dev/null arch/i386/boot/video.h
9238 --- /dev/null
9239 +++ a/arch/i386/boot/video.h
9240 @@ -0,0 +1,145 @@
9241 +/* -*- linux-c -*- ------------------------------------------------------- *
9242 + *
9243 + *   Copyright (C) 1991, 1992 Linus Torvalds
9244 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
9245 + *
9246 + *   This file is part of the Linux kernel, and is made available under
9247 + *   the terms of the GNU General Public License version 2.
9248 + *
9249 + * ----------------------------------------------------------------------- */
9250 +
9251 +/*
9252 + * arch/i386/boot/video.h
9253 + *
9254 + * Header file for the real-mode video probing code
9255 + */
9256 +
9257 +#ifndef BOOT_VIDEO_H
9258 +#define BOOT_VIDEO_H
9259 +
9260 +#include <linux/types.h>
9261 +
9262 +/* Enable autodetection of SVGA adapters and modes. */
9263 +#undef CONFIG_VIDEO_SVGA
9264 +
9265 +/* Enable autodetection of VESA modes */
9266 +#define CONFIG_VIDEO_VESA
9267 +
9268 +/* Retain screen contents when switching modes */
9269 +#define CONFIG_VIDEO_RETAIN
9270 +
9271 +/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
9272 +#undef CONFIG_VIDEO_400_HACK
9273 +
9274 +/* This code uses an extended set of video mode numbers. These include:
9275 + * Aliases for standard modes
9276 + *      NORMAL_VGA (-1)
9277 + *      EXTENDED_VGA (-2)
9278 + *      ASK_VGA (-3)
9279 + * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
9280 + * of compatibility when extending the table. These are between 0x00 and 0xff.
9281 + */
9282 +#define VIDEO_FIRST_MENU 0x0000
9283 +
9284 +/* Standard BIOS video modes (BIOS number + 0x0100) */
9285 +#define VIDEO_FIRST_BIOS 0x0100
9286 +
9287 +/* VESA BIOS video modes (VESA number + 0x0200) */
9288 +#define VIDEO_FIRST_VESA 0x0200
9289 +
9290 +/* Video7 special modes (BIOS number + 0x0900) */
9291 +#define VIDEO_FIRST_V7 0x0900
9292 +
9293 +/* Special video modes */
9294 +#define VIDEO_FIRST_SPECIAL 0x0f00
9295 +#define VIDEO_80x25 0x0f00
9296 +#define VIDEO_8POINT 0x0f01
9297 +#define VIDEO_80x43 0x0f02
9298 +#define VIDEO_80x28 0x0f03
9299 +#define VIDEO_CURRENT_MODE 0x0f04
9300 +#define VIDEO_80x30 0x0f05
9301 +#define VIDEO_80x34 0x0f06
9302 +#define VIDEO_80x60 0x0f07
9303 +#define VIDEO_GFX_HACK 0x0f08
9304 +#define VIDEO_LAST_SPECIAL 0x0f09
9305 +
9306 +/* Video modes given by resolution */
9307 +#define VIDEO_FIRST_RESOLUTION 0x1000
9308 +
9309 +/* The "recalculate timings" flag */
9310 +#define VIDEO_RECALC 0x8000
9311 +
9312 +/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
9313 +#ifdef CONFIG_VIDEO_RETAIN
9314 +void store_screen(void);
9315 +#define DO_STORE() store_screen()
9316 +#else
9317 +#define DO_STORE() ((void)0)
9318 +#endif /* CONFIG_VIDEO_RETAIN */
9319 +
9320 +/*
9321 + * Mode table structures
9322 + */
9323 +
9324 +struct mode_info {
9325 +       u16 mode;               /* Mode number (vga= style) */
9326 +       u8  x, y;               /* Width, height */
9327 +};
9328 +
9329 +struct card_info {
9330 +       const char *card_name;
9331 +       int (*set_mode)(struct mode_info *mode);
9332 +       int (*probe)(void);
9333 +       struct mode_info *modes;
9334 +       int nmodes;             /* Number of probed modes so far */
9335 +       int unsafe;             /* Probing is unsafe, only do after "scan" */
9336 +       u16 xmode_first;        /* Unprobed modes to try to call anyway */
9337 +       u16 xmode_n;            /* Size of unprobed mode range */
9338 +};
9339 +
9340 +#define __videocard struct card_info __attribute__((section(".videocards")))
9341 +extern struct card_info video_cards[], video_cards_end[];
9342 +
9343 +int mode_defined(u16 mode);    /* video.c */
9344 +
9345 +/* Basic video information */
9346 +#define ADAPTER_CGA    0       /* CGA/MDA/HGC */
9347 +#define ADAPTER_EGA    1
9348 +#define ADAPTER_VGA    2
9349 +
9350 +extern int adapter;
9351 +extern u16 video_segment;
9352 +extern int force_x, force_y;   /* Don't query the BIOS for cols/rows */
9353 +extern int do_restore;         /* Restore screen contents */
9354 +extern int graphic_mode;       /* Graphics mode with linear frame buffer */
9355 +
9356 +/*
9357 + * int $0x10 is notorious for touching registers it shouldn't.
9358 + * gcc doesn't like %ebp being clobbered, so define it as a push/pop
9359 + * sequence here.
9360 + */
9361 +#define INT10 "pushl %%ebp; int $0x10; popl %%ebp"
9362 +
9363 +/* Accessing VGA indexed registers */
9364 +static inline u8 in_idx(u16 port, u8 index)
9365 +{
9366 +       outb(index, port);
9367 +       return inb(port+1);
9368 +}
9369 +
9370 +static inline void out_idx(u8 v, u16 port, u8 index)
9371 +{
9372 +       outw(index+(v << 8), port);
9373 +}
9374 +
9375 +/* Writes a value to an indexed port and then reads the port again */
9376 +static inline u8 tst_idx(u8 v, u16 port, u8 index)
9377 +{
9378 +       out_idx(port, index, v);
9379 +       return in_idx(port, index);
9380 +}
9381 +
9382 +/* Get the I/O port of the VGA CRTC */
9383 +u16 vga_crtc(void);            /* video-vga.c */
9384 +
9385 +#endif /* BOOT_VIDEO_H */
9386 diff -puN /dev/null arch/i386/boot/voyager.c
9387 --- /dev/null
9388 +++ a/arch/i386/boot/voyager.c
9389 @@ -0,0 +1,46 @@
9390 +/* -*- linux-c -*- ------------------------------------------------------- *
9391 + *
9392 + *   Copyright (C) 1991, 1992 Linus Torvalds
9393 + *   Copyright 2007 rPath, Inc. - All Rights Reserved
9394 + *
9395 + *   This file is part of the Linux kernel, and is made available under
9396 + *   the terms of the GNU General Public License version 2.
9397 + *
9398 + * ----------------------------------------------------------------------- */
9399 +
9400 +/*
9401 + * arch/i386/boot/voyager.c
9402 + *
9403 + * Get the Voyager config information
9404 + */
9405 +
9406 +#include "boot.h"
9407 +
9408 +#ifdef CONFIG_X86_VOYAGER
9409 +
9410 +int query_voyager(void)
9411 +{
9412 +       u8 err;
9413 +       u16 es, di;
9414 +       /* Abuse the apm_bios_info area for this */
9415 +       u8 *data_ptr = (u8 *)&boot_params.apm_bios_info;
9416 +
9417 +       data_ptr[0] = 0xff;     /* Flag on config not found(?) */
9418 +
9419 +       asm("pushw %%es ; "
9420 +           "int $0x15 ; "
9421 +           "setc %0 ; "
9422 +           "movw %%es, %1 ; "
9423 +           "popw %%es"
9424 +           : "=qm" (err), "=rm" (es), "=D" (di)
9425 +           : "a" (0xffc0));
9426 +
9427 +       if (err)
9428 +               return -1;      /* Not Voyager */
9429 +
9430 +       set_fs(es);
9431 +       copy_from_fs(data_ptr, di, 7);  /* Table is 7 bytes apparently */
9432 +       return 0;
9433 +}
9434 +
9435 +#endif /* CONFIG_X86_VOYAGER */
9436 diff -puN arch/i386/kernel/cpu/Makefile~git-newsetup arch/i386/kernel/cpu/Makefile
9437 diff -puN /dev/null arch/i386/kernel/cpu/addon_cpuid_features.c
9438 --- /dev/null
9439 +++ a/arch/i386/kernel/cpu/addon_cpuid_features.c
9440 @@ -0,0 +1,50 @@
9441 +
9442 +/*
9443 + *     Routines to indentify additional cpu features that are scattered in
9444 + *     cpuid space.
9445 + */
9446 +
9447 +#include <linux/cpu.h>
9448 +
9449 +#include <asm/processor.h>
9450 +
9451 +struct cpuid_bit {
9452 +       u16 feature;
9453 +       u8 reg;
9454 +       u8 bit;
9455 +       u32 level;
9456 +};
9457 +
9458 +enum cpuid_regs {
9459 +       CR_EAX = 0,
9460 +       CR_ECX,
9461 +       CR_EDX,
9462 +       CR_EBX
9463 +};
9464 +
9465 +void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
9466 +{
9467 +       u32 max_level;
9468 +       u32 regs[4];
9469 +       const struct cpuid_bit *cb;
9470 +
9471 +       static const struct cpuid_bit cpuid_bits[] = {
9472 +               { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
9473 +               { 0, 0, 0, 0 }
9474 +       };
9475 +
9476 +       for (cb = cpuid_bits; cb->feature; cb++) {
9477 +
9478 +               /* Verify that the level is valid */
9479 +               max_level = cpuid_eax(cb->level & 0xffff0000);
9480 +               if (max_level < cb->level ||
9481 +                   max_level > (cb->level | 0xffff))
9482 +                       continue;
9483 +
9484 +               cpuid(cb->level, &regs[CR_EAX], &regs[CR_EBX],
9485 +                       &regs[CR_ECX], &regs[CR_EDX]);
9486 +
9487 +               if (regs[cb->reg] & (1 << cb->bit))
9488 +                       set_bit(cb->feature, c->x86_capability);
9489 +       }
9490 +}
9491 diff -puN arch/i386/kernel/cpu/common.c~git-newsetup arch/i386/kernel/cpu/common.c
9492 --- a/arch/i386/kernel/cpu/common.c~git-newsetup
9493 +++ a/arch/i386/kernel/cpu/common.c
9494 @@ -353,6 +353,8 @@ static void __cpuinit generic_identify(s
9495                         if ( xlvl >= 0x80000004 )
9496                                 get_model_name(c); /* Default name */
9497                 }
9498 +
9499 +               init_scattered_cpuid_features(c);
9500         }
9501  
9502         early_intel_workaround(c);
9503 diff -puN arch/i386/kernel/cpu/proc.c~git-newsetup arch/i386/kernel/cpu/proc.c
9504 --- a/arch/i386/kernel/cpu/proc.c~git-newsetup
9505 +++ a/arch/i386/kernel/cpu/proc.c
9506 @@ -29,7 +29,8 @@ static int show_cpuinfo(struct seq_file 
9507                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
9508                 NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
9509                 NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
9510 -               NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext", "3dnow",
9511 +               NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm",
9512 +               "3dnowext", "3dnow",
9513  
9514                 /* Transmeta-defined */
9515                 "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
9516 @@ -40,8 +41,9 @@ static int show_cpuinfo(struct seq_file 
9517                 /* Other (Linux-defined) */
9518                 "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
9519                 NULL, NULL, NULL, NULL,
9520 -               "constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL,
9521 -               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
9522 +               "constant_tsc", "up", NULL, "arch_perfmon",
9523 +               "pebs", "bts", NULL, "sync_rdtsc",
9524 +               "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
9525                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
9526  
9527                 /* Intel-defined (#2) */
9528 @@ -57,9 +59,16 @@ static int show_cpuinfo(struct seq_file 
9529                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
9530  
9531                 /* AMD-defined (#2) */
9532 -               "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8legacy", "abm",
9533 -               "sse4a", "misalignsse",
9534 -               "3dnowprefetch", "osvw", "ibs", NULL, NULL, NULL, NULL, NULL,
9535 +               "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8_legacy",
9536 +               "altmovcr8", "abm", "sse4a",
9537 +               "misalignsse", "3dnowprefetch",
9538 +               "osvw", "ibs", NULL, NULL, NULL, NULL,
9539 +               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
9540 +               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
9541 +
9542 +               /* Auxiliary (Linux-defined) */
9543 +               "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
9544 +               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
9545                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
9546                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
9547         };
9548 diff -puN arch/i386/kernel/e820.c~git-newsetup arch/i386/kernel/e820.c
9549 --- a/arch/i386/kernel/e820.c~git-newsetup
9550 +++ a/arch/i386/kernel/e820.c
9551 @@ -766,7 +766,7 @@ void __init print_memory_map(char *who)
9552                 case E820_NVS:
9553                                 printk("(ACPI NVS)\n");
9554                                 break;
9555 -               default:        printk("type %lu\n", e820.map[i].type);
9556 +               default:        printk("type %u\n", e820.map[i].type);
9557                                 break;
9558                 }
9559         }
9560 diff -puN arch/i386/kernel/setup.c~git-newsetup arch/i386/kernel/setup.c
9561 --- a/arch/i386/kernel/setup.c~git-newsetup
9562 +++ a/arch/i386/kernel/setup.c
9563 @@ -102,19 +102,10 @@ static unsigned int highmem_pages = -1;
9564  /*
9565   * Setup options
9566   */
9567 -struct drive_info_struct { char dummy[32]; } drive_info;
9568 -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
9569 -    defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
9570 -EXPORT_SYMBOL(drive_info);
9571 -#endif
9572  struct screen_info screen_info;
9573  EXPORT_SYMBOL(screen_info);
9574  struct apm_info apm_info;
9575  EXPORT_SYMBOL(apm_info);
9576 -struct sys_desc_table_struct {
9577 -       unsigned short length;
9578 -       unsigned char table[0];
9579 -};
9580  struct edid_info edid_info;
9581  EXPORT_SYMBOL_GPL(edid_info);
9582  struct ist_info ist_info;
9583 @@ -134,7 +125,7 @@ unsigned long saved_videomode;
9584  
9585  static char __initdata command_line[COMMAND_LINE_SIZE];
9586  
9587 -unsigned char __initdata boot_params[PARAM_SIZE];
9588 +struct boot_params __initdata boot_params;
9589  
9590  #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
9591  struct edd edd;
9592 @@ -528,7 +519,6 @@ void __init setup_arch(char **cmdline_p)
9593  #endif
9594  
9595         ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
9596 -       drive_info = DRIVE_INFO;
9597         screen_info = SCREEN_INFO;
9598         edid_info = EDID_INFO;
9599         apm_info.bios = APM_BIOS_INFO;
9600 diff -puN arch/i386/kernel/verify_cpu.S~git-newsetup /dev/null
9601 --- a/arch/i386/kernel/verify_cpu.S
9602 +++ /dev/null
9603 @@ -1,94 +0,0 @@
9604 -/* Check if CPU has some minimum CPUID bits
9605 -   This runs in 16bit mode so that the caller can still use the BIOS
9606 -   to output errors on the screen */
9607 -#include <asm/cpufeature.h>
9608 -#include <asm/msr.h>
9609 -
9610 -verify_cpu:
9611 -       pushfl                          # Save caller passed flags
9612 -       pushl   $0                      # Kill any dangerous flags
9613 -       popfl
9614 -
9615 -#if CONFIG_X86_MINIMUM_CPU_MODEL >= 4
9616 -       pushfl
9617 -       pop     %eax
9618 -       orl     $(1<<18),%eax           # try setting AC
9619 -       push    %eax
9620 -       popfl
9621 -       pushfl
9622 -       popl    %eax
9623 -       testl   $(1<<18),%eax
9624 -       jz      bad
9625 -#endif
9626 -#if REQUIRED_MASK1 != 0
9627 -       pushfl                          # standard way to check for cpuid
9628 -       popl    %eax
9629 -       movl    %eax,%ebx
9630 -       xorl    $0x200000,%eax
9631 -       pushl   %eax
9632 -       popfl
9633 -       pushfl
9634 -       popl    %eax
9635 -       cmpl    %eax,%ebx
9636 -       pushfl                          # standard way to check for cpuid
9637 -       popl    %eax
9638 -       movl    %eax,%ebx
9639 -       xorl    $0x200000,%eax
9640 -       pushl   %eax
9641 -       popfl
9642 -       pushfl
9643 -       popl    %eax
9644 -       cmpl    %eax,%ebx
9645 -       jz      bad                     # REQUIRED_MASK1 != 0 requires CPUID
9646 -
9647 -       movl    $0x0,%eax               # See if cpuid 1 is implemented
9648 -       cpuid
9649 -       cmpl    $0x1,%eax
9650 -       jb      bad                     # no cpuid 1
9651 -
9652 -#if REQUIRED_MASK1 & NEED_CMPXCHG64
9653 -       /* Some VIA C3s need magic MSRs to enable CX64. Do this here */
9654 -       cmpl    $0x746e6543,%ebx        # Cent
9655 -       jne     1f
9656 -       cmpl    $0x48727561,%edx        # aurH
9657 -       jne     1f
9658 -       cmpl    $0x736c7561,%ecx        # auls
9659 -       jne     1f
9660 -       movl    $1,%eax                 # check model
9661 -       cpuid
9662 -       movl    %eax,%ebx
9663 -       shr     $8,%ebx
9664 -       andl    $0xf,%ebx
9665 -       cmp     $6,%ebx                 # check family == 6
9666 -       jne     1f
9667 -       shr     $4,%eax
9668 -       andl    $0xf,%eax
9669 -       cmpl    $6,%eax                 # check model >= 6
9670 -       jb      1f
9671 -       # assume models >= 6 all support this MSR
9672 -       movl    $MSR_VIA_FCR,%ecx
9673 -       rdmsr
9674 -       orl     $((1<<1)|(1<<7)),%eax   # enable CMPXCHG64 and PGE
9675 -       wrmsr
9676 -1:
9677 -#endif
9678 -       movl    $0x1,%eax               # Does the cpu have what it takes
9679 -       cpuid
9680 -
9681 -#if CONFIG_X86_MINIMUM_CPU_MODEL > 4
9682 -#error add proper model checking here
9683 -#endif
9684 -
9685 -       andl    $REQUIRED_MASK1,%edx
9686 -       xorl    $REQUIRED_MASK1,%edx
9687 -       jnz     bad
9688 -#endif /* REQUIRED_MASK1 */
9689 -
9690 -       popfl
9691 -       xor     %eax,%eax
9692 -       ret
9693 -
9694 -bad:
9695 -       popfl
9696 -       movl    $1,%eax
9697 -       ret
9698 diff -puN arch/x86_64/Kconfig~git-newsetup arch/x86_64/Kconfig
9699 --- a/arch/x86_64/Kconfig~git-newsetup
9700 +++ a/arch/x86_64/Kconfig
9701 @@ -453,6 +453,10 @@ config NR_CPUS
9702           This is purely to save memory - each supported CPU requires
9703           memory in the static kernel configuration.
9704  
9705 +config PHYSICAL_ALIGN
9706 +       hex
9707 +       default "0x200000"
9708 +
9709  config HOTPLUG_CPU
9710         bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
9711         depends on SMP && HOTPLUG && EXPERIMENTAL
9712 diff -puN arch/x86_64/boot/Makefile~git-newsetup arch/x86_64/boot/Makefile
9713 --- a/arch/x86_64/boot/Makefile~git-newsetup
9714 +++ a/arch/x86_64/boot/Makefile
9715 @@ -1,135 +1,9 @@
9716  #
9717  # arch/x86_64/boot/Makefile
9718  #
9719 -# This file is subject to the terms and conditions of the GNU General Public
9720 -# License.  See the file "COPYING" in the main directory of this archive
9721 -# for more details.
9722 -#
9723 -# Copyright (C) 1994 by Linus Torvalds
9724 -#
9725 -
9726 -# ROOT_DEV specifies the default root-device when making the image.
9727 -# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
9728 -# the default of FLOPPY is used by 'build'.
9729 -
9730 -ROOT_DEV := CURRENT
9731 -
9732 -# If you want to preset the SVGA mode, uncomment the next line and
9733 -# set SVGA_MODE to whatever number you want.
9734 -# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
9735 -# The number is the same as you would ordinarily press at bootup.
9736 -
9737 -SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
9738 -
9739 -# If you want the RAM disk device, define this to be the size in blocks.
9740 -
9741 -#RAMDISK := -DRAMDISK=512
9742 -
9743 -targets                := vmlinux.bin bootsect bootsect.o \
9744 -                  setup setup.o bzImage mtools.conf
9745 -
9746 -EXTRA_CFLAGS := -m32
9747 -
9748 -hostprogs-y    := tools/build
9749 -HOST_EXTRACFLAGS += $(LINUXINCLUDE)
9750 -subdir-                := compressed/  #Let make clean descend in compressed/
9751 -# ---------------------------------------------------------------------------
9752 -
9753 -$(obj)/bzImage: IMAGE_OFFSET := 0x100000
9754 -$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
9755 -$(obj)/bzImage: BUILDFLAGS   := -b
9756 -
9757 -quiet_cmd_image = BUILD   $@
9758 -cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
9759 -           $(obj)/vmlinux.bin $(ROOT_DEV) > $@
9760 -
9761 -$(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
9762 -                             $(obj)/vmlinux.bin $(obj)/tools/build FORCE
9763 -       $(call if_changed,image)
9764 -       @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
9765 -
9766 -$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
9767 -       $(call if_changed,objcopy)
9768 -
9769 -LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
9770 -LDFLAGS_setup   := -Ttext 0x0 -s --oformat binary -e begtext
9771 -
9772 -$(obj)/setup $(obj)/bootsect: %: %.o FORCE
9773 -       $(call if_changed,ld)
9774 -
9775 -$(obj)/compressed/vmlinux: FORCE
9776 -       $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
9777 -
9778 -# Set this if you want to pass append arguments to the zdisk/fdimage/isoimage kernel
9779 -FDARGS = 
9780 -# Set this if you want an initrd included with the zdisk/fdimage/isoimage kernel
9781 -FDINITRD =
9782 -
9783 -image_cmdline = default linux $(FDARGS) $(if $(FDINITRD),initrd=initrd.img,)
9784 -
9785 -$(obj)/mtools.conf: $(src)/mtools.conf.in
9786 -       sed -e 's|@OBJ@|$(obj)|g' < $< > $@
9787 -
9788 -# This requires write access to /dev/fd0
9789 -zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
9790 -       MTOOLSRC=$(obj)/mtools.conf mformat a:                  ; sync
9791 -       syslinux /dev/fd0                                       ; sync
9792 -       echo '$(image_cmdline)' | \
9793 -               MTOOLSRC=$(obj)/mtools.conf mcopy - a:syslinux.cfg
9794 -       if [ -f '$(FDINITRD)' ] ; then \
9795 -               MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' a:initrd.img ; \
9796 -       fi
9797 -       MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux  ; sync
9798 -
9799 -# These require being root or having syslinux 2.02 or higher installed
9800 -fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf
9801 -       dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440
9802 -       MTOOLSRC=$(obj)/mtools.conf mformat v:                  ; sync
9803 -       syslinux $(obj)/fdimage                                 ; sync
9804 -       echo '$(image_cmdline)' | \
9805 -               MTOOLSRC=$(obj)/mtools.conf mcopy - v:syslinux.cfg
9806 -       if [ -f '$(FDINITRD)' ] ; then \
9807 -               MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' v:initrd.img ; \
9808 -       fi
9809 -       MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux  ; sync
9810 -
9811 -fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf
9812 -       dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880
9813 -       MTOOLSRC=$(obj)/mtools.conf mformat w:                  ; sync
9814 -       syslinux $(obj)/fdimage                                 ; sync
9815 -       echo '$(image_cmdline)' | \
9816 -               MTOOLSRC=$(obj)/mtools.conf mcopy - w:syslinux.cfg
9817 -       if [ -f '$(FDINITRD)' ] ; then \
9818 -               MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' w:initrd.img ; \
9819 -       fi
9820 -       MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux  ; sync
9821 -
9822 -isoimage: $(BOOTIMAGE)
9823 -       -rm -rf $(obj)/isoimage
9824 -       mkdir $(obj)/isoimage
9825 -       for i in lib lib64 share end ; do \
9826 -               if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
9827 -                       cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
9828 -                       break ; \
9829 -               fi ; \
9830 -               if [ $$i = end ] ; then exit 1 ; fi ; \
9831 -       done
9832 -       cp $(BOOTIMAGE) $(obj)/isoimage/linux
9833 -       echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg
9834 -       if [ -f '$(FDINITRD)' ] ; then \
9835 -               cp '$(FDINITRD)' $(obj)/isoimage/initrd.img ; \
9836 -       fi
9837 -       mkisofs -J -r -o $(obj)/image.iso -b isolinux.bin -c boot.cat \
9838 -               -no-emul-boot -boot-load-size 4 -boot-info-table \
9839 -               $(obj)/isoimage
9840 -       rm -rf $(obj)/isoimage
9841 -
9842 -zlilo: $(BOOTIMAGE)
9843 -       if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
9844 -       if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
9845 -       cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
9846 -       cp System.map $(INSTALL_PATH)/
9847 -       if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
9848 +# The actual boot code is shared with i386 including the Makefile.
9849 +# So tell kbuild that we fetch the code from i386 and include the
9850 +# Makefile from i386 too.
9851  
9852 -install:
9853 -       sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
9854 +src := arch/i386/boot
9855 +include $(src)/Makefile
9856 diff -puN arch/x86_64/boot/bootsect.S~git-newsetup /dev/null
9857 --- a/arch/x86_64/boot/bootsect.S
9858 +++ /dev/null
9859 @@ -1,98 +0,0 @@
9860 -/*
9861 - *     bootsect.S              Copyright (C) 1991, 1992 Linus Torvalds
9862 - *
9863 - *     modified by Drew Eckhardt
9864 - *     modified by Bruce Evans (bde)
9865 - *     modified by Chris Noe (May 1999) (as86 -> gas)
9866 - *     gutted by H. Peter Anvin (Jan 2003)
9867 - *
9868 - * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
9869 - * addresses must be multiplied by 16 to obtain their respective linear
9870 - * addresses. To avoid confusion, linear addresses are written using leading
9871 - * hex while segment addresses are written as segment:offset.
9872 - *
9873 - */
9874 -
9875 -#include <asm/boot.h>
9876 -
9877 -SETUPSECTS     = 4                     /* default nr of setup-sectors */
9878 -BOOTSEG                = 0x07C0                /* original address of boot-sector */
9879 -INITSEG                = DEF_INITSEG           /* we move boot here - out of the way */
9880 -SETUPSEG       = DEF_SETUPSEG          /* setup starts here */
9881 -SYSSEG         = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
9882 -SYSSIZE                = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
9883 -                                       /* to be loaded */
9884 -ROOT_DEV       = 0                     /* ROOT_DEV is now written by "build" */
9885 -SWAP_DEV       = 0                     /* SWAP_DEV is now written by "build" */
9886 -
9887 -#ifndef SVGA_MODE
9888 -#define SVGA_MODE ASK_VGA
9889 -#endif
9890 -
9891 -#ifndef RAMDISK
9892 -#define RAMDISK 0
9893 -#endif
9894 -
9895 -#ifndef ROOT_RDONLY
9896 -#define ROOT_RDONLY 1
9897 -#endif
9898 -
9899 -.code16
9900 -.text
9901 -
9902 -.global _start
9903 -_start:
9904 -
9905 -       # Normalize the start address
9906 -       jmpl    $BOOTSEG, $start2
9907 -
9908 -start2:
9909 -       movw    %cs, %ax
9910 -       movw    %ax, %ds
9911 -       movw    %ax, %es
9912 -       movw    %ax, %ss
9913 -       movw    $0x7c00, %sp
9914 -       sti
9915 -       cld
9916 -
9917 -       movw    $bugger_off_msg, %si
9918 -
9919 -msg_loop:
9920 -       lodsb
9921 -       andb    %al, %al
9922 -       jz      die
9923 -       movb    $0xe, %ah
9924 -       movw    $7, %bx
9925 -       int     $0x10
9926 -       jmp     msg_loop
9927 -
9928 -die:
9929 -       # Allow the user to press a key, then reboot
9930 -       xorw    %ax, %ax
9931 -       int     $0x16
9932 -       int     $0x19
9933 -
9934 -       # int 0x19 should never return.  In case it does anyway,
9935 -       # invoke the BIOS reset code...
9936 -       ljmp    $0xf000,$0xfff0
9937 -
9938 -
9939 -bugger_off_msg:
9940 -       .ascii  "Direct booting from floppy is no longer supported.\r\n"
9941 -       .ascii  "Please use a boot loader program instead.\r\n"
9942 -       .ascii  "\n"
9943 -       .ascii  "Remove disk and press any key to reboot . . .\r\n"
9944 -       .byte   0
9945 -
9946 -
9947 -       # Kernel attributes; used by setup
9948 -
9949 -       .org 497
9950 -setup_sects:   .byte SETUPSECTS
9951 -root_flags:    .word ROOT_RDONLY
9952 -syssize:       .word SYSSIZE
9953 -swap_dev:      .word SWAP_DEV
9954 -ram_size:      .word RAMDISK
9955 -vid_mode:      .word SVGA_MODE
9956 -root_dev:      .word ROOT_DEV
9957 -boot_flag:     .word 0xAA55
9958 diff -puN arch/x86_64/boot/compressed/Makefile~git-newsetup arch/x86_64/boot/compressed/Makefile
9959 --- a/arch/x86_64/boot/compressed/Makefile~git-newsetup
9960 +++ a/arch/x86_64/boot/compressed/Makefile
9961 @@ -7,11 +7,12 @@
9962  #
9963  
9964  targets                := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
9965 -EXTRA_AFLAGS   := -traditional
9966  
9967 -# cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with
9968 -# -m32
9969 -CFLAGS := -m64 -D__KERNEL__ -Iinclude -O2  -fno-strict-aliasing -fPIC -mcmodel=small -fno-builtin
9970 +CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2  \
9971 +         -fno-strict-aliasing -fPIC -mcmodel=small \
9972 +          $(call cc-option, -ffreestanding) \
9973 +          $(call cc-option, -fno-stack-protector)
9974 +AFLAGS  := $(CFLAGS) -D__ASSEMBLY__
9975  LDFLAGS := -m elf_x86_64
9976  
9977  LDFLAGS_vmlinux := -T
9978 diff -puN arch/x86_64/boot/compressed/head.S~git-newsetup arch/x86_64/boot/compressed/head.S
9979 --- a/arch/x86_64/boot/compressed/head.S~git-newsetup
9980 +++ a/arch/x86_64/boot/compressed/head.S
9981 @@ -46,10 +46,10 @@ startup_32:
9982   * at and where we were actually loaded at.  This can only be done
9983   * with a short local call on x86.  Nothing  else will tell us what
9984   * address we are running at.  The reserved chunk of the real-mode
9985 - * data at 0x34-0x3f are used as the stack for this calculation.
9986 - * Only 4 bytes are needed.
9987 + * data at 0x1e4 (defined as a scratch field) are used as the stack
9988 + * for this calculation. Only 4 bytes are needed.
9989   */
9990 -       leal    0x40(%esi), %esp
9991 +       leal    (0x1e4+4)(%esi), %esp
9992         call    1f
9993  1:     popl    %ebp
9994         subl    $1b, %ebp
9995 diff -puN arch/x86_64/boot/install.sh~git-newsetup /dev/null
9996 --- a/arch/x86_64/boot/install.sh
9997 +++ /dev/null
9998 @@ -1,2 +0,0 @@
9999 -#!/bin/sh
10000 -. $srctree/arch/i386/boot/install.sh
10001 diff -puN arch/x86_64/boot/mtools.conf.in~git-newsetup /dev/null
10002 --- a/arch/x86_64/boot/mtools.conf.in
10003 +++ /dev/null
10004 @@ -1,17 +0,0 @@
10005 -#
10006 -# mtools configuration file for "make (b)zdisk"
10007 -#
10008 -
10009 -# Actual floppy drive
10010 -drive a:
10011 -  file="/dev/fd0"
10012 -
10013 -# 1.44 MB floppy disk image
10014 -drive v:
10015 -  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=18 filter
10016 -
10017 -# 2.88 MB floppy disk image (mostly for virtual uses)
10018 -drive w:
10019 -  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=36 filter
10020 -
10021 -
10022 diff -puN arch/x86_64/boot/setup.S~git-newsetup /dev/null
10023 --- a/arch/x86_64/boot/setup.S
10024 +++ /dev/null
10025 @@ -1,826 +0,0 @@
10026 -/*
10027 - *     setup.S         Copyright (C) 1991, 1992 Linus Torvalds
10028 - *
10029 - * setup.s is responsible for getting the system data from the BIOS,
10030 - * and putting them into the appropriate places in system memory.
10031 - * both setup.s and system has been loaded by the bootblock.
10032 - *
10033 - * This code asks the bios for memory/disk/other parameters, and
10034 - * puts them in a "safe" place: 0x90000-0x901FF, ie where the
10035 - * boot-block used to be. It is then up to the protected mode
10036 - * system to read them from there before the area is overwritten
10037 - * for buffer-blocks.
10038 - *
10039 - * Move PS/2 aux init code to psaux.c
10040 - * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
10041 - *
10042 - * some changes and additional features by Christoph Niemann,
10043 - * March 1993/June 1994 (Christoph.Niemann@linux.org)
10044 - *
10045 - * add APM BIOS checking by Stephen Rothwell, May 1994
10046 - * (sfr@canb.auug.org.au)
10047 - *
10048 - * High load stuff, initrd support and position independency
10049 - * by Hans Lermen & Werner Almesberger, February 1996
10050 - * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
10051 - *
10052 - * Video handling moved to video.S by Martin Mares, March 1996
10053 - * <mj@k332.feld.cvut.cz>
10054 - *
10055 - * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
10056 - * parsons) to avoid loadlin confusion, July 1997
10057 - *
10058 - * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
10059 - * <stiker@northlink.com>
10060 - *
10061 - * Fix to work around buggy BIOSes which don't use carry bit correctly
10062 - * and/or report extended memory in CX/DX for e801h memory size detection 
10063 - * call.  As a result the kernel got wrong figures.  The int15/e801h docs
10064 - * from Ralf Brown interrupt list seem to indicate AX/BX should be used
10065 - * anyway.  So to avoid breaking many machines (presumably there was a reason
10066 - * to orginally use CX/DX instead of AX/BX), we do a kludge to see
10067 - * if CX/DX have been changed in the e801 call and if so use AX/BX .
10068 - * Michael Miller, April 2001 <michaelm@mjmm.org>
10069 - *
10070 - * Added long mode checking and SSE force. March 2003, Andi Kleen.             
10071 - */
10072 -
10073 -#include <asm/segment.h>
10074 -#include <linux/utsrelease.h>
10075 -#include <linux/compile.h>
10076 -#include <asm/boot.h>
10077 -#include <asm/e820.h>
10078 -#include <asm/page.h>
10079 -#include <asm/setup.h>
10080 -
10081 -/* Signature words to ensure LILO loaded us right */
10082 -#define SIG1   0xAA55
10083 -#define SIG2   0x5A5A
10084 -
10085 -INITSEG  = DEF_INITSEG         # 0x9000, we move boot here, out of the way
10086 -SYSSEG   = DEF_SYSSEG          # 0x1000, system loaded at 0x10000 (65536).
10087 -SETUPSEG = DEF_SETUPSEG                # 0x9020, this is the current segment
10088 -                               # ... and the former contents of CS
10089 -
10090 -DELTA_INITSEG = SETUPSEG - INITSEG     # 0x0020
10091 -
10092 -.code16
10093 -.globl begtext, begdata, begbss, endtext, enddata, endbss
10094 -
10095 -.text
10096 -begtext:
10097 -.data
10098 -begdata:
10099 -.bss
10100 -begbss:
10101 -.text
10102 -
10103 -start:
10104 -       jmp     trampoline
10105 -
10106 -# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
10107 -
10108 -               .ascii  "HdrS"          # header signature
10109 -               .word   0x0206          # header version number (>= 0x0105)
10110 -                                       # or else old loadlin-1.5 will fail)
10111 -realmode_swtch:        .word   0, 0            # default_switch, SETUPSEG
10112 -start_sys_seg: .word   SYSSEG
10113 -               .word   kernel_version  # pointing to kernel version string
10114 -                                       # above section of header is compatible
10115 -                                       # with loadlin-1.5 (header v1.5). Don't
10116 -                                       # change it.
10117 -
10118 -type_of_loader:        .byte   0               # = 0, old one (LILO, Loadlin,
10119 -                                       #      Bootlin, SYSLX, bootsect...)
10120 -                                       # See Documentation/i386/boot.txt for
10121 -                                       # assigned ids
10122 -       
10123 -# flags, unused bits must be zero (RFU) bit within loadflags
10124 -loadflags:
10125 -LOADED_HIGH    = 1                     # If set, the kernel is loaded high
10126 -CAN_USE_HEAP   = 0x80                  # If set, the loader also has set
10127 -                                       # heap_end_ptr to tell how much
10128 -                                       # space behind setup.S can be used for
10129 -                                       # heap purposes.
10130 -                                       # Only the loader knows what is free
10131 -#ifndef __BIG_KERNEL__
10132 -               .byte   0
10133 -#else
10134 -               .byte   LOADED_HIGH
10135 -#endif
10136 -
10137 -setup_move_size: .word  0x8000         # size to move, when setup is not
10138 -                                       # loaded at 0x90000. We will move setup 
10139 -                                       # to 0x90000 then just before jumping
10140 -                                       # into the kernel. However, only the
10141 -                                       # loader knows how much data behind
10142 -                                       # us also needs to be loaded.
10143 -
10144 -code32_start:                          # here loaders can put a different
10145 -                                       # start address for 32-bit code.
10146 -#ifndef __BIG_KERNEL__
10147 -               .long   0x1000          #   0x1000 = default for zImage
10148 -#else
10149 -               .long   0x100000        # 0x100000 = default for big kernel
10150 -#endif
10151 -
10152 -ramdisk_image: .long   0               # address of loaded ramdisk image
10153 -                                       # Here the loader puts the 32-bit
10154 -                                       # address where it loaded the image.
10155 -                                       # This only will be read by the kernel.
10156 -
10157 -ramdisk_size:  .long   0               # its size in bytes
10158 -
10159 -bootsect_kludge:
10160 -               .long   0               # obsolete
10161 -
10162 -heap_end_ptr:  .word   modelist+1024   # (Header version 0x0201 or later)
10163 -                                       # space from here (exclusive) down to
10164 -                                       # end of setup code can be used by setup
10165 -                                       # for local heap purposes.
10166 -
10167 -pad1:          .word   0
10168 -cmd_line_ptr:  .long 0                 # (Header version 0x0202 or later)
10169 -                                       # If nonzero, a 32-bit pointer
10170 -                                       # to the kernel command line.
10171 -                                       # The command line should be
10172 -                                       # located between the start of
10173 -                                       # setup and the end of low
10174 -                                       # memory (0xa0000), or it may
10175 -                                       # get overwritten before it
10176 -                                       # gets read.  If this field is
10177 -                                       # used, there is no longer
10178 -                                       # anything magical about the
10179 -                                       # 0x90000 segment; the setup
10180 -                                       # can be located anywhere in
10181 -                                       # low memory 0x10000 or higher.
10182 -
10183 -ramdisk_max:   .long 0xffffffff
10184 -kernel_alignment:  .long 0x200000       # physical addr alignment required for
10185 -                                       # protected mode relocatable kernel
10186 -#ifdef CONFIG_RELOCATABLE
10187 -relocatable_kernel:    .byte 1
10188 -#else
10189 -relocatable_kernel:    .byte 0
10190 -#endif
10191 -pad2:                  .byte 0
10192 -pad3:                  .word 0
10193 -
10194 -cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
10195 -                                                #added with boot protocol
10196 -                                                #version 2.06
10197 -
10198 -trampoline:    call    start_of_setup
10199 -               .align 16
10200 -                                       # The offset at this point is 0x240
10201 -               .space  (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
10202 -# End of setup header #####################################################
10203 -
10204 -start_of_setup:
10205 -# Bootlin depends on this being done early
10206 -       movw    $0x01500, %ax
10207 -       movb    $0x81, %dl
10208 -       int     $0x13
10209 -
10210 -#ifdef SAFE_RESET_DISK_CONTROLLER
10211 -# Reset the disk controller.
10212 -       movw    $0x0000, %ax
10213 -       movb    $0x80, %dl
10214 -       int     $0x13
10215 -#endif
10216 -
10217 -# Set %ds = %cs, we know that SETUPSEG = %cs at this point
10218 -       movw    %cs, %ax                # aka SETUPSEG
10219 -       movw    %ax, %ds
10220 -# Check signature at end of setup
10221 -       cmpw    $SIG1, setup_sig1
10222 -       jne     bad_sig
10223 -
10224 -       cmpw    $SIG2, setup_sig2
10225 -       jne     bad_sig
10226 -
10227 -       jmp     good_sig1
10228 -
10229 -# Routine to print asciiz string at ds:si
10230 -prtstr:
10231 -       lodsb
10232 -       andb    %al, %al
10233 -       jz      fin
10234 -
10235 -       call    prtchr
10236 -       jmp     prtstr
10237 -
10238 -fin:   ret
10239 -
10240 -# Space printing
10241 -prtsp2:        call    prtspc          # Print double space
10242 -prtspc:        movb    $0x20, %al      # Print single space (note: fall-thru)
10243 -
10244 -prtchr:        
10245 -       pushw   %ax
10246 -       pushw   %cx
10247 -       movw    $0007,%bx
10248 -       movw    $0x01, %cx
10249 -       movb    $0x0e, %ah
10250 -       int     $0x10
10251 -       popw    %cx
10252 -       popw    %ax
10253 -       ret
10254 -
10255 -beep:  movb    $0x07, %al
10256 -       jmp     prtchr
10257 -       
10258 -no_sig_mess: .string   "No setup signature found ..."
10259 -
10260 -good_sig1:
10261 -       jmp     good_sig
10262 -
10263 -# We now have to find the rest of the setup code/data
10264 -bad_sig:
10265 -       movw    %cs, %ax                        # SETUPSEG
10266 -       subw    $DELTA_INITSEG, %ax             # INITSEG
10267 -       movw    %ax, %ds
10268 -       xorb    %bh, %bh
10269 -       movb    (497), %bl                      # get setup sect from bootsect
10270 -       subw    $4, %bx                         # LILO loads 4 sectors of setup
10271 -       shlw    $8, %bx                         # convert to words (1sect=2^8 words)
10272 -       movw    %bx, %cx
10273 -       shrw    $3, %bx                         # convert to segment
10274 -       addw    $SYSSEG, %bx
10275 -       movw    %bx, %cs:start_sys_seg
10276 -# Move rest of setup code/data to here
10277 -       movw    $2048, %di                      # four sectors loaded by LILO
10278 -       subw    %si, %si
10279 -       movw    %cs, %ax                        # aka SETUPSEG
10280 -       movw    %ax, %es
10281 -       movw    $SYSSEG, %ax
10282 -       movw    %ax, %ds
10283 -       rep
10284 -       movsw
10285 -       movw    %cs, %ax                        # aka SETUPSEG
10286 -       movw    %ax, %ds
10287 -       cmpw    $SIG1, setup_sig1
10288 -       jne     no_sig
10289 -
10290 -       cmpw    $SIG2, setup_sig2
10291 -       jne     no_sig
10292 -
10293 -       jmp     good_sig
10294 -
10295 -no_sig:
10296 -       lea     no_sig_mess, %si
10297 -       call    prtstr
10298 -
10299 -no_sig_loop:
10300 -       jmp     no_sig_loop
10301 -
10302 -good_sig:
10303 -       movw    %cs, %ax                        # aka SETUPSEG
10304 -       subw    $DELTA_INITSEG, %ax             # aka INITSEG
10305 -       movw    %ax, %ds
10306 -# Check if an old loader tries to load a big-kernel
10307 -       testb   $LOADED_HIGH, %cs:loadflags     # Do we have a big kernel?
10308 -       jz      loader_ok                       # No, no danger for old loaders.
10309 -
10310 -       cmpb    $0, %cs:type_of_loader          # Do we have a loader that
10311 -                                               # can deal with us?
10312 -       jnz     loader_ok                       # Yes, continue.
10313 -
10314 -       pushw   %cs                             # No, we have an old loader,
10315 -       popw    %ds                             # die. 
10316 -       lea     loader_panic_mess, %si
10317 -       call    prtstr
10318 -
10319 -       jmp     no_sig_loop
10320 -
10321 -loader_panic_mess: .string "Wrong loader, giving up..."
10322 -
10323 -loader_ok:
10324 -       /* check for long mode. */
10325 -       /* we have to do this before the VESA setup, otherwise the user
10326 -          can't see the error message. */
10327 -       
10328 -       pushw   %ds
10329 -       movw    %cs,%ax
10330 -       movw    %ax,%ds
10331 -       
10332 -       call verify_cpu
10333 -       testl %eax,%eax
10334 -       jz sse_ok
10335 -
10336 -no_longmode:
10337 -       call    beep
10338 -       lea     long_mode_panic,%si
10339 -       call    prtstr
10340 -no_longmode_loop:              
10341 -       jmp     no_longmode_loop
10342 -long_mode_panic:
10343 -       .string "Your CPU does not support long mode. Use a 32bit distribution."
10344 -       .byte 0
10345 -
10346 -#include "../kernel/verify_cpu.S"
10347 -sse_ok:
10348 -       popw    %ds
10349 -       
10350 -# tell BIOS we want to go to long mode
10351 -       movl  $0xec00,%eax      # declare target operating mode
10352 -       movl  $2,%ebx           # long mode
10353 -       int $0x15                       
10354 -       
10355 -# Get memory size (extended mem, kB)
10356 -
10357 -       xorl    %eax, %eax
10358 -       movl    %eax, (0x1e0)
10359 -#ifndef STANDARD_MEMORY_BIOS_CALL
10360 -       movb    %al, (E820NR)
10361 -# Try three different memory detection schemes.  First, try
10362 -# e820h, which lets us assemble a memory map, then try e801h,
10363 -# which returns a 32-bit memory size, and finally 88h, which
10364 -# returns 0-64m
10365 -
10366 -# method E820H:
10367 -# the memory map from hell.  e820h returns memory classified into
10368 -# a whole bunch of different types, and allows memory holes and
10369 -# everything.  We scan through this memory map and build a list
10370 -# of the first 32 memory areas, which we return at [E820MAP].
10371 -# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
10372 -
10373 -#define SMAP  0x534d4150
10374 -
10375 -meme820:
10376 -       xorl    %ebx, %ebx                      # continuation counter
10377 -       movw    $E820MAP, %di                   # point into the whitelist
10378 -                                               # so we can have the bios
10379 -                                               # directly write into it.
10380 -
10381 -jmpe820:
10382 -       movl    $0x0000e820, %eax               # e820, upper word zeroed
10383 -       movl    $SMAP, %edx                     # ascii 'SMAP'
10384 -       movl    $20, %ecx                       # size of the e820rec
10385 -       pushw   %ds                             # data record.
10386 -       popw    %es
10387 -       int     $0x15                           # make the call
10388 -       jc      bail820                         # fall to e801 if it fails
10389 -
10390 -       cmpl    $SMAP, %eax                     # check the return is `SMAP'
10391 -       jne     bail820                         # fall to e801 if it fails
10392 -
10393 -#      cmpl    $1, 16(%di)                     # is this usable memory?
10394 -#      jne     again820
10395 -
10396 -       # If this is usable memory, we save it by simply advancing %di by
10397 -       # sizeof(e820rec).
10398 -       #
10399 -good820:
10400 -       movb    (E820NR), %al                   # up to 128 entries
10401 -       cmpb    $E820MAX, %al
10402 -       jae     bail820
10403 -
10404 -       incb    (E820NR)
10405 -       movw    %di, %ax
10406 -       addw    $20, %ax
10407 -       movw    %ax, %di
10408 -again820:
10409 -       cmpl    $0, %ebx                        # check to see if
10410 -       jne     jmpe820                         # %ebx is set to EOF
10411 -bail820:
10412 -
10413 -
10414 -# method E801H:
10415 -# memory size is in 1k chunksizes, to avoid confusing loadlin.
10416 -# we store the 0xe801 memory size in a completely different place,
10417 -# because it will most likely be longer than 16 bits.
10418 -# (use 1e0 because that's what Larry Augustine uses in his
10419 -# alternative new memory detection scheme, and it's sensible
10420 -# to write everything into the same place.)
10421 -
10422 -meme801:
10423 -       stc                                     # fix to work around buggy
10424 -       xorw    %cx,%cx                         # BIOSes which don't clear/set
10425 -       xorw    %dx,%dx                         # carry on pass/error of
10426 -                                               # e801h memory size call
10427 -                                               # or merely pass cx,dx though
10428 -                                               # without changing them.
10429 -       movw    $0xe801, %ax
10430 -       int     $0x15
10431 -       jc      mem88
10432 -
10433 -       cmpw    $0x0, %cx                       # Kludge to handle BIOSes
10434 -       jne     e801usecxdx                     # which report their extended
10435 -       cmpw    $0x0, %dx                       # memory in AX/BX rather than
10436 -       jne     e801usecxdx                     # CX/DX.  The spec I have read
10437 -       movw    %ax, %cx                        # seems to indicate AX/BX 
10438 -       movw    %bx, %dx                        # are more reasonable anyway...
10439 -
10440 -e801usecxdx:
10441 -       andl    $0xffff, %edx                   # clear sign extend
10442 -       shll    $6, %edx                        # and go from 64k to 1k chunks
10443 -       movl    %edx, (0x1e0)                   # store extended memory size
10444 -       andl    $0xffff, %ecx                   # clear sign extend
10445 -       addl    %ecx, (0x1e0)                   # and add lower memory into
10446 -                                               # total size.
10447 -
10448 -# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
10449 -# 64mb, depending on the bios) in ax.
10450 -mem88:
10451 -
10452 -#endif
10453 -       movb    $0x88, %ah
10454 -       int     $0x15
10455 -       movw    %ax, (2)
10456 -
10457 -# Set the keyboard repeat rate to the max
10458 -       movw    $0x0305, %ax
10459 -       xorw    %bx, %bx
10460 -       int     $0x16
10461 -
10462 -# Check for video adapter and its parameters and allow the
10463 -# user to browse video modes.
10464 -       call    video                           # NOTE: we need %ds pointing
10465 -                                               # to bootsector
10466 -
10467 -# Get hd0 data...
10468 -       xorw    %ax, %ax
10469 -       movw    %ax, %ds
10470 -       ldsw    (4 * 0x41), %si
10471 -       movw    %cs, %ax                        # aka SETUPSEG
10472 -       subw    $DELTA_INITSEG, %ax             # aka INITSEG
10473 -       pushw   %ax
10474 -       movw    %ax, %es
10475 -       movw    $0x0080, %di
10476 -       movw    $0x10, %cx
10477 -       pushw   %cx
10478 -       cld
10479 -       rep
10480 -       movsb
10481 -# Get hd1 data...
10482 -       xorw    %ax, %ax
10483 -       movw    %ax, %ds
10484 -       ldsw    (4 * 0x46), %si
10485 -       popw    %cx
10486 -       popw    %es
10487 -       movw    $0x0090, %di
10488 -       rep
10489 -       movsb
10490 -# Check that there IS a hd1 :-)
10491 -       movw    $0x01500, %ax
10492 -       movb    $0x81, %dl
10493 -       int     $0x13
10494 -       jc      no_disk1
10495 -       
10496 -       cmpb    $3, %ah
10497 -       je      is_disk1
10498 -
10499 -no_disk1:
10500 -       movw    %cs, %ax                        # aka SETUPSEG
10501 -       subw    $DELTA_INITSEG, %ax             # aka INITSEG
10502 -       movw    %ax, %es
10503 -       movw    $0x0090, %di
10504 -       movw    $0x10, %cx
10505 -       xorw    %ax, %ax
10506 -       cld
10507 -       rep
10508 -       stosb
10509 -is_disk1:
10510 -
10511 -# Check for PS/2 pointing device
10512 -       movw    %cs, %ax                        # aka SETUPSEG
10513 -       subw    $DELTA_INITSEG, %ax             # aka INITSEG
10514 -       movw    %ax, %ds
10515 -       movb    $0, (0x1ff)                     # default is no pointing device
10516 -       int     $0x11                           # int 0x11: equipment list
10517 -       testb   $0x04, %al                      # check if mouse installed
10518 -       jz      no_psmouse
10519 -
10520 -       movb    $0xAA, (0x1ff)                  # device present
10521 -no_psmouse:
10522 -
10523 -#include "../../i386/boot/edd.S"
10524 -
10525 -# Now we want to move to protected mode ...
10526 -       cmpw    $0, %cs:realmode_swtch
10527 -       jz      rmodeswtch_normal
10528 -
10529 -       lcall   *%cs:realmode_swtch
10530 -
10531 -       jmp     rmodeswtch_end
10532 -
10533 -rmodeswtch_normal:
10534 -        pushw  %cs
10535 -       call    default_switch
10536 -
10537 -rmodeswtch_end:
10538 -# we get the code32 start address and modify the below 'jmpi'
10539 -# (loader may have changed it)
10540 -       movl    %cs:code32_start, %eax
10541 -       movl    %eax, %cs:code32
10542 -
10543 -# Now we move the system to its rightful place ... but we check if we have a
10544 -# big-kernel. In that case we *must* not move it ...
10545 -       testb   $LOADED_HIGH, %cs:loadflags
10546 -       jz      do_move0                        # .. then we have a normal low
10547 -                                               # loaded zImage
10548 -                                               # .. or else we have a high
10549 -                                               # loaded bzImage
10550 -       jmp     end_move                        # ... and we skip moving
10551 -
10552 -do_move0:
10553 -       movw    $0x100, %ax                     # start of destination segment
10554 -       movw    %cs, %bp                        # aka SETUPSEG
10555 -       subw    $DELTA_INITSEG, %bp             # aka INITSEG
10556 -       movw    %cs:start_sys_seg, %bx          # start of source segment
10557 -       cld
10558 -do_move:
10559 -       movw    %ax, %es                        # destination segment
10560 -       incb    %ah                             # instead of add ax,#0x100
10561 -       movw    %bx, %ds                        # source segment
10562 -       addw    $0x100, %bx
10563 -       subw    %di, %di
10564 -       subw    %si, %si
10565 -       movw    $0x800, %cx
10566 -       rep
10567 -       movsw
10568 -       cmpw    %bp, %bx                        # assume start_sys_seg > 0x200,
10569 -                                               # so we will perhaps read one
10570 -                                               # page more than needed, but
10571 -                                               # never overwrite INITSEG
10572 -                                               # because destination is a
10573 -                                               # minimum one page below source
10574 -       jb      do_move
10575 -
10576 -end_move:
10577 -# then we load the segment descriptors
10578 -       movw    %cs, %ax                        # aka SETUPSEG
10579 -       movw    %ax, %ds
10580 -               
10581 -# Check whether we need to be downward compatible with version <=201
10582 -       cmpl    $0, cmd_line_ptr
10583 -       jne     end_move_self           # loader uses version >=202 features
10584 -       cmpb    $0x20, type_of_loader
10585 -       je      end_move_self           # bootsect loader, we know of it
10586 -
10587 -# Boot loader doesnt support boot protocol version 2.02.
10588 -# If we have our code not at 0x90000, we need to move it there now.
10589 -# We also then need to move the params behind it (commandline)
10590 -# Because we would overwrite the code on the current IP, we move
10591 -# it in two steps, jumping high after the first one.
10592 -       movw    %cs, %ax
10593 -       cmpw    $SETUPSEG, %ax
10594 -       je      end_move_self
10595 -
10596 -       cli                                     # make sure we really have
10597 -                                               # interrupts disabled !
10598 -                                               # because after this the stack
10599 -                                               # should not be used
10600 -       subw    $DELTA_INITSEG, %ax             # aka INITSEG
10601 -       movw    %ss, %dx
10602 -       cmpw    %ax, %dx
10603 -       jb      move_self_1
10604 -
10605 -       addw    $INITSEG, %dx
10606 -       subw    %ax, %dx                        # this will go into %ss after
10607 -                                               # the move
10608 -move_self_1:
10609 -       movw    %ax, %ds
10610 -       movw    $INITSEG, %ax                   # real INITSEG
10611 -       movw    %ax, %es
10612 -       movw    %cs:setup_move_size, %cx
10613 -       std                                     # we have to move up, so we use
10614 -                                               # direction down because the
10615 -                                               # areas may overlap
10616 -       movw    %cx, %di
10617 -       decw    %di
10618 -       movw    %di, %si
10619 -       subw    $move_self_here+0x200, %cx
10620 -       rep
10621 -       movsb
10622 -       ljmp    $SETUPSEG, $move_self_here
10623 -
10624 -move_self_here:
10625 -       movw    $move_self_here+0x200, %cx
10626 -       rep
10627 -       movsb
10628 -       movw    $SETUPSEG, %ax
10629 -       movw    %ax, %ds
10630 -       movw    %dx, %ss
10631 -end_move_self:                                 # now we are at the right place
10632 -       lidt    idt_48                          # load idt with 0,0
10633 -       xorl    %eax, %eax                      # Compute gdt_base
10634 -       movw    %ds, %ax                        # (Convert %ds:gdt to a linear ptr)
10635 -       shll    $4, %eax
10636 -       addl    $gdt, %eax
10637 -       movl    %eax, (gdt_48+2)
10638 -       lgdt    gdt_48                          # load gdt with whatever is
10639 -                                               # appropriate
10640 -
10641 -# that was painless, now we enable a20
10642 -       call    empty_8042
10643 -
10644 -       movb    $0xD1, %al                      # command write
10645 -       outb    %al, $0x64
10646 -       call    empty_8042
10647 -
10648 -       movb    $0xDF, %al                      # A20 on
10649 -       outb    %al, $0x60
10650 -       call    empty_8042
10651 -
10652 -#
10653 -#      You must preserve the other bits here. Otherwise embarrasing things
10654 -#      like laptops powering off on boot happen. Corrected version by Kira
10655 -#      Brown from Linux 2.2
10656 -#
10657 -       inb     $0x92, %al                      # 
10658 -       orb     $02, %al                        # "fast A20" version
10659 -       outb    %al, $0x92                      # some chips have only this
10660 -
10661 -# wait until a20 really *is* enabled; it can take a fair amount of
10662 -# time on certain systems; Toshiba Tecras are known to have this
10663 -# problem.  The memory location used here (0x200) is the int 0x80
10664 -# vector, which should be safe to use.
10665 -
10666 -       xorw    %ax, %ax                        # segment 0x0000
10667 -       movw    %ax, %fs
10668 -       decw    %ax                             # segment 0xffff (HMA)
10669 -       movw    %ax, %gs
10670 -a20_wait:
10671 -       incw    %ax                             # unused memory location <0xfff0
10672 -       movw    %ax, %fs:(0x200)                # we use the "int 0x80" vector
10673 -       cmpw    %gs:(0x210), %ax                # and its corresponding HMA addr
10674 -       je      a20_wait                        # loop until no longer aliased
10675 -
10676 -# make sure any possible coprocessor is properly reset..
10677 -       xorw    %ax, %ax
10678 -       outb    %al, $0xf0
10679 -       call    delay
10680 -
10681 -       outb    %al, $0xf1
10682 -       call    delay
10683 -
10684 -# well, that went ok, I hope. Now we mask all interrupts - the rest
10685 -# is done in init_IRQ().
10686 -       movb    $0xFF, %al                      # mask all interrupts for now
10687 -       outb    %al, $0xA1
10688 -       call    delay
10689 -       
10690 -       movb    $0xFB, %al                      # mask all irq's but irq2 which
10691 -       outb    %al, $0x21                      # is cascaded
10692 -
10693 -# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
10694 -# need no steenking BIOS anyway (except for the initial loading :-).
10695 -# The BIOS-routine wants lots of unnecessary data, and it's less
10696 -# "interesting" anyway. This is how REAL programmers do it.
10697 -#
10698 -# Well, now's the time to actually move into protected mode. To make
10699 -# things as simple as possible, we do no register set-up or anything,
10700 -# we let the gnu-compiled 32-bit programs do that. We just jump to
10701 -# absolute address 0x1000 (or the loader supplied one),
10702 -# in 32-bit protected mode.
10703 -#
10704 -# Note that the short jump isn't strictly needed, although there are
10705 -# reasons why it might be a good idea. It won't hurt in any case.
10706 -       movw    $1, %ax                         # protected mode (PE) bit
10707 -       lmsw    %ax                             # This is it!
10708 -       jmp     flush_instr
10709 -
10710 -flush_instr:
10711 -       xorw    %bx, %bx                        # Flag to indicate a boot
10712 -       xorl    %esi, %esi                      # Pointer to real-mode code
10713 -       movw    %cs, %si
10714 -       subw    $DELTA_INITSEG, %si
10715 -       shll    $4, %esi                        # Convert to 32-bit pointer
10716 -# NOTE: For high loaded big kernels we need a
10717 -#      jmpi    0x100000,__KERNEL_CS
10718 -#
10719 -#      but we yet haven't reloaded the CS register, so the default size 
10720 -#      of the target offset still is 16 bit.
10721 -#      However, using an operand prefix (0x66), the CPU will properly
10722 -#      take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
10723 -#      Manual, Mixing 16-bit and 32-bit code, page 16-6)
10724 -
10725 -       .byte 0x66, 0xea                        # prefix + jmpi-opcode
10726 -code32:        .long   0x1000                          # will be set to 0x100000
10727 -                                               # for big kernels
10728 -       .word   __KERNEL_CS
10729 -
10730 -# Here's a bunch of information about your current kernel..
10731 -kernel_version:        .ascii  UTS_RELEASE
10732 -               .ascii  " ("
10733 -               .ascii  LINUX_COMPILE_BY
10734 -               .ascii  "@"
10735 -               .ascii  LINUX_COMPILE_HOST
10736 -               .ascii  ") "
10737 -               .ascii  UTS_VERSION
10738 -               .byte   0
10739 -
10740 -# This is the default real mode switch routine.
10741 -# to be called just before protected mode transition
10742 -default_switch:
10743 -       cli                                     # no interrupts allowed !
10744 -       movb    $0x80, %al                      # disable NMI for bootup
10745 -                                               # sequence
10746 -       outb    %al, $0x70
10747 -       lret
10748 -
10749 -
10750 -# This routine checks that the keyboard command queue is empty
10751 -# (after emptying the output buffers)
10752 -#
10753 -# Some machines have delusions that the keyboard buffer is always full
10754 -# with no keyboard attached...
10755 -#
10756 -# If there is no keyboard controller, we will usually get 0xff
10757 -# to all the reads.  With each IO taking a microsecond and
10758 -# a timeout of 100,000 iterations, this can take about half a
10759 -# second ("delay" == outb to port 0x80). That should be ok,
10760 -# and should also be plenty of time for a real keyboard controller
10761 -# to empty.
10762 -#
10763 -
10764 -empty_8042:
10765 -       pushl   %ecx
10766 -       movl    $100000, %ecx
10767 -
10768 -empty_8042_loop:
10769 -       decl    %ecx
10770 -       jz      empty_8042_end_loop
10771 -
10772 -       call    delay
10773 -
10774 -       inb     $0x64, %al                      # 8042 status port
10775 -       testb   $1, %al                         # output buffer?
10776 -       jz      no_output
10777 -
10778 -       call    delay
10779 -       inb     $0x60, %al                      # read it
10780 -       jmp     empty_8042_loop
10781 -
10782 -no_output:
10783 -       testb   $2, %al                         # is input buffer full?
10784 -       jnz     empty_8042_loop                 # yes - loop
10785 -empty_8042_end_loop:
10786 -       popl    %ecx
10787 -       ret
10788 -
10789 -# Read the cmos clock. Return the seconds in al
10790 -gettime:
10791 -       pushw   %cx
10792 -       movb    $0x02, %ah
10793 -       int     $0x1a
10794 -       movb    %dh, %al                        # %dh contains the seconds
10795 -       andb    $0x0f, %al
10796 -       movb    %dh, %ah
10797 -       movb    $0x04, %cl
10798 -       shrb    %cl, %ah
10799 -       aad
10800 -       popw    %cx
10801 -       ret
10802 -
10803 -# Delay is needed after doing I/O
10804 -delay:
10805 -       outb    %al,$0x80
10806 -       ret
10807 -
10808 -# Descriptor tables
10809 -gdt:
10810 -       .word   0, 0, 0, 0                      # dummy
10811 -
10812 -       .word   0, 0, 0, 0                      # unused
10813 -
10814 -       .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
10815 -       .word   0                               # base address = 0
10816 -       .word   0x9A00                          # code read/exec
10817 -       .word   0x00CF                          # granularity = 4096, 386
10818 -                                               #  (+5th nibble of limit)
10819 -
10820 -       .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
10821 -       .word   0                               # base address = 0
10822 -       .word   0x9200                          # data read/write
10823 -       .word   0x00CF                          # granularity = 4096, 386
10824 -                                               #  (+5th nibble of limit)
10825 -gdt_end:
10826 -idt_48:
10827 -       .word   0                               # idt limit = 0
10828 -       .word   0, 0                            # idt base = 0L
10829 -gdt_48:
10830 -       .word   gdt_end-gdt-1                   # gdt limit
10831 -       .word   0, 0                            # gdt base (filled in later)
10832 -
10833 -# Include video setup & detection code
10834 -
10835 -#include "../../i386/boot/video.S"
10836 -
10837 -# Setup signature -- must be last
10838 -setup_sig1:    .word   SIG1
10839 -setup_sig2:    .word   SIG2
10840 -
10841 -# After this point, there is some free space which is used by the video mode
10842 -# handling code to store the temporary mode table (not used by the kernel).
10843 -
10844 -modelist:
10845 -
10846 -.text
10847 -endtext:
10848 -.data
10849 -enddata:
10850 -.bss
10851 -endbss:
10852 diff -puN arch/x86_64/boot/tools/build.c~git-newsetup /dev/null
10853 --- a/arch/x86_64/boot/tools/build.c
10854 +++ /dev/null
10855 @@ -1,185 +0,0 @@
10856 -/*
10857 - *  Copyright (C) 1991, 1992  Linus Torvalds
10858 - *  Copyright (C) 1997 Martin Mares
10859 - */
10860 -
10861 -/*
10862 - * This file builds a disk-image from three different files:
10863 - *
10864 - * - bootsect: compatibility mbr which prints an error message if
10865 - *             someone tries to boot the kernel directly.
10866 - * - setup: 8086 machine code, sets up system parm
10867 - * - system: 80386 code for actual system
10868 - *
10869 - * It does some checking that all files are of the correct type, and
10870 - * just writes the result to stdout, removing headers and padding to
10871 - * the right amount. It also writes some system data to stderr.
10872 - */
10873 -
10874 -/*
10875 - * Changes by tytso to allow root device specification
10876 - * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
10877 - * Cross compiling fixes by Gertjan van Wingerde, July 1996
10878 - * Rewritten by Martin Mares, April 1997
10879 - */
10880 -
10881 -#include <stdio.h>
10882 -#include <string.h>
10883 -#include <stdlib.h>
10884 -#include <stdarg.h>
10885 -#include <sys/types.h>
10886 -#include <sys/stat.h>
10887 -#include <sys/sysmacros.h>
10888 -#include <unistd.h>
10889 -#include <fcntl.h>
10890 -#include <asm/boot.h>
10891 -
10892 -typedef unsigned char byte;
10893 -typedef unsigned short word;
10894 -typedef unsigned long u32;
10895 -
10896 -#define DEFAULT_MAJOR_ROOT 0
10897 -#define DEFAULT_MINOR_ROOT 0
10898 -
10899 -/* Minimal number of setup sectors (see also bootsect.S) */
10900 -#define SETUP_SECTS 4
10901 -
10902 -byte buf[1024];
10903 -int fd;
10904 -int is_big_kernel;
10905 -
10906 -void die(const char * str, ...)
10907 -{
10908 -       va_list args;
10909 -       va_start(args, str);
10910 -       vfprintf(stderr, str, args);
10911 -       fputc('\n', stderr);
10912 -       exit(1);
10913 -}
10914 -
10915 -void file_open(const char *name)
10916 -{
10917 -       if ((fd = open(name, O_RDONLY, 0)) < 0)
10918 -               die("Unable to open `%s': %m", name);
10919 -}
10920 -
10921 -void usage(void)
10922 -{
10923 -       die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
10924 -}
10925 -
10926 -int main(int argc, char ** argv)
10927 -{
10928 -       unsigned int i, c, sz, setup_sectors;
10929 -       u32 sys_size;
10930 -       byte major_root, minor_root;
10931 -       struct stat sb;
10932 -
10933 -       if (argc > 2 && !strcmp(argv[1], "-b"))
10934 -         {
10935 -           is_big_kernel = 1;
10936 -           argc--, argv++;
10937 -         }
10938 -       if ((argc < 4) || (argc > 5))
10939 -               usage();
10940 -       if (argc > 4) {
10941 -               if (!strcmp(argv[4], "CURRENT")) {
10942 -                       if (stat("/", &sb)) {
10943 -                               perror("/");
10944 -                               die("Couldn't stat /");
10945 -                       }
10946 -                       major_root = major(sb.st_dev);
10947 -                       minor_root = minor(sb.st_dev);
10948 -               } else if (strcmp(argv[4], "FLOPPY")) {
10949 -                       if (stat(argv[4], &sb)) {
10950 -                               perror(argv[4]);
10951 -                               die("Couldn't stat root device.");
10952 -                       }
10953 -                       major_root = major(sb.st_rdev);
10954 -                       minor_root = minor(sb.st_rdev);
10955 -               } else {
10956 -                       major_root = 0;
10957 -                       minor_root = 0;
10958 -               }
10959 -       } else {
10960 -               major_root = DEFAULT_MAJOR_ROOT;
10961 -               minor_root = DEFAULT_MINOR_ROOT;
10962 -       }
10963 -       fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
10964 -
10965 -       file_open(argv[1]);
10966 -       i = read(fd, buf, sizeof(buf));
10967 -       fprintf(stderr,"Boot sector %d bytes.\n",i);
10968 -       if (i != 512)
10969 -               die("Boot block must be exactly 512 bytes");
10970 -       if (buf[510] != 0x55 || buf[511] != 0xaa)
10971 -               die("Boot block hasn't got boot flag (0xAA55)");
10972 -       buf[508] = minor_root;
10973 -       buf[509] = major_root;
10974 -       if (write(1, buf, 512) != 512)
10975 -               die("Write call failed");
10976 -       close (fd);
10977 -
10978 -       file_open(argv[2]);                                 /* Copy the setup code */
10979 -       for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
10980 -               if (write(1, buf, c) != c)
10981 -                       die("Write call failed");
10982 -       if (c != 0)
10983 -               die("read-error on `setup'");
10984 -       close (fd);
10985 -
10986 -       setup_sectors = (i + 511) / 512;        /* Pad unused space with zeros */
10987 -       /* for compatibility with ancient versions of LILO. */
10988 -       if (setup_sectors < SETUP_SECTS)
10989 -               setup_sectors = SETUP_SECTS;
10990 -       fprintf(stderr, "Setup is %d bytes.\n", i);
10991 -       memset(buf, 0, sizeof(buf));
10992 -       while (i < setup_sectors * 512) {
10993 -               c = setup_sectors * 512 - i;
10994 -               if (c > sizeof(buf))
10995 -                       c = sizeof(buf);
10996 -               if (write(1, buf, c) != c)
10997 -                       die("Write call failed");
10998 -               i += c;
10999 -       }
11000 -
11001 -       file_open(argv[3]);
11002 -       if (fstat (fd, &sb))
11003 -               die("Unable to stat `%s': %m", argv[3]);
11004 -       sz = sb.st_size;
11005 -       fprintf (stderr, "System is %d kB\n", sz/1024);
11006 -       sys_size = (sz + 15) / 16;
11007 -       if (!is_big_kernel && sys_size > DEF_SYSSIZE)
11008 -               die("System is too big. Try using bzImage or modules.");
11009 -       while (sz > 0) {
11010 -               int l, n;
11011 -
11012 -               l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
11013 -               if ((n=read(fd, buf, l)) != l) {
11014 -                       if (n < 0)
11015 -                               die("Error reading %s: %m", argv[3]);
11016 -                       else
11017 -                               die("%s: Unexpected EOF", argv[3]);
11018 -               }
11019 -               if (write(1, buf, l) != l)
11020 -                       die("Write failed");
11021 -               sz -= l;
11022 -       }
11023 -       close(fd);
11024 -
11025 -       if (lseek(1, 497, SEEK_SET) != 497)                 /* Write sizes to the bootsector */
11026 -               die("Output: seek failed");
11027 -       buf[0] = setup_sectors;
11028 -       if (write(1, buf, 1) != 1)
11029 -               die("Write of setup sector count failed");
11030 -       if (lseek(1, 500, SEEK_SET) != 500)
11031 -               die("Output: seek failed");
11032 -       buf[0] = (sys_size & 0xff);
11033 -       buf[1] = ((sys_size >> 8) & 0xff);
11034 -       buf[2] = ((sys_size >> 16) & 0xff);
11035 -       buf[3] = ((sys_size >> 24) & 0xff);
11036 -       if (write(1, buf, 4) != 4)
11037 -               die("Write of image length failed");
11038 -
11039 -       return 0;                                           /* Everything is OK */
11040 -}
11041 diff -puN arch/x86_64/kernel/Makefile~git-newsetup arch/x86_64/kernel/Makefile
11042 --- a/arch/x86_64/kernel/Makefile~git-newsetup
11043 +++ a/arch/x86_64/kernel/Makefile
11044 @@ -45,6 +45,7 @@ obj-$(CONFIG_PCI)             += early-quirks.o
11045  
11046  obj-y                          += topology.o
11047  obj-y                          += intel_cacheinfo.o
11048 +obj-y                          += addon_cpuid_features.o
11049  obj-y                          += pcspeaker.o
11050  
11051  CFLAGS_vsyscall.o              := $(PROFILING) -g0
11052 @@ -58,6 +59,7 @@ cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  
11053  topology-y                     += ../../i386/kernel/topology.o
11054  microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../i386/kernel/microcode.o
11055  intel_cacheinfo-y              += ../../i386/kernel/cpu/intel_cacheinfo.o
11056 +addon_cpuid_features-y         += ../../i386/kernel/cpu/addon_cpuid_features.o
11057  quirks-y                       += ../../i386/kernel/quirks.o
11058  i8237-y                                += ../../i386/kernel/i8237.o
11059  msr-$(subst m,y,$(CONFIG_X86_MSR))  += ../../i386/kernel/msr.o
11060 diff -puN arch/x86_64/kernel/setup.c~git-newsetup arch/x86_64/kernel/setup.c
11061 --- a/arch/x86_64/kernel/setup.c~git-newsetup
11062 +++ a/arch/x86_64/kernel/setup.c
11063 @@ -855,6 +855,8 @@ void __cpuinit identify_cpu(struct cpuin
11064                         c->x86_capability[2] = cpuid_edx(0x80860001);
11065         }
11066  
11067 +       init_scattered_cpuid_features(c);
11068 +
11069         c->apicid = phys_pkg_id(0);
11070  
11071         /*
11072 @@ -940,7 +942,7 @@ static int show_cpuinfo(struct seq_file 
11073                 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
11074                 "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
11075                 "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
11076 -               "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
11077 +               "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
11078  
11079                 /* AMD-defined */
11080                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11081 @@ -956,10 +958,11 @@ static int show_cpuinfo(struct seq_file 
11082                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11083  
11084                 /* Other (Linux-defined) */
11085 -               "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL,
11086 -               "constant_tsc", NULL, NULL,
11087 -               "up", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11088 -               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11089 +               "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
11090 +               NULL, NULL, NULL, NULL,
11091 +               "constant_tsc", "up", NULL, "arch_perfmon",
11092 +               "pebs", "bts", NULL, "sync_rdtsc",
11093 +               "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11094                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11095  
11096                 /* Intel-defined (#2) */
11097 @@ -970,7 +973,7 @@ static int show_cpuinfo(struct seq_file 
11098  
11099                 /* VIA/Cyrix/Centaur-defined */
11100                 NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
11101 -               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11102 +               "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
11103                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11104                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11105  
11106 @@ -981,6 +984,12 @@ static int show_cpuinfo(struct seq_file 
11107                 "osvw", "ibs", NULL, NULL, NULL, NULL,
11108                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11109                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11110 +
11111 +               /* Auxiliary (Linux-defined) */
11112 +               "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11113 +               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11114 +               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11115 +               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11116         };
11117         static char *x86_power_flags[] = { 
11118                 "ts",   /* temperature sensor */
11119 diff -puN arch/x86_64/kernel/verify_cpu.S~git-newsetup arch/x86_64/kernel/verify_cpu.S
11120 --- a/arch/x86_64/kernel/verify_cpu.S~git-newsetup
11121 +++ a/arch/x86_64/kernel/verify_cpu.S
11122 @@ -37,20 +37,6 @@ verify_cpu:
11123         pushl   $0                      # Kill any dangerous flags
11124         popfl
11125  
11126 -       /* minimum CPUID flags for x86-64 as defined by AMD */
11127 -#define M(x) (1<<(x))
11128 -#define M2(a,b) M(a)|M(b)
11129 -#define M4(a,b,c,d) M(a)|M(b)|M(c)|M(d)
11130 -
11131 -#define SSE_MASK \
11132 -       (M2(X86_FEATURE_XMM,X86_FEATURE_XMM2))
11133 -#define REQUIRED_MASK1 \
11134 -       (M4(X86_FEATURE_FPU,X86_FEATURE_PSE,X86_FEATURE_TSC,X86_FEATURE_MSR)|\
11135 -        M4(X86_FEATURE_PAE,X86_FEATURE_CX8,X86_FEATURE_PGE,X86_FEATURE_CMOV)|\
11136 -        M(X86_FEATURE_FXSR))
11137 -#define REQUIRED_MASK2 \
11138 -       (M(X86_FEATURE_LM - 32))
11139 -
11140         pushfl                          # standard way to check for cpuid
11141         popl    %eax
11142         movl    %eax,%ebx
11143 @@ -79,8 +65,8 @@ verify_cpu:
11144  verify_cpu_noamd:
11145         movl    $0x1,%eax               # Does the cpu have what it takes
11146         cpuid
11147 -       andl    $REQUIRED_MASK1,%edx
11148 -       xorl    $REQUIRED_MASK1,%edx
11149 +       andl    $REQUIRED_MASK0,%edx
11150 +       xorl    $REQUIRED_MASK0,%edx
11151         jnz     verify_cpu_no_longmode
11152  
11153         movl    $0x80000000,%eax        # See if extended cpuid is implemented
11154 @@ -90,8 +76,8 @@ verify_cpu_noamd:
11155  
11156         movl    $0x80000001,%eax        # Does the cpu have what it takes
11157         cpuid
11158 -       andl    $REQUIRED_MASK2,%edx
11159 -       xorl    $REQUIRED_MASK2,%edx
11160 +       andl    $REQUIRED_MASK1,%edx
11161 +       xorl    $REQUIRED_MASK1,%edx
11162         jnz     verify_cpu_no_longmode
11163  
11164  verify_cpu_sse_test:
11165 diff -puN drivers/ide/legacy/hd.c~git-newsetup drivers/ide/legacy/hd.c
11166 --- a/drivers/ide/legacy/hd.c~git-newsetup
11167 +++ a/drivers/ide/legacy/hd.c
11168 @@ -718,74 +718,25 @@ static int __init hd_init(void)
11169         device_timer.function = hd_times_out;
11170         blk_queue_hardsect_size(hd_queue, 512);
11171  
11172 -#ifdef __i386__
11173         if (!NR_HD) {
11174 -               extern struct drive_info drive_info;
11175 -               unsigned char *BIOS = (unsigned char *) &drive_info;
11176 -               unsigned long flags;
11177 -               int cmos_disks;
11178 -
11179 -               for (drive=0 ; drive<2 ; drive++) {
11180 -                       hd_info[drive].cyl = *(unsigned short *) BIOS;
11181 -                       hd_info[drive].head = *(2+BIOS);
11182 -                       hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
11183 -                       hd_info[drive].ctl = *(8+BIOS);
11184 -                       hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
11185 -                       hd_info[drive].sect = *(14+BIOS);
11186 -#ifdef does_not_work_for_everybody_with_scsi_but_helps_ibm_vp
11187 -                       if (hd_info[drive].cyl && NR_HD == drive)
11188 -                               NR_HD++;
11189 -#endif
11190 -                       BIOS += 16;
11191 -               }
11192 -
11193 -       /*
11194 -               We query CMOS about hard disks : it could be that 
11195 -               we have a SCSI/ESDI/etc controller that is BIOS
11196 -               compatible with ST-506, and thus showing up in our
11197 -               BIOS table, but not register compatible, and therefore
11198 -               not present in CMOS.
11199 -
11200 -               Furthermore, we will assume that our ST-506 drives
11201 -               <if any> are the primary drives in the system, and 
11202 -               the ones reflected as drive 1 or 2.
11203 -
11204 -               The first drive is stored in the high nibble of CMOS
11205 -               byte 0x12, the second in the low nibble.  This will be
11206 -               either a 4 bit drive type or 0xf indicating use byte 0x19 
11207 -               for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.
11208 -
11209 -               Needless to say, a non-zero value means we have 
11210 -               an AT controller hard disk for that drive.
11211 -
11212 -               Currently the rtc_lock is a bit academic since this
11213 -               driver is non-modular, but someday... ?         Paul G.
11214 -       */
11215 -
11216 -               spin_lock_irqsave(&rtc_lock, flags);
11217 -               cmos_disks = CMOS_READ(0x12);
11218 -               spin_unlock_irqrestore(&rtc_lock, flags);
11219 -
11220 -               if (cmos_disks & 0xf0) {
11221 -                       if (cmos_disks & 0x0f)
11222 -                               NR_HD = 2;
11223 -                       else
11224 -                               NR_HD = 1;
11225 -               }
11226 -       }
11227 -#endif /* __i386__ */
11228 -#ifdef __arm__
11229 -       if (!NR_HD) {
11230 -               /* We don't know anything about the drive.  This means
11231 +               /*
11232 +                * We don't know anything about the drive.  This means
11233                  * that you *MUST* specify the drive parameters to the
11234                  * kernel yourself.
11235 +                *
11236 +                * If we were on an i386, we used to read this info from
11237 +                * the BIOS or CMOS.  This doesn't work all that well,
11238 +                * since this assumes that this is a primary or secondary
11239 +                * drive, and if we're using this legacy driver, it's
11240 +                * probably an auxilliary controller added to recover
11241 +                * legacy data off an ST-506 drive.  Either way, it's
11242 +                * definitely safest to have the user explicitly specify
11243 +                * the information.
11244                  */
11245                 printk("hd: no drives specified - use hd=cyl,head,sectors"
11246                         " on kernel command line\n");
11247 -       }
11248 -#endif
11249 -       if (!NR_HD)
11250                 goto out;
11251 +       }
11252  
11253         for (drive=0 ; drive < NR_HD ; drive++) {
11254                 struct gendisk *disk = alloc_disk(64);
11255 diff -puN include/asm-i386/boot.h~git-newsetup include/asm-i386/boot.h
11256 --- a/include/asm-i386/boot.h~git-newsetup
11257 +++ a/include/asm-i386/boot.h
11258 @@ -1,5 +1,5 @@
11259 -#ifndef _LINUX_BOOT_H
11260 -#define _LINUX_BOOT_H
11261 +#ifndef _ASM_BOOT_H
11262 +#define _ASM_BOOT_H
11263  
11264  /* Don't touch these, unless you really know what you're doing. */
11265  #define DEF_INITSEG    0x9000
11266 @@ -17,4 +17,4 @@
11267                                 + (CONFIG_PHYSICAL_ALIGN - 1)) \
11268                                 & ~(CONFIG_PHYSICAL_ALIGN - 1))
11269  
11270 -#endif /* _LINUX_BOOT_H */
11271 +#endif /* _ASM_BOOT_H */
11272 diff -puN /dev/null include/asm-i386/bootparam.h
11273 --- /dev/null
11274 +++ a/include/asm-i386/bootparam.h
11275 @@ -0,0 +1,85 @@
11276 +#ifndef _ASM_BOOTPARAM_H
11277 +#define _ASM_BOOTPARAM_H
11278 +
11279 +#include <linux/types.h>
11280 +#include <linux/screen_info.h>
11281 +#include <linux/apm_bios.h>
11282 +#include <asm/e820.h>
11283 +#include <linux/edd.h>
11284 +#include <video/edid.h>
11285 +
11286 +struct setup_header {
11287 +       u8      setup_sects;
11288 +       u16     root_flags;
11289 +       u32     syssize;
11290 +       u16     ram_size;
11291 +       u16     vid_mode;
11292 +       u16     root_dev;
11293 +       u16     boot_flag;
11294 +       u16     jump;
11295 +       u32     header;
11296 +       u16     version;
11297 +       u32     realmode_swtch;
11298 +       u16     start_sys;
11299 +       u16     kernel_version;
11300 +       u8      type_of_loader;
11301 +       u8      loadflags;
11302 +#define LOADED_HIGH    0x01
11303 +#define CAN_USE_HEAP   0x80
11304 +       u16     setup_move_size;
11305 +       u32     code32_start;
11306 +       u32     ramdisk_image;
11307 +       u32     ramdisk_size;
11308 +       u32     bootsect_kludge;
11309 +       u16     heap_end_ptr;
11310 +       u16     _pad1;
11311 +       u32     cmd_line_ptr;
11312 +       u32     initrd_addr_max;
11313 +       u32     kernel_alignment;
11314 +       u8      relocatable_kernel;
11315 +} __attribute__((packed));
11316 +
11317 +struct sys_desc_table {
11318 +       u16 length;
11319 +       u8  table[14];
11320 +};
11321 +
11322 +struct efi_info {
11323 +       u32 _pad1;
11324 +       u32 efi_systab;
11325 +       u32 efi_memdesc_size;
11326 +       u32 efi_memdec_version;
11327 +       u32 efi_memmap;
11328 +       u32 fi_memmap_size;
11329 +       u32 _pad2[2];
11330 +};
11331 +
11332 +/* The so-called "zeropage" */
11333 +struct boot_params {
11334 +       struct screen_info screen_info;                 /* 0x000 */
11335 +       struct apm_bios_info apm_bios_info;             /* 0x040 */
11336 +       u8  _pad2[12];                                  /* 0x054 */
11337 +       u32 speedstep_info[4];                          /* 0x060 */
11338 +       u8  _pad3[16];                                  /* 0x070 */
11339 +       u8  hd0_info[16];       /* obsolete! */         /* 0x080 */
11340 +       u8  hd1_info[16];       /* obsolete! */         /* 0x090 */
11341 +       struct sys_desc_table sys_desc_table;           /* 0x0a0 */
11342 +       u8  _pad4[144];                                 /* 0x0b0 */
11343 +       struct edid_info edid_info;                     /* 0x140 */
11344 +       struct efi_info efi_info;                       /* 0x1c0 */
11345 +       u32 alt_mem_k;                                  /* 0x1e0 */
11346 +       u32 scratch;            /* Scratch field! */    /* 0x1e4 */
11347 +       u8  e820_entries;                               /* 0x1e8 */
11348 +       u8  eddbuf_entries;                             /* 0x1e9 */
11349 +       u8  edd_mbr_sig_buf_entries;                    /* 0x1ea */
11350 +       u8  _pad6[6];                                   /* 0x1eb */
11351 +       struct setup_header hdr;    /* setup header */  /* 0x1f1 */
11352 +       u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
11353 +       u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];        /* 0x290 */
11354 +       struct e820entry e820_map[E820MAX];             /* 0x2d0 */
11355 +       u8  _pad8[48];                                  /* 0xcd0 */
11356 +       struct edd_info eddbuf[EDDMAXNR];               /* 0xd00 */
11357 +       u8  _pad9[276];                                 /* 0xeec */
11358 +} __attribute__((packed));
11359 +
11360 +#endif /* _ASM_BOOTPARAM_H */
11361 diff -puN include/asm-i386/cpufeature.h~git-newsetup include/asm-i386/cpufeature.h
11362 --- a/include/asm-i386/cpufeature.h~git-newsetup
11363 +++ a/include/asm-i386/cpufeature.h
11364 @@ -12,7 +12,7 @@
11365  #endif
11366  #include <asm/required-features.h>
11367  
11368 -#define NCAPINTS       7       /* N 32-bit words worth of info */
11369 +#define NCAPINTS       8       /* N 32-bit words worth of info */
11370  
11371  /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
11372  #define X86_FEATURE_FPU                (0*32+ 0) /* Onboard FPU */
11373 @@ -81,6 +81,7 @@
11374  #define X86_FEATURE_BTS                (3*32+13)  /* Branch Trace Store */
11375  #define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */
11376  #define X86_FEATURE_SYNC_RDTSC (3*32+15)  /* RDTSC synchronizes the CPU */
11377 +#define X86_FEATURE_REP_GOOD   (3*32+16) /* rep microcode works well on this CPU */
11378  
11379  /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
11380  #define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */
11381 @@ -108,11 +109,24 @@
11382  #define X86_FEATURE_LAHF_LM    (6*32+ 0) /* LAHF/SAHF in long mode */
11383  #define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */
11384  
11385 -#define cpu_has(c, bit)                                        \
11386 -       ((__builtin_constant_p(bit) && (bit) < 32 &&    \
11387 -               (1UL << (bit)) & REQUIRED_MASK1) ?      \
11388 -               1 :                                     \
11389 -       test_bit(bit, (c)->x86_capability))
11390 +/*
11391 + * Auxiliary flags: Linux defined - For features scattered in various
11392 + * CPUID levels like 0x6, 0xA etc
11393 + */
11394 +#define X86_FEATURE_IDA                (7*32+ 0) /* Intel Dynamic Acceleration */
11395 +
11396 +#define cpu_has(c, bit)                                                        \
11397 +       (__builtin_constant_p(bit) &&                                   \
11398 +        ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) ||     \
11399 +          (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) ||     \
11400 +          (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) ||     \
11401 +          (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) ||     \
11402 +          (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) ||     \
11403 +          (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) ||     \
11404 +          (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) ||     \
11405 +          (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) )      \
11406 +         ? 1 :                                                         \
11407 +         test_bit(bit, (c)->x86_capability))
11408  #define boot_cpu_has(bit)      cpu_has(&boot_cpu_data, bit)
11409  
11410  #define cpu_has_fpu            boot_cpu_has(X86_FEATURE_FPU)
11411 diff -puN include/asm-i386/e820.h~git-newsetup include/asm-i386/e820.h
11412 --- a/include/asm-i386/e820.h~git-newsetup
11413 +++ a/include/asm-i386/e820.h
11414 @@ -25,13 +25,15 @@
11415  
11416  #ifndef __ASSEMBLY__
11417  
11418 +struct e820entry {
11419 +       u64 addr;       /* start of memory segment */
11420 +       u64 size;       /* size of memory segment */
11421 +       u32 type;       /* type of memory segment */
11422 +} __attribute__((packed));
11423 +
11424  struct e820map {
11425 -    int nr_map;
11426 -    struct e820entry {
11427 -       unsigned long long addr;        /* start of memory segment */
11428 -       unsigned long long size;        /* size of memory segment */
11429 -       unsigned long type;             /* type of memory segment */
11430 -    } map[E820MAX];
11431 +       u32 nr_map;
11432 +       struct e820entry map[E820MAX];
11433  };
11434  
11435  extern struct e820map e820;
11436 diff -puN include/asm-i386/processor.h~git-newsetup include/asm-i386/processor.h
11437 --- a/include/asm-i386/processor.h~git-newsetup
11438 +++ a/include/asm-i386/processor.h
11439 @@ -118,6 +118,7 @@ void __init cpu_detect(struct cpuinfo_x8
11440  extern void identify_boot_cpu(void);
11441  extern void identify_secondary_cpu(struct cpuinfo_x86 *);
11442  extern void print_cpu_info(struct cpuinfo_x86 *);
11443 +extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
11444  extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
11445  extern unsigned short num_cache_leaves;
11446  
11447 diff -puN include/asm-i386/required-features.h~git-newsetup include/asm-i386/required-features.h
11448 --- a/include/asm-i386/required-features.h~git-newsetup
11449 +++ a/include/asm-i386/required-features.h
11450 @@ -3,7 +3,7 @@
11451  
11452  /* Define minimum CPUID feature set for kernel These bits are checked
11453     really early to actually display a visible error message before the
11454 -   kernel dies.  Only add word 0 bits here
11455 +   kernel dies.  Make sure to assign features to the proper mask!
11456  
11457     Some requirements that are not in CPUID yet are also in the
11458     CONFIG_X86_MINIMUM_CPU mode which is checked too.
11459 @@ -11,24 +11,45 @@
11460     The real information is in arch/i386/Kconfig.cpu, this just converts
11461     the CONFIGs into a bitmask */
11462  
11463 +#ifndef CONFIG_MATH_EMULATION
11464 +# define NEED_FPU      (1<<(X86_FEATURE_FPU & 31))
11465 +#else
11466 +# define NEED_FPU      0
11467 +#endif
11468 +
11469  #ifdef CONFIG_X86_PAE
11470 -#define NEED_PAE       (1<<X86_FEATURE_PAE)
11471 +# define NEED_PAE      (1<<(X86_FEATURE_PAE & 31))
11472  #else
11473 -#define NEED_PAE       0
11474 +# define NEED_PAE      0
11475  #endif
11476  
11477  #ifdef CONFIG_X86_CMOV
11478 -#define NEED_CMOV      (1<<X86_FEATURE_CMOV)
11479 +# define NEED_CMOV     (1<<(X86_FEATURE_CMOV & 31))
11480  #else
11481 -#define NEED_CMOV      0
11482 +# define NEED_CMOV     0
11483  #endif
11484  
11485  #ifdef CONFIG_X86_CMPXCHG64
11486 -#define NEED_CMPXCHG64  (1<<X86_FEATURE_CX8)
11487 +# define NEED_CX8      (1<<(X86_FEATURE_CX8 & 31))
11488 +#else
11489 +# define NEED_CX8      0
11490 +#endif
11491 +
11492 +#define REQUIRED_MASK0 (NEED_FPU|NEED_PAE|NEED_CMOV|NEED_CX8)
11493 +
11494 +#ifdef CONFIG_X86_USE_3DNOW
11495 +# define NEED_3DNOW    (1<<(X86_FEATURE_3DNOW & 31))
11496  #else
11497 -#define NEED_CMPXCHG64  0
11498 +# define NEED_3DNOW    0
11499  #endif
11500  
11501 -#define REQUIRED_MASK1 (NEED_PAE|NEED_CMOV|NEED_CMPXCHG64)
11502 +#define REQUIRED_MASK1 (NEED_3DNOW)
11503 +
11504 +#define REQUIRED_MASK2 0
11505 +#define REQUIRED_MASK3 0
11506 +#define REQUIRED_MASK4 0
11507 +#define REQUIRED_MASK5 0
11508 +#define REQUIRED_MASK6 0
11509 +#define REQUIRED_MASK7 0
11510  
11511  #endif
11512 diff -puN include/asm-i386/setup.h~git-newsetup include/asm-i386/setup.h
11513 --- a/include/asm-i386/setup.h~git-newsetup
11514 +++ a/include/asm-i386/setup.h
11515 @@ -26,12 +26,15 @@
11516  #define NEW_CL_POINTER         0x228   /* Relative to real mode data */
11517  
11518  #ifndef __ASSEMBLY__
11519 +
11520 +#include <asm/bootparam.h>
11521 +
11522  /*
11523   * This is set up by the setup-routine at boot-time
11524   */
11525 -extern unsigned char boot_params[PARAM_SIZE];
11526 +extern struct boot_params boot_params;
11527  
11528 -#define PARAM  (boot_params)
11529 +#define PARAM  ((char *)&boot_params)
11530  #define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
11531  #define EXT_MEM_K (*(unsigned short *) (PARAM+2))
11532  #define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
11533 @@ -39,8 +42,7 @@ extern unsigned char boot_params[PARAM_S
11534  #define E820_MAP    ((struct e820entry *) (PARAM+E820MAP))
11535  #define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
11536  #define IST_INFO   (*(struct ist_info *) (PARAM+0x60))
11537 -#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
11538 -#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
11539 +#define SYS_DESC_TABLE (*(struct sys_desc_table *)(PARAM+0xa0))
11540  #define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4)))
11541  #define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8)))
11542  #define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc)))
11543 diff -puN include/asm-x86_64/alternative.h~git-newsetup include/asm-x86_64/alternative.h
11544 --- a/include/asm-x86_64/alternative.h~git-newsetup
11545 +++ a/include/asm-x86_64/alternative.h
11546 @@ -5,6 +5,41 @@
11547  
11548  #include <linux/types.h>
11549  #include <linux/stddef.h>
11550 +
11551 +/*
11552 + * Alternative inline assembly for SMP.
11553 + *
11554 + * The LOCK_PREFIX macro defined here replaces the LOCK and
11555 + * LOCK_PREFIX macros used everywhere in the source tree.
11556 + *
11557 + * SMP alternatives use the same data structures as the other
11558 + * alternatives and the X86_FEATURE_UP flag to indicate the case of a
11559 + * UP system running a SMP kernel.  The existing apply_alternatives()
11560 + * works fine for patching a SMP kernel for UP.
11561 + *
11562 + * The SMP alternative tables can be kept after boot and contain both
11563 + * UP and SMP versions of the instructions to allow switching back to
11564 + * SMP at runtime, when hotplugging in a new CPU, which is especially
11565 + * useful in virtualized environments.
11566 + *
11567 + * The very common lock prefix is handled as special case in a
11568 + * separate table which is a pure address list without replacement ptr
11569 + * and size information.  That keeps the table sizes small.
11570 + */
11571 +
11572 +#ifdef CONFIG_SMP
11573 +#define LOCK_PREFIX \
11574 +               ".section .smp_locks,\"a\"\n"   \
11575 +               "  .align 8\n"                  \
11576 +               "  .quad 661f\n" /* address */  \
11577 +               ".previous\n"                   \
11578 +               "661:\n\tlock; "
11579 +
11580 +#else /* ! CONFIG_SMP */
11581 +#define LOCK_PREFIX ""
11582 +#endif
11583 +
11584 +/* This must be included *after* the definition of LOCK_PREFIX */
11585  #include <asm/cpufeature.h>
11586  
11587  struct alt_instr {
11588 @@ -108,39 +143,6 @@ static inline void alternatives_smp_swit
11589   */
11590  #define ASM_OUTPUT2(a, b) a, b
11591  
11592 -/*
11593 - * Alternative inline assembly for SMP.
11594 - *
11595 - * The LOCK_PREFIX macro defined here replaces the LOCK and
11596 - * LOCK_PREFIX macros used everywhere in the source tree.
11597 - *
11598 - * SMP alternatives use the same data structures as the other
11599 - * alternatives and the X86_FEATURE_UP flag to indicate the case of a
11600 - * UP system running a SMP kernel.  The existing apply_alternatives()
11601 - * works fine for patching a SMP kernel for UP.
11602 - *
11603 - * The SMP alternative tables can be kept after boot and contain both
11604 - * UP and SMP versions of the instructions to allow switching back to
11605 - * SMP at runtime, when hotplugging in a new CPU, which is especially
11606 - * useful in virtualized environments.
11607 - *
11608 - * The very common lock prefix is handled as special case in a
11609 - * separate table which is a pure address list without replacement ptr
11610 - * and size information.  That keeps the table sizes small.
11611 - */
11612 -
11613 -#ifdef CONFIG_SMP
11614 -#define LOCK_PREFIX \
11615 -               ".section .smp_locks,\"a\"\n"   \
11616 -               "  .align 8\n"                  \
11617 -               "  .quad 661f\n" /* address */  \
11618 -               ".previous\n"                   \
11619 -               "661:\n\tlock; "
11620 -
11621 -#else /* ! CONFIG_SMP */
11622 -#define LOCK_PREFIX ""
11623 -#endif
11624 -
11625  struct paravirt_patch;
11626  #ifdef CONFIG_PARAVIRT
11627  void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end);
11628 diff -puN include/asm-x86_64/boot.h~git-newsetup include/asm-x86_64/boot.h
11629 --- a/include/asm-x86_64/boot.h~git-newsetup
11630 +++ a/include/asm-x86_64/boot.h
11631 @@ -1,15 +1 @@
11632 -#ifndef _LINUX_BOOT_H
11633 -#define _LINUX_BOOT_H
11634 -
11635 -/* Don't touch these, unless you really know what you're doing. */
11636 -#define DEF_INITSEG    0x9000
11637 -#define DEF_SYSSEG     0x1000
11638 -#define DEF_SETUPSEG   0x9020
11639 -#define DEF_SYSSIZE    0x7F00
11640 -
11641 -/* Internal svga startup constants */
11642 -#define NORMAL_VGA     0xffff          /* 80x25 mode */
11643 -#define EXTENDED_VGA   0xfffe          /* 80x50 mode */
11644 -#define ASK_VGA                0xfffd          /* ask for it at bootup */
11645 -
11646 -#endif
11647 +#include <asm-i386/boot.h>
11648 diff -puN /dev/null include/asm-x86_64/bootparam.h
11649 --- /dev/null
11650 +++ a/include/asm-x86_64/bootparam.h
11651 @@ -0,0 +1 @@
11652 +#include <asm-i386/bootparam.h>
11653 diff -puN include/asm-x86_64/cpufeature.h~git-newsetup include/asm-x86_64/cpufeature.h
11654 --- a/include/asm-x86_64/cpufeature.h~git-newsetup
11655 +++ a/include/asm-x86_64/cpufeature.h
11656 @@ -7,115 +7,24 @@
11657  #ifndef __ASM_X8664_CPUFEATURE_H
11658  #define __ASM_X8664_CPUFEATURE_H
11659  
11660 -#define NCAPINTS       7       /* N 32-bit words worth of info */
11661 +#include <asm-i386/cpufeature.h>
11662  
11663 -/* Intel-defined CPU features, CPUID level 0x00000001, word 0 */
11664 -#define X86_FEATURE_FPU                (0*32+ 0) /* Onboard FPU */
11665 -#define X86_FEATURE_VME                (0*32+ 1) /* Virtual Mode Extensions */
11666 -#define X86_FEATURE_DE         (0*32+ 2) /* Debugging Extensions */
11667 -#define X86_FEATURE_PSE        (0*32+ 3) /* Page Size Extensions */
11668 -#define X86_FEATURE_TSC                (0*32+ 4) /* Time Stamp Counter */
11669 -#define X86_FEATURE_MSR                (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
11670 -#define X86_FEATURE_PAE                (0*32+ 6) /* Physical Address Extensions */
11671 -#define X86_FEATURE_MCE                (0*32+ 7) /* Machine Check Architecture */
11672 -#define X86_FEATURE_CX8                (0*32+ 8) /* CMPXCHG8 instruction */
11673 -#define X86_FEATURE_APIC       (0*32+ 9) /* Onboard APIC */
11674 -#define X86_FEATURE_SEP                (0*32+11) /* SYSENTER/SYSEXIT */
11675 -#define X86_FEATURE_MTRR       (0*32+12) /* Memory Type Range Registers */
11676 -#define X86_FEATURE_PGE                (0*32+13) /* Page Global Enable */
11677 -#define X86_FEATURE_MCA                (0*32+14) /* Machine Check Architecture */
11678 -#define X86_FEATURE_CMOV       (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
11679 -#define X86_FEATURE_PAT                (0*32+16) /* Page Attribute Table */
11680 -#define X86_FEATURE_PSE36      (0*32+17) /* 36-bit PSEs */
11681 -#define X86_FEATURE_PN         (0*32+18) /* Processor serial number */
11682 -#define X86_FEATURE_CLFLSH     (0*32+19) /* Supports the CLFLUSH instruction */
11683 -#define X86_FEATURE_DS         (0*32+21) /* Debug Store */
11684 -#define X86_FEATURE_ACPI       (0*32+22) /* ACPI via MSR */
11685 -#define X86_FEATURE_MMX                (0*32+23) /* Multimedia Extensions */
11686 -#define X86_FEATURE_FXSR       (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
11687 -                                         /* of FPU context), and CR4.OSFXSR available */
11688 -#define X86_FEATURE_XMM                (0*32+25) /* Streaming SIMD Extensions */
11689 -#define X86_FEATURE_XMM2       (0*32+26) /* Streaming SIMD Extensions-2 */
11690 -#define X86_FEATURE_SELFSNOOP  (0*32+27) /* CPU self snoop */
11691 -#define X86_FEATURE_HT         (0*32+28) /* Hyper-Threading */
11692 -#define X86_FEATURE_ACC                (0*32+29) /* Automatic clock control */
11693 -#define X86_FEATURE_IA64       (0*32+30) /* IA-64 processor */
11694 -
11695 -/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
11696 -/* Don't duplicate feature flags which are redundant with Intel! */
11697 -#define X86_FEATURE_SYSCALL    (1*32+11) /* SYSCALL/SYSRET */
11698 -#define X86_FEATURE_MMXEXT     (1*32+22) /* AMD MMX extensions */
11699 -#define X86_FEATURE_FXSR_OPT   (1*32+25) /* FXSR optimizations */
11700 -#define X86_FEATURE_RDTSCP     (1*32+27) /* RDTSCP */
11701 -#define X86_FEATURE_LM         (1*32+29) /* Long Mode (x86-64) */
11702 -#define X86_FEATURE_3DNOWEXT   (1*32+30) /* AMD 3DNow! extensions */
11703 -#define X86_FEATURE_3DNOW      (1*32+31) /* 3DNow! */
11704 -
11705 -/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
11706 -#define X86_FEATURE_RECOVERY   (2*32+ 0) /* CPU in recovery mode */
11707 -#define X86_FEATURE_LONGRUN    (2*32+ 1) /* Longrun power control */
11708 -#define X86_FEATURE_LRTI       (2*32+ 3) /* LongRun table interface */
11709 -
11710 -/* Other features, Linux-defined mapping, word 3 */
11711 -/* This range is used for feature bits which conflict or are synthesized */
11712 -#define X86_FEATURE_CXMMX      (3*32+ 0) /* Cyrix MMX extensions */
11713 -#define X86_FEATURE_K6_MTRR    (3*32+ 1) /* AMD K6 nonstandard MTRRs */
11714 -#define X86_FEATURE_CYRIX_ARR  (3*32+ 2) /* Cyrix ARRs (= MTRRs) */
11715 -#define X86_FEATURE_CENTAUR_MCR        (3*32+ 3) /* Centaur MCRs (= MTRRs) */
11716 -#define X86_FEATURE_REP_GOOD   (3*32+ 4) /* rep microcode works well on this CPU */
11717 -#define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */
11718 -#define X86_FEATURE_SYNC_RDTSC  (3*32+6)  /* RDTSC syncs CPU core */
11719 -#define X86_FEATURE_FXSAVE_LEAK (3*32+7)  /* FIP/FOP/FDP leaks through FXSAVE */
11720 -#define X86_FEATURE_UP         (3*32+8) /* SMP kernel running on UP */
11721 -#define X86_FEATURE_ARCH_PERFMON (3*32+9) /* Intel Architectural PerfMon */
11722 -#define X86_FEATURE_PEBS       (3*32+10) /* Precise-Event Based Sampling */
11723 -#define X86_FEATURE_BTS                (3*32+11) /* Branch Trace Store */
11724 -
11725 -/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
11726 -#define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */
11727 -#define X86_FEATURE_MWAIT      (4*32+ 3) /* Monitor/Mwait support */
11728 -#define X86_FEATURE_DSCPL      (4*32+ 4) /* CPL Qualified Debug Store */
11729 -#define X86_FEATURE_EST                (4*32+ 7) /* Enhanced SpeedStep */
11730 -#define X86_FEATURE_TM2                (4*32+ 8) /* Thermal Monitor 2 */
11731 -#define X86_FEATURE_CID                (4*32+10) /* Context ID */
11732 -#define X86_FEATURE_CX16       (4*32+13) /* CMPXCHG16B */
11733 -#define X86_FEATURE_XTPR       (4*32+14) /* Send Task Priority Messages */
11734 -
11735 -/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
11736 -#define X86_FEATURE_XSTORE     (5*32+ 2) /* on-CPU RNG present (xstore insn) */
11737 -#define X86_FEATURE_XSTORE_EN  (5*32+ 3) /* on-CPU RNG enabled */
11738 -#define X86_FEATURE_XCRYPT     (5*32+ 6) /* on-CPU crypto (xcrypt insn) */
11739 -#define X86_FEATURE_XCRYPT_EN  (5*32+ 7) /* on-CPU crypto enabled */
11740 -
11741 -/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
11742 -#define X86_FEATURE_LAHF_LM    (6*32+ 0) /* LAHF/SAHF in long mode */
11743 -#define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */
11744 -
11745 -#define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
11746 -#define boot_cpu_has(bit)      test_bit(bit, boot_cpu_data.x86_capability)
11747 -
11748 -#define cpu_has_fpu            1
11749 +#undef  cpu_has_vme
11750  #define cpu_has_vme            0
11751 -#define cpu_has_de             1
11752 -#define cpu_has_pse            1
11753 -#define cpu_has_tsc            1
11754 +
11755 +#undef  cpu_has_pae
11756  #define cpu_has_pae            ___BUG___
11757 -#define cpu_has_pge            1
11758 -#define cpu_has_apic           boot_cpu_has(X86_FEATURE_APIC)
11759 -#define cpu_has_mtrr           1
11760 -#define cpu_has_mmx            1
11761 -#define cpu_has_fxsr           1
11762 -#define cpu_has_xmm            1
11763 -#define cpu_has_xmm2           1
11764 -#define cpu_has_xmm3           boot_cpu_has(X86_FEATURE_XMM3)
11765 -#define cpu_has_ht             boot_cpu_has(X86_FEATURE_HT)
11766 +
11767 +#undef  cpu_has_mp
11768  #define cpu_has_mp             1 /* XXX */
11769 +
11770 +#undef  cpu_has_k6_mtrr
11771  #define cpu_has_k6_mtrr        0
11772 +
11773 +#undef  cpu_has_cyrix_arr
11774  #define cpu_has_cyrix_arr      0
11775 +
11776 +#undef  cpu_has_centaur_mcr
11777  #define cpu_has_centaur_mcr    0
11778 -#define cpu_has_clflush               boot_cpu_has(X86_FEATURE_CLFLSH)
11779 -#define cpu_has_ds            boot_cpu_has(X86_FEATURE_DS)
11780 -#define cpu_has_pebs          boot_cpu_has(X86_FEATURE_PEBS)
11781 -#define cpu_has_bts           boot_cpu_has(X86_FEATURE_BTS)
11782  
11783  #endif /* __ASM_X8664_CPUFEATURE_H */
11784 diff -puN include/asm-x86_64/e820.h~git-newsetup include/asm-x86_64/e820.h
11785 --- a/include/asm-x86_64/e820.h~git-newsetup
11786 +++ a/include/asm-x86_64/e820.h
11787 @@ -11,7 +11,9 @@
11788  #ifndef __E820_HEADER
11789  #define __E820_HEADER
11790  
11791 -#include <linux/mmzone.h>
11792 +#ifndef _SETUP
11793 +# include <linux/mmzone.h>
11794 +#endif
11795  
11796  #define E820MAP        0x2d0           /* our map */
11797  #define E820MAX        128             /* number of entries in E820MAP */
11798 @@ -30,7 +32,7 @@ struct e820entry {
11799  } __attribute__((packed));
11800  
11801  struct e820map {
11802 -    int nr_map;
11803 +       u32 nr_map;
11804         struct e820entry map[E820MAX];
11805  };
11806  
11807 diff -puN include/asm-x86_64/processor.h~git-newsetup include/asm-x86_64/processor.h
11808 --- a/include/asm-x86_64/processor.h~git-newsetup
11809 +++ a/include/asm-x86_64/processor.h
11810 @@ -99,6 +99,7 @@ extern char ignore_irq13;
11811  
11812  extern void identify_cpu(struct cpuinfo_x86 *);
11813  extern void print_cpu_info(struct cpuinfo_x86 *);
11814 +extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
11815  extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
11816  extern unsigned short num_cache_leaves;
11817  
11818 @@ -367,8 +368,6 @@ static inline void sync_core(void)
11819         asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
11820  } 
11821  
11822 -#define cpu_has_fpu 1
11823 -
11824  #define ARCH_HAS_PREFETCH
11825  static inline void prefetch(void *x) 
11826  { 
11827 diff -puN /dev/null include/asm-x86_64/required-features.h
11828 --- /dev/null
11829 +++ a/include/asm-x86_64/required-features.h
11830 @@ -0,0 +1,46 @@
11831 +#ifndef _ASM_REQUIRED_FEATURES_H
11832 +#define _ASM_REQUIRED_FEATURES_H 1
11833 +
11834 +/* Define minimum CPUID feature set for kernel These bits are checked
11835 +   really early to actually display a visible error message before the
11836 +   kernel dies.  Make sure to assign features to the proper mask!
11837 +
11838 +   The real information is in arch/x86_64/Kconfig.cpu, this just converts
11839 +   the CONFIGs into a bitmask */
11840 +
11841 +/* x86-64 baseline features */
11842 +#define NEED_FPU       (1<<(X86_FEATURE_FPU & 31))
11843 +#define NEED_PSE       (1<<(X86_FEATURE_PSE & 31))
11844 +#define NEED_MSR       (1<<(X86_FEATURE_MSR & 31))
11845 +#define NEED_PAE       (1<<(X86_FEATURE_PAE & 31))
11846 +#define NEED_CX8       (1<<(X86_FEATURE_CX8 & 31))
11847 +#define NEED_PGE       (1<<(X86_FEATURE_PGE & 31))
11848 +#define NEED_FXSR      (1<<(X86_FEATURE_FXSR & 31))
11849 +#define NEED_CMOV      (1<<(X86_FEATURE_CMOV & 31))
11850 +#define NEED_XMM       (1<<(X86_FEATURE_XMM & 31))
11851 +#define NEED_XMM2      (1<<(X86_FEATURE_XMM2 & 31))
11852 +
11853 +#define REQUIRED_MASK0 (NEED_FPU|NEED_PSE|NEED_MSR|NEED_PAE|\
11854 +                        NEED_CX8|NEED_PGE|NEED_FXSR|NEED_CMOV|\
11855 +                        NEED_XMM|NEED_XMM2)
11856 +#define SSE_MASK       (NEED_XMM|NEED_XMM2)
11857 +
11858 +/* x86-64 baseline features */
11859 +#define NEED_LM                (1<<(X86_FEATURE_LM & 31))
11860 +
11861 +#ifdef CONFIG_X86_USE_3DNOW
11862 +# define NEED_3DNOW    (1<<(X86_FEATURE_3DNOW & 31))
11863 +#else
11864 +# define NEED_3DNOW    0
11865 +#endif
11866 +
11867 +#define REQUIRED_MASK1 (NEED_LM|NEED_3DNOW)
11868 +
11869 +#define REQUIRED_MASK2 0
11870 +#define REQUIRED_MASK3 0
11871 +#define REQUIRED_MASK4 0
11872 +#define REQUIRED_MASK5 0
11873 +#define REQUIRED_MASK6 0
11874 +#define REQUIRED_MASK7 0
11875 +
11876 +#endif
11877 diff -puN include/asm-x86_64/segment.h~git-newsetup include/asm-x86_64/segment.h
11878 --- a/include/asm-x86_64/segment.h~git-newsetup
11879 +++ a/include/asm-x86_64/segment.h
11880 @@ -3,6 +3,14 @@
11881  
11882  #include <asm/cache.h>
11883  
11884 +/* Simple and small GDT entries for booting only */
11885 +
11886 +#define GDT_ENTRY_BOOT_CS              2
11887 +#define __BOOT_CS      (GDT_ENTRY_BOOT_CS * 8)
11888 +
11889 +#define GDT_ENTRY_BOOT_DS              (GDT_ENTRY_BOOT_CS + 1)
11890 +#define __BOOT_DS      (GDT_ENTRY_BOOT_DS * 8)
11891 +
11892  #define __KERNEL_CS    0x10
11893  #define __KERNEL_DS    0x18
11894  
11895 diff -puN include/linux/edd.h~git-newsetup include/linux/edd.h
11896 --- a/include/linux/edd.h~git-newsetup
11897 +++ a/include/linux/edd.h
11898 @@ -49,10 +49,6 @@
11899  #define EDD_MBR_SIG_MAX 16        /* max number of signatures to store */
11900  #define EDD_MBR_SIG_NR_BUF 0x1ea  /* addr of number of MBR signtaures at EDD_MBR_SIG_BUF
11901                                      in boot_params - treat this as 1 byte  */
11902 -#define EDD_CL_EQUALS   0x3d646465     /* "edd=" */
11903 -#define EDD_CL_OFF      0x666f         /* "of" for off  */
11904 -#define EDD_CL_SKIP     0x6b73         /* "sk" for skipmbr */
11905 -#define EDD_CL_ON       0x6e6f        /* "on" for on */
11906  
11907  #ifndef __ASSEMBLY__
11908  
11909 diff -puN include/linux/screen_info.h~git-newsetup include/linux/screen_info.h
11910 --- a/include/linux/screen_info.h~git-newsetup
11911 +++ a/include/linux/screen_info.h
11912 @@ -10,7 +10,7 @@
11913  struct screen_info {
11914         u8  orig_x;             /* 0x00 */
11915         u8  orig_y;             /* 0x01 */
11916 -       u16 dontuse1;           /* 0x02 -- EXT_MEM_K sits here */
11917 +       u16 ext_mem_k;          /* 0x02 */
11918         u16 orig_video_page;    /* 0x04 */
11919         u8  orig_video_mode;    /* 0x06 */
11920         u8  orig_video_cols;    /* 0x07 */
11921 @@ -27,7 +27,7 @@ struct screen_info {
11922         u16 lfb_depth;          /* 0x16 */
11923         u32 lfb_base;           /* 0x18 */
11924         u32 lfb_size;           /* 0x1c */
11925 -       u16 dontuse2, dontuse3; /* 0x20 -- CL_MAGIC and CL_OFFSET here */
11926 +       u16 cl_magic, cl_offset; /* 0x20 */
11927         u16 lfb_linelength;     /* 0x24 */
11928         u8  red_size;           /* 0x26 */
11929         u8  red_pos;            /* 0x27 */
11930 @@ -42,9 +42,8 @@ struct screen_info {
11931         u16 pages;              /* 0x32 */
11932         u16 vesa_attributes;    /* 0x34 */
11933         u32 capabilities;       /* 0x36 */
11934 -                               /* 0x3a -- 0x3b reserved for future expansion */
11935 -                               /* 0x3c -- 0x3f micro stack for relocatable kernels */
11936 -};
11937 +       u8  _reserved[6];       /* 0x3a */
11938 +} __attribute__((packed));
11939  
11940  extern struct screen_info screen_info;
11941  
11942 _