|
|
@@ -1,11942 +0,0 @@
|
|
|
-GIT 1783e2f0f21444020e3dee1be46b1e34af0ea3e7 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/hpa/linux-2.6-newsetup.git
|
|
|
-
|
|
|
-commit 1783e2f0f21444020e3dee1be46b1e34af0ea3e7
|
|
|
-Author: Venki Pallipadi <[email protected]>
|
|
|
-Date: Wed Jun 20 14:12:39 2007 -0700
|
|
|
-
|
|
|
- Use a new CPU feature word to cover all Intel features that are spread around
|
|
|
-
|
|
|
- in different CPUID leafs like 0x5, 0x6 and 0xA. Make this
|
|
|
- feature detection code common across i386 and x86_64.
|
|
|
-
|
|
|
- Display Intel Dynamic Acceleration feature in /proc/cpuinfo. This feature
|
|
|
- will be enabled automatically by current acpi-cpufreq driver.
|
|
|
-
|
|
|
- Refer to Intel Software Developer's Manual for more details about the feature.
|
|
|
-
|
|
|
- Thanks to hpa (H Peter Anvin) for the making the actual code detecting the
|
|
|
- scattered features data-driven.
|
|
|
-
|
|
|
- Signed-off-by: Venkatesh Pallipadi <[email protected]>
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit cd19eb67cd6636a4e5c9df99631422c7c7286f59
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed Jun 20 14:33:17 2007 -0700
|
|
|
-
|
|
|
- x86 setup: move __bss_start into the .bss segment
|
|
|
-
|
|
|
- Move __bss_start into the .bss segment, and create __bss_end.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 100327ad6b609cd28970219be57d293847d1261d
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed Jun 6 22:07:01 2007 -0700
|
|
|
-
|
|
|
- x86 setup: remove TSC as a required feature
|
|
|
-
|
|
|
- Remove TSC as a required feature, in anticipation of CONFIG_X86_TSC
|
|
|
- removal.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 7c91a172b8af7d4ba087f1f88ed5b155ed459ca3
|
|
|
-Author: Antonino A. Daplas <[email protected]>
|
|
|
-Date: Tue Jun 5 19:21:05 2007 +0800
|
|
|
-
|
|
|
- i386: Set 6-bit DAC channel properties in vesa video setup
|
|
|
-
|
|
|
- If the video BIOS is not capable of switching or failed to switch the
|
|
|
- hardware to 8-bit DAC, the channel properties are not set. This leads
|
|
|
- to a blank (all black) display with vesafb at 8 bpp. Fix by defaulting
|
|
|
- to a 6-bit DAC.
|
|
|
-
|
|
|
- Signed-off-by: Antonino Daplas <[email protected]>
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 6eac2d442de8d87eac94a4ca8600bd87219fa06b
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue Jun 5 16:19:36 2007 -0700
|
|
|
-
|
|
|
- x86 setup: arch/i386/boot/cpucheck.c whitespace cleanup
|
|
|
-
|
|
|
- Remove stealth whitespace
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit f7d89f05a30433034a1b4651143afdbb2a8a9c92
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 24 16:56:44 2007 -0700
|
|
|
-
|
|
|
- hd.c: remove BIOS/CMOS queries
|
|
|
-
|
|
|
- An ST-506 disk these days is pretty much someone trying to pull ancient
|
|
|
- data using an auxilliary controller. Pulling data from the BIOS or CMOS
|
|
|
- is just plain wrong, since it's likely to be the primary OS disk... and
|
|
|
- would be user-entered data anyway. Instead, require the user enters it
|
|
|
- on the command line.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 14c2fdb3bbfd6a9a774980e446c2443150749891
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 24 15:25:10 2007 -0700
|
|
|
-
|
|
|
- x86: add back pbe bit to visible CPUID flags
|
|
|
-
|
|
|
- Add pbe back to the visible CPUID flags. We *do* correctly filter abuses
|
|
|
- of this bit for 3DNow! in all the appropriate paths.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit e071b068a3b9f318be314f0378e655e2eb50ac89
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 23 14:52:34 2007 -0700
|
|
|
-
|
|
|
- x86 setup: VIA feature mask MSR doesn't just apply to model <= 9
|
|
|
-
|
|
|
- The VIA feature mask MSR is known to be present on model 10, and it
|
|
|
- seems likely it will continue to be supported. Since we only touch the
|
|
|
- MSR if we're about to print an error message anyway, go ahead and be
|
|
|
- aggressive.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit abe0c5aa1827932cda9c754a3842ec22b278d704
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 22 17:17:41 2007 -0700
|
|
|
-
|
|
|
- x86 setup: correct inline assembly constraints in edd.c
|
|
|
-
|
|
|
- Fix the inline assembly constraints in edd.c. In particular, "driveno"
|
|
|
- was getting clobbered on some (buggy?) BIOSes.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit c2e5887ad275aab90673a3e33344f09946159cf7
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 18 10:02:55 2007 -0700
|
|
|
-
|
|
|
- x86 setup: force the assembler to generate a 2-byte jump in header
|
|
|
-
|
|
|
- The jump instruction in the header only has two bytes available, so
|
|
|
- it *better* be a 2-byte jump! Unfortunately, the assembler will
|
|
|
- always generate a 3/5-byte jump when the target is in a different
|
|
|
- section. Deal with that by generating the jump instruction
|
|
|
- explicitly from .byte's, just like we do elsewhere when we need a
|
|
|
- specific binary representation of a certain instruction.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit ce82e3b93eba48b6852822a03efa73c74e165d4f
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 17 15:44:48 2007 -0700
|
|
|
-
|
|
|
- x86 setup: move the symbol start_of_setup into the proper section.
|
|
|
-
|
|
|
- start_of_setup is the beginning of the executable code and should be
|
|
|
- located in the appropriate section.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit e5f3a529457a5bfaf8f8783fb86013221279a81c
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 17 15:43:19 2007 -0700
|
|
|
-
|
|
|
- x86 setup: add an ASSERT that the header ends up in the right place
|
|
|
-
|
|
|
- Just in case we have funnies involving the linker or people putting
|
|
|
- inappropriate align statements, make the linker abort if the setup
|
|
|
- header ends up in the wrong place.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit d9dbde725687ab99d1f529f49f14d1e280cc5cac
|
|
|
-Author: Alexander van Heukelum <[email protected]>
|
|
|
-Date: Thu May 17 20:54:25 2007 +0200
|
|
|
-
|
|
|
- x86 new setup: use appropriate sections for code and data
|
|
|
-
|
|
|
- An intermediate elf file is generated for the 16-bit setup code.
|
|
|
- The generated code can be viewed using objdump -m i8086 -d. As it
|
|
|
- stands, it also tries to disassemble the bugger_off_msg, which
|
|
|
- results in garbage. This introduces two new sections to separate
|
|
|
- the code and the data part of the bootsector stub. It also moves
|
|
|
- some code from the .header section (a data section) to .inittext.
|
|
|
-
|
|
|
- Signed-off-by: Alexander van Heukelum <[email protected]>
|
|
|
-
|
|
|
-commit 0d7558a81cf61e9fd2332a54897c5fd18df0d7f2
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 16 22:03:16 2007 -0700
|
|
|
-
|
|
|
- x86 setup: use -include code16gcc.h instead of explicit #include
|
|
|
-
|
|
|
- Use -include in the Makefile instead of #include to include code16gcc.h.
|
|
|
- This really is more of a compiler switch than anything else, and is a lot
|
|
|
- cleaner to do implicitly.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 017ce54e8a4a9628a76d6b510c7309a7e4e111a8
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 16 18:48:06 2007 -0700
|
|
|
-
|
|
|
- x86 setup: enable features on Centaur (VIA) and Transmeta processors
|
|
|
-
|
|
|
- AMD are not the only ones who sometimes mask features which the kernel
|
|
|
- may very well depend on. VIA and Transmeta do, too. Add code to enable
|
|
|
- these features during checking.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit b794f5f9c5089709f3df38c6d91869fa38a9c1a4
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 16 16:37:47 2007 -0700
|
|
|
-
|
|
|
- x86 setup: in older versions of ld, ASSERT() is an expression
|
|
|
-
|
|
|
- Older versions of ld (pre-2.15 or so) need:
|
|
|
-
|
|
|
- . = ASSERT(foo, "msg");
|
|
|
-
|
|
|
- instead of:
|
|
|
-
|
|
|
- ASSERT(foo, "msg")
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 21c2b7c99c417d07015ee8e516a634ec3d98c4ee
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 16 10:52:41 2007 -0700
|
|
|
-
|
|
|
- x86 setup: print a warning message if the bootloader gave us no heap.
|
|
|
-
|
|
|
- If the bootloader is so old it doesn't set the CAN_USE_HEAP flag,
|
|
|
- a lot of functionality will by necessity be disabled, so print a
|
|
|
- warning message. This means either a 2.00 protocol bootloader or
|
|
|
- a buggy bootloader; the Qemu bootloader falls in this category.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 52ca0431390d389a2a2246f02fe652ea84c1ddd8
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 16 10:51:03 2007 -0700
|
|
|
-
|
|
|
- x86 setup: rely on a compiled-in default for load high/load low
|
|
|
-
|
|
|
- When deciding if we should move the kernel from 0x10000 to 0x1000, as
|
|
|
- is required for a zImage kernel, rely on a compiled-in default since
|
|
|
- Qemu unconditionally zeroes the loadflags. This, of course, is a bug
|
|
|
- in Qemu, but still...
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 4db77a97793104a32e5fb83e62b943fa144b329d
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 16 08:45:37 2007 -0700
|
|
|
-
|
|
|
- x86 setup: correct assembly constraints.
|
|
|
-
|
|
|
- Double use of "d" in an asm() constraints; most gcc versions correctly
|
|
|
- detect and avoid using it, but some version of gcc runs itself into
|
|
|
- a brick wall instead. Fix the one "d" which should have been "a".
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 4fbccbc1457d6710d3a9ce55ad70ec6cb0b75fc5
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 15 09:16:29 2007 -0700
|
|
|
-
|
|
|
- x86 setup: include <asm/msr-index.h> not <asm/msr.h>
|
|
|
-
|
|
|
- <asm/msr.h> brings in the accessor functions, which may potentially
|
|
|
- bring in all other kinds of kernel headers which are inappropriate for
|
|
|
- the setup code. For the setup code, include <asm/msr-index.h>
|
|
|
- instead, which only includes the numeric constants.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 839cafa9c0020e7506722dd2a4fd82a71c2939cc
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Mon May 14 15:49:01 2007 -0700
|
|
|
-
|
|
|
- x86 setup: protocol 2.0[01]: base for CL_OFFSET depends on setup_move_size
|
|
|
-
|
|
|
- Handle the use of boot protocol 2.00 and 2.01: the base segment for
|
|
|
- CL_OFFSET depends on the value of setup_move_size.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit d60357ad68a694b03e9b952eadba5ac277c31df0
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Sat May 12 12:18:53 2007 -0700
|
|
|
-
|
|
|
- x86 setup: remove unused variable
|
|
|
-
|
|
|
- Remove unused variable
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit e21a2030b01081612259847321bcce13eae1e883
|
|
|
-Author: Sam Ravnborg <[email protected]>
|
|
|
-Date: Sat May 12 12:17:30 2007 -0700
|
|
|
-
|
|
|
- x86 setup: share i386 Makefile with x86_64
|
|
|
-
|
|
|
- The boot Makefile for i386 and x86_64 are equal
|
|
|
- except for the CFLAGS setting.
|
|
|
- Teach x86_64 to use the Makefile from i386 and
|
|
|
- make CFLAGS setting arch dependent in i386 Makefile.
|
|
|
-
|
|
|
- Signed-off-by: Sam Ravnborg <[email protected]>
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 8618d92339d0d106045f98f34833d863c3235cdb
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Sat May 12 00:32:12 2007 -0700
|
|
|
-
|
|
|
- x86 setup: video-bios.c missed the pointer to the set_mode method!
|
|
|
-
|
|
|
- We need the actual pointer to the set_mode method (oops!)
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 85dfc374ea9aad33b9e0315f07a4b2722dc11e3e
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Sat May 12 00:14:43 2007 -0700
|
|
|
-
|
|
|
- x86 setup: when setting unknown BIOS modes and failing, try to revert
|
|
|
-
|
|
|
- If we set an unknown BIOS mode and fail, then explicitly try to revert
|
|
|
- to the original mode.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit f4f7949f126d2f152b09fa9367b1ec693f2ea818
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 11 11:20:59 2007 -0700
|
|
|
-
|
|
|
- x86 setup: fix typo "video_bios" should be "video-bios"
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 51ba7113ea5b07189b7f8a0534d400a072535197
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 11 11:09:55 2007 -0700
|
|
|
-
|
|
|
- x86 setup: allow setting VESA modes "blind"
|
|
|
-
|
|
|
- Apparently, people really do set VESA modes "blind". As a result, make
|
|
|
- the framework for settting blind modes more general, to remove some
|
|
|
- special cases.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 1b8f73d9b2bf7630a2914ddab606db16fddb509e
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 10 22:08:45 2007 -0700
|
|
|
-
|
|
|
- x86_64: CONFIG_PHYSICAL_ALIGN should be 2 MB
|
|
|
-
|
|
|
- It's not actually used yet, but set CONFIG_PHYSICAL_ALIGN to 2 MB
|
|
|
- as it should be, to prevent conflicts with other works in progress.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit b81f3c88923e4470cd0942d4596fafc0fb1cf4fd
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 10 19:11:32 2007 -0700
|
|
|
-
|
|
|
- x86 setup: remove debugging statements
|
|
|
-
|
|
|
- Remove debugging statements in video.c that were not meant for
|
|
|
- production.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit be58b6d7e9c14e482bce495e8343955999dea77f
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 10 18:49:40 2007 -0700
|
|
|
-
|
|
|
- x86 setup: only restore the screen image when needed
|
|
|
-
|
|
|
- Only restore the screen image when needed. This is how the original
|
|
|
- code behaves, so it's presumably the desired behaviour.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 22f6bd8cc23b512af28e34ae7d40036982a0ac63
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 10 18:44:08 2007 -0700
|
|
|
-
|
|
|
- x86 setup: correct the definition of the GDT limit
|
|
|
-
|
|
|
- Like all other x86 segment limits, the GDT limit points to the last byte
|
|
|
- that is *permitted* to access, so it needs to be sizeof(boot_gdt)-1.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 7f73f1f4aa4c97745bffe07a3ebcf226a4965b00
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 10 15:47:48 2007 -0700
|
|
|
-
|
|
|
- x86 setup: Re-implement scanning for hidden video modes
|
|
|
-
|
|
|
- Re-implement scanning for hidden video modes. Every now and then,
|
|
|
- apparently, you can find them hidden like easter eggs.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 6770176714bc12ec92372311ac02c14f0d22776e
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 10 15:24:27 2007 -0700
|
|
|
-
|
|
|
- x86 setup: whitespace cleanup
|
|
|
-
|
|
|
- Clean up stealth whitespace.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit ba0480a3537cf471b08bdb99dae6d0780cfb1972
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 9 16:54:42 2007 -0700
|
|
|
-
|
|
|
- x86: sync the CPU feature string arrays
|
|
|
-
|
|
|
- With <asm/cpufeature.h> unified, synchronize the CPU feature string
|
|
|
- arrays. The whole kernel/cpu directory really needs to be unified.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit ecb53b84efddbad3d9aa49e95598550831324348
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 8 22:06:04 2007 -0700
|
|
|
-
|
|
|
- x86 setup: need to set orig_video_isVGA
|
|
|
-
|
|
|
- After detecting a VGA console, we need to set
|
|
|
- boot_params.screen_info.orig_video_isVGA.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit dc97fc053faff17b984ec962686caea52bd27628
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 8 20:51:17 2007 -0700
|
|
|
-
|
|
|
- x86 setup: boot sector should use ljmp, not jmpl
|
|
|
-
|
|
|
- We have an "jmpl" instruction in the boot sector, which was meant
|
|
|
- to be an "ljmp" instruction. It worked anyway because gas interpreted
|
|
|
- a two-argument "jmpl" as an "ljmpl" instruction, however, use plain
|
|
|
- "ljmp" (i.e. "ljmpw".)
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 7907f05e9692557c53c9ac13647db5e5343c7c76
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 8 20:27:10 2007 -0700
|
|
|
-
|
|
|
- x86 setup: only make VESA graphics modes selectable if CONFIG_FB
|
|
|
-
|
|
|
- If we select a VESA graphics mode, we better have framebuffer support
|
|
|
- or the user will have no console. Therefore, make these modes
|
|
|
- non-selectable if CONFIG_FB is not set.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 8e509f9ebc44f45544d231454e84f10bf78d5772
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 8 20:24:11 2007 -0700
|
|
|
-
|
|
|
- x86 setup: need to probe VESA EDID block 0 only
|
|
|
-
|
|
|
- The VESA EDID BIOS call takes the EDID block number in %dx, and may
|
|
|
- corrupt it by spec. Pass it in properly.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 9912b9aed7943773d1fadaa2e2e52f42af395048
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Mon May 7 18:22:04 2007 -0700
|
|
|
-
|
|
|
- x86 setup: add missing file "bitops.h" missing from previous checkins
|
|
|
-
|
|
|
- The file "bitops.h" was missing from previous checkins.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 732eb3fac2d772980e6555b8c69902c8107c72aa
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Mon May 7 14:59:43 2007 -0700
|
|
|
-
|
|
|
- x86 setup: add -fno-stack-protector; other Makefile fixes
|
|
|
-
|
|
|
- Add -fno-stack-protector for the gcc's that need that;
|
|
|
- Use -ffreestanding consistently;
|
|
|
- Use $(LINUXINCLUDE);
|
|
|
- Handle linker scripts consistently with other Makefiles.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 2d5e47f21202e156fe97aba0a88d158d5c157a33
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Mon May 7 14:45:25 2007 -0700
|
|
|
-
|
|
|
- x86 setup: swap cpu.c and cpucheck.c; rename functions
|
|
|
-
|
|
|
- Make cpucheck.c the reusable component; the generically-named cpu.c
|
|
|
- gets to be the wrapper. Accordingly, rename functions to make it
|
|
|
- less confusing.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit bf2a428a4e7c1ee3ab9acb23cfafb45e818887a1
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Mon May 7 14:09:38 2007 -0700
|
|
|
-
|
|
|
- x86 setup: remove code moved from cpucheck.c -> cpu.c
|
|
|
-
|
|
|
- Move all info about requirements into cpu.c.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 9ea8429fabe5df6aed6393ac3a00d0b64445ba6a
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Mon May 7 09:42:51 2007 -0700
|
|
|
-
|
|
|
- x86 setup: remove double nesting of a20_test()
|
|
|
-
|
|
|
- a20_test() was invoked as either a20_test() or a20_wait(), where the
|
|
|
- latter was simply a loop around a loop. Make the count a parameter
|
|
|
- instead; this is clearer and saves a couple of bytes.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 9edc55718f57195c664ee3175514d652f651cfd2
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Mon May 7 09:30:41 2007 -0700
|
|
|
-
|
|
|
- x86 setup: compile with -fomit-frame-pointer
|
|
|
-
|
|
|
- Compiling with -fomit-frame-pointer reduces the size by about 2%.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit e1003433f2d491bf17c79437cd75268da220dab5
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Mon May 7 09:30:04 2007 -0700
|
|
|
-
|
|
|
- x86 setup: be more paranoid about the stack setup in header.S
|
|
|
-
|
|
|
- In particular, deal correctly with the stack pointer being zero on entry.
|
|
|
- While we're at it, align the stack.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 853499c3dc3fcbeb192a613ac241d150ebc7c5a0
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Sun May 6 23:25:10 2007 -0700
|
|
|
-
|
|
|
- x86 setup: Factor out the environment-independent part of the CPU check.
|
|
|
-
|
|
|
- Factor out the environment-independent part of the CPU check so it can
|
|
|
- be invoked from other parts of the kernel as well.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit f235a61f6d6dff57883efad351d746540bcb8caf
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Sat May 5 22:16:54 2007 -0700
|
|
|
-
|
|
|
- x86 setup: when watching the setup size, take the stack into account
|
|
|
-
|
|
|
- When watching the setup size, we have to take the stack into account.
|
|
|
- In particular, the stack is used not only by the setup code itself, but
|
|
|
- by BIOS interrupt handlers and system calls. Reserve a minimum of
|
|
|
- 512 bytes.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 0d0e10091be48f7e4c8888e9d5c2836c704994f5
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Sat May 5 19:25:51 2007 -0700
|
|
|
-
|
|
|
- x86 setup: actually check the end of the heap.
|
|
|
-
|
|
|
- Keep track of where the heap ends and actually watch out for it.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 47aab0b8f4d012fad3c42b5b0754d3cb87961b37
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Sat May 5 15:47:58 2007 -0700
|
|
|
-
|
|
|
- x86 setup: coppyright rPath, Inc.
|
|
|
-
|
|
|
- This work was done on the dime of rPath, Inc.; they own the copyright.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit d22571534d7eabf9408f29d9da423e1c6e04445f
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Sat May 5 15:21:11 2007 -0700
|
|
|
-
|
|
|
- x86 setup: implement screen contents save/restore
|
|
|
-
|
|
|
- The old setup code had screen contents save and restore, so implement
|
|
|
- it for the new one as well.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit e5145601a752bd998e783d159c187d3017d45d6d
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Sat May 5 15:20:19 2007 -0700
|
|
|
-
|
|
|
- x86 setup: whitespace cleanup
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 045ecb52f91a74eecad93ffc8791eefe59cf7fd1
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Sat May 5 14:22:39 2007 -0700
|
|
|
-
|
|
|
- x86 setup: allow setting of VESA graphics modes; cleanups
|
|
|
-
|
|
|
- - Allow setting of VESA graphics modes (used by vesafb)
|
|
|
- - Clean up the macros related to the heap
|
|
|
- - #if 0 copy functions that aren't actually currently being used
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 58c04ed7e2d7d5979e1917a74b49bdc0f3dde211
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Sat May 5 12:06:14 2007 -0700
|
|
|
-
|
|
|
- x86 setup: move all VESA-related code into video-vesa.c; add EDID
|
|
|
-
|
|
|
- - Move all VESA-related code into video-vesa.c
|
|
|
- - Add VESA EDID query support
|
|
|
- - Remove some totally obsolete definitions from video.h
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 07bc3931175fb98256140275c03194426d441b74
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Sat May 5 12:04:40 2007 -0700
|
|
|
-
|
|
|
- x86-64: remove -traditional from AFLAGS
|
|
|
-
|
|
|
- In arch/x86_64/boot/compressed, remove -traditional from AFLAGS.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit a830f615eeef838d461cbf7bbbee8c1c84708ec8
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 18:44:38 2007 -0700
|
|
|
-
|
|
|
- x86 setup: share code between i386 and x86-64
|
|
|
-
|
|
|
- Share the boot (setup) code and tools between i386 and x86-64.
|
|
|
- The compression code is now running in 64-bit mode in order to support
|
|
|
- relocation, so do *not* share that code.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 3e159a323bdfa5d5a7be2c1f6be089ca22d598e0
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 18:43:35 2007 -0700
|
|
|
-
|
|
|
- x86-64: use 0x1b4 as the scratch area in boot_params, not 0x3c
|
|
|
-
|
|
|
- Use 0x1b4 as the scratch area in boot_params rather than 0x3c.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 4cf4424e7a0f29f251b781f9b5e3655b0645cb7f
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 18:26:18 2007 -0700
|
|
|
-
|
|
|
- Revert "x86-64: Make arch/x86-64/boot a symlink to arch/i386/boot"
|
|
|
-
|
|
|
- This reverts commit b2ad90f4969226fe8cf3edc5330711ed5fc20105.
|
|
|
-
|
|
|
- Restore arch/x86_64/boot as a separate directory hierarchy.
|
|
|
-
|
|
|
- Conflicts:
|
|
|
-
|
|
|
-commit 8ed1ae1d2f94410811b7cca4b1a426e37652457f
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 17:00:33 2007 -0700
|
|
|
-
|
|
|
- x86-64: It appears MTRR isn't a required feature after all.
|
|
|
-
|
|
|
- MTRR was documented as a required feature, but appears to boot fine
|
|
|
- without it (tested since Bochs doesn't have MTRR support.)
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 7c616d098579fb790662cdc703f2a0f26ea1668c
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 16:22:57 2007 -0700
|
|
|
-
|
|
|
- x86 setup: use 0x1e4 as scratch, instead of 0x3c
|
|
|
-
|
|
|
- The compressed relocation needs a 4-byte scratch area to obtain
|
|
|
- its own address.
|
|
|
-
|
|
|
- 0x3c is at the end of the video area, which is quite constrained -- it
|
|
|
- only has 6 bytes left (12 if we recycle the obsolete fields which invade
|
|
|
- this space.) Define 0x1e4 as a scratch field, and use it.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 5bc1019227e94576e4876d05ee920f59195bce90
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 16:09:15 2007 -0700
|
|
|
-
|
|
|
- x86 setup: boot_params.e820_map is just the map, not the count; adjust
|
|
|
-
|
|
|
- boot_params.e820_map is just a list of entries, whereas
|
|
|
- "struct e820map" contains a count as well. Thus, don't use
|
|
|
- "struct e820map" to describe struct boot_params.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 0f96b52497f444be2d52d1184ca90be49f713ea3
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 15:49:03 2007 -0700
|
|
|
-
|
|
|
- x86 setup: E820MAX is a definitional constant; no need to use sizeof hacks
|
|
|
-
|
|
|
- Now when we're using the standard headers for the setup code, we can use
|
|
|
- E820MAX instead of playing sizeof games.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 3a23a428b20cbb31fd7ff5516a053b99afc447f7
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 12:08:46 2007 -0700
|
|
|
-
|
|
|
- x86: move the bootparam structure definition into include/
|
|
|
-
|
|
|
- Move the bootparam structure definition into include/, and make other
|
|
|
- things use it. Haven't cleaned up all the macros yet, though.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit e93ec58911995971aa059990f8a91a02b05f6c8f
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 12:07:50 2007 -0700
|
|
|
-
|
|
|
- i386: change %lu to %u in arch/i386/kernel/e820.h
|
|
|
-
|
|
|
- It's an u32, print it with %u
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 2f47f004f614e2744867c0df274c55d8af2a42d5
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 12:06:04 2007 -0700
|
|
|
-
|
|
|
- x86: fix differences between i386 and x86-64 <asm/e820.h>
|
|
|
-
|
|
|
- Fix minor differences between i386 and x86-64 <asm/e820.h>
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 56ec52f14e948f430af941052adee98019a617b7
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 11:45:17 2007 -0700
|
|
|
-
|
|
|
- x86: fix the definition of struct screen_info
|
|
|
-
|
|
|
- Name the fields that aren't really struct screen_info, and declare
|
|
|
- the structure packed (the "capabilities" field is misaligned.)
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 1d4429eaa564b0085d9ee3aa2de57e87a093a14e
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 11:43:10 2007 -0700
|
|
|
-
|
|
|
- x86-64: Make arch/x86-64/boot a symlink to arch/i386/boot
|
|
|
-
|
|
|
- Until such time that Kbuild allows for a cleaner solution, make
|
|
|
- arch/x86-64/boot a symlink to arch/i386/boot.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 6a85f1b5fd041ea99d8604782559ce0502a60cc0
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 10:42:06 2007 -0700
|
|
|
-
|
|
|
- x86-64: rearrange includes due to unifications and inclusion from setup
|
|
|
-
|
|
|
- Unification caused a circular dependency between <asm/alternative.h>
|
|
|
- and <asm/cpufeature.h>; resolve this.
|
|
|
-
|
|
|
- Add #ifndef _SETUP in <asm/e820.h> so it can be included from the boot
|
|
|
- code.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit f6bbdc254bdbd5f7cf7a40c4cd6f9844af90824a
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 10:40:26 2007 -0700
|
|
|
-
|
|
|
- x86: Complete <asm/cpufeature.h> with the union of i386 and x86-64
|
|
|
-
|
|
|
- Add a feature to <asm/cpufeature.h> which was previously present
|
|
|
- in x86-64 but missing in i386.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 1a0819281060489901732914f67869e0aa8f26fd
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 10:39:32 2007 -0700
|
|
|
-
|
|
|
- x86: unify <asm/boot.h>
|
|
|
-
|
|
|
- Unify <asm/boot.h> between i386 and x86-64
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 8d9c54585f4623e0310f970fb5c6eda7ec1614df
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 10:38:35 2007 -0700
|
|
|
-
|
|
|
- x86-64: verify_cpu.S: use new masks
|
|
|
-
|
|
|
- Use the <asm/required-features.h> masks.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 6cf3308646bb7a3210f0f76bcb895b2dea76a93c
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 10:37:26 2007 -0700
|
|
|
-
|
|
|
- x86-64: fix compilation errors due to required-features.h change
|
|
|
-
|
|
|
- Fix compilation errors induced by required-features.h change.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 1324201a93ce380b46a3128826ecbd794e617e59
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 10:35:37 2007 -0700
|
|
|
-
|
|
|
- x86-64: <asm/segment.h>: add boot segment descriptors
|
|
|
-
|
|
|
- Add boot segment descriptors to <asm/segment.h> to match i386.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit a0b15a9e79ed0310813709cd0690d6838917fe82
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 10:34:37 2007 -0700
|
|
|
-
|
|
|
- x86-64: add CONFIG_PHYSICAL_ALIGN to match i386
|
|
|
-
|
|
|
- Add CONFIG_PHYSICAL_ALIGN to match i386, even though we don't use it.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 8f5d14d11a7318e257351ae477392c7f7e314602
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 10:33:54 2007 -0700
|
|
|
-
|
|
|
- x86 setup: cleanups for compatibility with x86-64
|
|
|
-
|
|
|
- These changes are necessary to compile on x86-64.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit a32f68b6d4023c1c6b1e62e8561189516c571ab9
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Fri May 4 08:40:07 2007 -0700
|
|
|
-
|
|
|
- x86 setup: add missing linker script
|
|
|
-
|
|
|
- Add linker script for the setup code, apparently missing from previous
|
|
|
- checkins.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 4f34ca8e926b2d0bf3a7502b99f8dfced8cdba9d
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 3 17:42:29 2007 -0700
|
|
|
-
|
|
|
- x86 setup: paranoia: clear the high half of %esp
|
|
|
-
|
|
|
- We're invoked in 16-bit mode from an unknown bootloader. Make sure
|
|
|
- we explicitly zero the upper half of %esp to avoid nasty surprises.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 19eb9b73cc1632a923003a002108b242af7a6080
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 3 17:35:41 2007 -0700
|
|
|
-
|
|
|
- x86 setup: bootlin is *so* dead...
|
|
|
-
|
|
|
- Bootlin was never able to load bzImage kernels, so who cares about it.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 3b9fb73c65151ee043bc74c333d9e3c9b1872125
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 3 10:56:40 2007 -0700
|
|
|
-
|
|
|
- x86 setup: apparently $(src) is insufficient, needs $(srctree)/$(src)
|
|
|
-
|
|
|
- For some unfanthomable reason the location of the source tree that
|
|
|
- corresponds to the current directory has to be written as
|
|
|
- $(srctree)/$(src) apparently. There might be a good reason for it,
|
|
|
- but shorthand would be appreciated, and $(src) really should be the
|
|
|
- short form.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit a6d01d375a2269be1e3a6b31bcc4d426ad5a473d
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 3 10:51:45 2007 -0700
|
|
|
-
|
|
|
- x86 setup: remove reference to obsolete cpureq.c
|
|
|
-
|
|
|
- cpureq.c has been removed; remove it from the Makefile too.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit cbe5b7585d800435080bcbf1b1fd242926982674
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 3 10:33:12 2007 -0700
|
|
|
-
|
|
|
- x86 setup: use the required masks from <asm/required-features.h>
|
|
|
-
|
|
|
- Use the now-uniform features from <asm/required-features.h>.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 99ed30180ecc1bb4e93f6edda5f6bad1adf3e630
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 3 10:31:12 2007 -0700
|
|
|
-
|
|
|
- x86: make the handling of required features consistent
|
|
|
-
|
|
|
- Make the handling of required features consistent between i386
|
|
|
- and x86-64.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 1120d70a2be8f2deb6bda64047da288d8f86dad3
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 3 00:09:53 2007 -0700
|
|
|
-
|
|
|
- x86: Kconfig.cpu: the minimum CPU model is always 3; WP_WORKS_OK = i486
|
|
|
-
|
|
|
- The minimum CPU model number is always 3 (i386), and if we have
|
|
|
- WP_WORKS_OK it means we need an i486.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit ebc308c204149b86984ae2216f5b9b2e63932028
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Thu May 3 00:08:48 2007 -0700
|
|
|
-
|
|
|
- x86 setup: use CONFIG_X86_MINIMUM_CPU_MODEL
|
|
|
-
|
|
|
- Use CONFIG_X86_MINIMUM_CPU_MODEL as defined in Kconfig.cpu.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 8b50b640e015bf5d0f65502437da6fcab46c391b
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 23:45:42 2007 -0700
|
|
|
-
|
|
|
- x86 setup: remove bogus "static"
|
|
|
-
|
|
|
- Remove invalid "static" declarations in cpu.c
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 35d23b60dfb110da81c24bcbfcda089cfc4fd264
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 23:37:50 2007 -0700
|
|
|
-
|
|
|
- x86 setup: cpu detection cleanups
|
|
|
-
|
|
|
- - Use <asm/processor-flags.h>
|
|
|
- - Make sure %cr0 isn't in a dangerous configuration before probing the FPU
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit a1150a03247b355d11a4bb696b8aae1f46612992
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 23:36:55 2007 -0700
|
|
|
-
|
|
|
- x86 setup: compile with -DSETUP
|
|
|
-
|
|
|
- Define SETUP to make it easier to share code with the rest of the kernel.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 7eb52e8ad1bdf01886023d1a13b3313084cd7db6
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 23:34:57 2007 -0700
|
|
|
-
|
|
|
- x86 setup: remove unused verify_cpu.S
|
|
|
-
|
|
|
- verify_cpu.S is obsoleted by boot/cpu.c.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit e90317a027c30176968220d18eb18bd6a9d9cc74
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 20:07:43 2007 -0700
|
|
|
-
|
|
|
- x86 setup: files missing from previous checkin (cpu.c, cpureq.c)
|
|
|
-
|
|
|
- These files were missing from a previous checkin; CPU feature-checking
|
|
|
- code and the list of CPU features to check for.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 060f9b3db33c67b5344b2b4110bc823eb776e5cd
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 19:51:34 2007 -0700
|
|
|
-
|
|
|
- x86 setup: whitespace cleanup
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 9f997a5569ec8fceaa15c2e9cf28e728e2ce118d
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 19:07:14 2007 -0700
|
|
|
-
|
|
|
- x86 setup: add CPU feature detect/abort on insufficient featurage
|
|
|
-
|
|
|
- The x86 setup is the right place to check features and abort if they
|
|
|
- are not present, since we can still get a message to the user via the
|
|
|
- firmware.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit de4e976376fddec340651ef40b16a45f6189619d
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 19:05:34 2007 -0700
|
|
|
-
|
|
|
- x86 setup: whitespace cleanup
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit bcd2d2f8de5d4568b6628aa133fce1ac40ece526
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 16:19:59 2007 -0700
|
|
|
-
|
|
|
- x86 setup: tag functions noreturn; error message on A20 failure
|
|
|
-
|
|
|
- Tag appropriate functions noreturn.
|
|
|
- If the A20 gate fails, output an error message and refuse to boot.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 752aef90cbfc888084bf11fd83f8f72b6a668fc9
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 15:45:08 2007 -0700
|
|
|
-
|
|
|
- x86 setup: clobber registers in keyboard BIOS call
|
|
|
-
|
|
|
- Keyboard BIOS call to set repeat rate is known to clobber registers on
|
|
|
- "many" BIOSes.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit dde94003e4759aab275732cf9f1834440cd381d0
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 15:44:21 2007 -0700
|
|
|
-
|
|
|
- x86 setup: implement APM BIOS probe
|
|
|
-
|
|
|
- APM BIOS probe ported from assembly
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 9403917d79e3349184318704476fa080836bd52c
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 15:17:14 2007 -0700
|
|
|
-
|
|
|
- x86 setup: remove references to obsolete probes
|
|
|
-
|
|
|
- Remove "Hello, World!" as well as references to probes which are no
|
|
|
- longer used...
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 712f65ffbd1d4b55b4c55d68b4dcd32406c28fb8
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 12:17:15 2007 -0700
|
|
|
-
|
|
|
- x86 setup: video.c: correct the handling of special mode numbers
|
|
|
-
|
|
|
- Special mode numbers with the high bit set need to be handled *before*
|
|
|
- masking out the high bit.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 9cf083204fe14cda3b09840eba8d131d2e48ccdf
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 11:44:16 2007 -0700
|
|
|
-
|
|
|
- x86 setup: Modern ATI cards pass the probe but lacks the modes.
|
|
|
-
|
|
|
- It appears modern ATI cards pass the probe for ATI-ness but lack the
|
|
|
- modes. Kill off the driver as being incorrect.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 890cbe950589e30af17eac9da800efc76e35e01d
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 11:32:21 2007 -0700
|
|
|
-
|
|
|
- x86 setup: a20.c: make empty_8042() return status
|
|
|
-
|
|
|
- Make functions which could reasonably return status do so. It may
|
|
|
- be relevant in the future, and it's a lot better if the programmer
|
|
|
- doesn't have to figure out where everything should hook in.
|
|
|
-
|
|
|
- Just on principle.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 08a44dc655e0086d23fc3c70cb93eb51eaeec259
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 11:31:03 2007 -0700
|
|
|
-
|
|
|
- x86 setup: video.c: clean up unused stuff
|
|
|
-
|
|
|
- Clean up unused variables that we have no intent on using, as well
|
|
|
- as other cruft.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 57e69acff1f577de430cae1523fd49a5d113e885
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 11:18:13 2007 -0700
|
|
|
-
|
|
|
- x86 setup: drop video mode range checking
|
|
|
-
|
|
|
- Drop video mode range checking. If someone really has, say, 12x40 mode
|
|
|
- visible through the BIOS then allow them to select it... odds are low
|
|
|
- that it will actually conflict with the very sparse allocation we have
|
|
|
- anyway.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit c0dda0b90f92d43872d55d295630a71cd357cfa6
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 11:15:53 2007 -0700
|
|
|
-
|
|
|
- x86 setup: if no specific video mode ID is given, generate one
|
|
|
-
|
|
|
- If we don't specify a certain video mode ID in the driver, then
|
|
|
- generate the 0xRRCC mode ID automatically.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 0db5086e79810e7c5d560006b1c9a7501a02d80c
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 11:10:28 2007 -0700
|
|
|
-
|
|
|
- x86 setup: Sadly, Cirrus removed extended text modes from their BIOS.
|
|
|
-
|
|
|
- In the later era of the Cirrus 54xx series, Cirrus removed extended text
|
|
|
- modes from their BIOS. Neither Qemu nor Bochs implement them in the BIOS.
|
|
|
- If we can find a direct-register-poking method of setting them that
|
|
|
- works in Bochs/Qemu it might be worthwhile to resurrect this; the probing
|
|
|
- routine *does* work.
|
|
|
-
|
|
|
- Of course, the Right Thing[TM] would be to submit such a routine to the
|
|
|
- Bochs/Qemu BIOS as a VESA text mode.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 41f3fddeeb764687bf3fb0cf77fd858128571d58
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Wed May 2 10:18:07 2007 -0700
|
|
|
-
|
|
|
- x86 setup: remove assembly implementation of putchar and puts
|
|
|
-
|
|
|
- Already unused, remove assembly implementation of putchar and puts.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit dfa94cd86aca2c01d2f5e14b6e7c3e8258276195
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 1 21:41:28 2007 -0700
|
|
|
-
|
|
|
- x86 setup: Call INT 15h AX=E820h properly
|
|
|
-
|
|
|
- The calling convention for BIOS call 15:E820 was messed up.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 2487575a36435c0a983febbb4f3751331bd2df7a
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 1 21:34:12 2007 -0700
|
|
|
-
|
|
|
- x86 setup: advance one e820 descriptor at a time...
|
|
|
-
|
|
|
- Adding sizeof(foo) to a foo * is not just useless, it's pretty damaging...
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 530d4f4f1732335ae8725c0b8c332a618e63ea1d
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 1 21:33:28 2007 -0700
|
|
|
-
|
|
|
- x86 setup: fix memcmp_[fg]s()
|
|
|
-
|
|
|
- Actually return a value from memcmp_[fg]s()...
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 8617cd56ff2e43303147da012b26c9dd46af726e
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 1 21:32:47 2007 -0700
|
|
|
-
|
|
|
- x86 setup: fix missing semicolon in video-ati.c
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 7bbf7fa3e199b9cef4877c5a56128faff8636cc9
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 1 21:26:48 2007 -0700
|
|
|
-
|
|
|
- x86 setup: make the video setup code actually do something...
|
|
|
-
|
|
|
- Basic video setup now works (there is still work to be done, however.)
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 45bcd4406e4b812b32d317d9b3b8db2e5f135a3c
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 1 21:25:20 2007 -0700
|
|
|
-
|
|
|
- x86 setup: segment descriptors need to be Present
|
|
|
-
|
|
|
- The segment descriptors were missing the Present bit.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit a39479d4ccf4dceffb623ad2ec7e2d708c38c637
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 1 21:24:32 2007 -0700
|
|
|
-
|
|
|
- build: setup sectors doesn't include the boot sector
|
|
|
-
|
|
|
- The "setup sectors" field doesn't include the old boot sector,
|
|
|
- even though the two are now one module.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit d8f3d4928ead72e8febe2fcd740d0fee71a61f42
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 1 21:23:44 2007 -0700
|
|
|
-
|
|
|
- x86 setup: in tty.c, actually tell it what character to print
|
|
|
-
|
|
|
- putchar() was missing the actual passing of the character code to the
|
|
|
- BIOS call, with very silly-looking results.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 4f1462ed0377e180484a223e622d62432baa64b7
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Tue May 1 21:22:46 2007 -0700
|
|
|
-
|
|
|
- x86 setup: printf.c needs code16gcc.h
|
|
|
-
|
|
|
- printf.c was missing code16gcc.h, with predictable consequences.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit a5ba7e6df198bd204b0f87fc6e3f68388b9d14c1
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Mon Apr 30 20:56:42 2007 -0700
|
|
|
-
|
|
|
- MAINTAINERS: formally take responsibility for the i386 boot code
|
|
|
-
|
|
|
- Change MAINTAINERS to formally take responsibility for the i386 boot code.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-
|
|
|
-commit 6c821fc005655a99eff6e86c2e4b13654de94dea
|
|
|
-Author: H. Peter Anvin <[email protected]>
|
|
|
-Date: Mon Apr 30 20:54:07 2007 -0700
|
|
|
-
|
|
|
- x86 setup code rewrite: initial development snapshot
|
|
|
-
|
|
|
- Clean up the setup code and rewrite it in C.
|
|
|
- This is an initial development snapshot, not a working tree.
|
|
|
-
|
|
|
- Signed-off-by: H. Peter Anvin <[email protected]>
|
|
|
-Signed-off-by: Andrew Morton <[email protected]>
|
|
|
----
|
|
|
-
|
|
|
- MAINTAINERS | 4
|
|
|
- arch/i386/Kconfig.cpu | 4
|
|
|
- arch/i386/boot/Makefile | 45
|
|
|
- arch/i386/boot/a20.c | 161 +
|
|
|
- arch/i386/boot/apm.c | 97
|
|
|
- arch/i386/boot/bitops.h | 45
|
|
|
- arch/i386/boot/boot.h | 290 ++
|
|
|
- arch/i386/boot/bootsect.S | 98
|
|
|
- arch/i386/boot/cmdline.c | 97
|
|
|
- arch/i386/boot/code16gcc.h | 9
|
|
|
- arch/i386/boot/compressed/Makefile | 7
|
|
|
- arch/i386/boot/compressed/head.S | 6
|
|
|
- arch/i386/boot/compressed/misc.c | 3
|
|
|
- arch/i386/boot/copy.S | 101
|
|
|
- arch/i386/boot/cpu.c | 69
|
|
|
- arch/i386/boot/cpucheck.c | 266 ++
|
|
|
- arch/i386/boot/edd.S | 231 --
|
|
|
- arch/i386/boot/edd.c | 196 +
|
|
|
- arch/i386/boot/header.S | 283 ++
|
|
|
- arch/i386/boot/main.c | 161 +
|
|
|
- arch/i386/boot/mca.c | 43
|
|
|
- arch/i386/boot/memory.c | 99
|
|
|
- arch/i386/boot/pm.c | 170 +
|
|
|
- arch/i386/boot/pmjump.S | 54
|
|
|
- arch/i386/boot/printf.c | 331 ++
|
|
|
- arch/i386/boot/setup.S | 1075 ---------
|
|
|
- arch/i386/boot/setup.ld | 54
|
|
|
- arch/i386/boot/string.c | 34
|
|
|
- arch/i386/boot/tools/build.c | 156 -
|
|
|
- arch/i386/boot/tty.c | 112
|
|
|
- arch/i386/boot/version.c | 23
|
|
|
- arch/i386/boot/vesa.h | 79
|
|
|
- arch/i386/boot/video-bios.c | 125 +
|
|
|
- arch/i386/boot/video-vesa.c | 283 ++
|
|
|
- arch/i386/boot/video-vga.c | 260 ++
|
|
|
- arch/i386/boot/video.S | 2043 ------------------
|
|
|
- arch/i386/boot/video.c | 456 ++++
|
|
|
- arch/i386/boot/video.h | 145 +
|
|
|
- arch/i386/boot/voyager.c | 46
|
|
|
- arch/i386/kernel/cpu/addon_cpuid_features.c | 50
|
|
|
- arch/i386/kernel/cpu/common.c | 2
|
|
|
- arch/i386/kernel/cpu/proc.c | 21
|
|
|
- arch/i386/kernel/e820.c | 2
|
|
|
- arch/i386/kernel/setup.c | 12
|
|
|
- arch/i386/kernel/verify_cpu.S | 94
|
|
|
- arch/x86_64/Kconfig | 4
|
|
|
- arch/x86_64/boot/Makefile | 136 -
|
|
|
- arch/x86_64/boot/bootsect.S | 98
|
|
|
- arch/x86_64/boot/compressed/Makefile | 9
|
|
|
- arch/x86_64/boot/compressed/head.S | 6
|
|
|
- arch/x86_64/boot/install.sh | 2
|
|
|
- arch/x86_64/boot/mtools.conf.in | 17
|
|
|
- arch/x86_64/boot/setup.S | 826 -------
|
|
|
- arch/x86_64/boot/tools/build.c | 185 -
|
|
|
- arch/x86_64/kernel/Makefile | 2
|
|
|
- arch/x86_64/kernel/setup.c | 21
|
|
|
- arch/x86_64/kernel/verify_cpu.S | 22
|
|
|
- drivers/ide/legacy/hd.c | 73
|
|
|
- include/asm-i386/boot.h | 6
|
|
|
- include/asm-i386/bootparam.h | 85
|
|
|
- include/asm-i386/cpufeature.h | 26
|
|
|
- include/asm-i386/e820.h | 14
|
|
|
- include/asm-i386/processor.h | 1
|
|
|
- include/asm-i386/required-features.h | 37
|
|
|
- include/asm-i386/setup.h | 10
|
|
|
- include/asm-x86_64/alternative.h | 68
|
|
|
- include/asm-x86_64/boot.h | 16
|
|
|
- include/asm-x86_64/bootparam.h | 1
|
|
|
- include/asm-x86_64/cpufeature.h | 115 -
|
|
|
- include/asm-x86_64/e820.h | 6
|
|
|
- include/asm-x86_64/processor.h | 3
|
|
|
- include/asm-x86_64/required-features.h | 46
|
|
|
- include/asm-x86_64/segment.h | 8
|
|
|
- include/linux/edd.h | 4
|
|
|
- include/linux/screen_info.h | 9
|
|
|
- 75 files changed, 4594 insertions(+), 5204 deletions(-)
|
|
|
-
|
|
|
-diff -puN MAINTAINERS~git-newsetup MAINTAINERS
|
|
|
---- a/MAINTAINERS~git-newsetup
|
|
|
-+++ a/MAINTAINERS
|
|
|
-@@ -1774,8 +1774,8 @@ T: http://www.harbaum.org/till/i2c_tiny_
|
|
|
- S: Maintained
|
|
|
-
|
|
|
- i386 BOOT CODE
|
|
|
--P: Riley H. Williams
|
|
|
--M: [email protected]
|
|
|
-+P: H. Peter Anvin
|
|
|
-+M: [email protected]
|
|
|
- L: [email protected]
|
|
|
- S: Maintained
|
|
|
-
|
|
|
-diff -puN arch/i386/Kconfig.cpu~git-newsetup arch/i386/Kconfig.cpu
|
|
|
---- a/arch/i386/Kconfig.cpu~git-newsetup
|
|
|
-+++ a/arch/i386/Kconfig.cpu
|
|
|
-@@ -346,6 +346,6 @@ config X86_CMOV
|
|
|
-
|
|
|
- config X86_MINIMUM_CPU_MODEL
|
|
|
- int
|
|
|
-- default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP
|
|
|
-- default "0"
|
|
|
-+ default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK
|
|
|
-+ default "3"
|
|
|
-
|
|
|
-diff -puN arch/i386/boot/Makefile~git-newsetup arch/i386/boot/Makefile
|
|
|
---- a/arch/i386/boot/Makefile~git-newsetup
|
|
|
-+++ a/arch/i386/boot/Makefile
|
|
|
-@@ -25,27 +25,53 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
|
|
|
-
|
|
|
- #RAMDISK := -DRAMDISK=512
|
|
|
-
|
|
|
--targets := vmlinux.bin bootsect bootsect.o \
|
|
|
-- setup setup.o zImage bzImage
|
|
|
-+targets := vmlinux.bin setup.bin setup.elf zImage bzImage
|
|
|
- subdir- := compressed
|
|
|
-
|
|
|
-+setup-y += a20.o apm.o cmdline.o copy.o cpu.o cpucheck.o edd.o
|
|
|
-+setup-y += header.o main.o mca.o memory.o pm.o pmjump.o
|
|
|
-+setup-y += printf.o string.o tty.o video.o version.o voyager.o
|
|
|
-+
|
|
|
-+# The link order of the video-*.o modules can matter. In particular,
|
|
|
-+# video-vga.o *must* be listed first, followed by video-vesa.o.
|
|
|
-+# Hardware-specific drivers should follow in the order they should be
|
|
|
-+# probed, and video-bios.o should typically be last.
|
|
|
-+setup-y += video-vga.o
|
|
|
-+setup-y += video-vesa.o
|
|
|
-+setup-y += video-bios.o
|
|
|
-+
|
|
|
- hostprogs-y := tools/build
|
|
|
-
|
|
|
- HOSTCFLAGS_build.o := $(LINUXINCLUDE)
|
|
|
-
|
|
|
- # ---------------------------------------------------------------------------
|
|
|
-
|
|
|
-+# How to compile the 16-bit code. Note we always compile for -march=i386,
|
|
|
-+# that way we can complain to the user if the CPU is insufficient.
|
|
|
-+cflags-i386 :=
|
|
|
-+cflags-x86_64 := -m32
|
|
|
-+CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
|
|
|
-+ $(cflags-$(ARCH)) \
|
|
|
-+ -Wall -Wstrict-prototypes \
|
|
|
-+ -march=i386 -mregparm=3 \
|
|
|
-+ -include $(srctree)/$(src)/code16gcc.h \
|
|
|
-+ -fno-strict-aliasing -fomit-frame-pointer \
|
|
|
-+ $(call cc-option, -ffreestanding) \
|
|
|
-+ $(call cc-option, -fno-stack-protector)
|
|
|
-+AFLAGS := $(CFLAGS) -D__ASSEMBLY__
|
|
|
-+
|
|
|
- $(obj)/zImage: IMAGE_OFFSET := 0x1000
|
|
|
- $(obj)/zImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK)
|
|
|
- $(obj)/bzImage: IMAGE_OFFSET := 0x100000
|
|
|
-+$(obj)/bzImage: EXTRA_CFLAGS := -D__BIG_KERNEL__
|
|
|
- $(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
|
|
|
- $(obj)/bzImage: BUILDFLAGS := -b
|
|
|
-
|
|
|
- quiet_cmd_image = BUILD $@
|
|
|
--cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
|
|
|
-+cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/setup.bin \
|
|
|
- $(obj)/vmlinux.bin $(ROOT_DEV) > $@
|
|
|
-
|
|
|
--$(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
|
|
|
-+$(obj)/zImage $(obj)/bzImage: $(obj)/setup.bin \
|
|
|
- $(obj)/vmlinux.bin $(obj)/tools/build FORCE
|
|
|
- $(call if_changed,image)
|
|
|
- @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
|
|
|
-@@ -53,12 +79,17 @@ $(obj)/zImage $(obj)/bzImage: $(obj)/boo
|
|
|
- $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
|
|
|
- $(call if_changed,objcopy)
|
|
|
-
|
|
|
--LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
|
|
|
--LDFLAGS_setup := -Ttext 0x0 -s --oformat binary -e begtext
|
|
|
-+SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
|
|
|
-
|
|
|
--$(obj)/setup $(obj)/bootsect: %: %.o FORCE
|
|
|
-+LDFLAGS_setup.elf := -T
|
|
|
-+$(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
|
|
|
- $(call if_changed,ld)
|
|
|
-
|
|
|
-+OBJCOPYFLAGS_setup.bin := -O binary
|
|
|
-+
|
|
|
-+$(obj)/setup.bin: $(obj)/setup.elf FORCE
|
|
|
-+ $(call if_changed,objcopy)
|
|
|
-+
|
|
|
- $(obj)/compressed/vmlinux: FORCE
|
|
|
- $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
|
|
|
-
|
|
|
-diff -puN /dev/null arch/i386/boot/a20.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/a20.c
|
|
|
-@@ -0,0 +1,161 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/a20.c
|
|
|
-+ *
|
|
|
-+ * Enable A20 gate (return -1 on failure)
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+
|
|
|
-+#define MAX_8042_LOOPS 100000
|
|
|
-+
|
|
|
-+static int empty_8042(void)
|
|
|
-+{
|
|
|
-+ u8 status;
|
|
|
-+ int loops = MAX_8042_LOOPS;
|
|
|
-+
|
|
|
-+ while (loops--) {
|
|
|
-+ io_delay();
|
|
|
-+
|
|
|
-+ status = inb(0x64);
|
|
|
-+ if (status & 1) {
|
|
|
-+ /* Read and discard input data */
|
|
|
-+ io_delay();
|
|
|
-+ (void)inb(0x60);
|
|
|
-+ } else if (!(status & 2)) {
|
|
|
-+ /* Buffers empty, finished! */
|
|
|
-+ return 0;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ return -1;
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Returns nonzero if the A20 line is enabled. The memory address
|
|
|
-+ used as a test is the int $0x80 vector, which should be safe. */
|
|
|
-+
|
|
|
-+#define A20_TEST_ADDR (4*0x80)
|
|
|
-+#define A20_TEST_SHORT 32
|
|
|
-+#define A20_TEST_LONG 2097152 /* 2^21 */
|
|
|
-+
|
|
|
-+static int a20_test(int loops)
|
|
|
-+{
|
|
|
-+ int ok = 0;
|
|
|
-+ int saved, ctr;
|
|
|
-+
|
|
|
-+ set_fs(0x0000);
|
|
|
-+ set_gs(0xffff);
|
|
|
-+
|
|
|
-+ saved = ctr = rdfs32(A20_TEST_ADDR);
|
|
|
-+
|
|
|
-+ while (loops--) {
|
|
|
-+ wrfs32(++ctr, A20_TEST_ADDR);
|
|
|
-+ io_delay(); /* Serialize and make delay constant */
|
|
|
-+ ok = rdgs32(A20_TEST_ADDR+0x10) ^ ctr;
|
|
|
-+ if (ok)
|
|
|
-+ break;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ wrfs32(saved, A20_TEST_ADDR);
|
|
|
-+ return ok;
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Quick test to see if A20 is already enabled */
|
|
|
-+static int a20_test_short(void)
|
|
|
-+{
|
|
|
-+ return a20_test(A20_TEST_SHORT);
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Longer test that actually waits for A20 to come on line; this
|
|
|
-+ is useful when dealing with the KBC or other slow external circuitry. */
|
|
|
-+static int a20_test_long(void)
|
|
|
-+{
|
|
|
-+ return a20_test(A20_TEST_LONG);
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void enable_a20_bios(void)
|
|
|
-+{
|
|
|
-+ asm volatile("pushfl; int $0x15; popfl"
|
|
|
-+ : : "a" ((u16)0x2401));
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void enable_a20_kbc(void)
|
|
|
-+{
|
|
|
-+ empty_8042();
|
|
|
-+
|
|
|
-+ outb(0xd1, 0x64); /* Command write */
|
|
|
-+ empty_8042();
|
|
|
-+
|
|
|
-+ outb(0xdf, 0x60); /* A20 on */
|
|
|
-+ empty_8042();
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void enable_a20_fast(void)
|
|
|
-+{
|
|
|
-+ u8 port_a;
|
|
|
-+
|
|
|
-+ port_a = inb(0x92); /* Configuration port A */
|
|
|
-+ port_a |= 0x02; /* Enable A20 */
|
|
|
-+ port_a &= ~0x01; /* Do not reset machine */
|
|
|
-+ outb(port_a, 0x92);
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Actual routine to enable A20; return 0 on ok, -1 on failure
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#define A20_ENABLE_LOOPS 255 /* Number of times to try */
|
|
|
-+
|
|
|
-+int enable_a20(void)
|
|
|
-+{
|
|
|
-+ int loops = A20_ENABLE_LOOPS;
|
|
|
-+
|
|
|
-+#if defined(CONFIG_X86_ELAN)
|
|
|
-+ /* Elan croaks if we try to touch the KBC */
|
|
|
-+ enable_a20_fast();
|
|
|
-+ while (!a20_test_long())
|
|
|
-+ ;
|
|
|
-+ return 0;
|
|
|
-+#elif defined(CONFIG_X86_VOYAGER)
|
|
|
-+ /* On Voyager, a20_test() is unsafe? */
|
|
|
-+ enable_a20_kbc();
|
|
|
-+ return 0;
|
|
|
-+#else
|
|
|
-+ while (loops--) {
|
|
|
-+ /* First, check to see if A20 is already enabled
|
|
|
-+ (legacy free, etc.) */
|
|
|
-+ if (a20_test_short())
|
|
|
-+ return 0;
|
|
|
-+
|
|
|
-+ /* Next, try the BIOS (INT 0x15, AX=0x2401) */
|
|
|
-+ enable_a20_bios();
|
|
|
-+ if (a20_test_short())
|
|
|
-+ return 0;
|
|
|
-+
|
|
|
-+ /* Try enabling A20 through the keyboard controller */
|
|
|
-+ empty_8042();
|
|
|
-+ if (a20_test_short())
|
|
|
-+ return 0; /* BIOS worked, but with delayed reaction */
|
|
|
-+
|
|
|
-+ enable_a20_kbc();
|
|
|
-+ if (a20_test_long())
|
|
|
-+ return 0;
|
|
|
-+
|
|
|
-+ /* Finally, try enabling the "fast A20 gate" */
|
|
|
-+ enable_a20_fast();
|
|
|
-+ if (a20_test_long())
|
|
|
-+ return 0;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ return -1;
|
|
|
-+#endif
|
|
|
-+}
|
|
|
-diff -puN /dev/null arch/i386/boot/apm.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/apm.c
|
|
|
-@@ -0,0 +1,97 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * Original APM BIOS checking by Stephen Rothwell, May 1994
|
|
|
-+ * ([email protected])
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/apm.c
|
|
|
-+ *
|
|
|
-+ * Get APM BIOS information
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+
|
|
|
-+#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
|
|
|
-+
|
|
|
-+int query_apm_bios(void)
|
|
|
-+{
|
|
|
-+ u16 ax, bx, cx, dx, di;
|
|
|
-+ u32 ebx, esi;
|
|
|
-+ u8 err;
|
|
|
-+
|
|
|
-+ /* APM BIOS installation check */
|
|
|
-+ ax = 0x5300;
|
|
|
-+ bx = cx = 0;
|
|
|
-+ asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
|
|
|
-+ : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
|
|
|
-+ : : "esi", "edi");
|
|
|
-+
|
|
|
-+ if (err)
|
|
|
-+ return -1; /* No APM BIOS */
|
|
|
-+
|
|
|
-+ if (bx != 0x504d) /* "PM" signature */
|
|
|
-+ return -1;
|
|
|
-+
|
|
|
-+ if (cx & 0x02) /* 32 bits supported? */
|
|
|
-+ return -1;
|
|
|
-+
|
|
|
-+ /* Disconnect first, just in case */
|
|
|
-+ ax = 0x5304;
|
|
|
-+ asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
|
|
|
-+ : "+a" (ax)
|
|
|
-+ : : "ebx", "ecx", "edx", "esi", "edi");
|
|
|
-+
|
|
|
-+ /* Paranoia */
|
|
|
-+ ebx = esi = 0;
|
|
|
-+ cx = dx = di = 0;
|
|
|
-+
|
|
|
-+ /* 32-bit connect */
|
|
|
-+ asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6"
|
|
|
-+ : "=a" (ax), "+b" (ebx), "+c" (cx), "+d" (dx),
|
|
|
-+ "+S" (esi), "+D" (di), "=m" (err)
|
|
|
-+ : "a" (0x5303));
|
|
|
-+
|
|
|
-+ boot_params.apm_bios_info.cseg = ax;
|
|
|
-+ boot_params.apm_bios_info.offset = ebx;
|
|
|
-+ boot_params.apm_bios_info.cseg_16 = cx;
|
|
|
-+ boot_params.apm_bios_info.dseg = dx;
|
|
|
-+ boot_params.apm_bios_info.cseg_len = (u16)esi;
|
|
|
-+ boot_params.apm_bios_info.cseg_16_len = esi >> 16;
|
|
|
-+ boot_params.apm_bios_info.dseg_len = di;
|
|
|
-+
|
|
|
-+ if (err)
|
|
|
-+ return -1;
|
|
|
-+
|
|
|
-+ /* Redo the installation check as the 32-bit connect;
|
|
|
-+ some BIOSes return different flags this way... */
|
|
|
-+
|
|
|
-+ ax = 0x5300;
|
|
|
-+ bx = cx = 0;
|
|
|
-+ asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
|
|
|
-+ : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
|
|
|
-+ : : "esi", "edi");
|
|
|
-+
|
|
|
-+ if (err || bx != 0x504d) {
|
|
|
-+ /* Failure with 32-bit connect, try to disconect and ignore */
|
|
|
-+ ax = 0x5304;
|
|
|
-+ bx = 0;
|
|
|
-+ asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
|
|
|
-+ : "+a" (ax), "+b" (bx)
|
|
|
-+ : : "ecx", "edx", "esi", "edi");
|
|
|
-+ return -1;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ boot_params.apm_bios_info.version = ax;
|
|
|
-+ boot_params.apm_bios_info.flags = cx;
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#endif
|
|
|
-diff -puN /dev/null arch/i386/boot/bitops.h
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/bitops.h
|
|
|
-@@ -0,0 +1,45 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/bitops.h
|
|
|
-+ *
|
|
|
-+ * Very simple bitops for the boot code.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#ifndef BOOT_BITOPS_H
|
|
|
-+#define BOOT_BITOPS_H
|
|
|
-+#define _LINUX_BITOPS_H /* Inhibit inclusion of <linux/bitops.h> */
|
|
|
-+
|
|
|
-+static inline int constant_test_bit(int nr, const void *addr)
|
|
|
-+{
|
|
|
-+ const u32 *p = (const u32 *)addr;
|
|
|
-+ return ((1UL << (nr & 31)) & (p[nr >> 5])) != 0;
|
|
|
-+}
|
|
|
-+static inline int variable_test_bit(int nr, const void *addr)
|
|
|
-+{
|
|
|
-+ u8 v;
|
|
|
-+ const u32 *p = (const u32 *)addr;
|
|
|
-+
|
|
|
-+ asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define test_bit(nr,addr) \
|
|
|
-+(__builtin_constant_p(nr) ? \
|
|
|
-+ constant_test_bit((nr),(addr)) : \
|
|
|
-+ variable_test_bit((nr),(addr)))
|
|
|
-+
|
|
|
-+static inline void set_bit(int nr, void *addr)
|
|
|
-+{
|
|
|
-+ asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
|
|
|
-+}
|
|
|
-+
|
|
|
-+#endif /* BOOT_BITOPS_H */
|
|
|
-diff -puN /dev/null arch/i386/boot/boot.h
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/boot.h
|
|
|
-@@ -0,0 +1,290 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/boot.h
|
|
|
-+ *
|
|
|
-+ * Header file for the real-mode kernel code
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#ifndef BOOT_BOOT_H
|
|
|
-+#define BOOT_BOOT_H
|
|
|
-+
|
|
|
-+#ifndef __ASSEMBLY__
|
|
|
-+
|
|
|
-+#include <stdarg.h>
|
|
|
-+#include <linux/types.h>
|
|
|
-+#include <linux/edd.h>
|
|
|
-+#include <asm/boot.h>
|
|
|
-+#include <asm/bootparam.h>
|
|
|
-+
|
|
|
-+/* Useful macros */
|
|
|
-+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
|
|
|
-+
|
|
|
-+extern struct setup_header hdr;
|
|
|
-+extern struct boot_params boot_params;
|
|
|
-+
|
|
|
-+/* Basic port I/O */
|
|
|
-+static inline void outb(u8 v, u16 port)
|
|
|
-+{
|
|
|
-+ asm volatile("outb %0,%1" : : "a" (v), "dN" (port));
|
|
|
-+}
|
|
|
-+static inline u8 inb(u16 port)
|
|
|
-+{
|
|
|
-+ u8 v;
|
|
|
-+ asm volatile("inb %1,%0" : "=a" (v) : "dN" (port));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static inline void outw(u16 v, u16 port)
|
|
|
-+{
|
|
|
-+ asm volatile("outw %0,%1" : : "a" (v), "dN" (port));
|
|
|
-+}
|
|
|
-+static inline u16 inw(u16 port)
|
|
|
-+{
|
|
|
-+ u16 v;
|
|
|
-+ asm volatile("inw %1,%0" : "=a" (v) : "dN" (port));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static inline void outl(u32 v, u16 port)
|
|
|
-+{
|
|
|
-+ asm volatile("outl %0,%1" : : "a" (v), "dn" (port));
|
|
|
-+}
|
|
|
-+static inline u32 inl(u32 port)
|
|
|
-+{
|
|
|
-+ u32 v;
|
|
|
-+ asm volatile("inl %1,%0" : "=a" (v) : "dN" (port));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static inline void io_delay(void)
|
|
|
-+{
|
|
|
-+ const u16 DELAY_PORT = 0x80;
|
|
|
-+ asm volatile("outb %%al,%0" : : "dN" (DELAY_PORT));
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* These functions are used to reference data in other segments. */
|
|
|
-+
|
|
|
-+static inline u16 ds(void)
|
|
|
-+{
|
|
|
-+ u16 seg;
|
|
|
-+ asm("movw %%ds,%0" : "=rm" (seg));
|
|
|
-+ return seg;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static inline void set_fs(u16 seg)
|
|
|
-+{
|
|
|
-+ asm volatile("movw %0,%%fs" : : "rm" (seg));
|
|
|
-+}
|
|
|
-+static inline u16 fs(void)
|
|
|
-+{
|
|
|
-+ u16 seg;
|
|
|
-+ asm("movw %%fs,%0" : "=rm" (seg));
|
|
|
-+ return seg;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static inline void set_gs(u16 seg)
|
|
|
-+{
|
|
|
-+ asm volatile("movw %0,%%gs" : : "rm" (seg));
|
|
|
-+}
|
|
|
-+static inline u16 gs(void)
|
|
|
-+{
|
|
|
-+ u16 seg;
|
|
|
-+ asm("movw %%gs,%0" : "=rm" (seg));
|
|
|
-+ return seg;
|
|
|
-+}
|
|
|
-+
|
|
|
-+typedef unsigned int addr_t;
|
|
|
-+
|
|
|
-+static inline u8 rdfs8(addr_t addr)
|
|
|
-+{
|
|
|
-+ u8 v;
|
|
|
-+ asm("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+static inline u16 rdfs16(addr_t addr)
|
|
|
-+{
|
|
|
-+ u16 v;
|
|
|
-+ asm("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+static inline u32 rdfs32(addr_t addr)
|
|
|
-+{
|
|
|
-+ u32 v;
|
|
|
-+ asm("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static inline void wrfs8(u8 v, addr_t addr)
|
|
|
-+{
|
|
|
-+ asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "r" (v));
|
|
|
-+}
|
|
|
-+static inline void wrfs16(u16 v, addr_t addr)
|
|
|
-+{
|
|
|
-+ asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "r" (v));
|
|
|
-+}
|
|
|
-+static inline void wrfs32(u32 v, addr_t addr)
|
|
|
-+{
|
|
|
-+ asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "r" (v));
|
|
|
-+}
|
|
|
-+
|
|
|
-+static inline u8 rdgs8(addr_t addr)
|
|
|
-+{
|
|
|
-+ u8 v;
|
|
|
-+ asm("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+static inline u16 rdgs16(addr_t addr)
|
|
|
-+{
|
|
|
-+ u16 v;
|
|
|
-+ asm("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+static inline u32 rdgs32(addr_t addr)
|
|
|
-+{
|
|
|
-+ u32 v;
|
|
|
-+ asm("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static inline void wrgs8(u8 v, addr_t addr)
|
|
|
-+{
|
|
|
-+ asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "r" (v));
|
|
|
-+}
|
|
|
-+static inline void wrgs16(u16 v, addr_t addr)
|
|
|
-+{
|
|
|
-+ asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "r" (v));
|
|
|
-+}
|
|
|
-+static inline void wrgs32(u32 v, addr_t addr)
|
|
|
-+{
|
|
|
-+ asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "r" (v));
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Note: these only return true/false, not a signed return value! */
|
|
|
-+static inline int memcmp(const void *s1, const void *s2, size_t len)
|
|
|
-+{
|
|
|
-+ u8 diff;
|
|
|
-+ asm("repe; cmpsb; setnz %0"
|
|
|
-+ : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
|
|
|
-+ return diff;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static inline int memcmp_fs(const void *s1, addr_t s2, size_t len)
|
|
|
-+{
|
|
|
-+ u8 diff;
|
|
|
-+ asm("fs; repe; cmpsb; setnz %0"
|
|
|
-+ : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
|
|
|
-+ return diff;
|
|
|
-+}
|
|
|
-+static inline int memcmp_gs(const void *s1, addr_t s2, size_t len)
|
|
|
-+{
|
|
|
-+ u8 diff;
|
|
|
-+ asm("gs; repe; cmpsb; setnz %0"
|
|
|
-+ : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
|
|
|
-+ return diff;
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Heap -- available for dynamic lists. */
|
|
|
-+#define STACK_SIZE 512 /* Minimum number of bytes for stack */
|
|
|
-+
|
|
|
-+extern char _end[];
|
|
|
-+extern char *HEAP;
|
|
|
-+extern char *heap_end;
|
|
|
-+#define RESET_HEAP() ((void *)( HEAP = _end ))
|
|
|
-+static inline char *__get_heap(size_t s, size_t a, size_t n)
|
|
|
-+{
|
|
|
-+ char *tmp;
|
|
|
-+
|
|
|
-+ HEAP = (char *)(((size_t)HEAP+(a-1)) & ~(a-1));
|
|
|
-+ tmp = HEAP;
|
|
|
-+ HEAP += s*n;
|
|
|
-+ return tmp;
|
|
|
-+}
|
|
|
-+#define GET_HEAP(type, n) \
|
|
|
-+ ((type *)__get_heap(sizeof(type),__alignof__(type),(n)))
|
|
|
-+
|
|
|
-+static inline int heap_free(void)
|
|
|
-+{
|
|
|
-+ return heap_end-HEAP;
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* copy.S */
|
|
|
-+
|
|
|
-+void copy_to_fs(addr_t dst, void *src, size_t len);
|
|
|
-+void *copy_from_fs(void *dst, addr_t src, size_t len);
|
|
|
-+void copy_to_gs(addr_t dst, void *src, size_t len);
|
|
|
-+void *copy_from_gs(void *dst, addr_t src, size_t len);
|
|
|
-+void *memcpy(void *dst, void *src, size_t len);
|
|
|
-+void *memset(void *dst, int c, size_t len);
|
|
|
-+
|
|
|
-+#define memcpy(d,s,l) __builtin_memcpy(d,s,l)
|
|
|
-+#define memset(d,c,l) __builtin_memset(d,c,l)
|
|
|
-+
|
|
|
-+/* a20.c */
|
|
|
-+int enable_a20(void);
|
|
|
-+
|
|
|
-+/* apm.c */
|
|
|
-+int query_apm_bios(void);
|
|
|
-+
|
|
|
-+/* cmdline.c */
|
|
|
-+int cmdline_find_option(const char *option, char *buffer, int bufsize);
|
|
|
-+
|
|
|
-+/* cpu.c, cpucheck.c */
|
|
|
-+int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
|
|
|
-+int validate_cpu(void);
|
|
|
-+
|
|
|
-+/* edd.c */
|
|
|
-+void query_edd(void);
|
|
|
-+
|
|
|
-+/* header.S */
|
|
|
-+void __attribute__((noreturn)) die(void);
|
|
|
-+
|
|
|
-+/* mca.c */
|
|
|
-+int query_mca(void);
|
|
|
-+
|
|
|
-+/* memory.c */
|
|
|
-+int detect_memory(void);
|
|
|
-+
|
|
|
-+/* pm.c */
|
|
|
-+void __attribute__((noreturn)) go_to_protected_mode(void);
|
|
|
-+
|
|
|
-+/* pmjump.S */
|
|
|
-+void __attribute__((noreturn))
|
|
|
-+ protected_mode_jump(u32 entrypoint, u32 bootparams);
|
|
|
-+
|
|
|
-+/* printf.c */
|
|
|
-+unsigned int atou(const char *s);
|
|
|
-+int sprintf(char *buf, const char *fmt, ...);
|
|
|
-+int vsprintf(char *buf, const char *fmt, va_list args);
|
|
|
-+int printf(const char *fmt, ...);
|
|
|
-+
|
|
|
-+/* string.c */
|
|
|
-+int strcmp(const char *str1, const char *str2);
|
|
|
-+
|
|
|
-+/* tty.c */
|
|
|
-+void puts(const char *);
|
|
|
-+void putchar(int);
|
|
|
-+int getchar(void);
|
|
|
-+void kbd_flush(void);
|
|
|
-+int getchar_timeout(void);
|
|
|
-+
|
|
|
-+/* video.c */
|
|
|
-+void set_video(void);
|
|
|
-+
|
|
|
-+/* video-vesa.c */
|
|
|
-+void vesa_store_edid(void);
|
|
|
-+
|
|
|
-+/* voyager.c */
|
|
|
-+int query_voyager(void);
|
|
|
-+
|
|
|
-+#endif /* __ASSEMBLY__ */
|
|
|
-+
|
|
|
-+#endif /* BOOT_BOOT_H */
|
|
|
-diff -puN arch/i386/boot/bootsect.S~git-newsetup /dev/null
|
|
|
---- a/arch/i386/boot/bootsect.S
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,98 +0,0 @@
|
|
|
--/*
|
|
|
-- * bootsect.S Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-- *
|
|
|
-- * modified by Drew Eckhardt
|
|
|
-- * modified by Bruce Evans (bde)
|
|
|
-- * modified by Chris Noe (May 1999) (as86 -> gas)
|
|
|
-- * gutted by H. Peter Anvin (Jan 2003)
|
|
|
-- *
|
|
|
-- * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment
|
|
|
-- * addresses must be multiplied by 16 to obtain their respective linear
|
|
|
-- * addresses. To avoid confusion, linear addresses are written using leading
|
|
|
-- * hex while segment addresses are written as segment:offset.
|
|
|
-- *
|
|
|
-- */
|
|
|
--
|
|
|
--#include <asm/boot.h>
|
|
|
--
|
|
|
--SETUPSECTS = 4 /* default nr of setup-sectors */
|
|
|
--BOOTSEG = 0x07C0 /* original address of boot-sector */
|
|
|
--INITSEG = DEF_INITSEG /* we move boot here - out of the way */
|
|
|
--SETUPSEG = DEF_SETUPSEG /* setup starts here */
|
|
|
--SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */
|
|
|
--SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */
|
|
|
-- /* to be loaded */
|
|
|
--ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */
|
|
|
--SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */
|
|
|
--
|
|
|
--#ifndef SVGA_MODE
|
|
|
--#define SVGA_MODE ASK_VGA
|
|
|
--#endif
|
|
|
--
|
|
|
--#ifndef RAMDISK
|
|
|
--#define RAMDISK 0
|
|
|
--#endif
|
|
|
--
|
|
|
--#ifndef ROOT_RDONLY
|
|
|
--#define ROOT_RDONLY 1
|
|
|
--#endif
|
|
|
--
|
|
|
--.code16
|
|
|
--.text
|
|
|
--
|
|
|
--.global _start
|
|
|
--_start:
|
|
|
--
|
|
|
-- # Normalize the start address
|
|
|
-- jmpl $BOOTSEG, $start2
|
|
|
--
|
|
|
--start2:
|
|
|
-- movw %cs, %ax
|
|
|
-- movw %ax, %ds
|
|
|
-- movw %ax, %es
|
|
|
-- movw %ax, %ss
|
|
|
-- movw $0x7c00, %sp
|
|
|
-- sti
|
|
|
-- cld
|
|
|
--
|
|
|
-- movw $bugger_off_msg, %si
|
|
|
--
|
|
|
--msg_loop:
|
|
|
-- lodsb
|
|
|
-- andb %al, %al
|
|
|
-- jz die
|
|
|
-- movb $0xe, %ah
|
|
|
-- movw $7, %bx
|
|
|
-- int $0x10
|
|
|
-- jmp msg_loop
|
|
|
--
|
|
|
--die:
|
|
|
-- # Allow the user to press a key, then reboot
|
|
|
-- xorw %ax, %ax
|
|
|
-- int $0x16
|
|
|
-- int $0x19
|
|
|
--
|
|
|
-- # int 0x19 should never return. In case it does anyway,
|
|
|
-- # invoke the BIOS reset code...
|
|
|
-- ljmp $0xf000,$0xfff0
|
|
|
--
|
|
|
--
|
|
|
--bugger_off_msg:
|
|
|
-- .ascii "Direct booting from floppy is no longer supported.\r\n"
|
|
|
-- .ascii "Please use a boot loader program instead.\r\n"
|
|
|
-- .ascii "\n"
|
|
|
-- .ascii "Remove disk and press any key to reboot . . .\r\n"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--
|
|
|
-- # Kernel attributes; used by setup
|
|
|
--
|
|
|
-- .org 497
|
|
|
--setup_sects: .byte SETUPSECTS
|
|
|
--root_flags: .word ROOT_RDONLY
|
|
|
--syssize: .word SYSSIZE
|
|
|
--swap_dev: .word SWAP_DEV
|
|
|
--ram_size: .word RAMDISK
|
|
|
--vid_mode: .word SVGA_MODE
|
|
|
--root_dev: .word ROOT_DEV
|
|
|
--boot_flag: .word 0xAA55
|
|
|
-diff -puN /dev/null arch/i386/boot/cmdline.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/cmdline.c
|
|
|
-@@ -0,0 +1,97 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/cmdline.c
|
|
|
-+ *
|
|
|
-+ * Simple command-line parser for early boot.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+
|
|
|
-+static inline int myisspace(u8 c)
|
|
|
-+{
|
|
|
-+ return c <= ' '; /* Close enough approximation */
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Find a non-boolean option, that is, "option=argument". In accordance
|
|
|
-+ * with standard Linux practice, if this option is repeated, this returns
|
|
|
-+ * the last instance on the command line.
|
|
|
-+ *
|
|
|
-+ * Returns the length of the argument (regardless of if it was
|
|
|
-+ * truncated to fit in the buffer), or -1 on not found.
|
|
|
-+ */
|
|
|
-+int cmdline_find_option(const char *option, char *buffer, int bufsize)
|
|
|
-+{
|
|
|
-+ u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr;
|
|
|
-+ addr_t cptr;
|
|
|
-+ char c;
|
|
|
-+ int len = -1;
|
|
|
-+ const char *opptr = NULL;
|
|
|
-+ char *bufptr = buffer;
|
|
|
-+ enum {
|
|
|
-+ st_wordstart, /* Start of word/after whitespace */
|
|
|
-+ st_wordcmp, /* Comparing this word */
|
|
|
-+ st_wordskip, /* Miscompare, skip */
|
|
|
-+ st_bufcpy /* Copying this to buffer */
|
|
|
-+ } state = st_wordstart;
|
|
|
-+
|
|
|
-+ if (!cmdline_ptr || cmdline_ptr >= 0x100000)
|
|
|
-+ return -1; /* No command line, or inaccessible */
|
|
|
-+
|
|
|
-+ cptr = cmdline_ptr & 0xf;
|
|
|
-+ set_fs(cmdline_ptr >> 4);
|
|
|
-+
|
|
|
-+ while (cptr < 0x10000 && (c = rdfs8(cptr++))) {
|
|
|
-+ switch (state) {
|
|
|
-+ case st_wordstart:
|
|
|
-+ if (myisspace(c))
|
|
|
-+ break;
|
|
|
-+
|
|
|
-+ /* else */
|
|
|
-+ state = st_wordcmp;
|
|
|
-+ opptr = option;
|
|
|
-+ /* fall through */
|
|
|
-+
|
|
|
-+ case st_wordcmp:
|
|
|
-+ if (c == '=' && !*opptr) {
|
|
|
-+ len = 0;
|
|
|
-+ bufptr = buffer;
|
|
|
-+ state = st_bufcpy;
|
|
|
-+ } else if (myisspace(c)) {
|
|
|
-+ state = st_wordstart;
|
|
|
-+ } else if (c != *opptr++) {
|
|
|
-+ state = st_wordskip;
|
|
|
-+ }
|
|
|
-+ break;
|
|
|
-+
|
|
|
-+ case st_wordskip:
|
|
|
-+ if (myisspace(c))
|
|
|
-+ state = st_wordstart;
|
|
|
-+ break;
|
|
|
-+
|
|
|
-+ case st_bufcpy:
|
|
|
-+ if (myisspace(c)) {
|
|
|
-+ state = st_wordstart;
|
|
|
-+ } else {
|
|
|
-+ if (len < bufsize-1)
|
|
|
-+ *bufptr++ = c;
|
|
|
-+ len++;
|
|
|
-+ }
|
|
|
-+ break;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ if (bufsize)
|
|
|
-+ *bufptr = '\0';
|
|
|
-+
|
|
|
-+ return len;
|
|
|
-+}
|
|
|
-diff -puN /dev/null arch/i386/boot/code16gcc.h
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/code16gcc.h
|
|
|
-@@ -0,0 +1,9 @@
|
|
|
-+/*
|
|
|
-+ * code16gcc.h
|
|
|
-+ *
|
|
|
-+ * This file is -include'd when compiling 16-bit C code.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#ifndef __ASSEMBLY__
|
|
|
-+asm(".code16gcc");
|
|
|
-+#endif
|
|
|
-diff -puN arch/i386/boot/compressed/Makefile~git-newsetup arch/i386/boot/compressed/Makefile
|
|
|
---- a/arch/i386/boot/compressed/Makefile~git-newsetup
|
|
|
-+++ a/arch/i386/boot/compressed/Makefile
|
|
|
-@@ -9,9 +9,14 @@ targets := vmlinux vmlinux.bin vmlinux.
|
|
|
- EXTRA_AFLAGS := -traditional
|
|
|
-
|
|
|
- LDFLAGS_vmlinux := -T
|
|
|
--CFLAGS_misc.o += -fPIC
|
|
|
- hostprogs-y := relocs
|
|
|
-
|
|
|
-+CFLAGS := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
|
|
|
-+ -fno-strict-aliasing -fPIC \
|
|
|
-+ $(call cc-option,-ffreestanding) \
|
|
|
-+ $(call cc-option,-fno-stack-protector)
|
|
|
-+LDFLAGS := -m elf_i386
|
|
|
-+
|
|
|
- $(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
|
|
|
- $(call if_changed,ld)
|
|
|
- @:
|
|
|
-diff -puN arch/i386/boot/compressed/head.S~git-newsetup arch/i386/boot/compressed/head.S
|
|
|
---- a/arch/i386/boot/compressed/head.S~git-newsetup
|
|
|
-+++ a/arch/i386/boot/compressed/head.S
|
|
|
-@@ -45,10 +45,10 @@ startup_32:
|
|
|
- * at and where we were actually loaded at. This can only be done
|
|
|
- * with a short local call on x86. Nothing else will tell us what
|
|
|
- * address we are running at. The reserved chunk of the real-mode
|
|
|
-- * data at 0x34-0x3f are used as the stack for this calculation.
|
|
|
-- * Only 4 bytes are needed.
|
|
|
-+ * data at 0x1e4 (defined as a scratch field) are used as the stack
|
|
|
-+ * for this calculation. Only 4 bytes are needed.
|
|
|
- */
|
|
|
-- leal 0x40(%esi), %esp
|
|
|
-+ leal (0x1e4+4)(%esi), %esp
|
|
|
- call 1f
|
|
|
- 1: popl %ebp
|
|
|
- subl $1b, %ebp
|
|
|
-diff -puN arch/i386/boot/compressed/misc.c~git-newsetup arch/i386/boot/compressed/misc.c
|
|
|
---- a/arch/i386/boot/compressed/misc.c~git-newsetup
|
|
|
-+++ a/arch/i386/boot/compressed/misc.c
|
|
|
-@@ -11,7 +11,6 @@
|
|
|
-
|
|
|
- #undef CONFIG_PARAVIRT
|
|
|
- #include <linux/linkage.h>
|
|
|
--#include <linux/vmalloc.h>
|
|
|
- #include <linux/screen_info.h>
|
|
|
- #include <asm/io.h>
|
|
|
- #include <asm/page.h>
|
|
|
-@@ -364,8 +363,10 @@ asmlinkage void decompress_kernel(void *
|
|
|
-
|
|
|
- if ((u32)output & (CONFIG_PHYSICAL_ALIGN -1))
|
|
|
- error("Destination address not CONFIG_PHYSICAL_ALIGN aligned");
|
|
|
-+#ifndef CONFIG_X86_64
|
|
|
- if (end > ((-__PAGE_OFFSET-(512 <<20)-1) & 0x7fffffff))
|
|
|
- error("Destination address too large");
|
|
|
-+#endif
|
|
|
- #ifndef CONFIG_RELOCATABLE
|
|
|
- if ((u32)output != LOAD_PHYSICAL_ADDR)
|
|
|
- error("Wrong destination address");
|
|
|
-diff -puN /dev/null arch/i386/boot/copy.S
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/copy.S
|
|
|
-@@ -0,0 +1,101 @@
|
|
|
-+/* ----------------------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/copy.S
|
|
|
-+ *
|
|
|
-+ * Memory copy routines
|
|
|
-+ */
|
|
|
-+
|
|
|
-+ .code16gcc
|
|
|
-+ .text
|
|
|
-+
|
|
|
-+ .globl memcpy
|
|
|
-+ .type memcpy, @function
|
|
|
-+memcpy:
|
|
|
-+ pushw %si
|
|
|
-+ pushw %di
|
|
|
-+ movw %ax, %di
|
|
|
-+ movw %dx, %si
|
|
|
-+ pushw %cx
|
|
|
-+ shrw $2, %cx
|
|
|
-+ rep; movsl
|
|
|
-+ popw %cx
|
|
|
-+ andw $3, %cx
|
|
|
-+ rep; movsb
|
|
|
-+ popw %di
|
|
|
-+ popw %si
|
|
|
-+ ret
|
|
|
-+ .size memcpy, .-memcpy
|
|
|
-+
|
|
|
-+ .globl memset
|
|
|
-+ .type memset, @function
|
|
|
-+memset:
|
|
|
-+ pushw %di
|
|
|
-+ movw %ax, %di
|
|
|
-+ movzbl %dl, %eax
|
|
|
-+ imull $0x01010101,%eax
|
|
|
-+ pushw %cx
|
|
|
-+ shrw $2, %cx
|
|
|
-+ rep; stosl
|
|
|
-+ popw %cx
|
|
|
-+ andw $3, %cx
|
|
|
-+ rep; stosb
|
|
|
-+ popw %di
|
|
|
-+ ret
|
|
|
-+ .size memset, .-memset
|
|
|
-+
|
|
|
-+ .globl copy_from_fs
|
|
|
-+ .type copy_from_fs, @function
|
|
|
-+copy_from_fs:
|
|
|
-+ pushw %ds
|
|
|
-+ pushw %fs
|
|
|
-+ popw %ds
|
|
|
-+ call memcpy
|
|
|
-+ popw %ds
|
|
|
-+ ret
|
|
|
-+ .size copy_from_fs, .-copy_from_fs
|
|
|
-+
|
|
|
-+ .globl copy_to_fs
|
|
|
-+ .type copy_to_fs, @function
|
|
|
-+copy_to_fs:
|
|
|
-+ pushw %es
|
|
|
-+ pushw %fs
|
|
|
-+ popw %es
|
|
|
-+ call memcpy
|
|
|
-+ popw %es
|
|
|
-+ ret
|
|
|
-+ .size copy_to_fs, .-copy_to_fs
|
|
|
-+
|
|
|
-+#if 0 /* Not currently used, but can be enabled as needed */
|
|
|
-+
|
|
|
-+ .globl copy_from_gs
|
|
|
-+ .type copy_from_gs, @function
|
|
|
-+copy_from_gs:
|
|
|
-+ pushw %ds
|
|
|
-+ pushw %gs
|
|
|
-+ popw %ds
|
|
|
-+ call memcpy
|
|
|
-+ popw %ds
|
|
|
-+ ret
|
|
|
-+ .size copy_from_gs, .-copy_from_gs
|
|
|
-+ .globl copy_to_gs
|
|
|
-+
|
|
|
-+ .type copy_to_gs, @function
|
|
|
-+copy_to_gs:
|
|
|
-+ pushw %es
|
|
|
-+ pushw %gs
|
|
|
-+ popw %es
|
|
|
-+ call memcpy
|
|
|
-+ popw %es
|
|
|
-+ ret
|
|
|
-+ .size copy_to_gs, .-copy_to_gs
|
|
|
-+
|
|
|
-+#endif
|
|
|
-diff -puN /dev/null arch/i386/boot/cpu.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/cpu.c
|
|
|
-@@ -0,0 +1,69 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/cpucheck.c
|
|
|
-+ *
|
|
|
-+ * Check for obligatory CPU features and abort if the features are not
|
|
|
-+ * present.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+#include "bitops.h"
|
|
|
-+#include <asm/cpufeature.h>
|
|
|
-+
|
|
|
-+static char *cpu_name(int level)
|
|
|
-+{
|
|
|
-+ static char buf[6];
|
|
|
-+
|
|
|
-+ if (level == 64) {
|
|
|
-+ return "x86-64";
|
|
|
-+ } else {
|
|
|
-+ sprintf(buf, "i%d86", level);
|
|
|
-+ return buf;
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+int validate_cpu(void)
|
|
|
-+{
|
|
|
-+ u32 *err_flags;
|
|
|
-+ int cpu_level, req_level;
|
|
|
-+
|
|
|
-+ check_cpu(&cpu_level, &req_level, &err_flags);
|
|
|
-+
|
|
|
-+ if (cpu_level < req_level) {
|
|
|
-+ printf("This kernel requires an %s CPU, ",
|
|
|
-+ cpu_name(req_level));
|
|
|
-+ printf("but only detected an %s CPU.\n",
|
|
|
-+ cpu_name(cpu_level));
|
|
|
-+ return -1;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ if (err_flags) {
|
|
|
-+ int i, j;
|
|
|
-+ puts("This kernel requires the following features "
|
|
|
-+ "not present on the CPU:\n");
|
|
|
-+
|
|
|
-+ for (i = 0; i < NCAPINTS; i++) {
|
|
|
-+ u32 e = err_flags[i];
|
|
|
-+
|
|
|
-+ for (j = 0; j < 32; j++) {
|
|
|
-+ if (e & 1)
|
|
|
-+ printf("%d:%d ", i, j);
|
|
|
-+
|
|
|
-+ e >>= 1;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ putchar('\n');
|
|
|
-+ return -1;
|
|
|
-+ } else {
|
|
|
-+ return 0;
|
|
|
-+ }
|
|
|
-+}
|
|
|
-diff -puN /dev/null arch/i386/boot/cpucheck.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/cpucheck.c
|
|
|
-@@ -0,0 +1,266 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/cpu.c
|
|
|
-+ *
|
|
|
-+ * Check for obligatory CPU features and abort if the features are not
|
|
|
-+ * present. This code should be compilable as 16-, 32- or 64-bit
|
|
|
-+ * code, so be very careful with types and inline assembly.
|
|
|
-+ *
|
|
|
-+ * This code should not contain any messages; that requires an
|
|
|
-+ * additional wrapper.
|
|
|
-+ *
|
|
|
-+ * As written, this code is not safe for inclusion into the kernel
|
|
|
-+ * proper (after FPU initialization, in particular).
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#ifdef _SETUP
|
|
|
-+# include "boot.h"
|
|
|
-+# include "bitops.h"
|
|
|
-+#endif
|
|
|
-+#include <linux/types.h>
|
|
|
-+#include <asm/cpufeature.h>
|
|
|
-+#include <asm/processor-flags.h>
|
|
|
-+#include <asm/required-features.h>
|
|
|
-+#include <asm/msr-index.h>
|
|
|
-+
|
|
|
-+struct cpu_features {
|
|
|
-+ int level;
|
|
|
-+ int model;
|
|
|
-+ u32 flags[NCAPINTS];
|
|
|
-+};
|
|
|
-+
|
|
|
-+static struct cpu_features cpu;
|
|
|
-+static u32 cpu_vendor[3];
|
|
|
-+static u32 err_flags[NCAPINTS];
|
|
|
-+
|
|
|
-+#ifdef CONFIG_X86_64
|
|
|
-+static const int req_level = 64;
|
|
|
-+#elif defined(CONFIG_X86_MINIMUM_CPU_MODEL)
|
|
|
-+static const int req_level = CONFIG_X86_MINIMUM_CPU_MODEL;
|
|
|
-+#else
|
|
|
-+static const int req_level = 3;
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+static const u32 req_flags[NCAPINTS] =
|
|
|
-+{
|
|
|
-+ REQUIRED_MASK0,
|
|
|
-+ REQUIRED_MASK1,
|
|
|
-+ REQUIRED_MASK2,
|
|
|
-+ REQUIRED_MASK3,
|
|
|
-+ REQUIRED_MASK4,
|
|
|
-+ REQUIRED_MASK5,
|
|
|
-+ REQUIRED_MASK6,
|
|
|
-+};
|
|
|
-+
|
|
|
-+#define A32(a,b,c,d) (((d) << 24)+((c) << 16)+((b) << 8)+(a))
|
|
|
-+
|
|
|
-+static int is_amd(void)
|
|
|
-+{
|
|
|
-+ return cpu_vendor[0] == A32('A','u','t','h') &&
|
|
|
-+ cpu_vendor[1] == A32('e','n','t','i') &&
|
|
|
-+ cpu_vendor[2] == A32('c','A','M','D');
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int is_centaur(void)
|
|
|
-+{
|
|
|
-+ return cpu_vendor[0] == A32('C','e','n','t') &&
|
|
|
-+ cpu_vendor[1] == A32('a','u','r','H') &&
|
|
|
-+ cpu_vendor[2] == A32('a','u','l','s');
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int is_transmeta(void)
|
|
|
-+{
|
|
|
-+ return cpu_vendor[0] == A32('G','e','n','u') &&
|
|
|
-+ cpu_vendor[1] == A32('i','n','e','T') &&
|
|
|
-+ cpu_vendor[2] == A32('M','x','8','6');
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int has_fpu(void)
|
|
|
-+{
|
|
|
-+ u16 fcw = -1, fsw = -1;
|
|
|
-+ u32 cr0;
|
|
|
-+
|
|
|
-+ asm("movl %%cr0,%0" : "=r" (cr0));
|
|
|
-+ if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
|
|
|
-+ cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
|
|
|
-+ asm volatile("movl %0,%%cr0" : : "r" (cr0));
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ asm("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw));
|
|
|
-+
|
|
|
-+ return fsw == 0 && (fcw & 0x103f) == 0x003f;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int has_eflag(u32 mask)
|
|
|
-+{
|
|
|
-+ u32 f0, f1;
|
|
|
-+
|
|
|
-+ asm("pushfl ; "
|
|
|
-+ "pushfl ; "
|
|
|
-+ "popl %0 ; "
|
|
|
-+ "movl %0,%1 ; "
|
|
|
-+ "xorl %2,%1 ; "
|
|
|
-+ "pushl %1 ; "
|
|
|
-+ "popfl ; "
|
|
|
-+ "pushfl ; "
|
|
|
-+ "popl %1 ; "
|
|
|
-+ "popfl"
|
|
|
-+ : "=r" (f0), "=r" (f1)
|
|
|
-+ : "g" (mask));
|
|
|
-+
|
|
|
-+ return !!((f0^f1) & mask);
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void get_flags(void)
|
|
|
-+{
|
|
|
-+ u32 max_intel_level, max_amd_level;
|
|
|
-+ u32 tfms;
|
|
|
-+
|
|
|
-+ if (has_fpu())
|
|
|
-+ set_bit(X86_FEATURE_FPU, cpu.flags);
|
|
|
-+
|
|
|
-+ if (has_eflag(X86_EFLAGS_ID)) {
|
|
|
-+ asm("cpuid"
|
|
|
-+ : "=a" (max_intel_level),
|
|
|
-+ "=b" (cpu_vendor[0]),
|
|
|
-+ "=d" (cpu_vendor[1]),
|
|
|
-+ "=c" (cpu_vendor[2])
|
|
|
-+ : "a" (0));
|
|
|
-+
|
|
|
-+ if (max_intel_level >= 0x00000001 &&
|
|
|
-+ max_intel_level <= 0x0000ffff) {
|
|
|
-+ asm("cpuid"
|
|
|
-+ : "=a" (tfms),
|
|
|
-+ "=c" (cpu.flags[4]),
|
|
|
-+ "=d" (cpu.flags[0])
|
|
|
-+ : "a" (0x00000001)
|
|
|
-+ : "ebx");
|
|
|
-+ cpu.level = (tfms >> 8) & 15;
|
|
|
-+ cpu.model = (tfms >> 4) & 15;
|
|
|
-+ if (cpu.level >= 6)
|
|
|
-+ cpu.model += ((tfms >> 16) & 0xf) << 4;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ asm("cpuid"
|
|
|
-+ : "=a" (max_amd_level)
|
|
|
-+ : "a" (0x80000000)
|
|
|
-+ : "ebx", "ecx", "edx");
|
|
|
-+
|
|
|
-+ if (max_amd_level >= 0x80000001 &&
|
|
|
-+ max_amd_level <= 0x8000ffff) {
|
|
|
-+ u32 eax = 0x80000001;
|
|
|
-+ asm("cpuid"
|
|
|
-+ : "+a" (eax),
|
|
|
-+ "=c" (cpu.flags[6]),
|
|
|
-+ "=d" (cpu.flags[1])
|
|
|
-+ : : "ebx");
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Returns a bitmask of which words we have error bits in */
|
|
|
-+static int check_flags(void)
|
|
|
-+{
|
|
|
-+ u32 err;
|
|
|
-+ int i;
|
|
|
-+
|
|
|
-+ err = 0;
|
|
|
-+ for (i = 0; i < NCAPINTS; i++) {
|
|
|
-+ err_flags[i] = req_flags[i] & ~cpu.flags[i];
|
|
|
-+ if (err_flags[i])
|
|
|
-+ err |= 1 << i;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ return err;
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Returns -1 on error.
|
|
|
-+ *
|
|
|
-+ * *cpu_level is set to the current CPU level; *req_level to the required
|
|
|
-+ * level. x86-64 is considered level 64 for this purpose.
|
|
|
-+ *
|
|
|
-+ * *err_flags_ptr is set to the flags error array if there are flags missing.
|
|
|
-+ */
|
|
|
-+int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
|
|
|
-+{
|
|
|
-+ int err;
|
|
|
-+
|
|
|
-+ memset(&cpu.flags, 0, sizeof cpu.flags);
|
|
|
-+ cpu.level = 3;
|
|
|
-+
|
|
|
-+ if (has_eflag(X86_EFLAGS_AC))
|
|
|
-+ cpu.level = 4;
|
|
|
-+
|
|
|
-+ get_flags();
|
|
|
-+ err = check_flags();
|
|
|
-+
|
|
|
-+ if (test_bit(X86_FEATURE_LM, cpu.flags))
|
|
|
-+ cpu.level = 64;
|
|
|
-+
|
|
|
-+ if (err == 0x01 &&
|
|
|
-+ !(err_flags[0] &
|
|
|
-+ ~((1 << X86_FEATURE_XMM)|(1 << X86_FEATURE_XMM2))) &&
|
|
|
-+ is_amd()) {
|
|
|
-+ /* If this is an AMD and we're only missing SSE+SSE2, try to
|
|
|
-+ turn them on */
|
|
|
-+
|
|
|
-+ u32 ecx = MSR_K7_HWCR;
|
|
|
-+ u32 eax, edx;
|
|
|
-+
|
|
|
-+ asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
|
|
|
-+ eax &= ~(1 << 15);
|
|
|
-+ asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
|
|
|
-+
|
|
|
-+ get_flags(); /* Make sure it really did something */
|
|
|
-+ err = check_flags();
|
|
|
-+ } else if (err == 0x01 &&
|
|
|
-+ !(err_flags[0] & ~(1 << X86_FEATURE_CX8)) &&
|
|
|
-+ is_centaur() && cpu.model >= 6) {
|
|
|
-+ /* If this is a VIA C3, we might have to enable CX8
|
|
|
-+ explicitly */
|
|
|
-+
|
|
|
-+ u32 ecx = MSR_VIA_FCR;
|
|
|
-+ u32 eax, edx;
|
|
|
-+
|
|
|
-+ asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
|
|
|
-+ eax |= (1<<1)|(1<<7);
|
|
|
-+ asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
|
|
|
-+
|
|
|
-+ set_bit(X86_FEATURE_CX8, cpu.flags);
|
|
|
-+ err = check_flags();
|
|
|
-+ } else if (err == 0x01 && is_transmeta()) {
|
|
|
-+ /* Transmeta might have masked feature bits in word 0 */
|
|
|
-+
|
|
|
-+ u32 ecx = 0x80860004;
|
|
|
-+ u32 eax, edx;
|
|
|
-+ u32 level = 1;
|
|
|
-+
|
|
|
-+ asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
|
|
|
-+ asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
|
|
|
-+ asm("cpuid"
|
|
|
-+ : "+a" (level), "=d" (cpu.flags[0])
|
|
|
-+ : : "ecx", "ebx");
|
|
|
-+ asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
|
|
|
-+
|
|
|
-+ err = check_flags();
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ if (err_flags_ptr)
|
|
|
-+ *err_flags_ptr = err ? err_flags : NULL;
|
|
|
-+ if (cpu_level_ptr)
|
|
|
-+ *cpu_level_ptr = cpu.level;
|
|
|
-+ if (req_level_ptr)
|
|
|
-+ *req_level_ptr = req_level;
|
|
|
-+
|
|
|
-+ return (cpu.level < req_level || err) ? -1 : 0;
|
|
|
-+}
|
|
|
-diff -puN arch/i386/boot/edd.S~git-newsetup /dev/null
|
|
|
---- a/arch/i386/boot/edd.S
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,231 +0,0 @@
|
|
|
--/*
|
|
|
-- * BIOS Enhanced Disk Drive support
|
|
|
-- * Copyright (C) 2002, 2003, 2004 Dell, Inc.
|
|
|
-- * by Matt Domsch <[email protected]> October 2002
|
|
|
-- * conformant to T13 Committee www.t13.org
|
|
|
-- * projects 1572D, 1484D, 1386D, 1226DT
|
|
|
-- * disk signature read by Matt Domsch <[email protected]>
|
|
|
-- * and Andrew Wilks <[email protected]> September 2003, June 2004
|
|
|
-- * legacy CHS retrieval by Patrick J. LoPresti <[email protected]>
|
|
|
-- * March 2004
|
|
|
-- * Command line option parsing, Matt Domsch, November 2004
|
|
|
-- */
|
|
|
--
|
|
|
--#include <linux/edd.h>
|
|
|
--#include <asm/setup.h>
|
|
|
--
|
|
|
--#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
|
|
|
--
|
|
|
--# It is assumed that %ds == INITSEG here
|
|
|
--
|
|
|
-- movb $0, (EDD_MBR_SIG_NR_BUF)
|
|
|
-- movb $0, (EDDNR)
|
|
|
--
|
|
|
--# Check the command line for options:
|
|
|
--# edd=of disables EDD completely (edd=off)
|
|
|
--# edd=sk skips the MBR test (edd=skipmbr)
|
|
|
--# edd=on re-enables EDD (edd=on)
|
|
|
--
|
|
|
-- pushl %esi
|
|
|
-- movw $edd_mbr_sig_start, %di # Default to edd=on
|
|
|
--
|
|
|
-- movl %cs:(cmd_line_ptr), %esi
|
|
|
-- andl %esi, %esi
|
|
|
-- jz old_cl # Old boot protocol?
|
|
|
--
|
|
|
--# Convert to a real-mode pointer in fs:si
|
|
|
-- movl %esi, %eax
|
|
|
-- shrl $4, %eax
|
|
|
-- movw %ax, %fs
|
|
|
-- andw $0xf, %si
|
|
|
-- jmp have_cl_pointer
|
|
|
--
|
|
|
--# Old-style boot protocol?
|
|
|
--old_cl:
|
|
|
-- push %ds # aka INITSEG
|
|
|
-- pop %fs
|
|
|
--
|
|
|
-- cmpw $0xa33f, (0x20)
|
|
|
-- jne done_cl # No command line at all?
|
|
|
-- movw (0x22), %si # Pointer relative to INITSEG
|
|
|
--
|
|
|
--# fs:si has the pointer to the command line now
|
|
|
--have_cl_pointer:
|
|
|
--
|
|
|
--# Loop through kernel command line one byte at a time. Just in
|
|
|
--# case the loader is buggy and failed to null-terminate the command line
|
|
|
--# terminate if we get close enough to the end of the segment that we
|
|
|
--# cannot fit "edd=XX"...
|
|
|
--cl_atspace:
|
|
|
-- cmpw $-5, %si # Watch for segment wraparound
|
|
|
-- jae done_cl
|
|
|
-- movl %fs:(%si), %eax
|
|
|
-- andb %al, %al # End of line?
|
|
|
-- jz done_cl
|
|
|
-- cmpl $EDD_CL_EQUALS, %eax
|
|
|
-- jz found_edd_equals
|
|
|
-- cmpb $0x20, %al # <= space consider whitespace
|
|
|
-- ja cl_skipword
|
|
|
-- incw %si
|
|
|
-- jmp cl_atspace
|
|
|
--
|
|
|
--cl_skipword:
|
|
|
-- cmpw $-5, %si # Watch for segment wraparound
|
|
|
-- jae done_cl
|
|
|
-- movb %fs:(%si), %al # End of string?
|
|
|
-- andb %al, %al
|
|
|
-- jz done_cl
|
|
|
-- cmpb $0x20, %al
|
|
|
-- jbe cl_atspace
|
|
|
-- incw %si
|
|
|
-- jmp cl_skipword
|
|
|
--
|
|
|
--found_edd_equals:
|
|
|
--# only looking at first two characters after equals
|
|
|
--# late overrides early on the command line, so keep going after finding something
|
|
|
-- movw %fs:4(%si), %ax
|
|
|
-- cmpw $EDD_CL_OFF, %ax # edd=of
|
|
|
-- je do_edd_off
|
|
|
-- cmpw $EDD_CL_SKIP, %ax # edd=sk
|
|
|
-- je do_edd_skipmbr
|
|
|
-- cmpw $EDD_CL_ON, %ax # edd=on
|
|
|
-- je do_edd_on
|
|
|
-- jmp cl_skipword
|
|
|
--do_edd_skipmbr:
|
|
|
-- movw $edd_start, %di
|
|
|
-- jmp cl_skipword
|
|
|
--do_edd_off:
|
|
|
-- movw $edd_done, %di
|
|
|
-- jmp cl_skipword
|
|
|
--do_edd_on:
|
|
|
-- movw $edd_mbr_sig_start, %di
|
|
|
-- jmp cl_skipword
|
|
|
--
|
|
|
--done_cl:
|
|
|
-- popl %esi
|
|
|
-- jmpw *%di
|
|
|
--
|
|
|
--# Read the first sector of each BIOS disk device and store the 4-byte signature
|
|
|
--edd_mbr_sig_start:
|
|
|
-- movb $0x80, %dl # from device 80
|
|
|
-- movw $EDD_MBR_SIG_BUF, %bx # store buffer ptr in bx
|
|
|
--edd_mbr_sig_read:
|
|
|
-- movl $0xFFFFFFFF, %eax
|
|
|
-- movl %eax, (%bx) # assume failure
|
|
|
-- pushw %bx
|
|
|
-- movb $READ_SECTORS, %ah
|
|
|
-- movb $1, %al # read 1 sector
|
|
|
-- movb $0, %dh # at head 0
|
|
|
-- movw $1, %cx # cylinder 0, sector 0
|
|
|
-- pushw %es
|
|
|
-- pushw %ds
|
|
|
-- popw %es
|
|
|
-- movw $EDDBUF, %bx # disk's data goes into EDDBUF
|
|
|
-- pushw %dx # work around buggy BIOSes
|
|
|
-- stc # work around buggy BIOSes
|
|
|
-- int $0x13
|
|
|
-- sti # work around buggy BIOSes
|
|
|
-- popw %dx
|
|
|
-- popw %es
|
|
|
-- popw %bx
|
|
|
-- jc edd_mbr_sig_done # on failure, we're done.
|
|
|
-- cmpb $0, %ah # some BIOSes do not set CF
|
|
|
-- jne edd_mbr_sig_done # on failure, we're done.
|
|
|
-- movl (EDDBUF+EDD_MBR_SIG_OFFSET), %eax # read sig out of the MBR
|
|
|
-- movl %eax, (%bx) # store success
|
|
|
-- incb (EDD_MBR_SIG_NR_BUF) # note that we stored something
|
|
|
-- incb %dl # increment to next device
|
|
|
-- addw $4, %bx # increment sig buffer ptr
|
|
|
-- cmpb $EDD_MBR_SIG_MAX, (EDD_MBR_SIG_NR_BUF) # Out of space?
|
|
|
-- jb edd_mbr_sig_read # keep looping
|
|
|
--edd_mbr_sig_done:
|
|
|
--
|
|
|
--# Do the BIOS Enhanced Disk Drive calls
|
|
|
--# This consists of two calls:
|
|
|
--# int 13h ah=41h "Check Extensions Present"
|
|
|
--# int 13h ah=48h "Get Device Parameters"
|
|
|
--# int 13h ah=08h "Legacy Get Device Parameters"
|
|
|
--#
|
|
|
--# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use
|
|
|
--# in the boot_params at EDDBUF. The first four bytes of which are
|
|
|
--# used to store the device number, interface support map and version
|
|
|
--# results from fn41. The next four bytes are used to store the legacy
|
|
|
--# cylinders, heads, and sectors from fn08. The following 74 bytes are used to
|
|
|
--# store the results from fn48. Starting from device 80h, fn41, then fn48
|
|
|
--# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE).
|
|
|
--# Then the pointer is incremented to store the data for the next call.
|
|
|
--# This repeats until either a device doesn't exist, or until EDDMAXNR
|
|
|
--# devices have been stored.
|
|
|
--# The one tricky part is that ds:si always points EDDEXTSIZE bytes into
|
|
|
--# the structure, and the fn41 and fn08 results are stored at offsets
|
|
|
--# from there. This removes the need to increment the pointer for
|
|
|
--# every store, and leaves it ready for the fn48 call.
|
|
|
--# A second one-byte buffer, EDDNR, in the boot_params stores
|
|
|
--# the number of BIOS devices which exist, up to EDDMAXNR.
|
|
|
--# In setup.c, copy_edd() stores both boot_params buffers away
|
|
|
--# for later use, as they would get overwritten otherwise.
|
|
|
--# This code is sensitive to the size of the structs in edd.h
|
|
|
--edd_start:
|
|
|
-- # %ds points to the bootsector
|
|
|
-- # result buffer for fn48
|
|
|
-- movw $EDDBUF+EDDEXTSIZE, %si # in ds:si, fn41 results
|
|
|
-- # kept just before that
|
|
|
-- movb $0x80, %dl # BIOS device 0x80
|
|
|
--
|
|
|
--edd_check_ext:
|
|
|
-- movb $CHECKEXTENSIONSPRESENT, %ah # Function 41
|
|
|
-- movw $EDDMAGIC1, %bx # magic
|
|
|
-- int $0x13 # make the call
|
|
|
-- jc edd_done # no more BIOS devices
|
|
|
--
|
|
|
-- cmpw $EDDMAGIC2, %bx # is magic right?
|
|
|
-- jne edd_next # nope, next...
|
|
|
--
|
|
|
-- movb %dl, %ds:-8(%si) # store device number
|
|
|
-- movb %ah, %ds:-7(%si) # store version
|
|
|
-- movw %cx, %ds:-6(%si) # store extensions
|
|
|
-- incb (EDDNR) # note that we stored something
|
|
|
--
|
|
|
--edd_get_device_params:
|
|
|
-- movw $EDDPARMSIZE, %ds:(%si) # put size
|
|
|
-- movw $0x0, %ds:2(%si) # work around buggy BIOSes
|
|
|
-- movb $GETDEVICEPARAMETERS, %ah # Function 48
|
|
|
-- int $0x13 # make the call
|
|
|
-- # Don't check for fail return
|
|
|
-- # it doesn't matter.
|
|
|
--edd_get_legacy_chs:
|
|
|
-- xorw %ax, %ax
|
|
|
-- movw %ax, %ds:-4(%si)
|
|
|
-- movw %ax, %ds:-2(%si)
|
|
|
-- # Ralf Brown's Interrupt List says to set ES:DI to
|
|
|
-- # 0000h:0000h "to guard against BIOS bugs"
|
|
|
-- pushw %es
|
|
|
-- movw %ax, %es
|
|
|
-- movw %ax, %di
|
|
|
-- pushw %dx # legacy call clobbers %dl
|
|
|
-- movb $LEGACYGETDEVICEPARAMETERS, %ah # Function 08
|
|
|
-- int $0x13 # make the call
|
|
|
-- jc edd_legacy_done # failed
|
|
|
-- movb %cl, %al # Low 6 bits are max
|
|
|
-- andb $0x3F, %al # sector number
|
|
|
-- movb %al, %ds:-1(%si) # Record max sect
|
|
|
-- movb %dh, %ds:-2(%si) # Record max head number
|
|
|
-- movb %ch, %al # Low 8 bits of max cyl
|
|
|
-- shr $6, %cl
|
|
|
-- movb %cl, %ah # High 2 bits of max cyl
|
|
|
-- movw %ax, %ds:-4(%si)
|
|
|
--
|
|
|
--edd_legacy_done:
|
|
|
-- popw %dx
|
|
|
-- popw %es
|
|
|
-- movw %si, %ax # increment si
|
|
|
-- addw $EDDPARMSIZE+EDDEXTSIZE, %ax
|
|
|
-- movw %ax, %si
|
|
|
--
|
|
|
--edd_next:
|
|
|
-- incb %dl # increment to next device
|
|
|
-- cmpb $EDDMAXNR, (EDDNR) # Out of space?
|
|
|
-- jb edd_check_ext # keep looping
|
|
|
--
|
|
|
--edd_done:
|
|
|
--#endif
|
|
|
-diff -puN /dev/null arch/i386/boot/edd.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/edd.c
|
|
|
-@@ -0,0 +1,196 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/edd.c
|
|
|
-+ *
|
|
|
-+ * Get EDD BIOS disk information
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+#include <linux/edd.h>
|
|
|
-+
|
|
|
-+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
|
|
|
-+
|
|
|
-+struct edd_dapa {
|
|
|
-+ u8 pkt_size;
|
|
|
-+ u8 rsvd;
|
|
|
-+ u16 sector_cnt;
|
|
|
-+ u16 buf_off, buf_seg;
|
|
|
-+ u64 lba;
|
|
|
-+ u64 buf_lin_addr;
|
|
|
-+};
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Note: this uses the heap to hold the loaded sector.
|
|
|
-+ */
|
|
|
-+static int read_sector(u8 devno, u64 lba, void *buf)
|
|
|
-+{
|
|
|
-+ struct edd_dapa dapa;
|
|
|
-+ u16 ax, bx, cx, dx, si;
|
|
|
-+
|
|
|
-+ memset(&dapa, 0, sizeof dapa);
|
|
|
-+ dapa.pkt_size = sizeof(dapa);
|
|
|
-+ dapa.sector_cnt = 1;
|
|
|
-+ dapa.buf_off = (size_t)buf;
|
|
|
-+ dapa.buf_seg = ds();
|
|
|
-+ dapa.lba = lba;
|
|
|
-+
|
|
|
-+ ax = 0x4200; /* Extended Read */
|
|
|
-+ si = (size_t)&dapa;
|
|
|
-+ dx = devno;
|
|
|
-+ asm("pushfl; stc; int $0x13; setc %%al; popfl"
|
|
|
-+ : "+a" (ax), "+S" (si), "+d" (dx)
|
|
|
-+ : "m" (dapa)
|
|
|
-+ : "ebx", "ecx", "edi", "memory");
|
|
|
-+
|
|
|
-+ if (!(u8)ax)
|
|
|
-+ return 0; /* OK */
|
|
|
-+
|
|
|
-+ ax = 0x0201; /* Legacy Read, one sector */
|
|
|
-+ cx = 0x0001; /* Sector 0-0-1 */
|
|
|
-+ dx = devno;
|
|
|
-+ bx = (size_t)buf;
|
|
|
-+ asm("pushfl; stc; int $0x13; setc %%al; popfl"
|
|
|
-+ : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
|
|
|
-+ : : "esi", "edi", "memory");
|
|
|
-+
|
|
|
-+ return -(u8)ax; /* 0 or -1 */
|
|
|
-+}
|
|
|
-+
|
|
|
-+static u32 read_mbr_sig(u8 devno, struct edd_info *ei)
|
|
|
-+{
|
|
|
-+ int sector_size;
|
|
|
-+ char *mbrbuf_ptr, *mbrbuf_end;
|
|
|
-+ u32 mbrsig;
|
|
|
-+ u32 buf_base, mbr_base;
|
|
|
-+ extern char _end[];
|
|
|
-+ static char mbr_buf[1024];
|
|
|
-+
|
|
|
-+ sector_size = ei->params.bytes_per_sector;
|
|
|
-+ if (!sector_size)
|
|
|
-+ sector_size = 512; /* Best available guess */
|
|
|
-+
|
|
|
-+ buf_base = (ds() << 4) + (u32)&_end;
|
|
|
-+ mbr_base = (buf_base+sector_size-1) & ~(sector_size-1);
|
|
|
-+ mbrbuf_ptr = mbr_buf + (mbr_base-buf_base);
|
|
|
-+ mbrbuf_end = mbrbuf_ptr + sector_size;
|
|
|
-+
|
|
|
-+ if (!(boot_params.hdr.loadflags & CAN_USE_HEAP))
|
|
|
-+ return 0;
|
|
|
-+ if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr)
|
|
|
-+ return 0;
|
|
|
-+
|
|
|
-+ if (read_sector(devno, 0, mbrbuf_ptr))
|
|
|
-+ return 0;
|
|
|
-+
|
|
|
-+ mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET];
|
|
|
-+ return mbrsig;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int get_edd_info(u8 devno, struct edd_info *ei)
|
|
|
-+{
|
|
|
-+ u16 ax, bx, cx, dx, di;
|
|
|
-+
|
|
|
-+ memset(ei, 0, sizeof *ei);
|
|
|
-+
|
|
|
-+ /* Check Extensions Present */
|
|
|
-+
|
|
|
-+ ax = 0x4100;
|
|
|
-+ bx = EDDMAGIC1;
|
|
|
-+ dx = devno;
|
|
|
-+ asm("pushfl; stc; int $0x13; setc %%al; popfl"
|
|
|
-+ : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
|
|
|
-+ : : "esi", "edi");
|
|
|
-+
|
|
|
-+ if ((u8)ax)
|
|
|
-+ return -1; /* No extended information */
|
|
|
-+
|
|
|
-+ if (bx != EDDMAGIC2)
|
|
|
-+ return -1;
|
|
|
-+
|
|
|
-+ ei->device = devno;
|
|
|
-+ ei->version = ax >> 8; /* EDD version number */
|
|
|
-+ ei->interface_support = cx; /* EDD functionality subsets */
|
|
|
-+
|
|
|
-+ /* Extended Get Device Parameters */
|
|
|
-+
|
|
|
-+ ei->params.length = sizeof(ei->params);
|
|
|
-+ ax = 0x4800;
|
|
|
-+ dx = devno;
|
|
|
-+ asm("pushfl; int $0x13; popfl"
|
|
|
-+ : "+a" (ax), "+d" (dx)
|
|
|
-+ : "S" (&ei->params)
|
|
|
-+ : "ebx", "ecx", "edi");
|
|
|
-+
|
|
|
-+ /* Get legacy CHS parameters */
|
|
|
-+
|
|
|
-+ /* Ralf Brown recommends setting ES:DI to 0:0 */
|
|
|
-+ ax = 0x0800;
|
|
|
-+ dx = devno;
|
|
|
-+ di = 0;
|
|
|
-+ asm("pushw %%es; "
|
|
|
-+ "movw %%di,%%es; "
|
|
|
-+ "pushfl; stc; int $0x13; setc %%al; popfl; "
|
|
|
-+ "popw %%es"
|
|
|
-+ : "+a" (ax), "=b" (bx), "=c" (cx), "+d" (dx), "+D" (di)
|
|
|
-+ : : "esi");
|
|
|
-+
|
|
|
-+ if ((u8)ax == 0) {
|
|
|
-+ ei->legacy_max_cylinder = (cx >> 8) + ((cx & 0xc0) << 2);
|
|
|
-+ ei->legacy_max_head = dx >> 8;
|
|
|
-+ ei->legacy_sectors_per_track = cx & 0x3f;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+void query_edd(void)
|
|
|
-+{
|
|
|
-+ char eddarg[8];
|
|
|
-+ int do_mbr = 1;
|
|
|
-+ int do_edd = 1;
|
|
|
-+ int devno;
|
|
|
-+ struct edd_info ei, *edp;
|
|
|
-+
|
|
|
-+ if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) {
|
|
|
-+ if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip"))
|
|
|
-+ do_mbr = 0;
|
|
|
-+ else if (!strcmp(eddarg, "off"))
|
|
|
-+ do_edd = 0;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ edp = (struct edd_info *)boot_params.eddbuf;
|
|
|
-+
|
|
|
-+ if (!do_edd)
|
|
|
-+ return;
|
|
|
-+
|
|
|
-+ for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
|
|
|
-+ /*
|
|
|
-+ * Scan the BIOS-supported hard disks and query EDD
|
|
|
-+ * information...
|
|
|
-+ */
|
|
|
-+ get_edd_info(devno, &ei);
|
|
|
-+
|
|
|
-+ if (boot_params.eddbuf_entries < EDDMAXNR) {
|
|
|
-+ memcpy(edp, &ei, sizeof ei);
|
|
|
-+ edp++;
|
|
|
-+ boot_params.eddbuf_entries++;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ if (do_mbr) {
|
|
|
-+ u32 mbr_sig;
|
|
|
-+ mbr_sig = read_mbr_sig(devno, &ei);
|
|
|
-+ boot_params.edd_mbr_sig_buffer[devno-0x80] = mbr_sig;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+#endif
|
|
|
-diff -puN /dev/null arch/i386/boot/header.S
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/header.S
|
|
|
-@@ -0,0 +1,283 @@
|
|
|
-+/*
|
|
|
-+ * header.S
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ *
|
|
|
-+ * Based on bootsect.S and setup.S
|
|
|
-+ * modified by more people than can be counted
|
|
|
-+ *
|
|
|
-+ * Rewritten as a common file by H. Peter Anvin (Apr 2007)
|
|
|
-+ *
|
|
|
-+ * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment
|
|
|
-+ * addresses must be multiplied by 16 to obtain their respective linear
|
|
|
-+ * addresses. To avoid confusion, linear addresses are written using leading
|
|
|
-+ * hex while segment addresses are written as segment:offset.
|
|
|
-+ *
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include <asm/segment.h>
|
|
|
-+#include <linux/utsrelease.h>
|
|
|
-+#include <asm/boot.h>
|
|
|
-+#include <asm/e820.h>
|
|
|
-+#include <asm/page.h>
|
|
|
-+#include <asm/setup.h>
|
|
|
-+#include "boot.h"
|
|
|
-+
|
|
|
-+SETUPSECTS = 4 /* default nr of setup-sectors */
|
|
|
-+BOOTSEG = 0x07C0 /* original address of boot-sector */
|
|
|
-+SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */
|
|
|
-+SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */
|
|
|
-+ /* to be loaded */
|
|
|
-+ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */
|
|
|
-+SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */
|
|
|
-+
|
|
|
-+#ifndef SVGA_MODE
|
|
|
-+#define SVGA_MODE ASK_VGA
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef RAMDISK
|
|
|
-+#define RAMDISK 0
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef ROOT_RDONLY
|
|
|
-+#define ROOT_RDONLY 1
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+ .code16
|
|
|
-+ .section ".bstext", "ax"
|
|
|
-+
|
|
|
-+ .global bootsect_start
|
|
|
-+bootsect_start:
|
|
|
-+
|
|
|
-+ # Normalize the start address
|
|
|
-+ ljmp $BOOTSEG, $start2
|
|
|
-+
|
|
|
-+start2:
|
|
|
-+ movw %cs, %ax
|
|
|
-+ movw %ax, %ds
|
|
|
-+ movw %ax, %es
|
|
|
-+ movw %ax, %ss
|
|
|
-+ xorw %sp, %sp
|
|
|
-+ sti
|
|
|
-+ cld
|
|
|
-+
|
|
|
-+ movw $bugger_off_msg, %si
|
|
|
-+
|
|
|
-+msg_loop:
|
|
|
-+ lodsb
|
|
|
-+ andb %al, %al
|
|
|
-+ jz bs_die
|
|
|
-+ movb $0xe, %ah
|
|
|
-+ movw $7, %bx
|
|
|
-+ int $0x10
|
|
|
-+ jmp msg_loop
|
|
|
-+
|
|
|
-+bs_die:
|
|
|
-+ # Allow the user to press a key, then reboot
|
|
|
-+ xorw %ax, %ax
|
|
|
-+ int $0x16
|
|
|
-+ int $0x19
|
|
|
-+
|
|
|
-+ # int 0x19 should never return. In case it does anyway,
|
|
|
-+ # invoke the BIOS reset code...
|
|
|
-+ ljmp $0xf000,$0xfff0
|
|
|
-+
|
|
|
-+ .section ".bsdata", "a"
|
|
|
-+bugger_off_msg:
|
|
|
-+ .ascii "Direct booting from floppy is no longer supported.\r\n"
|
|
|
-+ .ascii "Please use a boot loader program instead.\r\n"
|
|
|
-+ .ascii "\n"
|
|
|
-+ .ascii "Remove disk and press any key to reboot . . .\r\n"
|
|
|
-+ .byte 0
|
|
|
-+
|
|
|
-+
|
|
|
-+ # Kernel attributes; used by setup. This is part 1 of the
|
|
|
-+ # header, from the old boot sector.
|
|
|
-+
|
|
|
-+ .section ".header", "a"
|
|
|
-+ .globl hdr
|
|
|
-+hdr:
|
|
|
-+setup_sects: .byte SETUPSECTS
|
|
|
-+root_flags: .word ROOT_RDONLY
|
|
|
-+syssize: .long SYSSIZE
|
|
|
-+ram_size: .word RAMDISK
|
|
|
-+vid_mode: .word SVGA_MODE
|
|
|
-+root_dev: .word ROOT_DEV
|
|
|
-+boot_flag: .word 0xAA55
|
|
|
-+
|
|
|
-+ # offset 512, entry point
|
|
|
-+
|
|
|
-+ .globl _start
|
|
|
-+_start:
|
|
|
-+ # Explicitly enter this as bytes, or the assembler
|
|
|
-+ # tries to generate a 3-byte jump here, which causes
|
|
|
-+ # everything else to push off to the wrong offset.
|
|
|
-+ .byte 0xeb # short (2-byte) jump
|
|
|
-+ .byte start_of_setup-1f
|
|
|
-+1:
|
|
|
-+
|
|
|
-+ # Part 2 of the header, from the old setup.S
|
|
|
-+
|
|
|
-+ .ascii "HdrS" # header signature
|
|
|
-+ .word 0x0206 # header version number (>= 0x0105)
|
|
|
-+ # or else old loadlin-1.5 will fail)
|
|
|
-+ .globl realmode_swtch
|
|
|
-+realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
|
|
|
-+start_sys_seg: .word SYSSEG
|
|
|
-+ .word kernel_version-512 # pointing to kernel version string
|
|
|
-+ # above section of header is compatible
|
|
|
-+ # with loadlin-1.5 (header v1.5). Don't
|
|
|
-+ # change it.
|
|
|
-+
|
|
|
-+type_of_loader: .byte 0 # = 0, old one (LILO, Loadlin,
|
|
|
-+ # Bootlin, SYSLX, bootsect...)
|
|
|
-+ # See Documentation/i386/boot.txt for
|
|
|
-+ # assigned ids
|
|
|
-+
|
|
|
-+# flags, unused bits must be zero (RFU) bit within loadflags
|
|
|
-+loadflags:
|
|
|
-+LOADED_HIGH = 1 # If set, the kernel is loaded high
|
|
|
-+CAN_USE_HEAP = 0x80 # If set, the loader also has set
|
|
|
-+ # heap_end_ptr to tell how much
|
|
|
-+ # space behind setup.S can be used for
|
|
|
-+ # heap purposes.
|
|
|
-+ # Only the loader knows what is free
|
|
|
-+#ifndef __BIG_KERNEL__
|
|
|
-+ .byte 0
|
|
|
-+#else
|
|
|
-+ .byte LOADED_HIGH
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+setup_move_size: .word 0x8000 # size to move, when setup is not
|
|
|
-+ # loaded at 0x90000. We will move setup
|
|
|
-+ # to 0x90000 then just before jumping
|
|
|
-+ # into the kernel. However, only the
|
|
|
-+ # loader knows how much data behind
|
|
|
-+ # us also needs to be loaded.
|
|
|
-+
|
|
|
-+code32_start: # here loaders can put a different
|
|
|
-+ # start address for 32-bit code.
|
|
|
-+#ifndef __BIG_KERNEL__
|
|
|
-+ .long 0x1000 # 0x1000 = default for zImage
|
|
|
-+#else
|
|
|
-+ .long 0x100000 # 0x100000 = default for big kernel
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+ramdisk_image: .long 0 # address of loaded ramdisk image
|
|
|
-+ # Here the loader puts the 32-bit
|
|
|
-+ # address where it loaded the image.
|
|
|
-+ # This only will be read by the kernel.
|
|
|
-+
|
|
|
-+ramdisk_size: .long 0 # its size in bytes
|
|
|
-+
|
|
|
-+bootsect_kludge:
|
|
|
-+ .long 0 # obsolete
|
|
|
-+
|
|
|
-+heap_end_ptr: .word _end+1024 # (Header version 0x0201 or later)
|
|
|
-+ # space from here (exclusive) down to
|
|
|
-+ # end of setup code can be used by setup
|
|
|
-+ # for local heap purposes.
|
|
|
-+
|
|
|
-+pad1: .word 0
|
|
|
-+cmd_line_ptr: .long 0 # (Header version 0x0202 or later)
|
|
|
-+ # If nonzero, a 32-bit pointer
|
|
|
-+ # to the kernel command line.
|
|
|
-+ # The command line should be
|
|
|
-+ # located between the start of
|
|
|
-+ # setup and the end of low
|
|
|
-+ # memory (0xa0000), or it may
|
|
|
-+ # get overwritten before it
|
|
|
-+ # gets read. If this field is
|
|
|
-+ # used, there is no longer
|
|
|
-+ # anything magical about the
|
|
|
-+ # 0x90000 segment; the setup
|
|
|
-+ # can be located anywhere in
|
|
|
-+ # low memory 0x10000 or higher.
|
|
|
-+
|
|
|
-+ramdisk_max: .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
|
|
|
-+ # (Header version 0x0203 or later)
|
|
|
-+ # The highest safe address for
|
|
|
-+ # the contents of an initrd
|
|
|
-+
|
|
|
-+kernel_alignment: .long CONFIG_PHYSICAL_ALIGN #physical addr alignment
|
|
|
-+ #required for protected mode
|
|
|
-+ #kernel
|
|
|
-+#ifdef CONFIG_RELOCATABLE
|
|
|
-+relocatable_kernel: .byte 1
|
|
|
-+#else
|
|
|
-+relocatable_kernel: .byte 0
|
|
|
-+#endif
|
|
|
-+pad2: .byte 0
|
|
|
-+pad3: .word 0
|
|
|
-+
|
|
|
-+cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
|
|
|
-+ #added with boot protocol
|
|
|
-+ #version 2.06
|
|
|
-+
|
|
|
-+# End of setup header #####################################################
|
|
|
-+
|
|
|
-+ .section ".inittext", "ax"
|
|
|
-+start_of_setup:
|
|
|
-+#ifdef SAFE_RESET_DISK_CONTROLLER
|
|
|
-+# Reset the disk controller.
|
|
|
-+ movw $0x0000, %ax # Reset disk controller
|
|
|
-+ movb $0x80, %dl # All disks
|
|
|
-+ int $0x13
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+# We will have entired with %cs = %ds+0x20, normalize %cs so
|
|
|
-+# it is on par with the other segments.
|
|
|
-+ pushw %ds
|
|
|
-+ pushw $setup2
|
|
|
-+ lretw
|
|
|
-+
|
|
|
-+setup2:
|
|
|
-+# Force %es = %ds
|
|
|
-+ movw %ds, %ax
|
|
|
-+ movw %ax, %es
|
|
|
-+ cld
|
|
|
-+
|
|
|
-+# Stack paranoia: align the stack and make sure it is good
|
|
|
-+# for both 16- and 32-bit references. In particular, if we
|
|
|
-+# were meant to have been using the full 16-bit segment, the
|
|
|
-+# caller might have set %sp to zero, which breaks %esp-based
|
|
|
-+# references.
|
|
|
-+ andw $~3, %sp # dword align (might as well...)
|
|
|
-+ jnz 1f
|
|
|
-+ movw $0xfffc, %sp # Make sure we're not zero
|
|
|
-+1: movzwl %sp, %esp # Clear upper half of %esp
|
|
|
-+ sti
|
|
|
-+
|
|
|
-+# Check signature at end of setup
|
|
|
-+ cmpl $0x5a5aaa55, setup_sig
|
|
|
-+ jne setup_bad
|
|
|
-+
|
|
|
-+# Zero the bss
|
|
|
-+ movw $__bss_start, %di
|
|
|
-+ movw $_end+3, %cx
|
|
|
-+ xorl %eax, %eax
|
|
|
-+ subw %di, %cx
|
|
|
-+ shrw $2, %cx
|
|
|
-+ rep; stosl
|
|
|
-+
|
|
|
-+# Jump to C code (should not return)
|
|
|
-+ calll main
|
|
|
-+
|
|
|
-+# Setup corrupt somehow...
|
|
|
-+setup_bad:
|
|
|
-+ movl $setup_corrupt, %eax
|
|
|
-+ calll puts
|
|
|
-+ # Fall through...
|
|
|
-+
|
|
|
-+ .globl die
|
|
|
-+ .type die, @function
|
|
|
-+die:
|
|
|
-+ hlt
|
|
|
-+ jmp die
|
|
|
-+
|
|
|
-+ .size die, .-due
|
|
|
-+
|
|
|
-+ .section ".initdata", "a"
|
|
|
-+setup_corrupt:
|
|
|
-+ .byte 7
|
|
|
-+ .string "No setup signature found..."
|
|
|
-diff -puN /dev/null arch/i386/boot/main.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/main.c
|
|
|
-@@ -0,0 +1,161 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/main.c
|
|
|
-+ *
|
|
|
-+ * Main module for the real-mode kernel code
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+
|
|
|
-+struct boot_params boot_params __attribute__((aligned(16)));
|
|
|
-+
|
|
|
-+char *HEAP = _end;
|
|
|
-+char *heap_end = _end; /* Default end of heap = no heap */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Copy the header into the boot parameter block. Since this
|
|
|
-+ * screws up the old-style command line protocol, adjust by
|
|
|
-+ * filling in the new-style command line pointer instead.
|
|
|
-+ */
|
|
|
-+#define OLD_CL_MAGIC 0xA33F
|
|
|
-+#define OLD_CL_ADDRESS 0x20
|
|
|
-+
|
|
|
-+static void copy_boot_params(void)
|
|
|
-+{
|
|
|
-+ struct old_cmdline {
|
|
|
-+ u16 cl_magic;
|
|
|
-+ u16 cl_offset;
|
|
|
-+ };
|
|
|
-+ const struct old_cmdline * const oldcmd =
|
|
|
-+ (const struct old_cmdline *)OLD_CL_ADDRESS;
|
|
|
-+
|
|
|
-+ BUILD_BUG_ON(sizeof boot_params != 4096);
|
|
|
-+ memcpy(&boot_params.hdr, &hdr, sizeof hdr);
|
|
|
-+
|
|
|
-+ if (!boot_params.hdr.cmd_line_ptr &&
|
|
|
-+ oldcmd->cl_magic == OLD_CL_MAGIC) {
|
|
|
-+ /* Old-style command line protocol. */
|
|
|
-+ u16 cmdline_seg;
|
|
|
-+
|
|
|
-+ /* Figure out if the command line falls in the region
|
|
|
-+ of memory that an old kernel would have copied up
|
|
|
-+ to 0x90000... */
|
|
|
-+ if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
|
|
|
-+ cmdline_seg = ds();
|
|
|
-+ else
|
|
|
-+ cmdline_seg = 0x9000;
|
|
|
-+
|
|
|
-+ boot_params.hdr.cmd_line_ptr =
|
|
|
-+ (cmdline_seg << 4) + oldcmd->cl_offset;
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Set the keyboard repeat rate to maximum. Unclear why this
|
|
|
-+ * is done here; this might be possible to kill off as stale code.
|
|
|
-+ */
|
|
|
-+static void keyboard_set_repeat(void)
|
|
|
-+{
|
|
|
-+ u16 ax = 0x0305;
|
|
|
-+ u16 bx = 0;
|
|
|
-+ asm volatile("int $0x16"
|
|
|
-+ : "+a" (ax), "+b" (bx)
|
|
|
-+ : : "ecx", "edx", "esi", "edi");
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Get Intel SpeedStep IST information.
|
|
|
-+ */
|
|
|
-+static void query_speedstep_ist(void)
|
|
|
-+{
|
|
|
-+ asm("int $0x15"
|
|
|
-+ : "=a" (boot_params.speedstep_info[0]),
|
|
|
-+ "=b" (boot_params.speedstep_info[1]),
|
|
|
-+ "=c" (boot_params.speedstep_info[2]),
|
|
|
-+ "=d" (boot_params.speedstep_info[3])
|
|
|
-+ : "a" (0x0000e980), /* IST Support */
|
|
|
-+ "d" (0x47534943)); /* Request value */
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Tell the BIOS what CPU mode we intend to run in.
|
|
|
-+ */
|
|
|
-+static void set_bios_mode(void)
|
|
|
-+{
|
|
|
-+#ifdef CONFIG_X86_64
|
|
|
-+ u32 eax, ebx;
|
|
|
-+
|
|
|
-+ eax = 0xec00;
|
|
|
-+ ebx = 2;
|
|
|
-+ asm volatile("int $0x15"
|
|
|
-+ : "+a" (eax), "+b" (ebx)
|
|
|
-+ : : "ecx", "edx", "esi", "edi");
|
|
|
-+#endif
|
|
|
-+}
|
|
|
-+
|
|
|
-+void main(void)
|
|
|
-+{
|
|
|
-+ /* First, copy the boot header into the "zeropage" */
|
|
|
-+ copy_boot_params();
|
|
|
-+
|
|
|
-+ /* End of heap check */
|
|
|
-+ if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
|
|
|
-+ heap_end = (char *)(boot_params.hdr.heap_end_ptr
|
|
|
-+ +0x200-STACK_SIZE);
|
|
|
-+ } else {
|
|
|
-+ /* Boot protocol 2.00 only, no heap available */
|
|
|
-+ puts("WARNING: Ancient bootloader, some functionality "
|
|
|
-+ "may be limited!\n");
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Make sure we have all the proper CPU support */
|
|
|
-+ if (validate_cpu()) {
|
|
|
-+ puts("Unable to boot - please use a kernel appropriate "
|
|
|
-+ "for your CPU.\n");
|
|
|
-+ die();
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Tell the BIOS what CPU mode we intend to run in. */
|
|
|
-+ set_bios_mode();
|
|
|
-+
|
|
|
-+ /* Detect memory layout */
|
|
|
-+ detect_memory();
|
|
|
-+
|
|
|
-+ /* Set keyboard repeat rate (why?) */
|
|
|
-+ keyboard_set_repeat();
|
|
|
-+
|
|
|
-+ /* Set the video mode */
|
|
|
-+ set_video();
|
|
|
-+
|
|
|
-+ /* Query MCA information */
|
|
|
-+ query_mca();
|
|
|
-+
|
|
|
-+ /* Voyager */
|
|
|
-+#ifdef CONFIG_X86_VOYAGER
|
|
|
-+ query_voyager();
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+ /* Query SpeedStep IST information */
|
|
|
-+ query_speedstep_ist();
|
|
|
-+
|
|
|
-+ /* Query APM information */
|
|
|
-+#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
|
|
|
-+ query_apm_bios();
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+ /* Query EDD information */
|
|
|
-+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
|
|
|
-+ query_edd();
|
|
|
-+#endif
|
|
|
-+ /* Do the last things and invoke protected mode */
|
|
|
-+ go_to_protected_mode();
|
|
|
-+}
|
|
|
-diff -puN /dev/null arch/i386/boot/mca.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/mca.c
|
|
|
-@@ -0,0 +1,43 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/mca.c
|
|
|
-+ *
|
|
|
-+ * Get the MCA system description table
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+
|
|
|
-+int query_mca(void)
|
|
|
-+{
|
|
|
-+ u8 err;
|
|
|
-+ u16 es, bx, len;
|
|
|
-+
|
|
|
-+ asm("pushw %%es ; "
|
|
|
-+ "int $0x15 ; "
|
|
|
-+ "setc %0 ; "
|
|
|
-+ "movw %%es, %1 ; "
|
|
|
-+ "popw %%es"
|
|
|
-+ : "=acdSDm" (err), "=acdSDm" (es), "=b" (bx)
|
|
|
-+ : "a" (0xc000));
|
|
|
-+
|
|
|
-+ if (err)
|
|
|
-+ return -1; /* No MCA present */
|
|
|
-+
|
|
|
-+ set_fs(es);
|
|
|
-+ len = rdfs16(bx);
|
|
|
-+
|
|
|
-+ if (len > sizeof(boot_params.sys_desc_table))
|
|
|
-+ len = sizeof(boot_params.sys_desc_table);
|
|
|
-+
|
|
|
-+ copy_from_fs(&boot_params.sys_desc_table, bx, len);
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-diff -puN /dev/null arch/i386/boot/memory.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/memory.c
|
|
|
-@@ -0,0 +1,99 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/memory.c
|
|
|
-+ *
|
|
|
-+ * Memory detection code
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+
|
|
|
-+#define SMAP 0x534d4150 /* ASCII "SMAP" */
|
|
|
-+
|
|
|
-+static int detect_memory_e820(void)
|
|
|
-+{
|
|
|
-+ u32 next = 0;
|
|
|
-+ u32 size, id;
|
|
|
-+ u8 err;
|
|
|
-+ struct e820entry *desc = boot_params.e820_map;
|
|
|
-+
|
|
|
-+ do {
|
|
|
-+ size = sizeof(struct e820entry);
|
|
|
-+ id = SMAP;
|
|
|
-+ asm("int $0x15; setc %0"
|
|
|
-+ : "=am" (err), "+b" (next), "+d" (id), "+c" (size),
|
|
|
-+ "=m" (*desc)
|
|
|
-+ : "D" (desc), "a" (0xe820));
|
|
|
-+
|
|
|
-+ if (err || id != SMAP)
|
|
|
-+ break;
|
|
|
-+
|
|
|
-+ boot_params.e820_entries++;
|
|
|
-+ desc++;
|
|
|
-+ } while (next && boot_params.e820_entries < E820MAX);
|
|
|
-+
|
|
|
-+ return boot_params.e820_entries;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int detect_memory_e801(void)
|
|
|
-+{
|
|
|
-+ u16 ax, bx, cx, dx;
|
|
|
-+ u8 err;
|
|
|
-+
|
|
|
-+ bx = cx = dx = 0;
|
|
|
-+ ax = 0xe801;
|
|
|
-+ asm("stc; int $0x15; setc %0"
|
|
|
-+ : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
|
|
|
-+
|
|
|
-+ if (err)
|
|
|
-+ return -1;
|
|
|
-+
|
|
|
-+ /* Do we really need to do this? */
|
|
|
-+ if (cx || dx) {
|
|
|
-+ ax = cx;
|
|
|
-+ bx = dx;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ if (ax > 15*1024)
|
|
|
-+ return -1; /* Bogus! */
|
|
|
-+
|
|
|
-+ /* This ignores memory above 16MB if we have a memory hole
|
|
|
-+ there. If someone actually finds a machine with a memory
|
|
|
-+ hole at 16MB and no support for 0E820h they should probably
|
|
|
-+ generate a fake e820 map. */
|
|
|
-+ boot_params.alt_mem_k = (ax == 15*1024) ? (dx << 6)+ax : ax;
|
|
|
-+
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int detect_memory_88(void)
|
|
|
-+{
|
|
|
-+ u16 ax;
|
|
|
-+ u8 err;
|
|
|
-+
|
|
|
-+ ax = 0x8800;
|
|
|
-+ asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
|
|
|
-+
|
|
|
-+ boot_params.screen_info.ext_mem_k = ax;
|
|
|
-+
|
|
|
-+ return -err;
|
|
|
-+}
|
|
|
-+
|
|
|
-+int detect_memory(void)
|
|
|
-+{
|
|
|
-+ if (detect_memory_e820() > 0)
|
|
|
-+ return 0;
|
|
|
-+
|
|
|
-+ if (!detect_memory_e801())
|
|
|
-+ return 0;
|
|
|
-+
|
|
|
-+ return detect_memory_88();
|
|
|
-+}
|
|
|
-diff -puN /dev/null arch/i386/boot/pm.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/pm.c
|
|
|
-@@ -0,0 +1,170 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/pm.c
|
|
|
-+ *
|
|
|
-+ * Prepare the machine for transition to protected mode.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+#include <asm/segment.h>
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Invoke the realmode switch hook if present; otherwise
|
|
|
-+ * disable all interrupts.
|
|
|
-+ */
|
|
|
-+static void realmode_switch_hook(void)
|
|
|
-+{
|
|
|
-+ if (boot_params.hdr.realmode_swtch) {
|
|
|
-+ asm volatile("lcallw *%0"
|
|
|
-+ : : "m" (boot_params.hdr.realmode_swtch)
|
|
|
-+ : "eax", "ebx", "ecx", "edx");
|
|
|
-+ } else {
|
|
|
-+ asm volatile("cli");
|
|
|
-+ outb(0x80, 0x70); /* Disable NMI */
|
|
|
-+ io_delay();
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * A zImage kernel is loaded at 0x10000 but wants to run at 0x1000.
|
|
|
-+ * A bzImage kernel is loaded and runs at 0x100000.
|
|
|
-+ */
|
|
|
-+static void move_kernel_around(void)
|
|
|
-+{
|
|
|
-+ /* Note: rely on the compile-time option here rather than
|
|
|
-+ the LOADED_HIGH flag. The Qemu kernel loader unconditionally
|
|
|
-+ sets the loadflags to zero. */
|
|
|
-+#ifndef __BIG_KERNEL__
|
|
|
-+ u16 dst_seg, src_seg;
|
|
|
-+ u32 syssize;
|
|
|
-+
|
|
|
-+ dst_seg = 0x1000 >> 4;
|
|
|
-+ src_seg = 0x10000 >> 4;
|
|
|
-+ syssize = boot_params.hdr.syssize; /* Size in 16-byte paragraps */
|
|
|
-+
|
|
|
-+ while (syssize) {
|
|
|
-+ int paras = (syssize >= 0x1000) ? 0x1000 : syssize;
|
|
|
-+ int dwords = paras << 2;
|
|
|
-+
|
|
|
-+ asm volatile("pushw %%es ; "
|
|
|
-+ "pushw %%ds ; "
|
|
|
-+ "movw %1,%%es ; "
|
|
|
-+ "movw %2,%%ds ; "
|
|
|
-+ "xorw %%di,%%di ; "
|
|
|
-+ "xorw %%si,%%si ; "
|
|
|
-+ "rep;movsl ; "
|
|
|
-+ "popw %%ds ; "
|
|
|
-+ "popw %%es"
|
|
|
-+ : "+c" (dwords)
|
|
|
-+ : "rm" (dst_seg), "rm" (src_seg)
|
|
|
-+ : "esi", "edi");
|
|
|
-+
|
|
|
-+ syssize -= paras;
|
|
|
-+ dst_seg += paras;
|
|
|
-+ src_seg += paras;
|
|
|
-+ }
|
|
|
-+#endif
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Disable all interrupts at the legacy PIC.
|
|
|
-+ */
|
|
|
-+static void mask_all_interrupts(void)
|
|
|
-+{
|
|
|
-+ outb(0xff, 0xa1); /* Mask all interrupts on the seconday PIC */
|
|
|
-+ io_delay();
|
|
|
-+ outb(0xfb, 0x21); /* Mask all but cascade on the primary PIC */
|
|
|
-+ io_delay();
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Reset IGNNE# if asserted in the FPU.
|
|
|
-+ */
|
|
|
-+static void reset_coprocessor(void)
|
|
|
-+{
|
|
|
-+ outb(0, 0xf0);
|
|
|
-+ io_delay();
|
|
|
-+ outb(0, 0xf1);
|
|
|
-+ io_delay();
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Set up the GDT
|
|
|
-+ */
|
|
|
-+#define GDT_ENTRY(flags,base,limit) \
|
|
|
-+ (((u64)(base & 0xff000000) << 32) | \
|
|
|
-+ ((u64)flags << 40) | \
|
|
|
-+ ((u64)(limit & 0x00ff0000) << 32) | \
|
|
|
-+ ((u64)(base & 0x00ffff00) << 16) | \
|
|
|
-+ ((u64)(limit & 0x0000ffff)))
|
|
|
-+
|
|
|
-+struct gdt_ptr {
|
|
|
-+ u16 len;
|
|
|
-+ u32 ptr;
|
|
|
-+} __attribute__((packed));
|
|
|
-+
|
|
|
-+static void setup_gdt(void)
|
|
|
-+{
|
|
|
-+ /* There are machines which are known to not boot with the GDT
|
|
|
-+ being 8-byte unaligned. Intel recommends 16 byte alignment. */
|
|
|
-+ static const u64 boot_gdt[] __attribute__((aligned(16))) = {
|
|
|
-+ /* CS: code, read/execute, 4 GB, base 0 */
|
|
|
-+ [GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
|
|
|
-+ /* DS: data, read/write, 4 GB, base 0 */
|
|
|
-+ [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
|
|
|
-+ };
|
|
|
-+ struct gdt_ptr gdt;
|
|
|
-+
|
|
|
-+ gdt.len = sizeof(boot_gdt)-1;
|
|
|
-+ gdt.ptr = (u32)&boot_gdt + (ds() << 4);
|
|
|
-+
|
|
|
-+ asm volatile("lgdtl %0" : : "m" (gdt));
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Set up the IDT
|
|
|
-+ */
|
|
|
-+static void setup_idt(void)
|
|
|
-+{
|
|
|
-+ static const struct gdt_ptr null_idt = {0, 0};
|
|
|
-+ asm volatile("lidtl %0" : : "m" (null_idt));
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Actual invocation sequence
|
|
|
-+ */
|
|
|
-+void go_to_protected_mode(void)
|
|
|
-+{
|
|
|
-+ /* Hook before leaving real mode, also disables interrupts */
|
|
|
-+ realmode_switch_hook();
|
|
|
-+
|
|
|
-+ /* Move the kernel/setup to their final resting places */
|
|
|
-+ move_kernel_around();
|
|
|
-+
|
|
|
-+ /* Enable the A20 gate */
|
|
|
-+ if (enable_a20()) {
|
|
|
-+ puts("A20 gate not responding, unable to boot...\n");
|
|
|
-+ die();
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Reset coprocessor (IGNNE#) */
|
|
|
-+ reset_coprocessor();
|
|
|
-+
|
|
|
-+ /* Mask all interrupts in the PIC */
|
|
|
-+ mask_all_interrupts();
|
|
|
-+
|
|
|
-+ /* Actual transition to protected mode... */
|
|
|
-+ setup_idt();
|
|
|
-+ setup_gdt();
|
|
|
-+ protected_mode_jump(boot_params.hdr.code32_start,
|
|
|
-+ (u32)&boot_params + (ds() << 4));
|
|
|
-+}
|
|
|
-diff -puN /dev/null arch/i386/boot/pmjump.S
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/pmjump.S
|
|
|
-@@ -0,0 +1,54 @@
|
|
|
-+/* ----------------------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/pmjump.S
|
|
|
-+ *
|
|
|
-+ * The actual transition into protected mode
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include <asm/boot.h>
|
|
|
-+#include <asm/segment.h>
|
|
|
-+
|
|
|
-+ .text
|
|
|
-+
|
|
|
-+ .globl protected_mode_jump
|
|
|
-+ .type protected_mode_jump, @function
|
|
|
-+
|
|
|
-+ .code16
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * void protected_mode_jump(u32 entrypoint, u32 bootparams);
|
|
|
-+ */
|
|
|
-+protected_mode_jump:
|
|
|
-+ xorl %ebx, %ebx # Flag to indicate this is a boot
|
|
|
-+ movl %edx, %esi # Pointer to boot_params table
|
|
|
-+ movl %eax, 2f # Patch ljmpl instruction
|
|
|
-+ jmp 1f # Short jump to flush instruction q.
|
|
|
-+
|
|
|
-+1:
|
|
|
-+ movw $__BOOT_DS, %cx
|
|
|
-+
|
|
|
-+ movl %cr0, %edx
|
|
|
-+ orb $1, %dl # Protected mode (PE) bit
|
|
|
-+ movl %edx, %cr0
|
|
|
-+
|
|
|
-+ movw %cx, %ds
|
|
|
-+ movw %cx, %es
|
|
|
-+ movw %cx, %fs
|
|
|
-+ movw %cx, %gs
|
|
|
-+ movw %cx, %ss
|
|
|
-+
|
|
|
-+ # Jump to the 32-bit entrypoint
|
|
|
-+ .byte 0x66, 0xea # ljmpl opcode
|
|
|
-+2: .long 0 # offset
|
|
|
-+ .word __BOOT_CS # segment
|
|
|
-+
|
|
|
-+ .size protected_mode_jump, .-protected_mode_jump
|
|
|
-diff -puN /dev/null arch/i386/boot/printf.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/printf.c
|
|
|
-@@ -0,0 +1,331 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/printf.c
|
|
|
-+ *
|
|
|
-+ * Oh, it's a waste of space, but oh-so-yummy for debugging. This
|
|
|
-+ * version of printf() does not include 64-bit support. "Live with
|
|
|
-+ * it."
|
|
|
-+ *
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+
|
|
|
-+static inline int isdigit(int ch)
|
|
|
-+{
|
|
|
-+ return (ch >= '0') && (ch <= '9');
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int skip_atoi(const char **s)
|
|
|
-+{
|
|
|
-+ int i = 0;
|
|
|
-+
|
|
|
-+ while (isdigit(**s))
|
|
|
-+ i = i * 10 + *((*s)++) - '0';
|
|
|
-+ return i;
|
|
|
-+}
|
|
|
-+
|
|
|
-+unsigned int atou(const char *s)
|
|
|
-+{
|
|
|
-+ unsigned int i = 0;
|
|
|
-+ while (isdigit(*s))
|
|
|
-+ i = i * 10 + (*s++ - '0');
|
|
|
-+ return i;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int strnlen(const char *s, int maxlen)
|
|
|
-+{
|
|
|
-+ const char *es = s;
|
|
|
-+ while (*es && maxlen) {
|
|
|
-+ es++;
|
|
|
-+ maxlen--;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ return (es - s);
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define ZEROPAD 1 /* pad with zero */
|
|
|
-+#define SIGN 2 /* unsigned/signed long */
|
|
|
-+#define PLUS 4 /* show plus */
|
|
|
-+#define SPACE 8 /* space if plus */
|
|
|
-+#define LEFT 16 /* left justified */
|
|
|
-+#define SPECIAL 32 /* 0x */
|
|
|
-+#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
|
|
|
-+
|
|
|
-+#define do_div(n,base) ({ \
|
|
|
-+int __res; \
|
|
|
-+__res = ((unsigned long) n) % (unsigned) base; \
|
|
|
-+n = ((unsigned long) n) / (unsigned) base; \
|
|
|
-+__res; })
|
|
|
-+
|
|
|
-+static char *number(char *str, long num, int base, int size, int precision,
|
|
|
-+ int type)
|
|
|
-+{
|
|
|
-+ char c, sign, tmp[66];
|
|
|
-+ const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
|
-+ int i;
|
|
|
-+
|
|
|
-+ if (type & LARGE)
|
|
|
-+ digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
|
-+ if (type & LEFT)
|
|
|
-+ type &= ~ZEROPAD;
|
|
|
-+ if (base < 2 || base > 36)
|
|
|
-+ return 0;
|
|
|
-+ c = (type & ZEROPAD) ? '0' : ' ';
|
|
|
-+ sign = 0;
|
|
|
-+ if (type & SIGN) {
|
|
|
-+ if (num < 0) {
|
|
|
-+ sign = '-';
|
|
|
-+ num = -num;
|
|
|
-+ size--;
|
|
|
-+ } else if (type & PLUS) {
|
|
|
-+ sign = '+';
|
|
|
-+ size--;
|
|
|
-+ } else if (type & SPACE) {
|
|
|
-+ sign = ' ';
|
|
|
-+ size--;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ if (type & SPECIAL) {
|
|
|
-+ if (base == 16)
|
|
|
-+ size -= 2;
|
|
|
-+ else if (base == 8)
|
|
|
-+ size--;
|
|
|
-+ }
|
|
|
-+ i = 0;
|
|
|
-+ if (num == 0)
|
|
|
-+ tmp[i++] = '0';
|
|
|
-+ else
|
|
|
-+ while (num != 0)
|
|
|
-+ tmp[i++] = digits[do_div(num, base)];
|
|
|
-+ if (i > precision)
|
|
|
-+ precision = i;
|
|
|
-+ size -= precision;
|
|
|
-+ if (!(type & (ZEROPAD + LEFT)))
|
|
|
-+ while (size-- > 0)
|
|
|
-+ *str++ = ' ';
|
|
|
-+ if (sign)
|
|
|
-+ *str++ = sign;
|
|
|
-+ if (type & SPECIAL) {
|
|
|
-+ if (base == 8)
|
|
|
-+ *str++ = '0';
|
|
|
-+ else if (base == 16) {
|
|
|
-+ *str++ = '0';
|
|
|
-+ *str++ = digits[33];
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ if (!(type & LEFT))
|
|
|
-+ while (size-- > 0)
|
|
|
-+ *str++ = c;
|
|
|
-+ while (i < precision--)
|
|
|
-+ *str++ = '0';
|
|
|
-+ while (i-- > 0)
|
|
|
-+ *str++ = tmp[i];
|
|
|
-+ while (size-- > 0)
|
|
|
-+ *str++ = ' ';
|
|
|
-+ return str;
|
|
|
-+}
|
|
|
-+
|
|
|
-+int vsprintf(char *buf, const char *fmt, va_list args)
|
|
|
-+{
|
|
|
-+ int len;
|
|
|
-+ unsigned long num;
|
|
|
-+ int i, base;
|
|
|
-+ char *str;
|
|
|
-+ const char *s;
|
|
|
-+
|
|
|
-+ int flags; /* flags to number() */
|
|
|
-+
|
|
|
-+ int field_width; /* width of output field */
|
|
|
-+ int precision; /* min. # of digits for integers; max
|
|
|
-+ number of chars for from string */
|
|
|
-+ int qualifier; /* 'h', 'l', or 'L' for integer fields */
|
|
|
-+
|
|
|
-+ for (str = buf; *fmt; ++fmt) {
|
|
|
-+ if (*fmt != '%') {
|
|
|
-+ *str++ = *fmt;
|
|
|
-+ continue;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* process flags */
|
|
|
-+ flags = 0;
|
|
|
-+ repeat:
|
|
|
-+ ++fmt; /* this also skips first '%' */
|
|
|
-+ switch (*fmt) {
|
|
|
-+ case '-':
|
|
|
-+ flags |= LEFT;
|
|
|
-+ goto repeat;
|
|
|
-+ case '+':
|
|
|
-+ flags |= PLUS;
|
|
|
-+ goto repeat;
|
|
|
-+ case ' ':
|
|
|
-+ flags |= SPACE;
|
|
|
-+ goto repeat;
|
|
|
-+ case '#':
|
|
|
-+ flags |= SPECIAL;
|
|
|
-+ goto repeat;
|
|
|
-+ case '0':
|
|
|
-+ flags |= ZEROPAD;
|
|
|
-+ goto repeat;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* get field width */
|
|
|
-+ field_width = -1;
|
|
|
-+ if (isdigit(*fmt))
|
|
|
-+ field_width = skip_atoi(&fmt);
|
|
|
-+ else if (*fmt == '*') {
|
|
|
-+ ++fmt;
|
|
|
-+ /* it's the next argument */
|
|
|
-+ field_width = va_arg(args, int);
|
|
|
-+ if (field_width < 0) {
|
|
|
-+ field_width = -field_width;
|
|
|
-+ flags |= LEFT;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* get the precision */
|
|
|
-+ precision = -1;
|
|
|
-+ if (*fmt == '.') {
|
|
|
-+ ++fmt;
|
|
|
-+ if (isdigit(*fmt))
|
|
|
-+ precision = skip_atoi(&fmt);
|
|
|
-+ else if (*fmt == '*') {
|
|
|
-+ ++fmt;
|
|
|
-+ /* it's the next argument */
|
|
|
-+ precision = va_arg(args, int);
|
|
|
-+ }
|
|
|
-+ if (precision < 0)
|
|
|
-+ precision = 0;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* get the conversion qualifier */
|
|
|
-+ qualifier = -1;
|
|
|
-+ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
|
|
|
-+ qualifier = *fmt;
|
|
|
-+ ++fmt;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* default base */
|
|
|
-+ base = 10;
|
|
|
-+
|
|
|
-+ switch (*fmt) {
|
|
|
-+ case 'c':
|
|
|
-+ if (!(flags & LEFT))
|
|
|
-+ while (--field_width > 0)
|
|
|
-+ *str++ = ' ';
|
|
|
-+ *str++ = (unsigned char)va_arg(args, int);
|
|
|
-+ while (--field_width > 0)
|
|
|
-+ *str++ = ' ';
|
|
|
-+ continue;
|
|
|
-+
|
|
|
-+ case 's':
|
|
|
-+ s = va_arg(args, char *);
|
|
|
-+ len = strnlen(s, precision);
|
|
|
-+
|
|
|
-+ if (!(flags & LEFT))
|
|
|
-+ while (len < field_width--)
|
|
|
-+ *str++ = ' ';
|
|
|
-+ for (i = 0; i < len; ++i)
|
|
|
-+ *str++ = *s++;
|
|
|
-+ while (len < field_width--)
|
|
|
-+ *str++ = ' ';
|
|
|
-+ continue;
|
|
|
-+
|
|
|
-+ case 'p':
|
|
|
-+ if (field_width == -1) {
|
|
|
-+ field_width = 2 * sizeof(void *);
|
|
|
-+ flags |= ZEROPAD;
|
|
|
-+ }
|
|
|
-+ str = number(str,
|
|
|
-+ (unsigned long)va_arg(args, void *), 16,
|
|
|
-+ field_width, precision, flags);
|
|
|
-+ continue;
|
|
|
-+
|
|
|
-+ case 'n':
|
|
|
-+ if (qualifier == 'l') {
|
|
|
-+ long *ip = va_arg(args, long *);
|
|
|
-+ *ip = (str - buf);
|
|
|
-+ } else {
|
|
|
-+ int *ip = va_arg(args, int *);
|
|
|
-+ *ip = (str - buf);
|
|
|
-+ }
|
|
|
-+ continue;
|
|
|
-+
|
|
|
-+ case '%':
|
|
|
-+ *str++ = '%';
|
|
|
-+ continue;
|
|
|
-+
|
|
|
-+ /* integer number formats - set up the flags and "break" */
|
|
|
-+ case 'o':
|
|
|
-+ base = 8;
|
|
|
-+ break;
|
|
|
-+
|
|
|
-+ case 'X':
|
|
|
-+ flags |= LARGE;
|
|
|
-+ case 'x':
|
|
|
-+ base = 16;
|
|
|
-+ break;
|
|
|
-+
|
|
|
-+ case 'd':
|
|
|
-+ case 'i':
|
|
|
-+ flags |= SIGN;
|
|
|
-+ case 'u':
|
|
|
-+ break;
|
|
|
-+
|
|
|
-+ default:
|
|
|
-+ *str++ = '%';
|
|
|
-+ if (*fmt)
|
|
|
-+ *str++ = *fmt;
|
|
|
-+ else
|
|
|
-+ --fmt;
|
|
|
-+ continue;
|
|
|
-+ }
|
|
|
-+ if (qualifier == 'l')
|
|
|
-+ num = va_arg(args, unsigned long);
|
|
|
-+ else if (qualifier == 'h') {
|
|
|
-+ num = (unsigned short)va_arg(args, int);
|
|
|
-+ if (flags & SIGN)
|
|
|
-+ num = (short)num;
|
|
|
-+ } else if (flags & SIGN)
|
|
|
-+ num = va_arg(args, int);
|
|
|
-+ else
|
|
|
-+ num = va_arg(args, unsigned int);
|
|
|
-+ str = number(str, num, base, field_width, precision, flags);
|
|
|
-+ }
|
|
|
-+ *str = '\0';
|
|
|
-+ return str - buf;
|
|
|
-+}
|
|
|
-+
|
|
|
-+int sprintf(char *buf, const char *fmt, ...)
|
|
|
-+{
|
|
|
-+ va_list args;
|
|
|
-+ int i;
|
|
|
-+
|
|
|
-+ va_start(args, fmt);
|
|
|
-+ i = vsprintf(buf, fmt, args);
|
|
|
-+ va_end(args);
|
|
|
-+ return i;
|
|
|
-+}
|
|
|
-+
|
|
|
-+int printf(const char *fmt, ...)
|
|
|
-+{
|
|
|
-+ char printf_buf[1024];
|
|
|
-+ va_list args;
|
|
|
-+ int printed;
|
|
|
-+
|
|
|
-+ va_start(args, fmt);
|
|
|
-+ printed = vsprintf(printf_buf, fmt, args);
|
|
|
-+ va_end(args);
|
|
|
-+
|
|
|
-+ puts(printf_buf);
|
|
|
-+
|
|
|
-+ return printed;
|
|
|
-+}
|
|
|
-diff -puN arch/i386/boot/setup.S~git-newsetup /dev/null
|
|
|
---- a/arch/i386/boot/setup.S
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,1075 +0,0 @@
|
|
|
--/*
|
|
|
-- * setup.S Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-- *
|
|
|
-- * setup.s is responsible for getting the system data from the BIOS,
|
|
|
-- * and putting them into the appropriate places in system memory.
|
|
|
-- * both setup.s and system has been loaded by the bootblock.
|
|
|
-- *
|
|
|
-- * This code asks the bios for memory/disk/other parameters, and
|
|
|
-- * puts them in a "safe" place: 0x90000-0x901FF, ie where the
|
|
|
-- * boot-block used to be. It is then up to the protected mode
|
|
|
-- * system to read them from there before the area is overwritten
|
|
|
-- * for buffer-blocks.
|
|
|
-- *
|
|
|
-- * Move PS/2 aux init code to psaux.c
|
|
|
-- * ([email protected]) 03Oct92
|
|
|
-- *
|
|
|
-- * some changes and additional features by Christoph Niemann,
|
|
|
-- * March 1993/June 1994 ([email protected])
|
|
|
-- *
|
|
|
-- * add APM BIOS checking by Stephen Rothwell, May 1994
|
|
|
-- * ([email protected])
|
|
|
-- *
|
|
|
-- * High load stuff, initrd support and position independency
|
|
|
-- * by Hans Lermen & Werner Almesberger, February 1996
|
|
|
-- * <[email protected]>, <[email protected]>
|
|
|
-- *
|
|
|
-- * Video handling moved to video.S by Martin Mares, March 1996
|
|
|
-- * <[email protected]>
|
|
|
-- *
|
|
|
-- * Extended memory detection scheme retwiddled by [email protected] (david
|
|
|
-- * parsons) to avoid loadlin confusion, July 1997
|
|
|
-- *
|
|
|
-- * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
|
|
|
-- * <[email protected]>
|
|
|
-- *
|
|
|
-- * Fix to work around buggy BIOSes which don't use carry bit correctly
|
|
|
-- * and/or report extended memory in CX/DX for e801h memory size detection
|
|
|
-- * call. As a result the kernel got wrong figures. The int15/e801h docs
|
|
|
-- * from Ralf Brown interrupt list seem to indicate AX/BX should be used
|
|
|
-- * anyway. So to avoid breaking many machines (presumably there was a reason
|
|
|
-- * to orginally use CX/DX instead of AX/BX), we do a kludge to see
|
|
|
-- * if CX/DX have been changed in the e801 call and if so use AX/BX .
|
|
|
-- * Michael Miller, April 2001 <[email protected]>
|
|
|
-- *
|
|
|
-- * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes
|
|
|
-- * by Robert Schwebel, December 2001 <[email protected]>
|
|
|
-- */
|
|
|
--
|
|
|
--#include <asm/segment.h>
|
|
|
--#include <linux/utsrelease.h>
|
|
|
--#include <linux/compile.h>
|
|
|
--#include <asm/boot.h>
|
|
|
--#include <asm/e820.h>
|
|
|
--#include <asm/page.h>
|
|
|
--#include <asm/setup.h>
|
|
|
--
|
|
|
--/* Signature words to ensure LILO loaded us right */
|
|
|
--#define SIG1 0xAA55
|
|
|
--#define SIG2 0x5A5A
|
|
|
--
|
|
|
--INITSEG = DEF_INITSEG # 0x9000, we move boot here, out of the way
|
|
|
--SYSSEG = DEF_SYSSEG # 0x1000, system loaded at 0x10000 (65536).
|
|
|
--SETUPSEG = DEF_SETUPSEG # 0x9020, this is the current segment
|
|
|
-- # ... and the former contents of CS
|
|
|
--
|
|
|
--DELTA_INITSEG = SETUPSEG - INITSEG # 0x0020
|
|
|
--
|
|
|
--.code16
|
|
|
--.globl begtext, begdata, begbss, endtext, enddata, endbss
|
|
|
--
|
|
|
--.text
|
|
|
--begtext:
|
|
|
--.data
|
|
|
--begdata:
|
|
|
--.bss
|
|
|
--begbss:
|
|
|
--.text
|
|
|
--
|
|
|
--start:
|
|
|
-- jmp trampoline
|
|
|
--
|
|
|
--# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
|
|
|
--
|
|
|
-- .ascii "HdrS" # header signature
|
|
|
-- .word 0x0206 # header version number (>= 0x0105)
|
|
|
-- # or else old loadlin-1.5 will fail)
|
|
|
--realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
|
|
|
--start_sys_seg: .word SYSSEG
|
|
|
-- .word kernel_version # pointing to kernel version string
|
|
|
-- # above section of header is compatible
|
|
|
-- # with loadlin-1.5 (header v1.5). Don't
|
|
|
-- # change it.
|
|
|
--
|
|
|
--type_of_loader: .byte 0 # = 0, old one (LILO, Loadlin,
|
|
|
-- # Bootlin, SYSLX, bootsect...)
|
|
|
-- # See Documentation/i386/boot.txt for
|
|
|
-- # assigned ids
|
|
|
--
|
|
|
--# flags, unused bits must be zero (RFU) bit within loadflags
|
|
|
--loadflags:
|
|
|
--LOADED_HIGH = 1 # If set, the kernel is loaded high
|
|
|
--CAN_USE_HEAP = 0x80 # If set, the loader also has set
|
|
|
-- # heap_end_ptr to tell how much
|
|
|
-- # space behind setup.S can be used for
|
|
|
-- # heap purposes.
|
|
|
-- # Only the loader knows what is free
|
|
|
--#ifndef __BIG_KERNEL__
|
|
|
-- .byte 0
|
|
|
--#else
|
|
|
-- .byte LOADED_HIGH
|
|
|
--#endif
|
|
|
--
|
|
|
--setup_move_size: .word 0x8000 # size to move, when setup is not
|
|
|
-- # loaded at 0x90000. We will move setup
|
|
|
-- # to 0x90000 then just before jumping
|
|
|
-- # into the kernel. However, only the
|
|
|
-- # loader knows how much data behind
|
|
|
-- # us also needs to be loaded.
|
|
|
--
|
|
|
--code32_start: # here loaders can put a different
|
|
|
-- # start address for 32-bit code.
|
|
|
--#ifndef __BIG_KERNEL__
|
|
|
-- .long 0x1000 # 0x1000 = default for zImage
|
|
|
--#else
|
|
|
-- .long 0x100000 # 0x100000 = default for big kernel
|
|
|
--#endif
|
|
|
--
|
|
|
--ramdisk_image: .long 0 # address of loaded ramdisk image
|
|
|
-- # Here the loader puts the 32-bit
|
|
|
-- # address where it loaded the image.
|
|
|
-- # This only will be read by the kernel.
|
|
|
--
|
|
|
--ramdisk_size: .long 0 # its size in bytes
|
|
|
--
|
|
|
--bootsect_kludge:
|
|
|
-- .long 0 # obsolete
|
|
|
--
|
|
|
--heap_end_ptr: .word modelist+1024 # (Header version 0x0201 or later)
|
|
|
-- # space from here (exclusive) down to
|
|
|
-- # end of setup code can be used by setup
|
|
|
-- # for local heap purposes.
|
|
|
--
|
|
|
--pad1: .word 0
|
|
|
--cmd_line_ptr: .long 0 # (Header version 0x0202 or later)
|
|
|
-- # If nonzero, a 32-bit pointer
|
|
|
-- # to the kernel command line.
|
|
|
-- # The command line should be
|
|
|
-- # located between the start of
|
|
|
-- # setup and the end of low
|
|
|
-- # memory (0xa0000), or it may
|
|
|
-- # get overwritten before it
|
|
|
-- # gets read. If this field is
|
|
|
-- # used, there is no longer
|
|
|
-- # anything magical about the
|
|
|
-- # 0x90000 segment; the setup
|
|
|
-- # can be located anywhere in
|
|
|
-- # low memory 0x10000 or higher.
|
|
|
--
|
|
|
--ramdisk_max: .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
|
|
|
-- # (Header version 0x0203 or later)
|
|
|
-- # The highest safe address for
|
|
|
-- # the contents of an initrd
|
|
|
--
|
|
|
--kernel_alignment: .long CONFIG_PHYSICAL_ALIGN #physical addr alignment
|
|
|
-- #required for protected mode
|
|
|
-- #kernel
|
|
|
--#ifdef CONFIG_RELOCATABLE
|
|
|
--relocatable_kernel: .byte 1
|
|
|
--#else
|
|
|
--relocatable_kernel: .byte 0
|
|
|
--#endif
|
|
|
--pad2: .byte 0
|
|
|
--pad3: .word 0
|
|
|
--
|
|
|
--cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
|
|
|
-- #added with boot protocol
|
|
|
-- #version 2.06
|
|
|
--
|
|
|
--trampoline: call start_of_setup
|
|
|
-- .align 16
|
|
|
-- # The offset at this point is 0x240
|
|
|
-- .space (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
|
|
|
--# End of setup header #####################################################
|
|
|
--
|
|
|
--start_of_setup:
|
|
|
--# Bootlin depends on this being done early
|
|
|
-- movw $0x01500, %ax
|
|
|
-- movb $0x81, %dl
|
|
|
-- int $0x13
|
|
|
--
|
|
|
--#ifdef SAFE_RESET_DISK_CONTROLLER
|
|
|
--# Reset the disk controller.
|
|
|
-- movw $0x0000, %ax
|
|
|
-- movb $0x80, %dl
|
|
|
-- int $0x13
|
|
|
--#endif
|
|
|
--
|
|
|
--# Set %ds = %cs, we know that SETUPSEG = %cs at this point
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- movw %ax, %ds
|
|
|
--# Check signature at end of setup
|
|
|
-- cmpw $SIG1, setup_sig1
|
|
|
-- jne bad_sig
|
|
|
--
|
|
|
-- cmpw $SIG2, setup_sig2
|
|
|
-- jne bad_sig
|
|
|
--
|
|
|
-- jmp good_sig1
|
|
|
--
|
|
|
--# Routine to print asciiz string at ds:si
|
|
|
--prtstr:
|
|
|
-- lodsb
|
|
|
-- andb %al, %al
|
|
|
-- jz fin
|
|
|
--
|
|
|
-- call prtchr
|
|
|
-- jmp prtstr
|
|
|
--
|
|
|
--fin: ret
|
|
|
--
|
|
|
--# Space printing
|
|
|
--prtsp2: call prtspc # Print double space
|
|
|
--prtspc: movb $0x20, %al # Print single space (note: fall-thru)
|
|
|
--
|
|
|
--# Part of above routine, this one just prints ascii al
|
|
|
--prtchr: pushw %ax
|
|
|
-- pushw %cx
|
|
|
-- movw $7,%bx
|
|
|
-- movw $0x01, %cx
|
|
|
-- movb $0x0e, %ah
|
|
|
-- int $0x10
|
|
|
-- popw %cx
|
|
|
-- popw %ax
|
|
|
-- ret
|
|
|
--
|
|
|
--beep: movb $0x07, %al
|
|
|
-- jmp prtchr
|
|
|
--
|
|
|
--no_sig_mess: .string "No setup signature found ..."
|
|
|
--
|
|
|
--good_sig1:
|
|
|
-- jmp good_sig
|
|
|
--
|
|
|
--# We now have to find the rest of the setup code/data
|
|
|
--bad_sig:
|
|
|
-- movw %cs, %ax # SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %ax # INITSEG
|
|
|
-- movw %ax, %ds
|
|
|
-- xorb %bh, %bh
|
|
|
-- movb (497), %bl # get setup sect from bootsect
|
|
|
-- subw $4, %bx # LILO loads 4 sectors of setup
|
|
|
-- shlw $8, %bx # convert to words (1sect=2^8 words)
|
|
|
-- movw %bx, %cx
|
|
|
-- shrw $3, %bx # convert to segment
|
|
|
-- addw $SYSSEG, %bx
|
|
|
-- movw %bx, %cs:start_sys_seg
|
|
|
--# Move rest of setup code/data to here
|
|
|
-- movw $2048, %di # four sectors loaded by LILO
|
|
|
-- subw %si, %si
|
|
|
-- pushw %cs
|
|
|
-- popw %es
|
|
|
-- movw $SYSSEG, %ax
|
|
|
-- movw %ax, %ds
|
|
|
-- rep
|
|
|
-- movsw
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- movw %ax, %ds
|
|
|
-- cmpw $SIG1, setup_sig1
|
|
|
-- jne no_sig
|
|
|
--
|
|
|
-- cmpw $SIG2, setup_sig2
|
|
|
-- jne no_sig
|
|
|
--
|
|
|
-- jmp good_sig
|
|
|
--
|
|
|
--no_sig:
|
|
|
-- lea no_sig_mess, %si
|
|
|
-- call prtstr
|
|
|
--
|
|
|
--no_sig_loop:
|
|
|
-- hlt
|
|
|
-- jmp no_sig_loop
|
|
|
--
|
|
|
--good_sig:
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %ax # aka INITSEG
|
|
|
-- movw %ax, %ds
|
|
|
--# Check if an old loader tries to load a big-kernel
|
|
|
-- testb $LOADED_HIGH, %cs:loadflags # Do we have a big kernel?
|
|
|
-- jz loader_ok # No, no danger for old loaders.
|
|
|
--
|
|
|
-- cmpb $0, %cs:type_of_loader # Do we have a loader that
|
|
|
-- # can deal with us?
|
|
|
-- jnz loader_ok # Yes, continue.
|
|
|
--
|
|
|
-- pushw %cs # No, we have an old loader,
|
|
|
-- popw %ds # die.
|
|
|
-- lea loader_panic_mess, %si
|
|
|
-- call prtstr
|
|
|
--
|
|
|
-- jmp no_sig_loop
|
|
|
--
|
|
|
--loader_panic_mess: .string "Wrong loader, giving up..."
|
|
|
--
|
|
|
--# check minimum cpuid
|
|
|
--# we do this here because it is the last place we can actually
|
|
|
--# show a user visible error message. Later the video modus
|
|
|
--# might be already messed up.
|
|
|
--loader_ok:
|
|
|
-- call verify_cpu
|
|
|
-- testl %eax,%eax
|
|
|
-- jz cpu_ok
|
|
|
-- movw %cs,%ax # aka SETUPSEG
|
|
|
-- movw %ax,%ds
|
|
|
-- lea cpu_panic_mess,%si
|
|
|
-- call prtstr
|
|
|
--1: jmp 1b
|
|
|
--
|
|
|
--cpu_panic_mess:
|
|
|
-- .asciz "PANIC: CPU too old for this kernel."
|
|
|
--
|
|
|
--#include "../kernel/verify_cpu.S"
|
|
|
--
|
|
|
--cpu_ok:
|
|
|
--# Get memory size (extended mem, kB)
|
|
|
--
|
|
|
-- xorl %eax, %eax
|
|
|
-- movl %eax, (0x1e0)
|
|
|
--#ifndef STANDARD_MEMORY_BIOS_CALL
|
|
|
-- movb %al, (E820NR)
|
|
|
--# Try three different memory detection schemes. First, try
|
|
|
--# e820h, which lets us assemble a memory map, then try e801h,
|
|
|
--# which returns a 32-bit memory size, and finally 88h, which
|
|
|
--# returns 0-64m
|
|
|
--
|
|
|
--# method E820H:
|
|
|
--# the memory map from hell. e820h returns memory classified into
|
|
|
--# a whole bunch of different types, and allows memory holes and
|
|
|
--# everything. We scan through this memory map and build a list
|
|
|
--# of the first 32 memory areas, which we return at [E820MAP].
|
|
|
--# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
|
|
|
--
|
|
|
--#define SMAP 0x534d4150
|
|
|
--
|
|
|
--meme820:
|
|
|
-- xorl %ebx, %ebx # continuation counter
|
|
|
-- movw $E820MAP, %di # point into the whitelist
|
|
|
-- # so we can have the bios
|
|
|
-- # directly write into it.
|
|
|
--
|
|
|
--jmpe820:
|
|
|
-- movl $0x0000e820, %eax # e820, upper word zeroed
|
|
|
-- movl $SMAP, %edx # ascii 'SMAP'
|
|
|
-- movl $20, %ecx # size of the e820rec
|
|
|
-- pushw %ds # data record.
|
|
|
-- popw %es
|
|
|
-- int $0x15 # make the call
|
|
|
-- jc bail820 # fall to e801 if it fails
|
|
|
--
|
|
|
-- cmpl $SMAP, %eax # check the return is `SMAP'
|
|
|
-- jne bail820 # fall to e801 if it fails
|
|
|
--
|
|
|
--# cmpl $1, 16(%di) # is this usable memory?
|
|
|
--# jne again820
|
|
|
--
|
|
|
-- # If this is usable memory, we save it by simply advancing %di by
|
|
|
-- # sizeof(e820rec).
|
|
|
-- #
|
|
|
--good820:
|
|
|
-- movb (E820NR), %al # up to 128 entries
|
|
|
-- cmpb $E820MAX, %al
|
|
|
-- jae bail820
|
|
|
--
|
|
|
-- incb (E820NR)
|
|
|
-- movw %di, %ax
|
|
|
-- addw $20, %ax
|
|
|
-- movw %ax, %di
|
|
|
--again820:
|
|
|
-- cmpl $0, %ebx # check to see if
|
|
|
-- jne jmpe820 # %ebx is set to EOF
|
|
|
--bail820:
|
|
|
--
|
|
|
--
|
|
|
--# method E801H:
|
|
|
--# memory size is in 1k chunksizes, to avoid confusing loadlin.
|
|
|
--# we store the 0xe801 memory size in a completely different place,
|
|
|
--# because it will most likely be longer than 16 bits.
|
|
|
--# (use 1e0 because that's what Larry Augustine uses in his
|
|
|
--# alternative new memory detection scheme, and it's sensible
|
|
|
--# to write everything into the same place.)
|
|
|
--
|
|
|
--meme801:
|
|
|
-- stc # fix to work around buggy
|
|
|
-- xorw %cx,%cx # BIOSes which don't clear/set
|
|
|
-- xorw %dx,%dx # carry on pass/error of
|
|
|
-- # e801h memory size call
|
|
|
-- # or merely pass cx,dx though
|
|
|
-- # without changing them.
|
|
|
-- movw $0xe801, %ax
|
|
|
-- int $0x15
|
|
|
-- jc mem88
|
|
|
--
|
|
|
-- cmpw $0x0, %cx # Kludge to handle BIOSes
|
|
|
-- jne e801usecxdx # which report their extended
|
|
|
-- cmpw $0x0, %dx # memory in AX/BX rather than
|
|
|
-- jne e801usecxdx # CX/DX. The spec I have read
|
|
|
-- movw %ax, %cx # seems to indicate AX/BX
|
|
|
-- movw %bx, %dx # are more reasonable anyway...
|
|
|
--
|
|
|
--e801usecxdx:
|
|
|
-- andl $0xffff, %edx # clear sign extend
|
|
|
-- shll $6, %edx # and go from 64k to 1k chunks
|
|
|
-- movl %edx, (0x1e0) # store extended memory size
|
|
|
-- andl $0xffff, %ecx # clear sign extend
|
|
|
-- addl %ecx, (0x1e0) # and add lower memory into
|
|
|
-- # total size.
|
|
|
--
|
|
|
--# Ye Olde Traditional Methode. Returns the memory size (up to 16mb or
|
|
|
--# 64mb, depending on the bios) in ax.
|
|
|
--mem88:
|
|
|
--
|
|
|
--#endif
|
|
|
-- movb $0x88, %ah
|
|
|
-- int $0x15
|
|
|
-- movw %ax, (2)
|
|
|
--
|
|
|
--# Set the keyboard repeat rate to the max
|
|
|
-- movw $0x0305, %ax
|
|
|
-- xorw %bx, %bx
|
|
|
-- int $0x16
|
|
|
--
|
|
|
--# Check for video adapter and its parameters and allow the
|
|
|
--# user to browse video modes.
|
|
|
-- call video # NOTE: we need %ds pointing
|
|
|
-- # to bootsector
|
|
|
--
|
|
|
--# Get hd0 data...
|
|
|
-- xorw %ax, %ax
|
|
|
-- movw %ax, %ds
|
|
|
-- ldsw (4 * 0x41), %si
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %ax # aka INITSEG
|
|
|
-- pushw %ax
|
|
|
-- movw %ax, %es
|
|
|
-- movw $0x0080, %di
|
|
|
-- movw $0x10, %cx
|
|
|
-- pushw %cx
|
|
|
-- cld
|
|
|
-- rep
|
|
|
-- movsb
|
|
|
--# Get hd1 data...
|
|
|
-- xorw %ax, %ax
|
|
|
-- movw %ax, %ds
|
|
|
-- ldsw (4 * 0x46), %si
|
|
|
-- popw %cx
|
|
|
-- popw %es
|
|
|
-- movw $0x0090, %di
|
|
|
-- rep
|
|
|
-- movsb
|
|
|
--# Check that there IS a hd1 :-)
|
|
|
-- movw $0x01500, %ax
|
|
|
-- movb $0x81, %dl
|
|
|
-- int $0x13
|
|
|
-- jc no_disk1
|
|
|
--
|
|
|
-- cmpb $3, %ah
|
|
|
-- je is_disk1
|
|
|
--
|
|
|
--no_disk1:
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %ax # aka INITSEG
|
|
|
-- movw %ax, %es
|
|
|
-- movw $0x0090, %di
|
|
|
-- movw $0x10, %cx
|
|
|
-- xorw %ax, %ax
|
|
|
-- cld
|
|
|
-- rep
|
|
|
-- stosb
|
|
|
--is_disk1:
|
|
|
--# check for Micro Channel (MCA) bus
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %ax # aka INITSEG
|
|
|
-- movw %ax, %ds
|
|
|
-- xorw %ax, %ax
|
|
|
-- movw %ax, (0xa0) # set table length to 0
|
|
|
-- movb $0xc0, %ah
|
|
|
-- stc
|
|
|
-- int $0x15 # moves feature table to es:bx
|
|
|
-- jc no_mca
|
|
|
--
|
|
|
-- pushw %ds
|
|
|
-- movw %es, %ax
|
|
|
-- movw %ax, %ds
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %ax # aka INITSEG
|
|
|
-- movw %ax, %es
|
|
|
-- movw %bx, %si
|
|
|
-- movw $0xa0, %di
|
|
|
-- movw (%si), %cx
|
|
|
-- addw $2, %cx # table length is a short
|
|
|
-- cmpw $0x10, %cx
|
|
|
-- jc sysdesc_ok
|
|
|
--
|
|
|
-- movw $0x10, %cx # we keep only first 16 bytes
|
|
|
--sysdesc_ok:
|
|
|
-- rep
|
|
|
-- movsb
|
|
|
-- popw %ds
|
|
|
--no_mca:
|
|
|
--#ifdef CONFIG_X86_VOYAGER
|
|
|
-- movb $0xff, 0x40 # flag on config found
|
|
|
-- movb $0xc0, %al
|
|
|
-- mov $0xff, %ah
|
|
|
-- int $0x15 # put voyager config info at es:di
|
|
|
-- jc no_voyager
|
|
|
-- movw $0x40, %si # place voyager info in apm table
|
|
|
-- cld
|
|
|
-- movw $7, %cx
|
|
|
--voyager_rep:
|
|
|
-- movb %es:(%di), %al
|
|
|
-- movb %al,(%si)
|
|
|
-- incw %di
|
|
|
-- incw %si
|
|
|
-- decw %cx
|
|
|
-- jnz voyager_rep
|
|
|
--no_voyager:
|
|
|
--#endif
|
|
|
--# Check for PS/2 pointing device
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %ax # aka INITSEG
|
|
|
-- movw %ax, %ds
|
|
|
-- movb $0, (0x1ff) # default is no pointing device
|
|
|
-- int $0x11 # int 0x11: equipment list
|
|
|
-- testb $0x04, %al # check if mouse installed
|
|
|
-- jz no_psmouse
|
|
|
--
|
|
|
-- movb $0xAA, (0x1ff) # device present
|
|
|
--no_psmouse:
|
|
|
--
|
|
|
--#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
|
|
|
-- movl $0x0000E980, %eax # IST Support
|
|
|
-- movl $0x47534943, %edx # Request value
|
|
|
-- int $0x15
|
|
|
--
|
|
|
-- movl %eax, (96)
|
|
|
-- movl %ebx, (100)
|
|
|
-- movl %ecx, (104)
|
|
|
-- movl %edx, (108)
|
|
|
--#endif
|
|
|
--
|
|
|
--#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
|
|
|
--# Then check for an APM BIOS...
|
|
|
-- # %ds points to the bootsector
|
|
|
-- movw $0, 0x40 # version = 0 means no APM BIOS
|
|
|
-- movw $0x05300, %ax # APM BIOS installation check
|
|
|
-- xorw %bx, %bx
|
|
|
-- int $0x15
|
|
|
-- jc done_apm_bios # Nope, no APM BIOS
|
|
|
--
|
|
|
-- cmpw $0x0504d, %bx # Check for "PM" signature
|
|
|
-- jne done_apm_bios # No signature, no APM BIOS
|
|
|
--
|
|
|
-- andw $0x02, %cx # Is 32 bit supported?
|
|
|
-- je done_apm_bios # No 32-bit, no (good) APM BIOS
|
|
|
--
|
|
|
-- movw $0x05304, %ax # Disconnect first just in case
|
|
|
-- xorw %bx, %bx
|
|
|
-- int $0x15 # ignore return code
|
|
|
-- movw $0x05303, %ax # 32 bit connect
|
|
|
-- xorl %ebx, %ebx
|
|
|
-- xorw %cx, %cx # paranoia :-)
|
|
|
-- xorw %dx, %dx # ...
|
|
|
-- xorl %esi, %esi # ...
|
|
|
-- xorw %di, %di # ...
|
|
|
-- int $0x15
|
|
|
-- jc no_32_apm_bios # Ack, error.
|
|
|
--
|
|
|
-- movw %ax, (66) # BIOS code segment
|
|
|
-- movl %ebx, (68) # BIOS entry point offset
|
|
|
-- movw %cx, (72) # BIOS 16 bit code segment
|
|
|
-- movw %dx, (74) # BIOS data segment
|
|
|
-- movl %esi, (78) # BIOS code segment lengths
|
|
|
-- movw %di, (82) # BIOS data segment length
|
|
|
--# Redo the installation check as the 32 bit connect
|
|
|
--# modifies the flags returned on some BIOSs
|
|
|
-- movw $0x05300, %ax # APM BIOS installation check
|
|
|
-- xorw %bx, %bx
|
|
|
-- xorw %cx, %cx # paranoia
|
|
|
-- int $0x15
|
|
|
-- jc apm_disconnect # error -> shouldn't happen
|
|
|
--
|
|
|
-- cmpw $0x0504d, %bx # check for "PM" signature
|
|
|
-- jne apm_disconnect # no sig -> shouldn't happen
|
|
|
--
|
|
|
-- movw %ax, (64) # record the APM BIOS version
|
|
|
-- movw %cx, (76) # and flags
|
|
|
-- jmp done_apm_bios
|
|
|
--
|
|
|
--apm_disconnect: # Tidy up
|
|
|
-- movw $0x05304, %ax # Disconnect
|
|
|
-- xorw %bx, %bx
|
|
|
-- int $0x15 # ignore return code
|
|
|
--
|
|
|
-- jmp done_apm_bios
|
|
|
--
|
|
|
--no_32_apm_bios:
|
|
|
-- andw $0xfffd, (76) # remove 32 bit support bit
|
|
|
--done_apm_bios:
|
|
|
--#endif
|
|
|
--
|
|
|
--#include "edd.S"
|
|
|
--
|
|
|
--# Now we want to move to protected mode ...
|
|
|
-- cmpw $0, %cs:realmode_swtch
|
|
|
-- jz rmodeswtch_normal
|
|
|
--
|
|
|
-- lcall *%cs:realmode_swtch
|
|
|
--
|
|
|
-- jmp rmodeswtch_end
|
|
|
--
|
|
|
--rmodeswtch_normal:
|
|
|
-- pushw %cs
|
|
|
-- call default_switch
|
|
|
--
|
|
|
--rmodeswtch_end:
|
|
|
--# Now we move the system to its rightful place ... but we check if we have a
|
|
|
--# big-kernel. In that case we *must* not move it ...
|
|
|
-- testb $LOADED_HIGH, %cs:loadflags
|
|
|
-- jz do_move0 # .. then we have a normal low
|
|
|
-- # loaded zImage
|
|
|
-- # .. or else we have a high
|
|
|
-- # loaded bzImage
|
|
|
-- jmp end_move # ... and we skip moving
|
|
|
--
|
|
|
--do_move0:
|
|
|
-- movw $0x100, %ax # start of destination segment
|
|
|
-- movw %cs, %bp # aka SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %bp # aka INITSEG
|
|
|
-- movw %cs:start_sys_seg, %bx # start of source segment
|
|
|
-- cld
|
|
|
--do_move:
|
|
|
-- movw %ax, %es # destination segment
|
|
|
-- incb %ah # instead of add ax,#0x100
|
|
|
-- movw %bx, %ds # source segment
|
|
|
-- addw $0x100, %bx
|
|
|
-- subw %di, %di
|
|
|
-- subw %si, %si
|
|
|
-- movw $0x800, %cx
|
|
|
-- rep
|
|
|
-- movsw
|
|
|
-- cmpw %bp, %bx # assume start_sys_seg > 0x200,
|
|
|
-- # so we will perhaps read one
|
|
|
-- # page more than needed, but
|
|
|
-- # never overwrite INITSEG
|
|
|
-- # because destination is a
|
|
|
-- # minimum one page below source
|
|
|
-- jb do_move
|
|
|
--
|
|
|
--end_move:
|
|
|
--# then we load the segment descriptors
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- movw %ax, %ds
|
|
|
--
|
|
|
--# Check whether we need to be downward compatible with version <=201
|
|
|
-- cmpl $0, cmd_line_ptr
|
|
|
-- jne end_move_self # loader uses version >=202 features
|
|
|
-- cmpb $0x20, type_of_loader
|
|
|
-- je end_move_self # bootsect loader, we know of it
|
|
|
--
|
|
|
--# Boot loader doesnt support boot protocol version 2.02.
|
|
|
--# If we have our code not at 0x90000, we need to move it there now.
|
|
|
--# We also then need to move the params behind it (commandline)
|
|
|
--# Because we would overwrite the code on the current IP, we move
|
|
|
--# it in two steps, jumping high after the first one.
|
|
|
-- movw %cs, %ax
|
|
|
-- cmpw $SETUPSEG, %ax
|
|
|
-- je end_move_self
|
|
|
--
|
|
|
-- cli # make sure we really have
|
|
|
-- # interrupts disabled !
|
|
|
-- # because after this the stack
|
|
|
-- # should not be used
|
|
|
-- subw $DELTA_INITSEG, %ax # aka INITSEG
|
|
|
-- movw %ss, %dx
|
|
|
-- cmpw %ax, %dx
|
|
|
-- jb move_self_1
|
|
|
--
|
|
|
-- addw $INITSEG, %dx
|
|
|
-- subw %ax, %dx # this will go into %ss after
|
|
|
-- # the move
|
|
|
--move_self_1:
|
|
|
-- movw %ax, %ds
|
|
|
-- movw $INITSEG, %ax # real INITSEG
|
|
|
-- movw %ax, %es
|
|
|
-- movw %cs:setup_move_size, %cx
|
|
|
-- std # we have to move up, so we use
|
|
|
-- # direction down because the
|
|
|
-- # areas may overlap
|
|
|
-- movw %cx, %di
|
|
|
-- decw %di
|
|
|
-- movw %di, %si
|
|
|
-- subw $move_self_here+0x200, %cx
|
|
|
-- rep
|
|
|
-- movsb
|
|
|
-- ljmp $SETUPSEG, $move_self_here
|
|
|
--
|
|
|
--move_self_here:
|
|
|
-- movw $move_self_here+0x200, %cx
|
|
|
-- rep
|
|
|
-- movsb
|
|
|
-- movw $SETUPSEG, %ax
|
|
|
-- movw %ax, %ds
|
|
|
-- movw %dx, %ss
|
|
|
--end_move_self: # now we are at the right place
|
|
|
--
|
|
|
--#
|
|
|
--# Enable A20. This is at the very best an annoying procedure.
|
|
|
--# A20 code ported from SYSLINUX 1.52-1.63 by H. Peter Anvin.
|
|
|
--# AMD Elan bug fix by Robert Schwebel.
|
|
|
--#
|
|
|
--
|
|
|
--#if defined(CONFIG_X86_ELAN)
|
|
|
-- movb $0x02, %al # alternate A20 gate
|
|
|
-- outb %al, $0x92 # this works on SC410/SC520
|
|
|
--a20_elan_wait:
|
|
|
-- call a20_test
|
|
|
-- jz a20_elan_wait
|
|
|
-- jmp a20_done
|
|
|
--#endif
|
|
|
--
|
|
|
--
|
|
|
--A20_TEST_LOOPS = 32 # Iterations per wait
|
|
|
--A20_ENABLE_LOOPS = 255 # Total loops to try
|
|
|
--
|
|
|
--
|
|
|
--#ifndef CONFIG_X86_VOYAGER
|
|
|
--a20_try_loop:
|
|
|
--
|
|
|
-- # First, see if we are on a system with no A20 gate.
|
|
|
--a20_none:
|
|
|
-- call a20_test
|
|
|
-- jnz a20_done
|
|
|
--
|
|
|
-- # Next, try the BIOS (INT 0x15, AX=0x2401)
|
|
|
--a20_bios:
|
|
|
-- movw $0x2401, %ax
|
|
|
-- pushfl # Be paranoid about flags
|
|
|
-- int $0x15
|
|
|
-- popfl
|
|
|
--
|
|
|
-- call a20_test
|
|
|
-- jnz a20_done
|
|
|
--
|
|
|
-- # Try enabling A20 through the keyboard controller
|
|
|
--#endif /* CONFIG_X86_VOYAGER */
|
|
|
--a20_kbc:
|
|
|
-- call empty_8042
|
|
|
--
|
|
|
--#ifndef CONFIG_X86_VOYAGER
|
|
|
-- call a20_test # Just in case the BIOS worked
|
|
|
-- jnz a20_done # but had a delayed reaction.
|
|
|
--#endif
|
|
|
--
|
|
|
-- movb $0xD1, %al # command write
|
|
|
-- outb %al, $0x64
|
|
|
-- call empty_8042
|
|
|
--
|
|
|
-- movb $0xDF, %al # A20 on
|
|
|
-- outb %al, $0x60
|
|
|
-- call empty_8042
|
|
|
--
|
|
|
--#ifndef CONFIG_X86_VOYAGER
|
|
|
-- # Wait until a20 really *is* enabled; it can take a fair amount of
|
|
|
-- # time on certain systems; Toshiba Tecras are known to have this
|
|
|
-- # problem.
|
|
|
--a20_kbc_wait:
|
|
|
-- xorw %cx, %cx
|
|
|
--a20_kbc_wait_loop:
|
|
|
-- call a20_test
|
|
|
-- jnz a20_done
|
|
|
-- loop a20_kbc_wait_loop
|
|
|
--
|
|
|
-- # Final attempt: use "configuration port A"
|
|
|
--a20_fast:
|
|
|
-- inb $0x92, %al # Configuration Port A
|
|
|
-- orb $0x02, %al # "fast A20" version
|
|
|
-- andb $0xFE, %al # don't accidentally reset
|
|
|
-- outb %al, $0x92
|
|
|
--
|
|
|
-- # Wait for configuration port A to take effect
|
|
|
--a20_fast_wait:
|
|
|
-- xorw %cx, %cx
|
|
|
--a20_fast_wait_loop:
|
|
|
-- call a20_test
|
|
|
-- jnz a20_done
|
|
|
-- loop a20_fast_wait_loop
|
|
|
--
|
|
|
-- # A20 is still not responding. Try frobbing it again.
|
|
|
-- #
|
|
|
-- decb (a20_tries)
|
|
|
-- jnz a20_try_loop
|
|
|
--
|
|
|
-- movw $a20_err_msg, %si
|
|
|
-- call prtstr
|
|
|
--
|
|
|
--a20_die:
|
|
|
-- hlt
|
|
|
-- jmp a20_die
|
|
|
--
|
|
|
--a20_tries:
|
|
|
-- .byte A20_ENABLE_LOOPS
|
|
|
--
|
|
|
--a20_err_msg:
|
|
|
-- .ascii "linux: fatal error: A20 gate not responding!"
|
|
|
-- .byte 13, 10, 0
|
|
|
--
|
|
|
-- # If we get here, all is good
|
|
|
--a20_done:
|
|
|
--
|
|
|
--#endif /* CONFIG_X86_VOYAGER */
|
|
|
--# set up gdt and idt and 32bit start address
|
|
|
-- lidt idt_48 # load idt with 0,0
|
|
|
-- xorl %eax, %eax # Compute gdt_base
|
|
|
-- movw %ds, %ax # (Convert %ds:gdt to a linear ptr)
|
|
|
-- shll $4, %eax
|
|
|
-- addl %eax, code32
|
|
|
-- addl $gdt, %eax
|
|
|
-- movl %eax, (gdt_48+2)
|
|
|
-- lgdt gdt_48 # load gdt with whatever is
|
|
|
-- # appropriate
|
|
|
--
|
|
|
--# make sure any possible coprocessor is properly reset..
|
|
|
-- xorw %ax, %ax
|
|
|
-- outb %al, $0xf0
|
|
|
-- call delay
|
|
|
--
|
|
|
-- outb %al, $0xf1
|
|
|
-- call delay
|
|
|
--
|
|
|
--# well, that went ok, I hope. Now we mask all interrupts - the rest
|
|
|
--# is done in init_IRQ().
|
|
|
-- movb $0xFF, %al # mask all interrupts for now
|
|
|
-- outb %al, $0xA1
|
|
|
-- call delay
|
|
|
--
|
|
|
-- movb $0xFB, %al # mask all irq's but irq2 which
|
|
|
-- outb %al, $0x21 # is cascaded
|
|
|
--
|
|
|
--# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
|
|
|
--# need no steenking BIOS anyway (except for the initial loading :-).
|
|
|
--# The BIOS-routine wants lots of unnecessary data, and it's less
|
|
|
--# "interesting" anyway. This is how REAL programmers do it.
|
|
|
--#
|
|
|
--# Well, now's the time to actually move into protected mode. To make
|
|
|
--# things as simple as possible, we do no register set-up or anything,
|
|
|
--# we let the gnu-compiled 32-bit programs do that. We just jump to
|
|
|
--# absolute address 0x1000 (or the loader supplied one),
|
|
|
--# in 32-bit protected mode.
|
|
|
--#
|
|
|
--# Note that the short jump isn't strictly needed, although there are
|
|
|
--# reasons why it might be a good idea. It won't hurt in any case.
|
|
|
-- movw $1, %ax # protected mode (PE) bit
|
|
|
-- lmsw %ax # This is it!
|
|
|
-- jmp flush_instr
|
|
|
--
|
|
|
--flush_instr:
|
|
|
-- xorw %bx, %bx # Flag to indicate a boot
|
|
|
-- xorl %esi, %esi # Pointer to real-mode code
|
|
|
-- movw %cs, %si
|
|
|
-- subw $DELTA_INITSEG, %si
|
|
|
-- shll $4, %esi # Convert to 32-bit pointer
|
|
|
--
|
|
|
--# jump to startup_32 in arch/i386/boot/compressed/head.S
|
|
|
--#
|
|
|
--# NOTE: For high loaded big kernels we need a
|
|
|
--# jmpi 0x100000,__BOOT_CS
|
|
|
--#
|
|
|
--# but we yet haven't reloaded the CS register, so the default size
|
|
|
--# of the target offset still is 16 bit.
|
|
|
--# However, using an operand prefix (0x66), the CPU will properly
|
|
|
--# take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
|
|
|
--# Manual, Mixing 16-bit and 32-bit code, page 16-6)
|
|
|
--
|
|
|
-- .byte 0x66, 0xea # prefix + jmpi-opcode
|
|
|
--code32: .long startup_32 # will be set to %cs+startup_32
|
|
|
-- .word __BOOT_CS
|
|
|
--.code32
|
|
|
--startup_32:
|
|
|
-- movl $(__BOOT_DS), %eax
|
|
|
-- movl %eax, %ds
|
|
|
-- movl %eax, %es
|
|
|
-- movl %eax, %fs
|
|
|
-- movl %eax, %gs
|
|
|
-- movl %eax, %ss
|
|
|
--
|
|
|
-- xorl %eax, %eax
|
|
|
--1: incl %eax # check that A20 really IS enabled
|
|
|
-- movl %eax, 0x00000000 # loop forever if it isn't
|
|
|
-- cmpl %eax, 0x00100000
|
|
|
-- je 1b
|
|
|
--
|
|
|
-- # Jump to the 32bit entry point
|
|
|
-- jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi)
|
|
|
--.code16
|
|
|
--
|
|
|
--# Here's a bunch of information about your current kernel..
|
|
|
--kernel_version: .ascii UTS_RELEASE
|
|
|
-- .ascii " ("
|
|
|
-- .ascii LINUX_COMPILE_BY
|
|
|
-- .ascii "@"
|
|
|
-- .ascii LINUX_COMPILE_HOST
|
|
|
-- .ascii ") "
|
|
|
-- .ascii UTS_VERSION
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# This is the default real mode switch routine.
|
|
|
--# to be called just before protected mode transition
|
|
|
--default_switch:
|
|
|
-- cli # no interrupts allowed !
|
|
|
-- movb $0x80, %al # disable NMI for bootup
|
|
|
-- # sequence
|
|
|
-- outb %al, $0x70
|
|
|
-- lret
|
|
|
--
|
|
|
--
|
|
|
--#ifndef CONFIG_X86_VOYAGER
|
|
|
--# This routine tests whether or not A20 is enabled. If so, it
|
|
|
--# exits with zf = 0.
|
|
|
--#
|
|
|
--# The memory address used, 0x200, is the int $0x80 vector, which
|
|
|
--# should be safe.
|
|
|
--
|
|
|
--A20_TEST_ADDR = 4*0x80
|
|
|
--
|
|
|
--a20_test:
|
|
|
-- pushw %cx
|
|
|
-- pushw %ax
|
|
|
-- xorw %cx, %cx
|
|
|
-- movw %cx, %fs # Low memory
|
|
|
-- decw %cx
|
|
|
-- movw %cx, %gs # High memory area
|
|
|
-- movw $A20_TEST_LOOPS, %cx
|
|
|
-- movw %fs:(A20_TEST_ADDR), %ax
|
|
|
-- pushw %ax
|
|
|
--a20_test_wait:
|
|
|
-- incw %ax
|
|
|
-- movw %ax, %fs:(A20_TEST_ADDR)
|
|
|
-- call delay # Serialize and make delay constant
|
|
|
-- cmpw %gs:(A20_TEST_ADDR+0x10), %ax
|
|
|
-- loope a20_test_wait
|
|
|
--
|
|
|
-- popw %fs:(A20_TEST_ADDR)
|
|
|
-- popw %ax
|
|
|
-- popw %cx
|
|
|
-- ret
|
|
|
--
|
|
|
--#endif /* CONFIG_X86_VOYAGER */
|
|
|
--
|
|
|
--# This routine checks that the keyboard command queue is empty
|
|
|
--# (after emptying the output buffers)
|
|
|
--#
|
|
|
--# Some machines have delusions that the keyboard buffer is always full
|
|
|
--# with no keyboard attached...
|
|
|
--#
|
|
|
--# If there is no keyboard controller, we will usually get 0xff
|
|
|
--# to all the reads. With each IO taking a microsecond and
|
|
|
--# a timeout of 100,000 iterations, this can take about half a
|
|
|
--# second ("delay" == outb to port 0x80). That should be ok,
|
|
|
--# and should also be plenty of time for a real keyboard controller
|
|
|
--# to empty.
|
|
|
--#
|
|
|
--
|
|
|
--empty_8042:
|
|
|
-- pushl %ecx
|
|
|
-- movl $100000, %ecx
|
|
|
--
|
|
|
--empty_8042_loop:
|
|
|
-- decl %ecx
|
|
|
-- jz empty_8042_end_loop
|
|
|
--
|
|
|
-- call delay
|
|
|
--
|
|
|
-- inb $0x64, %al # 8042 status port
|
|
|
-- testb $1, %al # output buffer?
|
|
|
-- jz no_output
|
|
|
--
|
|
|
-- call delay
|
|
|
-- inb $0x60, %al # read it
|
|
|
-- jmp empty_8042_loop
|
|
|
--
|
|
|
--no_output:
|
|
|
-- testb $2, %al # is input buffer full?
|
|
|
-- jnz empty_8042_loop # yes - loop
|
|
|
--empty_8042_end_loop:
|
|
|
-- popl %ecx
|
|
|
-- ret
|
|
|
--
|
|
|
--# Read the cmos clock. Return the seconds in al
|
|
|
--gettime:
|
|
|
-- pushw %cx
|
|
|
-- movb $0x02, %ah
|
|
|
-- int $0x1a
|
|
|
-- movb %dh, %al # %dh contains the seconds
|
|
|
-- andb $0x0f, %al
|
|
|
-- movb %dh, %ah
|
|
|
-- movb $0x04, %cl
|
|
|
-- shrb %cl, %ah
|
|
|
-- aad
|
|
|
-- popw %cx
|
|
|
-- ret
|
|
|
--
|
|
|
--# Delay is needed after doing I/O
|
|
|
--delay:
|
|
|
-- outb %al,$0x80
|
|
|
-- ret
|
|
|
--
|
|
|
--# Descriptor tables
|
|
|
--#
|
|
|
--# NOTE: The intel manual says gdt should be sixteen bytes aligned for
|
|
|
--# efficiency reasons. However, there are machines which are known not
|
|
|
--# to boot with misaligned GDTs, so alter this at your peril! If you alter
|
|
|
--# GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two
|
|
|
--# empty GDT entries (one for NULL and one reserved).
|
|
|
--#
|
|
|
--# NOTE: On some CPUs, the GDT must be 8 byte aligned. This is
|
|
|
--# true for the Voyager Quad CPU card which will not boot without
|
|
|
--# This directive. 16 byte aligment is recommended by intel.
|
|
|
--#
|
|
|
-- .align 16
|
|
|
--gdt:
|
|
|
-- .fill GDT_ENTRY_BOOT_CS,8,0
|
|
|
--
|
|
|
-- .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
|
|
|
-- .word 0 # base address = 0
|
|
|
-- .word 0x9A00 # code read/exec
|
|
|
-- .word 0x00CF # granularity = 4096, 386
|
|
|
-- # (+5th nibble of limit)
|
|
|
--
|
|
|
-- .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
|
|
|
-- .word 0 # base address = 0
|
|
|
-- .word 0x9200 # data read/write
|
|
|
-- .word 0x00CF # granularity = 4096, 386
|
|
|
-- # (+5th nibble of limit)
|
|
|
--gdt_end:
|
|
|
-- .align 4
|
|
|
--
|
|
|
-- .word 0 # alignment byte
|
|
|
--idt_48:
|
|
|
-- .word 0 # idt limit = 0
|
|
|
-- .word 0, 0 # idt base = 0L
|
|
|
--
|
|
|
-- .word 0 # alignment byte
|
|
|
--gdt_48:
|
|
|
-- .word gdt_end - gdt - 1 # gdt limit
|
|
|
-- .word 0, 0 # gdt base (filled in later)
|
|
|
--
|
|
|
--# Include video setup & detection code
|
|
|
--
|
|
|
--#include "video.S"
|
|
|
--
|
|
|
--# Setup signature -- must be last
|
|
|
--setup_sig1: .word SIG1
|
|
|
--setup_sig2: .word SIG2
|
|
|
--
|
|
|
--# After this point, there is some free space which is used by the video mode
|
|
|
--# handling code to store the temporary mode table (not used by the kernel).
|
|
|
--
|
|
|
--modelist:
|
|
|
--
|
|
|
--.text
|
|
|
--endtext:
|
|
|
--.data
|
|
|
--enddata:
|
|
|
--.bss
|
|
|
--endbss:
|
|
|
-diff -puN /dev/null arch/i386/boot/setup.ld
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/setup.ld
|
|
|
-@@ -0,0 +1,54 @@
|
|
|
-+/*
|
|
|
-+ * setup.ld
|
|
|
-+ *
|
|
|
-+ * Linker script for the i386 setup code
|
|
|
-+ */
|
|
|
-+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
|
|
-+OUTPUT_ARCH(i386)
|
|
|
-+ENTRY(_start)
|
|
|
-+
|
|
|
-+SECTIONS
|
|
|
-+{
|
|
|
-+ . = 0;
|
|
|
-+ .bstext : { *(.bstext) }
|
|
|
-+ .bsdata : { *(.bsdata) }
|
|
|
-+
|
|
|
-+ . = 497;
|
|
|
-+ .header : { *(.header) }
|
|
|
-+ .inittext : { *(.inittext) }
|
|
|
-+ .initdata : { *(.initdata) }
|
|
|
-+ .text : { *(.text*) }
|
|
|
-+
|
|
|
-+ . = ALIGN(16);
|
|
|
-+ .rodata : { *(.rodata*) }
|
|
|
-+
|
|
|
-+ .videocards : {
|
|
|
-+ video_cards = .;
|
|
|
-+ *(.videocards)
|
|
|
-+ video_cards_end = .;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ . = ALIGN(16);
|
|
|
-+ .data : { *(.data*) }
|
|
|
-+
|
|
|
-+ .signature : {
|
|
|
-+ setup_sig = .;
|
|
|
-+ LONG(0x5a5aaa55)
|
|
|
-+ }
|
|
|
-+
|
|
|
-+
|
|
|
-+ . = ALIGN(16);
|
|
|
-+ .bss :
|
|
|
-+ {
|
|
|
-+ __bss_start = .;
|
|
|
-+ *(.bss)
|
|
|
-+ __bss_end = .;
|
|
|
-+ }
|
|
|
-+ . = ALIGN(16);
|
|
|
-+ _end = .;
|
|
|
-+
|
|
|
-+ /DISCARD/ : { *(.note*) }
|
|
|
-+
|
|
|
-+ . = ASSERT(_end <= 0x8000, "Setup too big!");
|
|
|
-+ . = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
|
|
|
-+}
|
|
|
-diff -puN /dev/null arch/i386/boot/string.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/string.c
|
|
|
-@@ -0,0 +1,34 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/string.c
|
|
|
-+ *
|
|
|
-+ * Very basic string functions
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+#include <linux/edd.h>
|
|
|
-+
|
|
|
-+int strcmp(const char *str1, const char *str2)
|
|
|
-+{
|
|
|
-+ const unsigned char *s1 = (const unsigned char *)str1;
|
|
|
-+ const unsigned char *s2 = (const unsigned char *)str2;
|
|
|
-+ int delta = 0;
|
|
|
-+
|
|
|
-+ while (*s1 || *s2) {
|
|
|
-+ delta = *s2 - *s1;
|
|
|
-+ if (delta)
|
|
|
-+ return delta;
|
|
|
-+ s1++;
|
|
|
-+ s2++;
|
|
|
-+ }
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-diff -puN arch/i386/boot/tools/build.c~git-newsetup arch/i386/boot/tools/build.c
|
|
|
---- a/arch/i386/boot/tools/build.c~git-newsetup
|
|
|
-+++ a/arch/i386/boot/tools/build.c
|
|
|
-@@ -1,13 +1,12 @@
|
|
|
- /*
|
|
|
- * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
- * Copyright (C) 1997 Martin Mares
|
|
|
-+ * Copyright (C) 2007 H. Peter Anvin
|
|
|
- */
|
|
|
-
|
|
|
- /*
|
|
|
- * This file builds a disk-image from three different files:
|
|
|
- *
|
|
|
-- * - bootsect: compatibility mbr which prints an error message if
|
|
|
-- * someone tries to boot the kernel directly.
|
|
|
- * - setup: 8086 machine code, sets up system parm
|
|
|
- * - system: 80386 code for actual system
|
|
|
- *
|
|
|
-@@ -21,6 +20,7 @@
|
|
|
- * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
|
|
|
- * Cross compiling fixes by Gertjan van Wingerde, July 1996
|
|
|
- * Rewritten by Martin Mares, April 1997
|
|
|
-+ * Substantially overhauled by H. Peter Anvin, April 2007
|
|
|
- */
|
|
|
-
|
|
|
- #include <stdio.h>
|
|
|
-@@ -32,23 +32,25 @@
|
|
|
- #include <sys/sysmacros.h>
|
|
|
- #include <unistd.h>
|
|
|
- #include <fcntl.h>
|
|
|
-+#include <sys/mman.h>
|
|
|
- #include <asm/boot.h>
|
|
|
-
|
|
|
--typedef unsigned char byte;
|
|
|
--typedef unsigned short word;
|
|
|
--typedef unsigned long u32;
|
|
|
-+typedef unsigned char u8;
|
|
|
-+typedef unsigned short u16;
|
|
|
-+typedef unsigned long u32;
|
|
|
-
|
|
|
- #define DEFAULT_MAJOR_ROOT 0
|
|
|
- #define DEFAULT_MINOR_ROOT 0
|
|
|
-
|
|
|
--/* Minimal number of setup sectors (see also bootsect.S) */
|
|
|
--#define SETUP_SECTS 4
|
|
|
-+/* Minimal number of setup sectors */
|
|
|
-+#define SETUP_SECT_MIN 5
|
|
|
-+#define SETUP_SECT_MAX 64
|
|
|
-
|
|
|
--byte buf[1024];
|
|
|
--int fd;
|
|
|
-+/* This must be large enough to hold the entire setup */
|
|
|
-+u8 buf[SETUP_SECT_MAX*512];
|
|
|
- int is_big_kernel;
|
|
|
-
|
|
|
--void die(const char * str, ...)
|
|
|
-+static void die(const char * str, ...)
|
|
|
- {
|
|
|
- va_list args;
|
|
|
- va_start(args, str);
|
|
|
-@@ -57,15 +59,9 @@ void die(const char * str, ...)
|
|
|
- exit(1);
|
|
|
- }
|
|
|
-
|
|
|
--void file_open(const char *name)
|
|
|
-+static void usage(void)
|
|
|
- {
|
|
|
-- if ((fd = open(name, O_RDONLY, 0)) < 0)
|
|
|
-- die("Unable to open `%s': %m", name);
|
|
|
--}
|
|
|
--
|
|
|
--void usage(void)
|
|
|
--{
|
|
|
-- die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
|
|
|
-+ die("Usage: build [-b] setup system [rootdev] [> image]");
|
|
|
- }
|
|
|
-
|
|
|
- int main(int argc, char ** argv)
|
|
|
-@@ -73,27 +69,30 @@ int main(int argc, char ** argv)
|
|
|
- unsigned int i, sz, setup_sectors;
|
|
|
- int c;
|
|
|
- u32 sys_size;
|
|
|
-- byte major_root, minor_root;
|
|
|
-+ u8 major_root, minor_root;
|
|
|
- struct stat sb;
|
|
|
-+ FILE *file;
|
|
|
-+ int fd;
|
|
|
-+ void *kernel;
|
|
|
-
|
|
|
- if (argc > 2 && !strcmp(argv[1], "-b"))
|
|
|
- {
|
|
|
- is_big_kernel = 1;
|
|
|
- argc--, argv++;
|
|
|
- }
|
|
|
-- if ((argc < 4) || (argc > 5))
|
|
|
-+ if ((argc < 3) || (argc > 4))
|
|
|
- usage();
|
|
|
-- if (argc > 4) {
|
|
|
-- if (!strcmp(argv[4], "CURRENT")) {
|
|
|
-+ if (argc > 3) {
|
|
|
-+ if (!strcmp(argv[3], "CURRENT")) {
|
|
|
- if (stat("/", &sb)) {
|
|
|
- perror("/");
|
|
|
- die("Couldn't stat /");
|
|
|
- }
|
|
|
- major_root = major(sb.st_dev);
|
|
|
- minor_root = minor(sb.st_dev);
|
|
|
-- } else if (strcmp(argv[4], "FLOPPY")) {
|
|
|
-- if (stat(argv[4], &sb)) {
|
|
|
-- perror(argv[4]);
|
|
|
-+ } else if (strcmp(argv[3], "FLOPPY")) {
|
|
|
-+ if (stat(argv[3], &sb)) {
|
|
|
-+ perror(argv[3]);
|
|
|
- die("Couldn't stat root device.");
|
|
|
- }
|
|
|
- major_root = major(sb.st_rdev);
|
|
|
-@@ -108,79 +107,62 @@ int main(int argc, char ** argv)
|
|
|
- }
|
|
|
- fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
|
|
|
-
|
|
|
-- file_open(argv[1]);
|
|
|
-- i = read(fd, buf, sizeof(buf));
|
|
|
-- fprintf(stderr,"Boot sector %d bytes.\n",i);
|
|
|
-- if (i != 512)
|
|
|
-- die("Boot block must be exactly 512 bytes");
|
|
|
-+ /* Copy the setup code */
|
|
|
-+ file = fopen(argv[1], "r");
|
|
|
-+ if (!file)
|
|
|
-+ die("Unable to open `%s': %m", argv[1]);
|
|
|
-+ c = fread(buf, 1, sizeof(buf), file);
|
|
|
-+ if (ferror(file))
|
|
|
-+ die("read-error on `setup'");
|
|
|
-+ if (c < 1024)
|
|
|
-+ die("The setup must be at least 1024 bytes");
|
|
|
- if (buf[510] != 0x55 || buf[511] != 0xaa)
|
|
|
- die("Boot block hasn't got boot flag (0xAA55)");
|
|
|
-+ fclose(file);
|
|
|
-+
|
|
|
-+ /* Pad unused space with zeros */
|
|
|
-+ setup_sectors = (c + 511) / 512;
|
|
|
-+ if (setup_sectors < SETUP_SECT_MIN)
|
|
|
-+ setup_sectors = SETUP_SECT_MIN;
|
|
|
-+ i = setup_sectors*512;
|
|
|
-+ memset(buf+c, 0, i-c);
|
|
|
-+
|
|
|
-+ /* Set the default root device */
|
|
|
- buf[508] = minor_root;
|
|
|
- buf[509] = major_root;
|
|
|
-- if (write(1, buf, 512) != 512)
|
|
|
-- die("Write call failed");
|
|
|
-- close (fd);
|
|
|
--
|
|
|
-- file_open(argv[2]); /* Copy the setup code */
|
|
|
-- for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
|
|
|
-- if (write(1, buf, c) != c)
|
|
|
-- die("Write call failed");
|
|
|
-- if (c != 0)
|
|
|
-- die("read-error on `setup'");
|
|
|
-- close (fd);
|
|
|
-
|
|
|
-- setup_sectors = (i + 511) / 512; /* Pad unused space with zeros */
|
|
|
-- /* for compatibility with ancient versions of LILO. */
|
|
|
-- if (setup_sectors < SETUP_SECTS)
|
|
|
-- setup_sectors = SETUP_SECTS;
|
|
|
-- fprintf(stderr, "Setup is %d bytes.\n", i);
|
|
|
-- memset(buf, 0, sizeof(buf));
|
|
|
-- while (i < setup_sectors * 512) {
|
|
|
-- c = setup_sectors * 512 - i;
|
|
|
-- if (c > sizeof(buf))
|
|
|
-- c = sizeof(buf);
|
|
|
-- if (write(1, buf, c) != c)
|
|
|
-- die("Write call failed");
|
|
|
-- i += c;
|
|
|
-- }
|
|
|
-+ fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
|
|
|
-
|
|
|
-- file_open(argv[3]);
|
|
|
-- if (fstat (fd, &sb))
|
|
|
-- die("Unable to stat `%s': %m", argv[3]);
|
|
|
-+ /* Open and stat the kernel file */
|
|
|
-+ fd = open(argv[2], O_RDONLY);
|
|
|
-+ if (fd < 0)
|
|
|
-+ die("Unable to open `%s': %m", argv[2]);
|
|
|
-+ if (fstat(fd, &sb))
|
|
|
-+ die("Unable to stat `%s': %m", argv[2]);
|
|
|
- sz = sb.st_size;
|
|
|
-- fprintf (stderr, "System is %d kB\n", sz/1024);
|
|
|
-+ fprintf (stderr, "System is %d kB\n", (sz+1023)/1024);
|
|
|
-+ kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
|
|
|
-+ if (kernel == MAP_FAILED)
|
|
|
-+ die("Unable to mmap '%s': %m", argv[2]);
|
|
|
- sys_size = (sz + 15) / 16;
|
|
|
- if (!is_big_kernel && sys_size > DEF_SYSSIZE)
|
|
|
- die("System is too big. Try using bzImage or modules.");
|
|
|
-- while (sz > 0) {
|
|
|
-- int l, n;
|
|
|
-
|
|
|
-- l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
|
|
|
-- if ((n=read(fd, buf, l)) != l) {
|
|
|
-- if (n < 0)
|
|
|
-- die("Error reading %s: %m", argv[3]);
|
|
|
-- else
|
|
|
-- die("%s: Unexpected EOF", argv[3]);
|
|
|
-- }
|
|
|
-- if (write(1, buf, l) != l)
|
|
|
-- die("Write failed");
|
|
|
-- sz -= l;
|
|
|
-- }
|
|
|
-+ /* Patch the setup code with the appropriate size parameters */
|
|
|
-+ buf[0x1f1] = setup_sectors-1;
|
|
|
-+ buf[0x1f4] = sys_size;
|
|
|
-+ buf[0x1f5] = sys_size >> 8;
|
|
|
-+ buf[0x1f6] = sys_size >> 16;
|
|
|
-+ buf[0x1f7] = sys_size >> 24;
|
|
|
-+
|
|
|
-+ if (fwrite(buf, 1, i, stdout) != i)
|
|
|
-+ die("Writing setup failed");
|
|
|
-+
|
|
|
-+ /* Copy the kernel code */
|
|
|
-+ if (fwrite(kernel, 1, sz, stdout) != sz)
|
|
|
-+ die("Writing kernel failed");
|
|
|
- close(fd);
|
|
|
-
|
|
|
-- if (lseek(1, 497, SEEK_SET) != 497) /* Write sizes to the bootsector */
|
|
|
-- die("Output: seek failed");
|
|
|
-- buf[0] = setup_sectors;
|
|
|
-- if (write(1, buf, 1) != 1)
|
|
|
-- die("Write of setup sector count failed");
|
|
|
-- if (lseek(1, 500, SEEK_SET) != 500)
|
|
|
-- die("Output: seek failed");
|
|
|
-- buf[0] = (sys_size & 0xff);
|
|
|
-- buf[1] = ((sys_size >> 8) & 0xff);
|
|
|
-- buf[2] = ((sys_size >> 16) & 0xff);
|
|
|
-- buf[3] = ((sys_size >> 24) & 0xff);
|
|
|
-- if (write(1, buf, 4) != 4)
|
|
|
-- die("Write of image length failed");
|
|
|
--
|
|
|
-- return 0; /* Everything is OK */
|
|
|
-+ /* Everything is OK */
|
|
|
-+ return 0;
|
|
|
- }
|
|
|
-diff -puN /dev/null arch/i386/boot/tty.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/tty.c
|
|
|
-@@ -0,0 +1,112 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/tty.c
|
|
|
-+ *
|
|
|
-+ * Very simple screen I/O
|
|
|
-+ * XXX: Probably should add very simple serial I/O?
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * These functions are in .inittext so they can be used to signal
|
|
|
-+ * error during initialization.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+void __attribute__((section(".inittext"))) putchar(int ch)
|
|
|
-+{
|
|
|
-+ unsigned char c = ch;
|
|
|
-+
|
|
|
-+ if (c == '\n')
|
|
|
-+ putchar('\r'); /* \n -> \r\n */
|
|
|
-+
|
|
|
-+ /* int $0x10 is known to have bugs involving touching registers
|
|
|
-+ it shouldn't. Be extra conservative... */
|
|
|
-+ asm volatile("pushal; int $0x10; popal"
|
|
|
-+ : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
|
|
|
-+}
|
|
|
-+
|
|
|
-+void __attribute__((section(".inittext"))) puts(const char *str)
|
|
|
-+{
|
|
|
-+ int n = 0;
|
|
|
-+ while (*str) {
|
|
|
-+ putchar(*str++);
|
|
|
-+ n++;
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Read the CMOS clock through the BIOS, and return the
|
|
|
-+ * seconds in BCD.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+static u8 gettime(void)
|
|
|
-+{
|
|
|
-+ u16 ax = 0x0200;
|
|
|
-+ u16 cx, dx;
|
|
|
-+
|
|
|
-+ asm("int $0x1a"
|
|
|
-+ : "+a" (ax), "=c" (cx), "=d" (dx)
|
|
|
-+ : : "ebx", "esi", "edi");
|
|
|
-+
|
|
|
-+ return dx >> 8;
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Read from the keyboard
|
|
|
-+ */
|
|
|
-+int getchar(void)
|
|
|
-+{
|
|
|
-+ u16 ax = 0;
|
|
|
-+ asm("int $0x16" : "+a" (ax));
|
|
|
-+
|
|
|
-+ return ax & 0xff;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int kbd_pending(void)
|
|
|
-+{
|
|
|
-+ u8 pending;
|
|
|
-+ asm("int $0x16; setnz %0"
|
|
|
-+ : "=rm" (pending)
|
|
|
-+ : "a" (0x0100));
|
|
|
-+ return pending;
|
|
|
-+}
|
|
|
-+
|
|
|
-+void kbd_flush(void)
|
|
|
-+{
|
|
|
-+ for (;;) {
|
|
|
-+ if (!kbd_pending())
|
|
|
-+ break;
|
|
|
-+ getchar();
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+int getchar_timeout(void)
|
|
|
-+{
|
|
|
-+ int cnt = 30;
|
|
|
-+ int t0, t1;
|
|
|
-+
|
|
|
-+ t0 = gettime();
|
|
|
-+
|
|
|
-+ while (cnt) {
|
|
|
-+ if (kbd_pending())
|
|
|
-+ return getchar();
|
|
|
-+
|
|
|
-+ t1 = gettime();
|
|
|
-+ if (t0 != t1) {
|
|
|
-+ cnt--;
|
|
|
-+ t0 = t1;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ return 0; /* Timeout! */
|
|
|
-+}
|
|
|
-diff -puN /dev/null arch/i386/boot/version.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/version.c
|
|
|
-@@ -0,0 +1,23 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/version.c
|
|
|
-+ *
|
|
|
-+ * Kernel version string
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+#include <linux/utsrelease.h>
|
|
|
-+#include <linux/compile.h>
|
|
|
-+
|
|
|
-+const char kernel_version[] =
|
|
|
-+ UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") "
|
|
|
-+ UTS_VERSION;
|
|
|
-diff -puN /dev/null arch/i386/boot/vesa.h
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/vesa.h
|
|
|
-@@ -0,0 +1,79 @@
|
|
|
-+/* ----------------------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright 1999-2007 H. Peter Anvin - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This program is free software; you can redistribute it and/or modify
|
|
|
-+ * it under the terms of the GNU General Public License as published by
|
|
|
-+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
|
|
|
-+ * Boston MA 02111-1307, USA; either version 2 of the License, or
|
|
|
-+ * (at your option) any later version; incorporated herein by reference.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+#ifndef BOOT_VESA_H
|
|
|
-+#define BOOT_VESA_H
|
|
|
-+
|
|
|
-+typedef struct {
|
|
|
-+ u16 off, seg;
|
|
|
-+} far_ptr;
|
|
|
-+
|
|
|
-+/* VESA General Information table */
|
|
|
-+struct vesa_general_info {
|
|
|
-+ u32 signature; /* 0 Magic number = "VESA" */
|
|
|
-+ u16 version; /* 4 */
|
|
|
-+ far_ptr vendor_string; /* 6 */
|
|
|
-+ u32 capabilities; /* 10 */
|
|
|
-+ far_ptr video_mode_ptr; /* 14 */
|
|
|
-+ u16 total_memory; /* 18 */
|
|
|
-+
|
|
|
-+ u16 oem_software_rev; /* 20 */
|
|
|
-+ far_ptr oem_vendor_name_ptr; /* 22 */
|
|
|
-+ far_ptr oem_product_name_ptr; /* 26 */
|
|
|
-+ far_ptr oem_product_rev_ptr; /* 30 */
|
|
|
-+
|
|
|
-+ u8 reserved[222]; /* 34 */
|
|
|
-+ u8 oem_data[256]; /* 256 */
|
|
|
-+} __attribute__((packed));
|
|
|
-+
|
|
|
-+#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
|
|
|
-+#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24))
|
|
|
-+
|
|
|
-+struct vesa_mode_info {
|
|
|
-+ u16 mode_attr; /* 0 */
|
|
|
-+ u8 win_attr[2]; /* 2 */
|
|
|
-+ u16 win_grain; /* 4 */
|
|
|
-+ u16 win_size; /* 6 */
|
|
|
-+ u16 win_seg[2]; /* 8 */
|
|
|
-+ far_ptr win_scheme; /* 12 */
|
|
|
-+ u16 logical_scan; /* 16 */
|
|
|
-+
|
|
|
-+ u16 h_res; /* 18 */
|
|
|
-+ u16 v_res; /* 20 */
|
|
|
-+ u8 char_width; /* 22 */
|
|
|
-+ u8 char_height; /* 23 */
|
|
|
-+ u8 memory_planes; /* 24 */
|
|
|
-+ u8 bpp; /* 25 */
|
|
|
-+ u8 banks; /* 26 */
|
|
|
-+ u8 memory_layout; /* 27 */
|
|
|
-+ u8 bank_size; /* 28 */
|
|
|
-+ u8 image_planes; /* 29 */
|
|
|
-+ u8 page_function; /* 30 */
|
|
|
-+
|
|
|
-+ u8 rmask; /* 31 */
|
|
|
-+ u8 rpos; /* 32 */
|
|
|
-+ u8 gmask; /* 33 */
|
|
|
-+ u8 gpos; /* 34 */
|
|
|
-+ u8 bmask; /* 35 */
|
|
|
-+ u8 bpos; /* 36 */
|
|
|
-+ u8 resv_mask; /* 37 */
|
|
|
-+ u8 resv_pos; /* 38 */
|
|
|
-+ u8 dcm_info; /* 39 */
|
|
|
-+
|
|
|
-+ u32 lfb_ptr; /* 40 Linear frame buffer address */
|
|
|
-+ u32 offscreen_ptr; /* 44 Offscreen memory address */
|
|
|
-+ u16 offscreen_size; /* 48 */
|
|
|
-+
|
|
|
-+ u8 reserved[206]; /* 50 */
|
|
|
-+} __attribute__((packed));
|
|
|
-+
|
|
|
-+#endif /* LIB_SYS_VESA_H */
|
|
|
-diff -puN /dev/null arch/i386/boot/video-bios.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/video-bios.c
|
|
|
-@@ -0,0 +1,125 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/video-bios.c
|
|
|
-+ *
|
|
|
-+ * Standard video BIOS modes
|
|
|
-+ *
|
|
|
-+ * We have two options for this; silent and scanned.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+#include "video.h"
|
|
|
-+
|
|
|
-+__videocard video_bios;
|
|
|
-+
|
|
|
-+/* Set a conventional BIOS mode */
|
|
|
-+static int set_bios_mode(u8 mode);
|
|
|
-+
|
|
|
-+static int bios_set_mode(struct mode_info *mi)
|
|
|
-+{
|
|
|
-+ return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS);
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int set_bios_mode(u8 mode)
|
|
|
-+{
|
|
|
-+ u16 ax;
|
|
|
-+ u8 new_mode;
|
|
|
-+
|
|
|
-+ ax = mode; /* AH=0x00 Set Video Mode */
|
|
|
-+ asm volatile(INT10
|
|
|
-+ : "+a" (ax)
|
|
|
-+ : : "ebx", "ecx", "edx", "esi", "edi");
|
|
|
-+
|
|
|
-+ ax = 0x0f00; /* Get Current Video Mode */
|
|
|
-+ asm volatile(INT10
|
|
|
-+ : "+a" (ax)
|
|
|
-+ : : "ebx", "ecx", "edx", "esi", "edi");
|
|
|
-+
|
|
|
-+ do_restore = 1; /* Assume video contents was lost */
|
|
|
-+ new_mode = ax & 0x7f; /* Not all BIOSes are clean with the top bit */
|
|
|
-+
|
|
|
-+ if (new_mode == mode)
|
|
|
-+ return 0; /* Mode change OK */
|
|
|
-+
|
|
|
-+ if (new_mode != boot_params.screen_info.orig_video_mode) {
|
|
|
-+ /* Mode setting failed, but we didn't end up where we
|
|
|
-+ started. That's bad. Try to revert to the original
|
|
|
-+ video mode. */
|
|
|
-+ ax = boot_params.screen_info.orig_video_mode;
|
|
|
-+ asm volatile(INT10
|
|
|
-+ : "+a" (ax)
|
|
|
-+ : : "ebx", "ecx", "edx", "esi", "edi");
|
|
|
-+ }
|
|
|
-+ return -1;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int bios_probe(void)
|
|
|
-+{
|
|
|
-+ u8 mode;
|
|
|
-+ u8 saved_mode = boot_params.screen_info.orig_video_mode;
|
|
|
-+ u16 crtc;
|
|
|
-+ struct mode_info *mi;
|
|
|
-+ int nmodes = 0;
|
|
|
-+
|
|
|
-+ if (adapter != ADAPTER_EGA && adapter != ADAPTER_VGA)
|
|
|
-+ return 0;
|
|
|
-+
|
|
|
-+ set_fs(0);
|
|
|
-+ crtc = vga_crtc();
|
|
|
-+
|
|
|
-+ video_bios.modes = GET_HEAP(struct mode_info, 0);
|
|
|
-+
|
|
|
-+ for (mode = 0x14; mode <= 0x7f; mode++) {
|
|
|
-+ if (heap_free() < sizeof(struct mode_info))
|
|
|
-+ break;
|
|
|
-+
|
|
|
-+ if (mode_defined(VIDEO_FIRST_BIOS+mode))
|
|
|
-+ continue;
|
|
|
-+
|
|
|
-+ if (set_bios_mode(mode))
|
|
|
-+ continue;
|
|
|
-+
|
|
|
-+ /* Try to verify that it's a text mode. */
|
|
|
-+
|
|
|
-+ /* Attribute Controller: make graphics controller disabled */
|
|
|
-+ if (in_idx(0x3c0, 0x10) & 0x01)
|
|
|
-+ continue;
|
|
|
-+
|
|
|
-+ /* Graphics Controller: verify Alpha addressing enabled */
|
|
|
-+ if (in_idx(0x3ce, 0x06) & 0x01)
|
|
|
-+ continue;
|
|
|
-+
|
|
|
-+ /* CRTC cursor location low should be zero(?) */
|
|
|
-+ if (in_idx(crtc, 0x0f))
|
|
|
-+ continue;
|
|
|
-+
|
|
|
-+ mi = GET_HEAP(struct mode_info, 1);
|
|
|
-+ mi->mode = VIDEO_FIRST_BIOS+mode;
|
|
|
-+ mi->x = rdfs16(0x44a);
|
|
|
-+ mi->y = rdfs8(0x484)+1;
|
|
|
-+ nmodes++;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ set_bios_mode(saved_mode);
|
|
|
-+
|
|
|
-+ return nmodes;
|
|
|
-+}
|
|
|
-+
|
|
|
-+__videocard video_bios =
|
|
|
-+{
|
|
|
-+ .card_name = "BIOS (scanned)",
|
|
|
-+ .probe = bios_probe,
|
|
|
-+ .set_mode = bios_set_mode,
|
|
|
-+ .unsafe = 1,
|
|
|
-+ .xmode_first = VIDEO_FIRST_BIOS,
|
|
|
-+ .xmode_n = 0x80,
|
|
|
-+};
|
|
|
-diff -puN /dev/null arch/i386/boot/video-vesa.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/video-vesa.c
|
|
|
-@@ -0,0 +1,283 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/video-vesa.c
|
|
|
-+ *
|
|
|
-+ * VESA text modes
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+#include "video.h"
|
|
|
-+#include "vesa.h"
|
|
|
-+
|
|
|
-+/* VESA information */
|
|
|
-+static struct vesa_general_info vginfo;
|
|
|
-+static struct vesa_mode_info vminfo;
|
|
|
-+
|
|
|
-+__videocard video_vesa;
|
|
|
-+
|
|
|
-+static void vesa_store_mode_params_graphics(void);
|
|
|
-+
|
|
|
-+static int vesa_probe(void)
|
|
|
-+{
|
|
|
-+#ifdef CONFIG_VIDEO_VESA
|
|
|
-+ u16 ax;
|
|
|
-+ u16 mode;
|
|
|
-+ addr_t mode_ptr;
|
|
|
-+ struct mode_info *mi;
|
|
|
-+ int nmodes = 0;
|
|
|
-+
|
|
|
-+ video_vesa.modes = GET_HEAP(struct mode_info, 0);
|
|
|
-+
|
|
|
-+ vginfo.signature = VBE2_MAGIC;
|
|
|
-+
|
|
|
-+ /* Optimistically assume a VESA BIOS is register-clean... */
|
|
|
-+ ax = 0x4f00;
|
|
|
-+ asm("int $0x10" : "+a" (ax), "=m" (vginfo) : "D" (&vginfo));
|
|
|
-+
|
|
|
-+ if (ax != 0x004f ||
|
|
|
-+ vginfo.signature != VESA_MAGIC ||
|
|
|
-+ vginfo.version < 0x0102)
|
|
|
-+ return 0; /* Not present */
|
|
|
-+
|
|
|
-+ set_fs(vginfo.video_mode_ptr.seg);
|
|
|
-+ mode_ptr = vginfo.video_mode_ptr.off;
|
|
|
-+
|
|
|
-+ while ((mode = rdfs16(mode_ptr)) != 0xffff) {
|
|
|
-+ mode_ptr += 2;
|
|
|
-+
|
|
|
-+ if (heap_free() < sizeof(struct mode_info))
|
|
|
-+ break; /* Heap full, can't save mode info */
|
|
|
-+
|
|
|
-+ if (mode & ~0x1ff)
|
|
|
-+ continue;
|
|
|
-+
|
|
|
-+ memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
|
|
|
-+
|
|
|
-+ ax = 0x4f01;
|
|
|
-+ asm("int $0x10"
|
|
|
-+ : "+a" (ax), "=m" (vminfo)
|
|
|
-+ : "c" (mode), "D" (&vminfo));
|
|
|
-+
|
|
|
-+ if (ax != 0x004f)
|
|
|
-+ continue;
|
|
|
-+
|
|
|
-+ if ((vminfo.mode_attr & 0x15) == 0x05) {
|
|
|
-+ /* Text Mode, TTY BIOS supported,
|
|
|
-+ supported by hardware */
|
|
|
-+ mi = GET_HEAP(struct mode_info, 1);
|
|
|
-+ mi->mode = mode + VIDEO_FIRST_VESA;
|
|
|
-+ mi->x = vminfo.h_res;
|
|
|
-+ mi->y = vminfo.v_res;
|
|
|
-+ nmodes++;
|
|
|
-+ } else if ((vminfo.mode_attr & 0x99) == 0x99) {
|
|
|
-+#ifdef CONFIG_FB
|
|
|
-+ /* Graphics mode, color, linear frame buffer
|
|
|
-+ supported -- register the mode but hide from
|
|
|
-+ the menu. Only do this if framebuffer is
|
|
|
-+ configured, however, otherwise the user will
|
|
|
-+ be left without a screen. */
|
|
|
-+ mi = GET_HEAP(struct mode_info, 1);
|
|
|
-+ mi->mode = mode + VIDEO_FIRST_VESA;
|
|
|
-+ mi->x = mi->y = 0;
|
|
|
-+ nmodes++;
|
|
|
-+#endif
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ return nmodes;
|
|
|
-+#else
|
|
|
-+ return 0;
|
|
|
-+#endif
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int vesa_set_mode(struct mode_info *mode)
|
|
|
-+{
|
|
|
-+ u16 ax;
|
|
|
-+ int is_graphic;
|
|
|
-+ u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;
|
|
|
-+
|
|
|
-+ memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
|
|
|
-+
|
|
|
-+ ax = 0x4f01;
|
|
|
-+ asm("int $0x10"
|
|
|
-+ : "+a" (ax), "=m" (vminfo)
|
|
|
-+ : "c" (vesa_mode), "D" (&vminfo));
|
|
|
-+
|
|
|
-+ if (ax != 0x004f)
|
|
|
-+ return -1;
|
|
|
-+
|
|
|
-+ if ((vminfo.mode_attr & 0x15) == 0x05) {
|
|
|
-+ /* It's a supported text mode */
|
|
|
-+ is_graphic = 0;
|
|
|
-+ } else if ((vminfo.mode_attr & 0x99) == 0x99) {
|
|
|
-+ /* It's a graphics mode with linear frame buffer */
|
|
|
-+ is_graphic = 1;
|
|
|
-+ vesa_mode |= 0x4000; /* Request linear frame buffer */
|
|
|
-+ } else {
|
|
|
-+ return -1; /* Invalid mode */
|
|
|
-+ }
|
|
|
-+
|
|
|
-+
|
|
|
-+ ax = 0x4f02;
|
|
|
-+ asm volatile("int $0x10"
|
|
|
-+ : "+a" (ax)
|
|
|
-+ : "b" (vesa_mode), "D" (0));
|
|
|
-+
|
|
|
-+ if (ax != 0x004f)
|
|
|
-+ return -1;
|
|
|
-+
|
|
|
-+ graphic_mode = is_graphic;
|
|
|
-+ if (!is_graphic) {
|
|
|
-+ /* Text mode */
|
|
|
-+ force_x = mode->x;
|
|
|
-+ force_y = mode->y;
|
|
|
-+ do_restore = 1;
|
|
|
-+ } else {
|
|
|
-+ /* Graphics mode */
|
|
|
-+ vesa_store_mode_params_graphics();
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+
|
|
|
-+/* Switch DAC to 8-bit mode */
|
|
|
-+static void vesa_dac_set_8bits(void)
|
|
|
-+{
|
|
|
-+ u8 dac_size = 6;
|
|
|
-+
|
|
|
-+ /* If possible, switch the DAC to 8-bit mode */
|
|
|
-+ if (vginfo.capabilities & 1) {
|
|
|
-+ u16 ax, bx;
|
|
|
-+
|
|
|
-+ ax = 0x4f08;
|
|
|
-+ bx = 0x0800;
|
|
|
-+ asm volatile(INT10
|
|
|
-+ : "+a" (ax), "+b" (bx)
|
|
|
-+ : : "ecx", "edx", "esi", "edi");
|
|
|
-+
|
|
|
-+ if (ax == 0x004f)
|
|
|
-+ dac_size = bx >> 8;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Set the color sizes to the DAC size, and offsets to 0 */
|
|
|
-+ boot_params.screen_info.red_size = dac_size;
|
|
|
-+ boot_params.screen_info.green_size = dac_size;
|
|
|
-+ boot_params.screen_info.blue_size = dac_size;
|
|
|
-+ boot_params.screen_info.rsvd_size = dac_size;
|
|
|
-+
|
|
|
-+ boot_params.screen_info.red_pos = 0;
|
|
|
-+ boot_params.screen_info.green_pos = 0;
|
|
|
-+ boot_params.screen_info.blue_pos = 0;
|
|
|
-+ boot_params.screen_info.rsvd_pos = 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Save the VESA protected mode info */
|
|
|
-+static void vesa_store_pm_info(void)
|
|
|
-+{
|
|
|
-+ u16 ax, bx, di, es;
|
|
|
-+
|
|
|
-+ ax = 0x4f0a;
|
|
|
-+ bx = di = 0;
|
|
|
-+ asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
|
|
|
-+ : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
|
|
|
-+ : : "ecx", "esi");
|
|
|
-+
|
|
|
-+ if (ax != 0x004f)
|
|
|
-+ return;
|
|
|
-+
|
|
|
-+ boot_params.screen_info.vesapm_seg = es;
|
|
|
-+ boot_params.screen_info.vesapm_off = di;
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Save video mode parameters for graphics mode
|
|
|
-+ */
|
|
|
-+static void vesa_store_mode_params_graphics(void)
|
|
|
-+{
|
|
|
-+ /* Tell the kernel we're in VESA graphics mode */
|
|
|
-+ boot_params.screen_info.orig_video_isVGA = 0x23;
|
|
|
-+
|
|
|
-+ /* Mode parameters */
|
|
|
-+ boot_params.screen_info.vesa_attributes = vminfo.mode_attr;
|
|
|
-+ boot_params.screen_info.lfb_linelength = vminfo.logical_scan;
|
|
|
-+ boot_params.screen_info.lfb_width = vminfo.h_res;
|
|
|
-+ boot_params.screen_info.lfb_height = vminfo.v_res;
|
|
|
-+ boot_params.screen_info.lfb_depth = vminfo.bpp;
|
|
|
-+ boot_params.screen_info.pages = vminfo.image_planes;
|
|
|
-+ boot_params.screen_info.lfb_base = vminfo.lfb_ptr;
|
|
|
-+ memcpy(&boot_params.screen_info.red_size,
|
|
|
-+ &vminfo.rmask, 8);
|
|
|
-+
|
|
|
-+ /* General parameters */
|
|
|
-+ boot_params.screen_info.lfb_size = vginfo.total_memory;
|
|
|
-+
|
|
|
-+ if (vminfo.bpp <= 8)
|
|
|
-+ vesa_dac_set_8bits();
|
|
|
-+
|
|
|
-+ vesa_store_pm_info();
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Save EDID information for the kernel; this is invoked, separately,
|
|
|
-+ * after mode-setting.
|
|
|
-+ */
|
|
|
-+void vesa_store_edid(void)
|
|
|
-+{
|
|
|
-+#ifdef CONFIG_FIRMWARE_EDID
|
|
|
-+ u16 ax, bx, cx, dx, di;
|
|
|
-+
|
|
|
-+ /* Apparently used as a nonsense token... */
|
|
|
-+ memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info);
|
|
|
-+
|
|
|
-+ if (vginfo.version < 0x0200)
|
|
|
-+ return; /* EDID requires VBE 2.0+ */
|
|
|
-+
|
|
|
-+ ax = 0x4f15; /* VBE DDC */
|
|
|
-+ bx = 0x0000; /* Report DDC capabilities */
|
|
|
-+ cx = 0; /* Controller 0 */
|
|
|
-+ di = 0; /* ES:DI must be 0 by spec */
|
|
|
-+
|
|
|
-+ /* Note: The VBE DDC spec is different from the main VESA spec;
|
|
|
-+ we genuinely have to assume all registers are destroyed here. */
|
|
|
-+
|
|
|
-+ asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
|
|
|
-+ : "+a" (ax), "+b" (bx)
|
|
|
-+ : "c" (cx), "D" (di)
|
|
|
-+ : "esi");
|
|
|
-+
|
|
|
-+ if (ax != 0x004f)
|
|
|
-+ return; /* No EDID */
|
|
|
-+
|
|
|
-+ /* BH = time in seconds to transfer EDD information */
|
|
|
-+ /* BL = DDC level supported */
|
|
|
-+
|
|
|
-+ ax = 0x4f15; /* VBE DDC */
|
|
|
-+ bx = 0x0001; /* Read EDID */
|
|
|
-+ cx = 0; /* Controller 0 */
|
|
|
-+ dx = 0; /* EDID block number */
|
|
|
-+ di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
|
|
|
-+ asm(INT10
|
|
|
-+ : "+a" (ax), "+b" (bx), "+d" (dx)
|
|
|
-+ : "c" (cx), "D" (di)
|
|
|
-+ : "esi");
|
|
|
-+#endif /* CONFIG_FIRMWARE_EDID */
|
|
|
-+}
|
|
|
-+
|
|
|
-+__videocard video_vesa =
|
|
|
-+{
|
|
|
-+ .card_name = "VESA",
|
|
|
-+ .probe = vesa_probe,
|
|
|
-+ .set_mode = vesa_set_mode,
|
|
|
-+ .xmode_first = VIDEO_FIRST_VESA,
|
|
|
-+ .xmode_n = 0x200,
|
|
|
-+};
|
|
|
-diff -puN /dev/null arch/i386/boot/video-vga.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/video-vga.c
|
|
|
-@@ -0,0 +1,260 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/video-vga.c
|
|
|
-+ *
|
|
|
-+ * Common all-VGA modes
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+#include "video.h"
|
|
|
-+
|
|
|
-+static struct mode_info vga_modes[] = {
|
|
|
-+ { VIDEO_80x25, 80, 25 },
|
|
|
-+ { VIDEO_8POINT, 80, 50 },
|
|
|
-+ { VIDEO_80x43, 80, 43 },
|
|
|
-+ { VIDEO_80x28, 80, 28 },
|
|
|
-+ { VIDEO_80x30, 80, 30 },
|
|
|
-+ { VIDEO_80x34, 80, 34 },
|
|
|
-+ { VIDEO_80x60, 80, 60 },
|
|
|
-+};
|
|
|
-+
|
|
|
-+static struct mode_info ega_modes[] = {
|
|
|
-+ { VIDEO_80x25, 80, 25 },
|
|
|
-+ { VIDEO_8POINT, 80, 43 },
|
|
|
-+};
|
|
|
-+
|
|
|
-+static struct mode_info cga_modes[] = {
|
|
|
-+ { VIDEO_80x25, 80, 25 },
|
|
|
-+};
|
|
|
-+
|
|
|
-+__videocard video_vga;
|
|
|
-+
|
|
|
-+/* Set basic 80x25 mode */
|
|
|
-+static u8 vga_set_basic_mode(void)
|
|
|
-+{
|
|
|
-+ u16 ax;
|
|
|
-+ u8 rows;
|
|
|
-+ u8 mode;
|
|
|
-+
|
|
|
-+#ifdef CONFIG_VIDEO_400_HACK
|
|
|
-+ if (adapter >= ADAPTER_VGA) {
|
|
|
-+ asm(INT10
|
|
|
-+ : : "a" (0x1202), "b" (0x0030)
|
|
|
-+ : "ecx", "edx", "esi", "edi");
|
|
|
-+ }
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+ ax = 0x0f00;
|
|
|
-+ asm(INT10
|
|
|
-+ : "+a" (ax)
|
|
|
-+ : : "ebx", "ecx", "edx", "esi", "edi");
|
|
|
-+
|
|
|
-+ mode = (u8)ax;
|
|
|
-+
|
|
|
-+ set_fs(0);
|
|
|
-+ rows = rdfs8(0x484); /* rows minus one */
|
|
|
-+
|
|
|
-+#ifndef CONFIG_VIDEO_400_HACK
|
|
|
-+ if ((ax == 0x5003 || ax == 0x5007) &&
|
|
|
-+ (rows == 0 || rows == 24))
|
|
|
-+ return mode;
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+ if (mode != 3 && mode != 7)
|
|
|
-+ mode = 3;
|
|
|
-+
|
|
|
-+ /* Set the mode */
|
|
|
-+ asm volatile(INT10
|
|
|
-+ : : "a" (mode)
|
|
|
-+ : "ebx", "ecx", "edx", "esi", "edi");
|
|
|
-+ do_restore = 1;
|
|
|
-+ return mode;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void vga_set_8font(void)
|
|
|
-+{
|
|
|
-+ /* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
|
|
|
-+
|
|
|
-+ /* Set 8x8 font */
|
|
|
-+ asm volatile(INT10 : : "a" (0x1112), "b" (0));
|
|
|
-+
|
|
|
-+ /* Use alternate print screen */
|
|
|
-+ asm volatile(INT10 : : "a" (0x1200), "b" (0x20));
|
|
|
-+
|
|
|
-+ /* Turn off cursor emulation */
|
|
|
-+ asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
|
|
|
-+
|
|
|
-+ /* Cursor is scan lines 6-7 */
|
|
|
-+ asm volatile(INT10 : : "a" (0x0100), "c" (0x0607));
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void vga_set_14font(void)
|
|
|
-+{
|
|
|
-+ /* Set 9x14 font - 80x28 on VGA */
|
|
|
-+
|
|
|
-+ /* Set 9x14 font */
|
|
|
-+ asm volatile(INT10 : : "a" (0x1111), "b" (0));
|
|
|
-+
|
|
|
-+ /* Turn off cursor emulation */
|
|
|
-+ asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
|
|
|
-+
|
|
|
-+ /* Cursor is scan lines 11-12 */
|
|
|
-+ asm volatile(INT10 : : "a" (0x0100), "c" (0x0b0c));
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void vga_set_80x43(void)
|
|
|
-+{
|
|
|
-+ /* Set 80x43 mode on VGA (not EGA) */
|
|
|
-+
|
|
|
-+ /* Set 350 scans */
|
|
|
-+ asm volatile(INT10 : : "a" (0x1201), "b" (0x30));
|
|
|
-+
|
|
|
-+ /* Reset video mode */
|
|
|
-+ asm volatile(INT10 : : "a" (0x0003));
|
|
|
-+
|
|
|
-+ vga_set_8font();
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* I/O address of the VGA CRTC */
|
|
|
-+u16 vga_crtc(void)
|
|
|
-+{
|
|
|
-+ return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void vga_set_480_scanlines(int end)
|
|
|
-+{
|
|
|
-+ u16 crtc;
|
|
|
-+ u8 csel;
|
|
|
-+
|
|
|
-+ crtc = vga_crtc();
|
|
|
-+
|
|
|
-+ out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */
|
|
|
-+ out_idx(0x0b, crtc, 0x06); /* Vertical total */
|
|
|
-+ out_idx(0x3e, crtc, 0x07); /* Vertical overflow */
|
|
|
-+ out_idx(0xea, crtc, 0x10); /* Vertical sync start */
|
|
|
-+ out_idx(end, crtc, 0x12); /* Vertical display end */
|
|
|
-+ out_idx(0xe7, crtc, 0x15); /* Vertical blank start */
|
|
|
-+ out_idx(0x04, crtc, 0x16); /* Vertical blank end */
|
|
|
-+ csel = inb(0x3cc);
|
|
|
-+ csel &= 0x0d;
|
|
|
-+ csel |= 0xe2;
|
|
|
-+ outb(csel, 0x3cc);
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void vga_set_80x30(void)
|
|
|
-+{
|
|
|
-+ vga_set_480_scanlines(0xdf);
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void vga_set_80x34(void)
|
|
|
-+{
|
|
|
-+ vga_set_14font();
|
|
|
-+ vga_set_480_scanlines(0xdb);
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void vga_set_80x60(void)
|
|
|
-+{
|
|
|
-+ vga_set_8font();
|
|
|
-+ vga_set_480_scanlines(0xdf);
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int vga_set_mode(struct mode_info *mode)
|
|
|
-+{
|
|
|
-+ /* Set the basic mode */
|
|
|
-+ vga_set_basic_mode();
|
|
|
-+
|
|
|
-+ /* Override a possibly broken BIOS */
|
|
|
-+ force_x = mode->x;
|
|
|
-+ force_y = mode->y;
|
|
|
-+
|
|
|
-+ switch (mode->mode) {
|
|
|
-+ case VIDEO_80x25:
|
|
|
-+ break;
|
|
|
-+ case VIDEO_8POINT:
|
|
|
-+ vga_set_8font();
|
|
|
-+ break;
|
|
|
-+ case VIDEO_80x43:
|
|
|
-+ vga_set_80x43();
|
|
|
-+ break;
|
|
|
-+ case VIDEO_80x28:
|
|
|
-+ vga_set_14font();
|
|
|
-+ break;
|
|
|
-+ case VIDEO_80x30:
|
|
|
-+ vga_set_80x30();
|
|
|
-+ break;
|
|
|
-+ case VIDEO_80x34:
|
|
|
-+ vga_set_80x34();
|
|
|
-+ break;
|
|
|
-+ case VIDEO_80x60:
|
|
|
-+ vga_set_80x60();
|
|
|
-+ break;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Note: this probe includes basic information required by all
|
|
|
-+ * systems. It should be executed first, by making sure
|
|
|
-+ * video-vga.c is listed first in the Makefile.
|
|
|
-+ */
|
|
|
-+static int vga_probe(void)
|
|
|
-+{
|
|
|
-+ static const char *card_name[] = {
|
|
|
-+ "CGA/MDA/HGC", "EGA", "VGA"
|
|
|
-+ };
|
|
|
-+ static struct mode_info *mode_lists[] = {
|
|
|
-+ cga_modes,
|
|
|
-+ ega_modes,
|
|
|
-+ vga_modes,
|
|
|
-+ };
|
|
|
-+ static int mode_count[] = {
|
|
|
-+ sizeof(cga_modes)/sizeof(struct mode_info),
|
|
|
-+ sizeof(ega_modes)/sizeof(struct mode_info),
|
|
|
-+ sizeof(vga_modes)/sizeof(struct mode_info),
|
|
|
-+ };
|
|
|
-+ u8 vga_flag;
|
|
|
-+
|
|
|
-+ asm(INT10
|
|
|
-+ : "=b" (boot_params.screen_info.orig_video_ega_bx)
|
|
|
-+ : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
|
|
|
-+ : "ecx", "edx", "esi", "edi");
|
|
|
-+
|
|
|
-+ /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
|
|
|
-+ if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
|
|
|
-+ /* EGA/VGA */
|
|
|
-+ asm(INT10
|
|
|
-+ : "=a" (vga_flag)
|
|
|
-+ : "a" (0x1a00)
|
|
|
-+ : "ebx", "ecx", "edx", "esi", "edi");
|
|
|
-+
|
|
|
-+ if (vga_flag == 0x1a) {
|
|
|
-+ adapter = ADAPTER_VGA;
|
|
|
-+ boot_params.screen_info.orig_video_isVGA = 1;
|
|
|
-+ } else {
|
|
|
-+ adapter = ADAPTER_EGA;
|
|
|
-+ }
|
|
|
-+ } else {
|
|
|
-+ adapter = ADAPTER_CGA;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ video_vga.modes = mode_lists[adapter];
|
|
|
-+ video_vga.card_name = card_name[adapter];
|
|
|
-+ return mode_count[adapter];
|
|
|
-+}
|
|
|
-+
|
|
|
-+__videocard video_vga =
|
|
|
-+{
|
|
|
-+ .card_name = "VGA",
|
|
|
-+ .probe = vga_probe,
|
|
|
-+ .set_mode = vga_set_mode,
|
|
|
-+};
|
|
|
-diff -puN arch/i386/boot/video.S~git-newsetup /dev/null
|
|
|
---- a/arch/i386/boot/video.S
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,2043 +0,0 @@
|
|
|
--/* video.S
|
|
|
-- *
|
|
|
-- * Display adapter & video mode setup, version 2.13 (14-May-99)
|
|
|
-- *
|
|
|
-- * Copyright (C) 1995 -- 1998 Martin Mares <[email protected]>
|
|
|
-- * Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
|
|
|
-- *
|
|
|
-- * Rewritten to use GNU 'as' by Chris Noe <[email protected]> May 1999
|
|
|
-- *
|
|
|
-- * For further information, look at Documentation/svga.txt.
|
|
|
-- *
|
|
|
-- */
|
|
|
--
|
|
|
--/* Enable autodetection of SVGA adapters and modes. */
|
|
|
--#undef CONFIG_VIDEO_SVGA
|
|
|
--
|
|
|
--/* Enable autodetection of VESA modes */
|
|
|
--#define CONFIG_VIDEO_VESA
|
|
|
--
|
|
|
--/* Enable compacting of mode table */
|
|
|
--#define CONFIG_VIDEO_COMPACT
|
|
|
--
|
|
|
--/* Retain screen contents when switching modes */
|
|
|
--#define CONFIG_VIDEO_RETAIN
|
|
|
--
|
|
|
--/* Enable local mode list */
|
|
|
--#undef CONFIG_VIDEO_LOCAL
|
|
|
--
|
|
|
--/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
|
|
|
--#undef CONFIG_VIDEO_400_HACK
|
|
|
--
|
|
|
--/* Hack that lets you force specific BIOS mode ID and specific dimensions */
|
|
|
--#undef CONFIG_VIDEO_GFX_HACK
|
|
|
--#define VIDEO_GFX_BIOS_AX 0x4f02 /* 800x600 on ThinkPad */
|
|
|
--#define VIDEO_GFX_BIOS_BX 0x0102
|
|
|
--#define VIDEO_GFX_DUMMY_RESOLUTION 0x6425 /* 100x37 */
|
|
|
--
|
|
|
--/* This code uses an extended set of video mode numbers. These include:
|
|
|
-- * Aliases for standard modes
|
|
|
-- * NORMAL_VGA (-1)
|
|
|
-- * EXTENDED_VGA (-2)
|
|
|
-- * ASK_VGA (-3)
|
|
|
-- * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
|
|
|
-- * of compatibility when extending the table. These are between 0x00 and 0xff.
|
|
|
-- */
|
|
|
--#define VIDEO_FIRST_MENU 0x0000
|
|
|
--
|
|
|
--/* Standard BIOS video modes (BIOS number + 0x0100) */
|
|
|
--#define VIDEO_FIRST_BIOS 0x0100
|
|
|
--
|
|
|
--/* VESA BIOS video modes (VESA number + 0x0200) */
|
|
|
--#define VIDEO_FIRST_VESA 0x0200
|
|
|
--
|
|
|
--/* Video7 special modes (BIOS number + 0x0900) */
|
|
|
--#define VIDEO_FIRST_V7 0x0900
|
|
|
--
|
|
|
--/* Special video modes */
|
|
|
--#define VIDEO_FIRST_SPECIAL 0x0f00
|
|
|
--#define VIDEO_80x25 0x0f00
|
|
|
--#define VIDEO_8POINT 0x0f01
|
|
|
--#define VIDEO_80x43 0x0f02
|
|
|
--#define VIDEO_80x28 0x0f03
|
|
|
--#define VIDEO_CURRENT_MODE 0x0f04
|
|
|
--#define VIDEO_80x30 0x0f05
|
|
|
--#define VIDEO_80x34 0x0f06
|
|
|
--#define VIDEO_80x60 0x0f07
|
|
|
--#define VIDEO_GFX_HACK 0x0f08
|
|
|
--#define VIDEO_LAST_SPECIAL 0x0f09
|
|
|
--
|
|
|
--/* Video modes given by resolution */
|
|
|
--#define VIDEO_FIRST_RESOLUTION 0x1000
|
|
|
--
|
|
|
--/* The "recalculate timings" flag */
|
|
|
--#define VIDEO_RECALC 0x8000
|
|
|
--
|
|
|
--/* Positions of various video parameters passed to the kernel */
|
|
|
--/* (see also include/linux/tty.h) */
|
|
|
--#define PARAM_CURSOR_POS 0x00
|
|
|
--#define PARAM_VIDEO_PAGE 0x04
|
|
|
--#define PARAM_VIDEO_MODE 0x06
|
|
|
--#define PARAM_VIDEO_COLS 0x07
|
|
|
--#define PARAM_VIDEO_EGA_BX 0x0a
|
|
|
--#define PARAM_VIDEO_LINES 0x0e
|
|
|
--#define PARAM_HAVE_VGA 0x0f
|
|
|
--#define PARAM_FONT_POINTS 0x10
|
|
|
--
|
|
|
--#define PARAM_LFB_WIDTH 0x12
|
|
|
--#define PARAM_LFB_HEIGHT 0x14
|
|
|
--#define PARAM_LFB_DEPTH 0x16
|
|
|
--#define PARAM_LFB_BASE 0x18
|
|
|
--#define PARAM_LFB_SIZE 0x1c
|
|
|
--#define PARAM_LFB_LINELENGTH 0x24
|
|
|
--#define PARAM_LFB_COLORS 0x26
|
|
|
--#define PARAM_VESAPM_SEG 0x2e
|
|
|
--#define PARAM_VESAPM_OFF 0x30
|
|
|
--#define PARAM_LFB_PAGES 0x32
|
|
|
--#define PARAM_VESA_ATTRIB 0x34
|
|
|
--#define PARAM_CAPABILITIES 0x36
|
|
|
--
|
|
|
--/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
|
|
|
--#ifdef CONFIG_VIDEO_RETAIN
|
|
|
--#define DO_STORE call store_screen
|
|
|
--#else
|
|
|
--#define DO_STORE
|
|
|
--#endif /* CONFIG_VIDEO_RETAIN */
|
|
|
--
|
|
|
--# This is the main entry point called by setup.S
|
|
|
--# %ds *must* be pointing to the bootsector
|
|
|
--video: pushw %ds # We use different segments
|
|
|
-- pushw %ds # FS contains original DS
|
|
|
-- popw %fs
|
|
|
-- pushw %cs # DS is equal to CS
|
|
|
-- popw %ds
|
|
|
-- pushw %cs # ES is equal to CS
|
|
|
-- popw %es
|
|
|
-- xorw %ax, %ax
|
|
|
-- movw %ax, %gs # GS is zero
|
|
|
-- cld
|
|
|
-- call basic_detect # Basic adapter type testing (EGA/VGA/MDA/CGA)
|
|
|
--#ifdef CONFIG_VIDEO_SELECT
|
|
|
-- movw %fs:(0x01fa), %ax # User selected video mode
|
|
|
-- cmpw $ASK_VGA, %ax # Bring up the menu
|
|
|
-- jz vid2
|
|
|
--
|
|
|
-- call mode_set # Set the mode
|
|
|
-- jc vid1
|
|
|
--
|
|
|
-- leaw badmdt, %si # Invalid mode ID
|
|
|
-- call prtstr
|
|
|
--vid2: call mode_menu
|
|
|
--vid1:
|
|
|
--#ifdef CONFIG_VIDEO_RETAIN
|
|
|
-- call restore_screen # Restore screen contents
|
|
|
--#endif /* CONFIG_VIDEO_RETAIN */
|
|
|
-- call store_edid
|
|
|
--#endif /* CONFIG_VIDEO_SELECT */
|
|
|
-- call mode_params # Store mode parameters
|
|
|
-- popw %ds # Restore original DS
|
|
|
-- ret
|
|
|
--
|
|
|
--# Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel.
|
|
|
--basic_detect:
|
|
|
-- movb $0, %fs:(PARAM_HAVE_VGA)
|
|
|
-- movb $0x12, %ah # Check EGA/VGA
|
|
|
-- movb $0x10, %bl
|
|
|
-- int $0x10
|
|
|
-- movw %bx, %fs:(PARAM_VIDEO_EGA_BX) # Identifies EGA to the kernel
|
|
|
-- cmpb $0x10, %bl # No, it's a CGA/MDA/HGA card.
|
|
|
-- je basret
|
|
|
--
|
|
|
-- incb adapter
|
|
|
-- movw $0x1a00, %ax # Check EGA or VGA?
|
|
|
-- int $0x10
|
|
|
-- cmpb $0x1a, %al # 1a means VGA...
|
|
|
-- jne basret # anything else is EGA.
|
|
|
--
|
|
|
-- incb %fs:(PARAM_HAVE_VGA) # We've detected a VGA
|
|
|
-- incb adapter
|
|
|
--basret: ret
|
|
|
--
|
|
|
--# Store the video mode parameters for later usage by the kernel.
|
|
|
--# This is done by asking the BIOS except for the rows/columns
|
|
|
--# parameters in the default 80x25 mode -- these are set directly,
|
|
|
--# because some very obscure BIOSes supply insane values.
|
|
|
--mode_params:
|
|
|
--#ifdef CONFIG_VIDEO_SELECT
|
|
|
-- cmpb $0, graphic_mode
|
|
|
-- jnz mopar_gr
|
|
|
--#endif
|
|
|
-- movb $0x03, %ah # Read cursor position
|
|
|
-- xorb %bh, %bh
|
|
|
-- int $0x10
|
|
|
-- movw %dx, %fs:(PARAM_CURSOR_POS)
|
|
|
-- movb $0x0f, %ah # Read page/mode/width
|
|
|
-- int $0x10
|
|
|
-- movw %bx, %fs:(PARAM_VIDEO_PAGE)
|
|
|
-- movw %ax, %fs:(PARAM_VIDEO_MODE) # Video mode and screen width
|
|
|
-- cmpb $0x7, %al # MDA/HGA => segment differs
|
|
|
-- jnz mopar0
|
|
|
--
|
|
|
-- movw $0xb000, video_segment
|
|
|
--mopar0: movw %gs:(0x485), %ax # Font size
|
|
|
-- movw %ax, %fs:(PARAM_FONT_POINTS) # (valid only on EGA/VGA)
|
|
|
-- movw force_size, %ax # Forced size?
|
|
|
-- orw %ax, %ax
|
|
|
-- jz mopar1
|
|
|
--
|
|
|
-- movb %ah, %fs:(PARAM_VIDEO_COLS)
|
|
|
-- movb %al, %fs:(PARAM_VIDEO_LINES)
|
|
|
-- ret
|
|
|
--
|
|
|
--mopar1: movb $25, %al
|
|
|
-- cmpb $0, adapter # If we are on CGA/MDA/HGA, the
|
|
|
-- jz mopar2 # screen must have 25 lines.
|
|
|
--
|
|
|
-- movb %gs:(0x484), %al # On EGA/VGA, use the EGA+ BIOS
|
|
|
-- incb %al # location of max lines.
|
|
|
--mopar2: movb %al, %fs:(PARAM_VIDEO_LINES)
|
|
|
-- ret
|
|
|
--
|
|
|
--#ifdef CONFIG_VIDEO_SELECT
|
|
|
--# Fetching of VESA frame buffer parameters
|
|
|
--mopar_gr:
|
|
|
-- leaw modelist+1024, %di
|
|
|
-- movb $0x23, %fs:(PARAM_HAVE_VGA)
|
|
|
-- movw 16(%di), %ax
|
|
|
-- movw %ax, %fs:(PARAM_LFB_LINELENGTH)
|
|
|
-- movw 18(%di), %ax
|
|
|
-- movw %ax, %fs:(PARAM_LFB_WIDTH)
|
|
|
-- movw 20(%di), %ax
|
|
|
-- movw %ax, %fs:(PARAM_LFB_HEIGHT)
|
|
|
-- movb 25(%di), %al
|
|
|
-- movb $0, %ah
|
|
|
-- movw %ax, %fs:(PARAM_LFB_DEPTH)
|
|
|
-- movb 29(%di), %al
|
|
|
-- movb $0, %ah
|
|
|
-- movw %ax, %fs:(PARAM_LFB_PAGES)
|
|
|
-- movl 40(%di), %eax
|
|
|
-- movl %eax, %fs:(PARAM_LFB_BASE)
|
|
|
-- movl 31(%di), %eax
|
|
|
-- movl %eax, %fs:(PARAM_LFB_COLORS)
|
|
|
-- movl 35(%di), %eax
|
|
|
-- movl %eax, %fs:(PARAM_LFB_COLORS+4)
|
|
|
-- movw 0(%di), %ax
|
|
|
-- movw %ax, %fs:(PARAM_VESA_ATTRIB)
|
|
|
--
|
|
|
--# get video mem size
|
|
|
-- leaw modelist+1024, %di
|
|
|
-- movw $0x4f00, %ax
|
|
|
-- int $0x10
|
|
|
-- xorl %eax, %eax
|
|
|
-- movw 18(%di), %ax
|
|
|
-- movl %eax, %fs:(PARAM_LFB_SIZE)
|
|
|
--
|
|
|
--# store mode capabilities
|
|
|
-- movl 10(%di), %eax
|
|
|
-- movl %eax, %fs:(PARAM_CAPABILITIES)
|
|
|
--
|
|
|
--# switching the DAC to 8-bit is for <= 8 bpp only
|
|
|
-- movw %fs:(PARAM_LFB_DEPTH), %ax
|
|
|
-- cmpw $8, %ax
|
|
|
-- jg dac_done
|
|
|
--
|
|
|
--# get DAC switching capability
|
|
|
-- xorl %eax, %eax
|
|
|
-- movb 10(%di), %al
|
|
|
-- testb $1, %al
|
|
|
-- jz dac_set
|
|
|
--
|
|
|
--# attempt to switch DAC to 8-bit
|
|
|
-- movw $0x4f08, %ax
|
|
|
-- movw $0x0800, %bx
|
|
|
-- int $0x10
|
|
|
-- cmpw $0x004f, %ax
|
|
|
-- jne dac_set
|
|
|
-- movb %bh, dac_size # store actual DAC size
|
|
|
--
|
|
|
--dac_set:
|
|
|
--# set color size to DAC size
|
|
|
-- movb dac_size, %al
|
|
|
-- movb %al, %fs:(PARAM_LFB_COLORS+0)
|
|
|
-- movb %al, %fs:(PARAM_LFB_COLORS+2)
|
|
|
-- movb %al, %fs:(PARAM_LFB_COLORS+4)
|
|
|
-- movb %al, %fs:(PARAM_LFB_COLORS+6)
|
|
|
--
|
|
|
--# set color offsets to 0
|
|
|
-- movb $0, %fs:(PARAM_LFB_COLORS+1)
|
|
|
-- movb $0, %fs:(PARAM_LFB_COLORS+3)
|
|
|
-- movb $0, %fs:(PARAM_LFB_COLORS+5)
|
|
|
-- movb $0, %fs:(PARAM_LFB_COLORS+7)
|
|
|
--
|
|
|
--dac_done:
|
|
|
--# get protected mode interface informations
|
|
|
-- movw $0x4f0a, %ax
|
|
|
-- xorw %bx, %bx
|
|
|
-- xorw %di, %di
|
|
|
-- int $0x10
|
|
|
-- cmp $0x004f, %ax
|
|
|
-- jnz no_pm
|
|
|
--
|
|
|
-- movw %es, %fs:(PARAM_VESAPM_SEG)
|
|
|
-- movw %di, %fs:(PARAM_VESAPM_OFF)
|
|
|
--no_pm: ret
|
|
|
--
|
|
|
--# The video mode menu
|
|
|
--mode_menu:
|
|
|
-- leaw keymsg, %si # "Return/Space/Timeout" message
|
|
|
-- call prtstr
|
|
|
-- call flush
|
|
|
--nokey: call getkt
|
|
|
--
|
|
|
-- cmpb $0x0d, %al # ENTER ?
|
|
|
-- je listm # yes - manual mode selection
|
|
|
--
|
|
|
-- cmpb $0x20, %al # SPACE ?
|
|
|
-- je defmd1 # no - repeat
|
|
|
--
|
|
|
-- call beep
|
|
|
-- jmp nokey
|
|
|
--
|
|
|
--defmd1: ret # No mode chosen? Default 80x25
|
|
|
--
|
|
|
--listm: call mode_table # List mode table
|
|
|
--listm0: leaw name_bann, %si # Print adapter name
|
|
|
-- call prtstr
|
|
|
-- movw card_name, %si
|
|
|
-- orw %si, %si
|
|
|
-- jnz an2
|
|
|
--
|
|
|
-- movb adapter, %al
|
|
|
-- leaw old_name, %si
|
|
|
-- orb %al, %al
|
|
|
-- jz an1
|
|
|
--
|
|
|
-- leaw ega_name, %si
|
|
|
-- decb %al
|
|
|
-- jz an1
|
|
|
--
|
|
|
-- leaw vga_name, %si
|
|
|
-- jmp an1
|
|
|
--
|
|
|
--an2: call prtstr
|
|
|
-- leaw svga_name, %si
|
|
|
--an1: call prtstr
|
|
|
-- leaw listhdr, %si # Table header
|
|
|
-- call prtstr
|
|
|
-- movb $0x30, %dl # DL holds mode number
|
|
|
-- leaw modelist, %si
|
|
|
--lm1: cmpw $ASK_VGA, (%si) # End?
|
|
|
-- jz lm2
|
|
|
--
|
|
|
-- movb %dl, %al # Menu selection number
|
|
|
-- call prtchr
|
|
|
-- call prtsp2
|
|
|
-- lodsw
|
|
|
-- call prthw # Mode ID
|
|
|
-- call prtsp2
|
|
|
-- movb 0x1(%si), %al
|
|
|
-- call prtdec # Rows
|
|
|
-- movb $0x78, %al # the letter 'x'
|
|
|
-- call prtchr
|
|
|
-- lodsw
|
|
|
-- call prtdec # Columns
|
|
|
-- movb $0x0d, %al # New line
|
|
|
-- call prtchr
|
|
|
-- movb $0x0a, %al
|
|
|
-- call prtchr
|
|
|
-- incb %dl # Next character
|
|
|
-- cmpb $0x3a, %dl
|
|
|
-- jnz lm1
|
|
|
--
|
|
|
-- movb $0x61, %dl
|
|
|
-- jmp lm1
|
|
|
--
|
|
|
--lm2: leaw prompt, %si # Mode prompt
|
|
|
-- call prtstr
|
|
|
-- leaw edit_buf, %di # Editor buffer
|
|
|
--lm3: call getkey
|
|
|
-- cmpb $0x0d, %al # Enter?
|
|
|
-- jz lment
|
|
|
--
|
|
|
-- cmpb $0x08, %al # Backspace?
|
|
|
-- jz lmbs
|
|
|
--
|
|
|
-- cmpb $0x20, %al # Printable?
|
|
|
-- jc lm3
|
|
|
--
|
|
|
-- cmpw $edit_buf+4, %di # Enough space?
|
|
|
-- jz lm3
|
|
|
--
|
|
|
-- stosb
|
|
|
-- call prtchr
|
|
|
-- jmp lm3
|
|
|
--
|
|
|
--lmbs: cmpw $edit_buf, %di # Backspace
|
|
|
-- jz lm3
|
|
|
--
|
|
|
-- decw %di
|
|
|
-- movb $0x08, %al
|
|
|
-- call prtchr
|
|
|
-- call prtspc
|
|
|
-- movb $0x08, %al
|
|
|
-- call prtchr
|
|
|
-- jmp lm3
|
|
|
--
|
|
|
--lment: movb $0, (%di)
|
|
|
-- leaw crlft, %si
|
|
|
-- call prtstr
|
|
|
-- leaw edit_buf, %si
|
|
|
-- cmpb $0, (%si) # Empty string = default mode
|
|
|
-- jz lmdef
|
|
|
--
|
|
|
-- cmpb $0, 1(%si) # One character = menu selection
|
|
|
-- jz mnusel
|
|
|
--
|
|
|
-- cmpw $0x6373, (%si) # "scan" => mode scanning
|
|
|
-- jnz lmhx
|
|
|
--
|
|
|
-- cmpw $0x6e61, 2(%si)
|
|
|
-- jz lmscan
|
|
|
--
|
|
|
--lmhx: xorw %bx, %bx # Else => mode ID in hex
|
|
|
--lmhex: lodsb
|
|
|
-- orb %al, %al
|
|
|
-- jz lmuse1
|
|
|
--
|
|
|
-- subb $0x30, %al
|
|
|
-- jc lmbad
|
|
|
--
|
|
|
-- cmpb $10, %al
|
|
|
-- jc lmhx1
|
|
|
--
|
|
|
-- subb $7, %al
|
|
|
-- andb $0xdf, %al
|
|
|
-- cmpb $10, %al
|
|
|
-- jc lmbad
|
|
|
--
|
|
|
-- cmpb $16, %al
|
|
|
-- jnc lmbad
|
|
|
--
|
|
|
--lmhx1: shlw $4, %bx
|
|
|
-- orb %al, %bl
|
|
|
-- jmp lmhex
|
|
|
--
|
|
|
--lmuse1: movw %bx, %ax
|
|
|
-- jmp lmuse
|
|
|
--
|
|
|
--mnusel: lodsb # Menu selection
|
|
|
-- xorb %ah, %ah
|
|
|
-- subb $0x30, %al
|
|
|
-- jc lmbad
|
|
|
--
|
|
|
-- cmpb $10, %al
|
|
|
-- jc lmuse
|
|
|
--
|
|
|
-- cmpb $0x61-0x30, %al
|
|
|
-- jc lmbad
|
|
|
--
|
|
|
-- subb $0x61-0x30-10, %al
|
|
|
-- cmpb $36, %al
|
|
|
-- jnc lmbad
|
|
|
--
|
|
|
--lmuse: call mode_set
|
|
|
-- jc lmdef
|
|
|
--
|
|
|
--lmbad: leaw unknt, %si
|
|
|
-- call prtstr
|
|
|
-- jmp lm2
|
|
|
--lmscan: cmpb $0, adapter # Scanning only on EGA/VGA
|
|
|
-- jz lmbad
|
|
|
--
|
|
|
-- movw $0, mt_end # Scanning of modes is
|
|
|
-- movb $1, scanning # done as new autodetection.
|
|
|
-- call mode_table
|
|
|
-- jmp listm0
|
|
|
--lmdef: ret
|
|
|
--
|
|
|
--# Additional parts of mode_set... (relative jumps, you know)
|
|
|
--setv7: # Video7 extended modes
|
|
|
-- DO_STORE
|
|
|
-- subb $VIDEO_FIRST_V7>>8, %bh
|
|
|
-- movw $0x6f05, %ax
|
|
|
-- int $0x10
|
|
|
-- stc
|
|
|
-- ret
|
|
|
--
|
|
|
--_setrec: jmp setrec # Ugly...
|
|
|
--_set_80x25: jmp set_80x25
|
|
|
--
|
|
|
--# Aliases for backward compatibility.
|
|
|
--setalias:
|
|
|
-- movw $VIDEO_80x25, %ax
|
|
|
-- incw %bx
|
|
|
-- jz mode_set
|
|
|
--
|
|
|
-- movb $VIDEO_8POINT-VIDEO_FIRST_SPECIAL, %al
|
|
|
-- incw %bx
|
|
|
-- jnz setbad # Fall-through!
|
|
|
--
|
|
|
--# Setting of user mode (AX=mode ID) => CF=success
|
|
|
--mode_set:
|
|
|
-- movw %ax, %fs:(0x01fa) # Store mode for use in acpi_wakeup.S
|
|
|
-- movw %ax, %bx
|
|
|
-- cmpb $0xff, %ah
|
|
|
-- jz setalias
|
|
|
--
|
|
|
-- testb $VIDEO_RECALC>>8, %ah
|
|
|
-- jnz _setrec
|
|
|
--
|
|
|
-- cmpb $VIDEO_FIRST_RESOLUTION>>8, %ah
|
|
|
-- jnc setres
|
|
|
--
|
|
|
-- cmpb $VIDEO_FIRST_SPECIAL>>8, %ah
|
|
|
-- jz setspc
|
|
|
--
|
|
|
-- cmpb $VIDEO_FIRST_V7>>8, %ah
|
|
|
-- jz setv7
|
|
|
--
|
|
|
-- cmpb $VIDEO_FIRST_VESA>>8, %ah
|
|
|
-- jnc check_vesa
|
|
|
--
|
|
|
-- orb %ah, %ah
|
|
|
-- jz setmenu
|
|
|
--
|
|
|
-- decb %ah
|
|
|
-- jz setbios
|
|
|
--
|
|
|
--setbad: clc
|
|
|
-- movb $0, do_restore # The screen needn't be restored
|
|
|
-- ret
|
|
|
--
|
|
|
--setvesa:
|
|
|
-- DO_STORE
|
|
|
-- subb $VIDEO_FIRST_VESA>>8, %bh
|
|
|
-- movw $0x4f02, %ax # VESA BIOS mode set call
|
|
|
-- int $0x10
|
|
|
-- cmpw $0x004f, %ax # AL=4f if implemented
|
|
|
-- jnz setbad # AH=0 if OK
|
|
|
--
|
|
|
-- stc
|
|
|
-- ret
|
|
|
--
|
|
|
--setbios:
|
|
|
-- DO_STORE
|
|
|
-- int $0x10 # Standard BIOS mode set call
|
|
|
-- pushw %bx
|
|
|
-- movb $0x0f, %ah # Check if really set
|
|
|
-- int $0x10
|
|
|
-- popw %bx
|
|
|
-- cmpb %bl, %al
|
|
|
-- jnz setbad
|
|
|
--
|
|
|
-- stc
|
|
|
-- ret
|
|
|
--
|
|
|
--setspc: xorb %bh, %bh # Set special mode
|
|
|
-- cmpb $VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl
|
|
|
-- jnc setbad
|
|
|
--
|
|
|
-- addw %bx, %bx
|
|
|
-- jmp *spec_inits(%bx)
|
|
|
--
|
|
|
--setmenu:
|
|
|
-- orb %al, %al # 80x25 is an exception
|
|
|
-- jz _set_80x25
|
|
|
--
|
|
|
-- pushw %bx # Set mode chosen from menu
|
|
|
-- call mode_table # Build the mode table
|
|
|
-- popw %ax
|
|
|
-- shlw $2, %ax
|
|
|
-- addw %ax, %si
|
|
|
-- cmpw %di, %si
|
|
|
-- jnc setbad
|
|
|
--
|
|
|
-- movw (%si), %ax # Fetch mode ID
|
|
|
--_m_s: jmp mode_set
|
|
|
--
|
|
|
--setres: pushw %bx # Set mode chosen by resolution
|
|
|
-- call mode_table
|
|
|
-- popw %bx
|
|
|
-- xchgb %bl, %bh
|
|
|
--setr1: lodsw
|
|
|
-- cmpw $ASK_VGA, %ax # End of the list?
|
|
|
-- jz setbad
|
|
|
--
|
|
|
-- lodsw
|
|
|
-- cmpw %bx, %ax
|
|
|
-- jnz setr1
|
|
|
--
|
|
|
-- movw -4(%si), %ax # Fetch mode ID
|
|
|
-- jmp _m_s
|
|
|
--
|
|
|
--check_vesa:
|
|
|
--#ifdef CONFIG_FIRMWARE_EDID
|
|
|
-- leaw modelist+1024, %di
|
|
|
-- movw $0x4f00, %ax
|
|
|
-- int $0x10
|
|
|
-- cmpw $0x004f, %ax
|
|
|
-- jnz setbad
|
|
|
--
|
|
|
-- movw 4(%di), %ax
|
|
|
-- movw %ax, vbe_version
|
|
|
--#endif
|
|
|
-- leaw modelist+1024, %di
|
|
|
-- subb $VIDEO_FIRST_VESA>>8, %bh
|
|
|
-- movw %bx, %cx # Get mode information structure
|
|
|
-- movw $0x4f01, %ax
|
|
|
-- int $0x10
|
|
|
-- addb $VIDEO_FIRST_VESA>>8, %bh
|
|
|
-- cmpw $0x004f, %ax
|
|
|
-- jnz setbad
|
|
|
--
|
|
|
-- movb (%di), %al # Check capabilities.
|
|
|
-- andb $0x19, %al
|
|
|
-- cmpb $0x09, %al
|
|
|
-- jz setvesa # This is a text mode
|
|
|
--
|
|
|
-- movb (%di), %al # Check capabilities.
|
|
|
-- andb $0x99, %al
|
|
|
-- cmpb $0x99, %al
|
|
|
-- jnz _setbad # Doh! No linear frame buffer.
|
|
|
--
|
|
|
-- subb $VIDEO_FIRST_VESA>>8, %bh
|
|
|
-- orw $0x4000, %bx # Use linear frame buffer
|
|
|
-- movw $0x4f02, %ax # VESA BIOS mode set call
|
|
|
-- int $0x10
|
|
|
-- cmpw $0x004f, %ax # AL=4f if implemented
|
|
|
-- jnz _setbad # AH=0 if OK
|
|
|
--
|
|
|
-- movb $1, graphic_mode # flag graphic mode
|
|
|
-- movb $0, do_restore # no screen restore
|
|
|
-- stc
|
|
|
-- ret
|
|
|
--
|
|
|
--_setbad: jmp setbad # Ugly...
|
|
|
--
|
|
|
--# Recalculate vertical display end registers -- this fixes various
|
|
|
--# inconsistencies of extended modes on many adapters. Called when
|
|
|
--# the VIDEO_RECALC flag is set in the mode ID.
|
|
|
--
|
|
|
--setrec: subb $VIDEO_RECALC>>8, %ah # Set the base mode
|
|
|
-- call mode_set
|
|
|
-- jnc rct3
|
|
|
--
|
|
|
-- movw %gs:(0x485), %ax # Font size in pixels
|
|
|
-- movb %gs:(0x484), %bl # Number of rows
|
|
|
-- incb %bl
|
|
|
-- mulb %bl # Number of visible
|
|
|
-- decw %ax # scan lines - 1
|
|
|
-- movw $0x3d4, %dx
|
|
|
-- movw %ax, %bx
|
|
|
-- movb $0x12, %al # Lower 8 bits
|
|
|
-- movb %bl, %ah
|
|
|
-- outw %ax, %dx
|
|
|
-- movb $0x07, %al # Bits 8 and 9 in the overflow register
|
|
|
-- call inidx
|
|
|
-- xchgb %al, %ah
|
|
|
-- andb $0xbd, %ah
|
|
|
-- shrb %bh
|
|
|
-- jnc rct1
|
|
|
-- orb $0x02, %ah
|
|
|
--rct1: shrb %bh
|
|
|
-- jnc rct2
|
|
|
-- orb $0x40, %ah
|
|
|
--rct2: movb $0x07, %al
|
|
|
-- outw %ax, %dx
|
|
|
-- stc
|
|
|
--rct3: ret
|
|
|
--
|
|
|
--# Table of routines for setting of the special modes.
|
|
|
--spec_inits:
|
|
|
-- .word set_80x25
|
|
|
-- .word set_8pixel
|
|
|
-- .word set_80x43
|
|
|
-- .word set_80x28
|
|
|
-- .word set_current
|
|
|
-- .word set_80x30
|
|
|
-- .word set_80x34
|
|
|
-- .word set_80x60
|
|
|
-- .word set_gfx
|
|
|
--
|
|
|
--# Set the 80x25 mode. If already set, do nothing.
|
|
|
--set_80x25:
|
|
|
-- movw $0x5019, force_size # Override possibly broken BIOS
|
|
|
--use_80x25:
|
|
|
--#ifdef CONFIG_VIDEO_400_HACK
|
|
|
-- movw $0x1202, %ax # Force 400 scan lines
|
|
|
-- movb $0x30, %bl
|
|
|
-- int $0x10
|
|
|
--#else
|
|
|
-- movb $0x0f, %ah # Get current mode ID
|
|
|
-- int $0x10
|
|
|
-- cmpw $0x5007, %ax # Mode 7 (80x25 mono) is the only one available
|
|
|
-- jz st80 # on CGA/MDA/HGA and is also available on EGAM
|
|
|
--
|
|
|
-- cmpw $0x5003, %ax # Unknown mode, force 80x25 color
|
|
|
-- jnz force3
|
|
|
--
|
|
|
--st80: cmpb $0, adapter # CGA/MDA/HGA => mode 3/7 is always 80x25
|
|
|
-- jz set80
|
|
|
--
|
|
|
-- movb %gs:(0x0484), %al # This is EGA+ -- beware of 80x50 etc.
|
|
|
-- orb %al, %al # Some buggy BIOS'es set 0 rows
|
|
|
-- jz set80
|
|
|
--
|
|
|
-- cmpb $24, %al # It's hopefully correct
|
|
|
-- jz set80
|
|
|
--#endif /* CONFIG_VIDEO_400_HACK */
|
|
|
--force3: DO_STORE
|
|
|
-- movw $0x0003, %ax # Forced set
|
|
|
-- int $0x10
|
|
|
--set80: stc
|
|
|
-- ret
|
|
|
--
|
|
|
--# Set the 80x50/80x43 8-pixel mode. Simple BIOS calls.
|
|
|
--set_8pixel:
|
|
|
-- DO_STORE
|
|
|
-- call use_80x25 # The base is 80x25
|
|
|
--set_8pt:
|
|
|
-- movw $0x1112, %ax # Use 8x8 font
|
|
|
-- xorb %bl, %bl
|
|
|
-- int $0x10
|
|
|
-- movw $0x1200, %ax # Use alternate print screen
|
|
|
-- movb $0x20, %bl
|
|
|
-- int $0x10
|
|
|
-- movw $0x1201, %ax # Turn off cursor emulation
|
|
|
-- movb $0x34, %bl
|
|
|
-- int $0x10
|
|
|
-- movb $0x01, %ah # Define cursor scan lines 6-7
|
|
|
-- movw $0x0607, %cx
|
|
|
-- int $0x10
|
|
|
--set_current:
|
|
|
-- stc
|
|
|
-- ret
|
|
|
--
|
|
|
--# Set the 80x28 mode. This mode works on all VGA's, because it's a standard
|
|
|
--# 80x25 mode with 14-point fonts instead of 16-point.
|
|
|
--set_80x28:
|
|
|
-- DO_STORE
|
|
|
-- call use_80x25 # The base is 80x25
|
|
|
--set14: movw $0x1111, %ax # Use 9x14 font
|
|
|
-- xorb %bl, %bl
|
|
|
-- int $0x10
|
|
|
-- movb $0x01, %ah # Define cursor scan lines 11-12
|
|
|
-- movw $0x0b0c, %cx
|
|
|
-- int $0x10
|
|
|
-- stc
|
|
|
-- ret
|
|
|
--
|
|
|
--# Set the 80x43 mode. This mode is works on all VGA's.
|
|
|
--# It's a 350-scanline mode with 8-pixel font.
|
|
|
--set_80x43:
|
|
|
-- DO_STORE
|
|
|
-- movw $0x1201, %ax # Set 350 scans
|
|
|
-- movb $0x30, %bl
|
|
|
-- int $0x10
|
|
|
-- movw $0x0003, %ax # Reset video mode
|
|
|
-- int $0x10
|
|
|
-- jmp set_8pt # Use 8-pixel font
|
|
|
--
|
|
|
--# Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font.
|
|
|
--set_80x30:
|
|
|
-- call use_80x25 # Start with real 80x25
|
|
|
-- DO_STORE
|
|
|
-- movw $0x3cc, %dx # Get CRTC port
|
|
|
-- inb %dx, %al
|
|
|
-- movb $0xd4, %dl
|
|
|
-- rorb %al # Mono or color?
|
|
|
-- jc set48a
|
|
|
--
|
|
|
-- movb $0xb4, %dl
|
|
|
--set48a: movw $0x0c11, %ax # Vertical sync end (also unlocks CR0-7)
|
|
|
-- call outidx
|
|
|
-- movw $0x0b06, %ax # Vertical total
|
|
|
-- call outidx
|
|
|
-- movw $0x3e07, %ax # (Vertical) overflow
|
|
|
-- call outidx
|
|
|
-- movw $0xea10, %ax # Vertical sync start
|
|
|
-- call outidx
|
|
|
-- movw $0xdf12, %ax # Vertical display end
|
|
|
-- call outidx
|
|
|
-- movw $0xe715, %ax # Vertical blank start
|
|
|
-- call outidx
|
|
|
-- movw $0x0416, %ax # Vertical blank end
|
|
|
-- call outidx
|
|
|
-- pushw %dx
|
|
|
-- movb $0xcc, %dl # Misc output register (read)
|
|
|
-- inb %dx, %al
|
|
|
-- movb $0xc2, %dl # (write)
|
|
|
-- andb $0x0d, %al # Preserve clock select bits and color bit
|
|
|
-- orb $0xe2, %al # Set correct sync polarity
|
|
|
-- outb %al, %dx
|
|
|
-- popw %dx
|
|
|
-- movw $0x501e, force_size
|
|
|
-- stc # That's all.
|
|
|
-- ret
|
|
|
--
|
|
|
--# Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font.
|
|
|
--set_80x34:
|
|
|
-- call set_80x30 # Set 480 scans
|
|
|
-- call set14 # And 14-pt font
|
|
|
-- movw $0xdb12, %ax # VGA vertical display end
|
|
|
-- movw $0x5022, force_size
|
|
|
--setvde: call outidx
|
|
|
-- stc
|
|
|
-- ret
|
|
|
--
|
|
|
--# Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font.
|
|
|
--set_80x60:
|
|
|
-- call set_80x30 # Set 480 scans
|
|
|
-- call set_8pt # And 8-pt font
|
|
|
-- movw $0xdf12, %ax # VGA vertical display end
|
|
|
-- movw $0x503c, force_size
|
|
|
-- jmp setvde
|
|
|
--
|
|
|
--# Special hack for ThinkPad graphics
|
|
|
--set_gfx:
|
|
|
--#ifdef CONFIG_VIDEO_GFX_HACK
|
|
|
-- movw $VIDEO_GFX_BIOS_AX, %ax
|
|
|
-- movw $VIDEO_GFX_BIOS_BX, %bx
|
|
|
-- int $0x10
|
|
|
-- movw $VIDEO_GFX_DUMMY_RESOLUTION, force_size
|
|
|
-- stc
|
|
|
--#endif
|
|
|
-- ret
|
|
|
--
|
|
|
--#ifdef CONFIG_VIDEO_RETAIN
|
|
|
--
|
|
|
--# Store screen contents to temporary buffer.
|
|
|
--store_screen:
|
|
|
-- cmpb $0, do_restore # Already stored?
|
|
|
-- jnz stsr
|
|
|
--
|
|
|
-- testb $CAN_USE_HEAP, loadflags # Have we space for storing?
|
|
|
-- jz stsr
|
|
|
--
|
|
|
-- pushw %ax
|
|
|
-- pushw %bx
|
|
|
-- pushw force_size # Don't force specific size
|
|
|
-- movw $0, force_size
|
|
|
-- call mode_params # Obtain params of current mode
|
|
|
-- popw force_size
|
|
|
-- movb %fs:(PARAM_VIDEO_LINES), %ah
|
|
|
-- movb %fs:(PARAM_VIDEO_COLS), %al
|
|
|
-- movw %ax, %bx # BX=dimensions
|
|
|
-- mulb %ah
|
|
|
-- movw %ax, %cx # CX=number of characters
|
|
|
-- addw %ax, %ax # Calculate image size
|
|
|
-- addw $modelist+1024+4, %ax
|
|
|
-- cmpw heap_end_ptr, %ax
|
|
|
-- jnc sts1 # Unfortunately, out of memory
|
|
|
--
|
|
|
-- movw %fs:(PARAM_CURSOR_POS), %ax # Store mode params
|
|
|
-- leaw modelist+1024, %di
|
|
|
-- stosw
|
|
|
-- movw %bx, %ax
|
|
|
-- stosw
|
|
|
-- pushw %ds # Store the screen
|
|
|
-- movw video_segment, %ds
|
|
|
-- xorw %si, %si
|
|
|
-- rep
|
|
|
-- movsw
|
|
|
-- popw %ds
|
|
|
-- incb do_restore # Screen will be restored later
|
|
|
--sts1: popw %bx
|
|
|
-- popw %ax
|
|
|
--stsr: ret
|
|
|
--
|
|
|
--# Restore screen contents from temporary buffer.
|
|
|
--restore_screen:
|
|
|
-- cmpb $0, do_restore # Has the screen been stored?
|
|
|
-- jz res1
|
|
|
--
|
|
|
-- call mode_params # Get parameters of current mode
|
|
|
-- movb %fs:(PARAM_VIDEO_LINES), %cl
|
|
|
-- movb %fs:(PARAM_VIDEO_COLS), %ch
|
|
|
-- leaw modelist+1024, %si # Screen buffer
|
|
|
-- lodsw # Set cursor position
|
|
|
-- movw %ax, %dx
|
|
|
-- cmpb %cl, %dh
|
|
|
-- jc res2
|
|
|
--
|
|
|
-- movb %cl, %dh
|
|
|
-- decb %dh
|
|
|
--res2: cmpb %ch, %dl
|
|
|
-- jc res3
|
|
|
--
|
|
|
-- movb %ch, %dl
|
|
|
-- decb %dl
|
|
|
--res3: movb $0x02, %ah
|
|
|
-- movb $0x00, %bh
|
|
|
-- int $0x10
|
|
|
-- lodsw # Display size
|
|
|
-- movb %ah, %dl # DL=number of lines
|
|
|
-- movb $0, %ah # BX=phys. length of orig. line
|
|
|
-- movw %ax, %bx
|
|
|
-- cmpb %cl, %dl # Too many?
|
|
|
-- jc res4
|
|
|
--
|
|
|
-- pushw %ax
|
|
|
-- movb %dl, %al
|
|
|
-- subb %cl, %al
|
|
|
-- mulb %bl
|
|
|
-- addw %ax, %si
|
|
|
-- addw %ax, %si
|
|
|
-- popw %ax
|
|
|
-- movb %cl, %dl
|
|
|
--res4: cmpb %ch, %al # Too wide?
|
|
|
-- jc res5
|
|
|
--
|
|
|
-- movb %ch, %al # AX=width of src. line
|
|
|
--res5: movb $0, %cl
|
|
|
-- xchgb %ch, %cl
|
|
|
-- movw %cx, %bp # BP=width of dest. line
|
|
|
-- pushw %es
|
|
|
-- movw video_segment, %es
|
|
|
-- xorw %di, %di # Move the data
|
|
|
-- addw %bx, %bx # Convert BX and BP to _bytes_
|
|
|
-- addw %bp, %bp
|
|
|
--res6: pushw %si
|
|
|
-- pushw %di
|
|
|
-- movw %ax, %cx
|
|
|
-- rep
|
|
|
-- movsw
|
|
|
-- popw %di
|
|
|
-- popw %si
|
|
|
-- addw %bp, %di
|
|
|
-- addw %bx, %si
|
|
|
-- decb %dl
|
|
|
-- jnz res6
|
|
|
--
|
|
|
-- popw %es # Done
|
|
|
--res1: ret
|
|
|
--#endif /* CONFIG_VIDEO_RETAIN */
|
|
|
--
|
|
|
--# Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)
|
|
|
--outidx: outb %al, %dx
|
|
|
-- pushw %ax
|
|
|
-- movb %ah, %al
|
|
|
-- incw %dx
|
|
|
-- outb %al, %dx
|
|
|
-- decw %dx
|
|
|
-- popw %ax
|
|
|
-- ret
|
|
|
--
|
|
|
--# Build the table of video modes (stored after the setup.S code at the
|
|
|
--# `modelist' label. Each video mode record looks like:
|
|
|
--# .word MODE-ID (our special mode ID (see above))
|
|
|
--# .byte rows (number of rows)
|
|
|
--# .byte columns (number of columns)
|
|
|
--# Returns address of the end of the table in DI, the end is marked
|
|
|
--# with a ASK_VGA ID.
|
|
|
--mode_table:
|
|
|
-- movw mt_end, %di # Already filled?
|
|
|
-- orw %di, %di
|
|
|
-- jnz mtab1x
|
|
|
--
|
|
|
-- leaw modelist, %di # Store standard modes:
|
|
|
-- movl $VIDEO_80x25 + 0x50190000, %eax # The 80x25 mode (ALL)
|
|
|
-- stosl
|
|
|
-- movb adapter, %al # CGA/MDA/HGA -- no more modes
|
|
|
-- orb %al, %al
|
|
|
-- jz mtabe
|
|
|
--
|
|
|
-- decb %al
|
|
|
-- jnz mtabv
|
|
|
--
|
|
|
-- movl $VIDEO_8POINT + 0x502b0000, %eax # The 80x43 EGA mode
|
|
|
-- stosl
|
|
|
-- jmp mtabe
|
|
|
--
|
|
|
--mtab1x: jmp mtab1
|
|
|
--
|
|
|
--mtabv: leaw vga_modes, %si # All modes for std VGA
|
|
|
-- movw $vga_modes_end-vga_modes, %cx
|
|
|
-- rep # I'm unable to use movsw as I don't know how to store a half
|
|
|
-- movsb # of the expression above to cx without using explicit shr.
|
|
|
--
|
|
|
-- cmpb $0, scanning # Mode scan requested?
|
|
|
-- jz mscan1
|
|
|
--
|
|
|
-- call mode_scan
|
|
|
--mscan1:
|
|
|
--
|
|
|
--#ifdef CONFIG_VIDEO_LOCAL
|
|
|
-- call local_modes
|
|
|
--#endif /* CONFIG_VIDEO_LOCAL */
|
|
|
--
|
|
|
--#ifdef CONFIG_VIDEO_VESA
|
|
|
-- call vesa_modes # Detect VESA VGA modes
|
|
|
--#endif /* CONFIG_VIDEO_VESA */
|
|
|
--
|
|
|
--#ifdef CONFIG_VIDEO_SVGA
|
|
|
-- cmpb $0, scanning # Bypass when scanning
|
|
|
-- jnz mscan2
|
|
|
--
|
|
|
-- call svga_modes # Detect SVGA cards & modes
|
|
|
--mscan2:
|
|
|
--#endif /* CONFIG_VIDEO_SVGA */
|
|
|
--
|
|
|
--mtabe:
|
|
|
--
|
|
|
--#ifdef CONFIG_VIDEO_COMPACT
|
|
|
-- leaw modelist, %si
|
|
|
-- movw %di, %dx
|
|
|
-- movw %si, %di
|
|
|
--cmt1: cmpw %dx, %si # Scan all modes
|
|
|
-- jz cmt2
|
|
|
--
|
|
|
-- leaw modelist, %bx # Find in previous entries
|
|
|
-- movw 2(%si), %cx
|
|
|
--cmt3: cmpw %bx, %si
|
|
|
-- jz cmt4
|
|
|
--
|
|
|
-- cmpw 2(%bx), %cx # Found => don't copy this entry
|
|
|
-- jz cmt5
|
|
|
--
|
|
|
-- addw $4, %bx
|
|
|
-- jmp cmt3
|
|
|
--
|
|
|
--cmt4: movsl # Copy entry
|
|
|
-- jmp cmt1
|
|
|
--
|
|
|
--cmt5: addw $4, %si # Skip entry
|
|
|
-- jmp cmt1
|
|
|
--
|
|
|
--cmt2:
|
|
|
--#endif /* CONFIG_VIDEO_COMPACT */
|
|
|
--
|
|
|
-- movw $ASK_VGA, (%di) # End marker
|
|
|
-- movw %di, mt_end
|
|
|
--mtab1: leaw modelist, %si # SI=mode list, DI=list end
|
|
|
--ret0: ret
|
|
|
--
|
|
|
--# Modes usable on all standard VGAs
|
|
|
--vga_modes:
|
|
|
-- .word VIDEO_8POINT
|
|
|
-- .word 0x5032 # 80x50
|
|
|
-- .word VIDEO_80x43
|
|
|
-- .word 0x502b # 80x43
|
|
|
-- .word VIDEO_80x28
|
|
|
-- .word 0x501c # 80x28
|
|
|
-- .word VIDEO_80x30
|
|
|
-- .word 0x501e # 80x30
|
|
|
-- .word VIDEO_80x34
|
|
|
-- .word 0x5022 # 80x34
|
|
|
-- .word VIDEO_80x60
|
|
|
-- .word 0x503c # 80x60
|
|
|
--#ifdef CONFIG_VIDEO_GFX_HACK
|
|
|
-- .word VIDEO_GFX_HACK
|
|
|
-- .word VIDEO_GFX_DUMMY_RESOLUTION
|
|
|
--#endif
|
|
|
--
|
|
|
--vga_modes_end:
|
|
|
--# Detect VESA modes.
|
|
|
--
|
|
|
--#ifdef CONFIG_VIDEO_VESA
|
|
|
--vesa_modes:
|
|
|
-- cmpb $2, adapter # VGA only
|
|
|
-- jnz ret0
|
|
|
--
|
|
|
-- movw %di, %bp # BP=original mode table end
|
|
|
-- addw $0x200, %di # Buffer space
|
|
|
-- movw $0x4f00, %ax # VESA Get card info call
|
|
|
-- int $0x10
|
|
|
-- movw %bp, %di
|
|
|
-- cmpw $0x004f, %ax # Successful?
|
|
|
-- jnz ret0
|
|
|
--
|
|
|
-- cmpw $0x4556, 0x200(%di)
|
|
|
-- jnz ret0
|
|
|
--
|
|
|
-- cmpw $0x4153, 0x202(%di)
|
|
|
-- jnz ret0
|
|
|
--
|
|
|
-- movw $vesa_name, card_name # Set name to "VESA VGA"
|
|
|
-- pushw %gs
|
|
|
-- lgsw 0x20e(%di), %si # GS:SI=mode list
|
|
|
-- movw $128, %cx # Iteration limit
|
|
|
--vesa1:
|
|
|
--# gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst.
|
|
|
--# XXX: lodsw %gs:(%si), %ax # Get next mode in the list
|
|
|
-- gs; lodsw
|
|
|
-- cmpw $0xffff, %ax # End of the table?
|
|
|
-- jz vesar
|
|
|
--
|
|
|
-- cmpw $0x0080, %ax # Check validity of mode ID
|
|
|
-- jc vesa2
|
|
|
--
|
|
|
-- orb %ah, %ah # Valid IDs: 0x0000-0x007f/0x0100-0x07ff
|
|
|
-- jz vesan # Certain BIOSes report 0x80-0xff!
|
|
|
--
|
|
|
-- cmpw $0x0800, %ax
|
|
|
-- jnc vesae
|
|
|
--
|
|
|
--vesa2: pushw %cx
|
|
|
-- movw %ax, %cx # Get mode information structure
|
|
|
-- movw $0x4f01, %ax
|
|
|
-- int $0x10
|
|
|
-- movw %cx, %bx # BX=mode number
|
|
|
-- addb $VIDEO_FIRST_VESA>>8, %bh
|
|
|
-- popw %cx
|
|
|
-- cmpw $0x004f, %ax
|
|
|
-- jnz vesan # Don't report errors (buggy BIOSES)
|
|
|
--
|
|
|
-- movb (%di), %al # Check capabilities. We require
|
|
|
-- andb $0x19, %al # a color text mode.
|
|
|
-- cmpb $0x09, %al
|
|
|
-- jnz vesan
|
|
|
--
|
|
|
-- cmpw $0xb800, 8(%di) # Standard video memory address required
|
|
|
-- jnz vesan
|
|
|
--
|
|
|
-- testb $2, (%di) # Mode characteristics supplied?
|
|
|
-- movw %bx, (%di) # Store mode number
|
|
|
-- jz vesa3
|
|
|
--
|
|
|
-- xorw %dx, %dx
|
|
|
-- movw 0x12(%di), %bx # Width
|
|
|
-- orb %bh, %bh
|
|
|
-- jnz vesan
|
|
|
--
|
|
|
-- movb %bl, 0x3(%di)
|
|
|
-- movw 0x14(%di), %ax # Height
|
|
|
-- orb %ah, %ah
|
|
|
-- jnz vesan
|
|
|
--
|
|
|
-- movb %al, 2(%di)
|
|
|
-- mulb %bl
|
|
|
-- cmpw $8193, %ax # Small enough for Linux console driver?
|
|
|
-- jnc vesan
|
|
|
--
|
|
|
-- jmp vesaok
|
|
|
--
|
|
|
--vesa3: subw $0x8108, %bx # This mode has no detailed info specified,
|
|
|
-- jc vesan # so it must be a standard VESA mode.
|
|
|
--
|
|
|
-- cmpw $5, %bx
|
|
|
-- jnc vesan
|
|
|
--
|
|
|
-- movw vesa_text_mode_table(%bx), %ax
|
|
|
-- movw %ax, 2(%di)
|
|
|
--vesaok: addw $4, %di # The mode is valid. Store it.
|
|
|
--vesan: loop vesa1 # Next mode. Limit exceeded => error
|
|
|
--vesae: leaw vesaer, %si
|
|
|
-- call prtstr
|
|
|
-- movw %bp, %di # Discard already found modes.
|
|
|
--vesar: popw %gs
|
|
|
-- ret
|
|
|
--
|
|
|
--# Dimensions of standard VESA text modes
|
|
|
--vesa_text_mode_table:
|
|
|
-- .byte 60, 80 # 0108
|
|
|
-- .byte 25, 132 # 0109
|
|
|
-- .byte 43, 132 # 010A
|
|
|
-- .byte 50, 132 # 010B
|
|
|
-- .byte 60, 132 # 010C
|
|
|
--#endif /* CONFIG_VIDEO_VESA */
|
|
|
--
|
|
|
--# Scan for video modes. A bit dirty, but should work.
|
|
|
--mode_scan:
|
|
|
-- movw $0x0100, %cx # Start with mode 0
|
|
|
--scm1: movb $0, %ah # Test the mode
|
|
|
-- movb %cl, %al
|
|
|
-- int $0x10
|
|
|
-- movb $0x0f, %ah
|
|
|
-- int $0x10
|
|
|
-- cmpb %cl, %al
|
|
|
-- jnz scm2 # Mode not set
|
|
|
--
|
|
|
-- movw $0x3c0, %dx # Test if it's a text mode
|
|
|
-- movb $0x10, %al # Mode bits
|
|
|
-- call inidx
|
|
|
-- andb $0x03, %al
|
|
|
-- jnz scm2
|
|
|
--
|
|
|
-- movb $0xce, %dl # Another set of mode bits
|
|
|
-- movb $0x06, %al
|
|
|
-- call inidx
|
|
|
-- shrb %al
|
|
|
-- jc scm2
|
|
|
--
|
|
|
-- movb $0xd4, %dl # Cursor location
|
|
|
-- movb $0x0f, %al
|
|
|
-- call inidx
|
|
|
-- orb %al, %al
|
|
|
-- jnz scm2
|
|
|
--
|
|
|
-- movw %cx, %ax # Ok, store the mode
|
|
|
-- stosw
|
|
|
-- movb %gs:(0x484), %al # Number of rows
|
|
|
-- incb %al
|
|
|
-- stosb
|
|
|
-- movw %gs:(0x44a), %ax # Number of columns
|
|
|
-- stosb
|
|
|
--scm2: incb %cl
|
|
|
-- jns scm1
|
|
|
--
|
|
|
-- movw $0x0003, %ax # Return back to mode 3
|
|
|
-- int $0x10
|
|
|
-- ret
|
|
|
--
|
|
|
--tstidx: outw %ax, %dx # OUT DX,AX and inidx
|
|
|
--inidx: outb %al, %dx # Read from indexed VGA register
|
|
|
-- incw %dx # AL=index, DX=index reg port -> AL=data
|
|
|
-- inb %dx, %al
|
|
|
-- decw %dx
|
|
|
-- ret
|
|
|
--
|
|
|
--# Try to detect type of SVGA card and supply (usually approximate) video
|
|
|
--# mode table for it.
|
|
|
--
|
|
|
--#ifdef CONFIG_VIDEO_SVGA
|
|
|
--svga_modes:
|
|
|
-- leaw svga_table, %si # Test all known SVGA adapters
|
|
|
--dosvga: lodsw
|
|
|
-- movw %ax, %bp # Default mode table
|
|
|
-- orw %ax, %ax
|
|
|
-- jz didsv1
|
|
|
--
|
|
|
-- lodsw # Pointer to test routine
|
|
|
-- pushw %si
|
|
|
-- pushw %di
|
|
|
-- pushw %es
|
|
|
-- movw $0xc000, %bx
|
|
|
-- movw %bx, %es
|
|
|
-- call *%ax # Call test routine
|
|
|
-- popw %es
|
|
|
-- popw %di
|
|
|
-- popw %si
|
|
|
-- orw %bp, %bp
|
|
|
-- jz dosvga
|
|
|
--
|
|
|
-- movw %bp, %si # Found, copy the modes
|
|
|
-- movb svga_prefix, %ah
|
|
|
--cpsvga: lodsb
|
|
|
-- orb %al, %al
|
|
|
-- jz didsv
|
|
|
--
|
|
|
-- stosw
|
|
|
-- movsw
|
|
|
-- jmp cpsvga
|
|
|
--
|
|
|
--didsv: movw %si, card_name # Store pointer to card name
|
|
|
--didsv1: ret
|
|
|
--
|
|
|
--# Table of all known SVGA cards. For each card, we store a pointer to
|
|
|
--# a table of video modes supported by the card and a pointer to a routine
|
|
|
--# used for testing of presence of the card. The video mode table is always
|
|
|
--# followed by the name of the card or the chipset.
|
|
|
--svga_table:
|
|
|
-- .word ati_md, ati_test
|
|
|
-- .word oak_md, oak_test
|
|
|
-- .word paradise_md, paradise_test
|
|
|
-- .word realtek_md, realtek_test
|
|
|
-- .word s3_md, s3_test
|
|
|
-- .word chips_md, chips_test
|
|
|
-- .word video7_md, video7_test
|
|
|
-- .word cirrus5_md, cirrus5_test
|
|
|
-- .word cirrus6_md, cirrus6_test
|
|
|
-- .word cirrus1_md, cirrus1_test
|
|
|
-- .word ahead_md, ahead_test
|
|
|
-- .word everex_md, everex_test
|
|
|
-- .word genoa_md, genoa_test
|
|
|
-- .word trident_md, trident_test
|
|
|
-- .word tseng_md, tseng_test
|
|
|
-- .word 0
|
|
|
--
|
|
|
--# Test routines and mode tables:
|
|
|
--
|
|
|
--# S3 - The test algorithm was taken from the SuperProbe package
|
|
|
--# for XFree86 1.2.1. Report bugs to [email protected]
|
|
|
--s3_test:
|
|
|
-- movw $0x0f35, %cx # we store some constants in cl/ch
|
|
|
-- movw $0x03d4, %dx
|
|
|
-- movb $0x38, %al
|
|
|
-- call inidx
|
|
|
-- movb %al, %bh # store current CRT-register 0x38
|
|
|
-- movw $0x0038, %ax
|
|
|
-- call outidx # disable writing to special regs
|
|
|
-- movb %cl, %al # check whether we can write special reg 0x35
|
|
|
-- call inidx
|
|
|
-- movb %al, %bl # save the current value of CRT reg 0x35
|
|
|
-- andb $0xf0, %al # clear bits 0-3
|
|
|
-- movb %al, %ah
|
|
|
-- movb %cl, %al # and write it to CRT reg 0x35
|
|
|
-- call outidx
|
|
|
-- call inidx # now read it back
|
|
|
-- andb %ch, %al # clear the upper 4 bits
|
|
|
-- jz s3_2 # the first test failed. But we have a
|
|
|
--
|
|
|
-- movb %bl, %ah # second chance
|
|
|
-- movb %cl, %al
|
|
|
-- call outidx
|
|
|
-- jmp s3_1 # do the other tests
|
|
|
--
|
|
|
--s3_2: movw %cx, %ax # load ah with 0xf and al with 0x35
|
|
|
-- orb %bl, %ah # set the upper 4 bits of ah with the orig value
|
|
|
-- call outidx # write ...
|
|
|
-- call inidx # ... and reread
|
|
|
-- andb %cl, %al # turn off the upper 4 bits
|
|
|
-- pushw %ax
|
|
|
-- movb %bl, %ah # restore old value in register 0x35
|
|
|
-- movb %cl, %al
|
|
|
-- call outidx
|
|
|
-- popw %ax
|
|
|
-- cmpb %ch, %al # setting lower 4 bits was successful => bad
|
|
|
-- je no_s3 # writing is allowed => this is not an S3
|
|
|
--
|
|
|
--s3_1: movw $0x4838, %ax # allow writing to special regs by putting
|
|
|
-- call outidx # magic number into CRT-register 0x38
|
|
|
-- movb %cl, %al # check whether we can write special reg 0x35
|
|
|
-- call inidx
|
|
|
-- movb %al, %bl
|
|
|
-- andb $0xf0, %al
|
|
|
-- movb %al, %ah
|
|
|
-- movb %cl, %al
|
|
|
-- call outidx
|
|
|
-- call inidx
|
|
|
-- andb %ch, %al
|
|
|
-- jnz no_s3 # no, we can't write => no S3
|
|
|
--
|
|
|
-- movw %cx, %ax
|
|
|
-- orb %bl, %ah
|
|
|
-- call outidx
|
|
|
-- call inidx
|
|
|
-- andb %ch, %al
|
|
|
-- pushw %ax
|
|
|
-- movb %bl, %ah # restore old value in register 0x35
|
|
|
-- movb %cl, %al
|
|
|
-- call outidx
|
|
|
-- popw %ax
|
|
|
-- cmpb %ch, %al
|
|
|
-- jne no_s31 # writing not possible => no S3
|
|
|
-- movb $0x30, %al
|
|
|
-- call inidx # now get the S3 id ...
|
|
|
-- leaw idS3, %di
|
|
|
-- movw $0x10, %cx
|
|
|
-- repne
|
|
|
-- scasb
|
|
|
-- je no_s31
|
|
|
--
|
|
|
-- movb %bh, %ah
|
|
|
-- movb $0x38, %al
|
|
|
-- jmp s3rest
|
|
|
--
|
|
|
--no_s3: movb $0x35, %al # restore CRT register 0x35
|
|
|
-- movb %bl, %ah
|
|
|
-- call outidx
|
|
|
--no_s31: xorw %bp, %bp # Detection failed
|
|
|
--s3rest: movb %bh, %ah
|
|
|
-- movb $0x38, %al # restore old value of CRT register 0x38
|
|
|
-- jmp outidx
|
|
|
--
|
|
|
--idS3: .byte 0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
|
|
|
-- .byte 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
|
|
|
--
|
|
|
--s3_md: .byte 0x54, 0x2b, 0x84
|
|
|
-- .byte 0x55, 0x19, 0x84
|
|
|
-- .byte 0
|
|
|
-- .ascii "S3"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# ATI cards.
|
|
|
--ati_test:
|
|
|
-- leaw idati, %si
|
|
|
-- movw $0x31, %di
|
|
|
-- movw $0x09, %cx
|
|
|
-- repe
|
|
|
-- cmpsb
|
|
|
-- je atiok
|
|
|
--
|
|
|
-- xorw %bp, %bp
|
|
|
--atiok: ret
|
|
|
--
|
|
|
--idati: .ascii "761295520"
|
|
|
--
|
|
|
--ati_md: .byte 0x23, 0x19, 0x84
|
|
|
-- .byte 0x33, 0x2c, 0x84
|
|
|
-- .byte 0x22, 0x1e, 0x64
|
|
|
-- .byte 0x21, 0x19, 0x64
|
|
|
-- .byte 0x58, 0x21, 0x50
|
|
|
-- .byte 0x5b, 0x1e, 0x50
|
|
|
-- .byte 0
|
|
|
-- .ascii "ATI"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# AHEAD
|
|
|
--ahead_test:
|
|
|
-- movw $0x200f, %ax
|
|
|
-- movw $0x3ce, %dx
|
|
|
-- outw %ax, %dx
|
|
|
-- incw %dx
|
|
|
-- inb %dx, %al
|
|
|
-- cmpb $0x20, %al
|
|
|
-- je isahed
|
|
|
--
|
|
|
-- cmpb $0x21, %al
|
|
|
-- je isahed
|
|
|
--
|
|
|
-- xorw %bp, %bp
|
|
|
--isahed: ret
|
|
|
--
|
|
|
--ahead_md:
|
|
|
-- .byte 0x22, 0x2c, 0x84
|
|
|
-- .byte 0x23, 0x19, 0x84
|
|
|
-- .byte 0x24, 0x1c, 0x84
|
|
|
-- .byte 0x2f, 0x32, 0xa0
|
|
|
-- .byte 0x32, 0x22, 0x50
|
|
|
-- .byte 0x34, 0x42, 0x50
|
|
|
-- .byte 0
|
|
|
-- .ascii "Ahead"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# Chips & Tech.
|
|
|
--chips_test:
|
|
|
-- movw $0x3c3, %dx
|
|
|
-- inb %dx, %al
|
|
|
-- orb $0x10, %al
|
|
|
-- outb %al, %dx
|
|
|
-- movw $0x104, %dx
|
|
|
-- inb %dx, %al
|
|
|
-- movb %al, %bl
|
|
|
-- movw $0x3c3, %dx
|
|
|
-- inb %dx, %al
|
|
|
-- andb $0xef, %al
|
|
|
-- outb %al, %dx
|
|
|
-- cmpb $0xa5, %bl
|
|
|
-- je cantok
|
|
|
--
|
|
|
-- xorw %bp, %bp
|
|
|
--cantok: ret
|
|
|
--
|
|
|
--chips_md:
|
|
|
-- .byte 0x60, 0x19, 0x84
|
|
|
-- .byte 0x61, 0x32, 0x84
|
|
|
-- .byte 0
|
|
|
-- .ascii "Chips & Technologies"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# Cirrus Logic 5X0
|
|
|
--cirrus1_test:
|
|
|
-- movw $0x3d4, %dx
|
|
|
-- movb $0x0c, %al
|
|
|
-- outb %al, %dx
|
|
|
-- incw %dx
|
|
|
-- inb %dx, %al
|
|
|
-- movb %al, %bl
|
|
|
-- xorb %al, %al
|
|
|
-- outb %al, %dx
|
|
|
-- decw %dx
|
|
|
-- movb $0x1f, %al
|
|
|
-- outb %al, %dx
|
|
|
-- incw %dx
|
|
|
-- inb %dx, %al
|
|
|
-- movb %al, %bh
|
|
|
-- xorb %ah, %ah
|
|
|
-- shlb $4, %al
|
|
|
-- movw %ax, %cx
|
|
|
-- movb %bh, %al
|
|
|
-- shrb $4, %al
|
|
|
-- addw %ax, %cx
|
|
|
-- shlw $8, %cx
|
|
|
-- addw $6, %cx
|
|
|
-- movw %cx, %ax
|
|
|
-- movw $0x3c4, %dx
|
|
|
-- outw %ax, %dx
|
|
|
-- incw %dx
|
|
|
-- inb %dx, %al
|
|
|
-- andb %al, %al
|
|
|
-- jnz nocirr
|
|
|
--
|
|
|
-- movb %bh, %al
|
|
|
-- outb %al, %dx
|
|
|
-- inb %dx, %al
|
|
|
-- cmpb $0x01, %al
|
|
|
-- je iscirr
|
|
|
--
|
|
|
--nocirr: xorw %bp, %bp
|
|
|
--iscirr: movw $0x3d4, %dx
|
|
|
-- movb %bl, %al
|
|
|
-- xorb %ah, %ah
|
|
|
-- shlw $8, %ax
|
|
|
-- addw $0x0c, %ax
|
|
|
-- outw %ax, %dx
|
|
|
-- ret
|
|
|
--
|
|
|
--cirrus1_md:
|
|
|
-- .byte 0x1f, 0x19, 0x84
|
|
|
-- .byte 0x20, 0x2c, 0x84
|
|
|
-- .byte 0x22, 0x1e, 0x84
|
|
|
-- .byte 0x31, 0x25, 0x64
|
|
|
-- .byte 0
|
|
|
-- .ascii "Cirrus Logic 5X0"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# Cirrus Logic 54XX
|
|
|
--cirrus5_test:
|
|
|
-- movw $0x3c4, %dx
|
|
|
-- movb $6, %al
|
|
|
-- call inidx
|
|
|
-- movb %al, %bl # BL=backup
|
|
|
-- movw $6, %ax
|
|
|
-- call tstidx
|
|
|
-- cmpb $0x0f, %al
|
|
|
-- jne c5fail
|
|
|
--
|
|
|
-- movw $0x1206, %ax
|
|
|
-- call tstidx
|
|
|
-- cmpb $0x12, %al
|
|
|
-- jne c5fail
|
|
|
--
|
|
|
-- movb $0x1e, %al
|
|
|
-- call inidx
|
|
|
-- movb %al, %bh
|
|
|
-- movb %bh, %ah
|
|
|
-- andb $0xc0, %ah
|
|
|
-- movb $0x1e, %al
|
|
|
-- call tstidx
|
|
|
-- andb $0x3f, %al
|
|
|
-- jne c5xx
|
|
|
--
|
|
|
-- movb $0x1e, %al
|
|
|
-- movb %bh, %ah
|
|
|
-- orb $0x3f, %ah
|
|
|
-- call tstidx
|
|
|
-- xorb $0x3f, %al
|
|
|
-- andb $0x3f, %al
|
|
|
--c5xx: pushf
|
|
|
-- movb $0x1e, %al
|
|
|
-- movb %bh, %ah
|
|
|
-- outw %ax, %dx
|
|
|
-- popf
|
|
|
-- je c5done
|
|
|
--
|
|
|
--c5fail: xorw %bp, %bp
|
|
|
--c5done: movb $6, %al
|
|
|
-- movb %bl, %ah
|
|
|
-- outw %ax, %dx
|
|
|
-- ret
|
|
|
--
|
|
|
--cirrus5_md:
|
|
|
-- .byte 0x14, 0x19, 0x84
|
|
|
-- .byte 0x54, 0x2b, 0x84
|
|
|
-- .byte 0
|
|
|
-- .ascii "Cirrus Logic 54XX"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# Cirrus Logic 64XX -- no known extra modes, but must be identified, because
|
|
|
--# it's misidentified by the Ahead test.
|
|
|
--cirrus6_test:
|
|
|
-- movw $0x3ce, %dx
|
|
|
-- movb $0x0a, %al
|
|
|
-- call inidx
|
|
|
-- movb %al, %bl # BL=backup
|
|
|
-- movw $0xce0a, %ax
|
|
|
-- call tstidx
|
|
|
-- orb %al, %al
|
|
|
-- jne c2fail
|
|
|
--
|
|
|
-- movw $0xec0a, %ax
|
|
|
-- call tstidx
|
|
|
-- cmpb $0x01, %al
|
|
|
-- jne c2fail
|
|
|
--
|
|
|
-- movb $0xaa, %al
|
|
|
-- call inidx # 4X, 5X, 7X and 8X are valid 64XX chip ID's.
|
|
|
-- shrb $4, %al
|
|
|
-- subb $4, %al
|
|
|
-- jz c6done
|
|
|
--
|
|
|
-- decb %al
|
|
|
-- jz c6done
|
|
|
--
|
|
|
-- subb $2, %al
|
|
|
-- jz c6done
|
|
|
--
|
|
|
-- decb %al
|
|
|
-- jz c6done
|
|
|
--
|
|
|
--c2fail: xorw %bp, %bp
|
|
|
--c6done: movb $0x0a, %al
|
|
|
-- movb %bl, %ah
|
|
|
-- outw %ax, %dx
|
|
|
-- ret
|
|
|
--
|
|
|
--cirrus6_md:
|
|
|
-- .byte 0
|
|
|
-- .ascii "Cirrus Logic 64XX"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# Everex / Trident
|
|
|
--everex_test:
|
|
|
-- movw $0x7000, %ax
|
|
|
-- xorw %bx, %bx
|
|
|
-- int $0x10
|
|
|
-- cmpb $0x70, %al
|
|
|
-- jne noevrx
|
|
|
--
|
|
|
-- shrw $4, %dx
|
|
|
-- cmpw $0x678, %dx
|
|
|
-- je evtrid
|
|
|
--
|
|
|
-- cmpw $0x236, %dx
|
|
|
-- jne evrxok
|
|
|
--
|
|
|
--evtrid: leaw trident_md, %bp
|
|
|
--evrxok: ret
|
|
|
--
|
|
|
--noevrx: xorw %bp, %bp
|
|
|
-- ret
|
|
|
--
|
|
|
--everex_md:
|
|
|
-- .byte 0x03, 0x22, 0x50
|
|
|
-- .byte 0x04, 0x3c, 0x50
|
|
|
-- .byte 0x07, 0x2b, 0x64
|
|
|
-- .byte 0x08, 0x4b, 0x64
|
|
|
-- .byte 0x0a, 0x19, 0x84
|
|
|
-- .byte 0x0b, 0x2c, 0x84
|
|
|
-- .byte 0x16, 0x1e, 0x50
|
|
|
-- .byte 0x18, 0x1b, 0x64
|
|
|
-- .byte 0x21, 0x40, 0xa0
|
|
|
-- .byte 0x40, 0x1e, 0x84
|
|
|
-- .byte 0
|
|
|
-- .ascii "Everex/Trident"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# Genoa.
|
|
|
--genoa_test:
|
|
|
-- leaw idgenoa, %si # Check Genoa 'clues'
|
|
|
-- xorw %ax, %ax
|
|
|
-- movb %es:(0x37), %al
|
|
|
-- movw %ax, %di
|
|
|
-- movw $0x04, %cx
|
|
|
-- decw %si
|
|
|
-- decw %di
|
|
|
--l1: incw %si
|
|
|
-- incw %di
|
|
|
-- movb (%si), %al
|
|
|
-- testb %al, %al
|
|
|
-- jz l2
|
|
|
--
|
|
|
-- cmpb %es:(%di), %al
|
|
|
--l2: loope l1
|
|
|
-- orw %cx, %cx
|
|
|
-- je isgen
|
|
|
--
|
|
|
-- xorw %bp, %bp
|
|
|
--isgen: ret
|
|
|
--
|
|
|
--idgenoa: .byte 0x77, 0x00, 0x99, 0x66
|
|
|
--
|
|
|
--genoa_md:
|
|
|
-- .byte 0x58, 0x20, 0x50
|
|
|
-- .byte 0x5a, 0x2a, 0x64
|
|
|
-- .byte 0x60, 0x19, 0x84
|
|
|
-- .byte 0x61, 0x1d, 0x84
|
|
|
-- .byte 0x62, 0x20, 0x84
|
|
|
-- .byte 0x63, 0x2c, 0x84
|
|
|
-- .byte 0x64, 0x3c, 0x84
|
|
|
-- .byte 0x6b, 0x4f, 0x64
|
|
|
-- .byte 0x72, 0x3c, 0x50
|
|
|
-- .byte 0x74, 0x42, 0x50
|
|
|
-- .byte 0x78, 0x4b, 0x64
|
|
|
-- .byte 0
|
|
|
-- .ascii "Genoa"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# OAK
|
|
|
--oak_test:
|
|
|
-- leaw idoakvga, %si
|
|
|
-- movw $0x08, %di
|
|
|
-- movw $0x08, %cx
|
|
|
-- repe
|
|
|
-- cmpsb
|
|
|
-- je isoak
|
|
|
--
|
|
|
-- xorw %bp, %bp
|
|
|
--isoak: ret
|
|
|
--
|
|
|
--idoakvga: .ascii "OAK VGA "
|
|
|
--
|
|
|
--oak_md: .byte 0x4e, 0x3c, 0x50
|
|
|
-- .byte 0x4f, 0x3c, 0x84
|
|
|
-- .byte 0x50, 0x19, 0x84
|
|
|
-- .byte 0x51, 0x2b, 0x84
|
|
|
-- .byte 0
|
|
|
-- .ascii "OAK"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# WD Paradise.
|
|
|
--paradise_test:
|
|
|
-- leaw idparadise, %si
|
|
|
-- movw $0x7d, %di
|
|
|
-- movw $0x04, %cx
|
|
|
-- repe
|
|
|
-- cmpsb
|
|
|
-- je ispara
|
|
|
--
|
|
|
-- xorw %bp, %bp
|
|
|
--ispara: ret
|
|
|
--
|
|
|
--idparadise: .ascii "VGA="
|
|
|
--
|
|
|
--paradise_md:
|
|
|
-- .byte 0x41, 0x22, 0x50
|
|
|
-- .byte 0x47, 0x1c, 0x84
|
|
|
-- .byte 0x55, 0x19, 0x84
|
|
|
-- .byte 0x54, 0x2c, 0x84
|
|
|
-- .byte 0
|
|
|
-- .ascii "Paradise"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# Trident.
|
|
|
--trident_test:
|
|
|
-- movw $0x3c4, %dx
|
|
|
-- movb $0x0e, %al
|
|
|
-- outb %al, %dx
|
|
|
-- incw %dx
|
|
|
-- inb %dx, %al
|
|
|
-- xchgb %al, %ah
|
|
|
-- xorb %al, %al
|
|
|
-- outb %al, %dx
|
|
|
-- inb %dx, %al
|
|
|
-- xchgb %ah, %al
|
|
|
-- movb %al, %bl # Strange thing ... in the book this wasn't
|
|
|
-- andb $0x02, %bl # necessary but it worked on my card which
|
|
|
-- jz setb2 # is a trident. Without it the screen goes
|
|
|
-- # blurred ...
|
|
|
-- andb $0xfd, %al
|
|
|
-- jmp clrb2
|
|
|
--
|
|
|
--setb2: orb $0x02, %al
|
|
|
--clrb2: outb %al, %dx
|
|
|
-- andb $0x0f, %ah
|
|
|
-- cmpb $0x02, %ah
|
|
|
-- je istrid
|
|
|
--
|
|
|
-- xorw %bp, %bp
|
|
|
--istrid: ret
|
|
|
--
|
|
|
--trident_md:
|
|
|
-- .byte 0x50, 0x1e, 0x50
|
|
|
-- .byte 0x51, 0x2b, 0x50
|
|
|
-- .byte 0x52, 0x3c, 0x50
|
|
|
-- .byte 0x57, 0x19, 0x84
|
|
|
-- .byte 0x58, 0x1e, 0x84
|
|
|
-- .byte 0x59, 0x2b, 0x84
|
|
|
-- .byte 0x5a, 0x3c, 0x84
|
|
|
-- .byte 0
|
|
|
-- .ascii "Trident"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# Tseng.
|
|
|
--tseng_test:
|
|
|
-- movw $0x3cd, %dx
|
|
|
-- inb %dx, %al # Could things be this simple ! :-)
|
|
|
-- movb %al, %bl
|
|
|
-- movb $0x55, %al
|
|
|
-- outb %al, %dx
|
|
|
-- inb %dx, %al
|
|
|
-- movb %al, %ah
|
|
|
-- movb %bl, %al
|
|
|
-- outb %al, %dx
|
|
|
-- cmpb $0x55, %ah
|
|
|
-- je istsen
|
|
|
--
|
|
|
--isnot: xorw %bp, %bp
|
|
|
--istsen: ret
|
|
|
--
|
|
|
--tseng_md:
|
|
|
-- .byte 0x26, 0x3c, 0x50
|
|
|
-- .byte 0x2a, 0x28, 0x64
|
|
|
-- .byte 0x23, 0x19, 0x84
|
|
|
-- .byte 0x24, 0x1c, 0x84
|
|
|
-- .byte 0x22, 0x2c, 0x84
|
|
|
-- .byte 0x21, 0x3c, 0x84
|
|
|
-- .byte 0
|
|
|
-- .ascii "Tseng"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# Video7.
|
|
|
--video7_test:
|
|
|
-- movw $0x3cc, %dx
|
|
|
-- inb %dx, %al
|
|
|
-- movw $0x3b4, %dx
|
|
|
-- andb $0x01, %al
|
|
|
-- jz even7
|
|
|
--
|
|
|
-- movw $0x3d4, %dx
|
|
|
--even7: movb $0x0c, %al
|
|
|
-- outb %al, %dx
|
|
|
-- incw %dx
|
|
|
-- inb %dx, %al
|
|
|
-- movb %al, %bl
|
|
|
-- movb $0x55, %al
|
|
|
-- outb %al, %dx
|
|
|
-- inb %dx, %al
|
|
|
-- decw %dx
|
|
|
-- movb $0x1f, %al
|
|
|
-- outb %al, %dx
|
|
|
-- incw %dx
|
|
|
-- inb %dx, %al
|
|
|
-- movb %al, %bh
|
|
|
-- decw %dx
|
|
|
-- movb $0x0c, %al
|
|
|
-- outb %al, %dx
|
|
|
-- incw %dx
|
|
|
-- movb %bl, %al
|
|
|
-- outb %al, %dx
|
|
|
-- movb $0x55, %al
|
|
|
-- xorb $0xea, %al
|
|
|
-- cmpb %bh, %al
|
|
|
-- jne isnot
|
|
|
--
|
|
|
-- movb $VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching
|
|
|
-- ret
|
|
|
--
|
|
|
--video7_md:
|
|
|
-- .byte 0x40, 0x2b, 0x50
|
|
|
-- .byte 0x43, 0x3c, 0x50
|
|
|
-- .byte 0x44, 0x3c, 0x64
|
|
|
-- .byte 0x41, 0x19, 0x84
|
|
|
-- .byte 0x42, 0x2c, 0x84
|
|
|
-- .byte 0x45, 0x1c, 0x84
|
|
|
-- .byte 0
|
|
|
-- .ascii "Video 7"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# Realtek VGA
|
|
|
--realtek_test:
|
|
|
-- leaw idrtvga, %si
|
|
|
-- movw $0x45, %di
|
|
|
-- movw $0x0b, %cx
|
|
|
-- repe
|
|
|
-- cmpsb
|
|
|
-- je isrt
|
|
|
--
|
|
|
-- xorw %bp, %bp
|
|
|
--isrt: ret
|
|
|
--
|
|
|
--idrtvga: .ascii "REALTEK VGA"
|
|
|
--
|
|
|
--realtek_md:
|
|
|
-- .byte 0x1a, 0x3c, 0x50
|
|
|
-- .byte 0x1b, 0x19, 0x84
|
|
|
-- .byte 0x1c, 0x1e, 0x84
|
|
|
-- .byte 0x1d, 0x2b, 0x84
|
|
|
-- .byte 0x1e, 0x3c, 0x84
|
|
|
-- .byte 0
|
|
|
-- .ascii "REALTEK"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--#endif /* CONFIG_VIDEO_SVGA */
|
|
|
--
|
|
|
--# User-defined local mode table (VGA only)
|
|
|
--#ifdef CONFIG_VIDEO_LOCAL
|
|
|
--local_modes:
|
|
|
-- leaw local_mode_table, %si
|
|
|
--locm1: lodsw
|
|
|
-- orw %ax, %ax
|
|
|
-- jz locm2
|
|
|
--
|
|
|
-- stosw
|
|
|
-- movsw
|
|
|
-- jmp locm1
|
|
|
--
|
|
|
--locm2: ret
|
|
|
--
|
|
|
--# This is the table of local video modes which can be supplied manually
|
|
|
--# by the user. Each entry consists of mode ID (word) and dimensions
|
|
|
--# (byte for column count and another byte for row count). These modes
|
|
|
--# are placed before all SVGA and VESA modes and override them if table
|
|
|
--# compacting is enabled. The table must end with a zero word followed
|
|
|
--# by NUL-terminated video adapter name.
|
|
|
--local_mode_table:
|
|
|
-- .word 0x0100 # Example: 40x25
|
|
|
-- .byte 25,40
|
|
|
-- .word 0
|
|
|
-- .ascii "Local"
|
|
|
-- .byte 0
|
|
|
--#endif /* CONFIG_VIDEO_LOCAL */
|
|
|
--
|
|
|
--# Read a key and return the ASCII code in al, scan code in ah
|
|
|
--getkey: xorb %ah, %ah
|
|
|
-- int $0x16
|
|
|
-- ret
|
|
|
--
|
|
|
--# Read a key with a timeout of 30 seconds.
|
|
|
--# The hardware clock is used to get the time.
|
|
|
--getkt: call gettime
|
|
|
-- addb $30, %al # Wait 30 seconds
|
|
|
-- cmpb $60, %al
|
|
|
-- jl lminute
|
|
|
--
|
|
|
-- subb $60, %al
|
|
|
--lminute:
|
|
|
-- movb %al, %cl
|
|
|
--again: movb $0x01, %ah
|
|
|
-- int $0x16
|
|
|
-- jnz getkey # key pressed, so get it
|
|
|
--
|
|
|
-- call gettime
|
|
|
-- cmpb %cl, %al
|
|
|
-- jne again
|
|
|
--
|
|
|
-- movb $0x20, %al # timeout, return `space'
|
|
|
-- ret
|
|
|
--
|
|
|
--# Flush the keyboard buffer
|
|
|
--flush: movb $0x01, %ah
|
|
|
-- int $0x16
|
|
|
-- jz empty
|
|
|
--
|
|
|
-- xorb %ah, %ah
|
|
|
-- int $0x16
|
|
|
-- jmp flush
|
|
|
--
|
|
|
--empty: ret
|
|
|
--
|
|
|
--# Print hexadecimal number.
|
|
|
--prthw: pushw %ax
|
|
|
-- movb %ah, %al
|
|
|
-- call prthb
|
|
|
-- popw %ax
|
|
|
--prthb: pushw %ax
|
|
|
-- shrb $4, %al
|
|
|
-- call prthn
|
|
|
-- popw %ax
|
|
|
-- andb $0x0f, %al
|
|
|
--prthn: cmpb $0x0a, %al
|
|
|
-- jc prth1
|
|
|
--
|
|
|
-- addb $0x07, %al
|
|
|
--prth1: addb $0x30, %al
|
|
|
-- jmp prtchr
|
|
|
--
|
|
|
--# Print decimal number in al
|
|
|
--prtdec: pushw %ax
|
|
|
-- pushw %cx
|
|
|
-- xorb %ah, %ah
|
|
|
-- movb $0x0a, %cl
|
|
|
-- idivb %cl
|
|
|
-- cmpb $0x09, %al
|
|
|
-- jbe lt100
|
|
|
--
|
|
|
-- call prtdec
|
|
|
-- jmp skip10
|
|
|
--
|
|
|
--lt100: addb $0x30, %al
|
|
|
-- call prtchr
|
|
|
--skip10: movb %ah, %al
|
|
|
-- addb $0x30, %al
|
|
|
-- call prtchr
|
|
|
-- popw %cx
|
|
|
-- popw %ax
|
|
|
-- ret
|
|
|
--
|
|
|
--store_edid:
|
|
|
--#ifdef CONFIG_FIRMWARE_EDID
|
|
|
-- pushw %es # just save all registers
|
|
|
-- pushw %ax
|
|
|
-- pushw %bx
|
|
|
-- pushw %cx
|
|
|
-- pushw %dx
|
|
|
-- pushw %di
|
|
|
--
|
|
|
-- pushw %fs
|
|
|
-- popw %es
|
|
|
--
|
|
|
-- movl $0x13131313, %eax # memset block with 0x13
|
|
|
-- movw $32, %cx
|
|
|
-- movw $0x140, %di
|
|
|
-- cld
|
|
|
-- rep
|
|
|
-- stosl
|
|
|
--
|
|
|
-- cmpw $0x0200, vbe_version # only do EDID on >= VBE2.0
|
|
|
-- jl no_edid
|
|
|
--
|
|
|
-- pushw %es # save ES
|
|
|
-- xorw %di, %di # Report Capability
|
|
|
-- pushw %di
|
|
|
-- popw %es # ES:DI must be 0:0
|
|
|
-- movw $0x4f15, %ax
|
|
|
-- xorw %bx, %bx
|
|
|
-- xorw %cx, %cx
|
|
|
-- int $0x10
|
|
|
-- popw %es # restore ES
|
|
|
--
|
|
|
-- cmpb $0x00, %ah # call successful
|
|
|
-- jne no_edid
|
|
|
--
|
|
|
-- cmpb $0x4f, %al # function supported
|
|
|
-- jne no_edid
|
|
|
--
|
|
|
-- movw $0x4f15, %ax # do VBE/DDC
|
|
|
-- movw $0x01, %bx
|
|
|
-- movw $0x00, %cx
|
|
|
-- movw $0x00, %dx
|
|
|
-- movw $0x140, %di
|
|
|
-- int $0x10
|
|
|
--
|
|
|
--no_edid:
|
|
|
-- popw %di # restore all registers
|
|
|
-- popw %dx
|
|
|
-- popw %cx
|
|
|
-- popw %bx
|
|
|
-- popw %ax
|
|
|
-- popw %es
|
|
|
--#endif
|
|
|
-- ret
|
|
|
--
|
|
|
--# VIDEO_SELECT-only variables
|
|
|
--mt_end: .word 0 # End of video mode table if built
|
|
|
--edit_buf: .space 6 # Line editor buffer
|
|
|
--card_name: .word 0 # Pointer to adapter name
|
|
|
--scanning: .byte 0 # Performing mode scan
|
|
|
--do_restore: .byte 0 # Screen contents altered during mode change
|
|
|
--svga_prefix: .byte VIDEO_FIRST_BIOS>>8 # Default prefix for BIOS modes
|
|
|
--graphic_mode: .byte 0 # Graphic mode with a linear frame buffer
|
|
|
--dac_size: .byte 6 # DAC bit depth
|
|
|
--vbe_version: .word 0 # VBE bios version
|
|
|
--
|
|
|
--# Status messages
|
|
|
--keymsg: .ascii "Press <RETURN> to see video modes available, "
|
|
|
-- .ascii "<SPACE> to continue or wait 30 secs"
|
|
|
-- .byte 0x0d, 0x0a, 0
|
|
|
--
|
|
|
--listhdr: .byte 0x0d, 0x0a
|
|
|
-- .ascii "Mode: COLSxROWS:"
|
|
|
--
|
|
|
--crlft: .byte 0x0d, 0x0a, 0
|
|
|
--
|
|
|
--prompt: .byte 0x0d, 0x0a
|
|
|
-- .asciz "Enter mode number or `scan': "
|
|
|
--
|
|
|
--unknt: .asciz "Unknown mode ID. Try again."
|
|
|
--
|
|
|
--badmdt: .ascii "You passed an undefined mode number."
|
|
|
-- .byte 0x0d, 0x0a, 0
|
|
|
--
|
|
|
--vesaer: .ascii "Error: Scanning of VESA modes failed. Please "
|
|
|
-- .ascii "report to <[email protected]>."
|
|
|
-- .byte 0x0d, 0x0a, 0
|
|
|
--
|
|
|
--old_name: .asciz "CGA/MDA/HGA"
|
|
|
--
|
|
|
--ega_name: .asciz "EGA"
|
|
|
--
|
|
|
--svga_name: .ascii " "
|
|
|
--
|
|
|
--vga_name: .asciz "VGA"
|
|
|
--
|
|
|
--vesa_name: .asciz "VESA"
|
|
|
--
|
|
|
--name_bann: .asciz "Video adapter: "
|
|
|
--#endif /* CONFIG_VIDEO_SELECT */
|
|
|
--
|
|
|
--# Other variables:
|
|
|
--adapter: .byte 0 # Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA
|
|
|
--video_segment: .word 0xb800 # Video memory segment
|
|
|
--force_size: .word 0 # Use this size instead of the one in BIOS vars
|
|
|
-diff -puN /dev/null arch/i386/boot/video.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/video.c
|
|
|
-@@ -0,0 +1,456 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/video.c
|
|
|
-+ *
|
|
|
-+ * Select video mode
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+#include "video.h"
|
|
|
-+#include "vesa.h"
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Mode list variables
|
|
|
-+ */
|
|
|
-+static struct card_info cards[]; /* List of cards to probe for */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Common variables
|
|
|
-+ */
|
|
|
-+int adapter; /* 0=CGA/MDA/HGC, 1=EGA, 2=VGA+ */
|
|
|
-+u16 video_segment;
|
|
|
-+int force_x, force_y; /* Don't query the BIOS for cols/rows */
|
|
|
-+
|
|
|
-+int do_restore = 0; /* Screen contents changed during mode flip */
|
|
|
-+int graphic_mode; /* Graphic mode with linear frame buffer */
|
|
|
-+
|
|
|
-+static void store_cursor_position(void)
|
|
|
-+{
|
|
|
-+ u16 curpos;
|
|
|
-+ u16 ax, bx;
|
|
|
-+
|
|
|
-+ ax = 0x0300;
|
|
|
-+ bx = 0;
|
|
|
-+ asm(INT10
|
|
|
-+ : "=d" (curpos), "+a" (ax), "+b" (bx)
|
|
|
-+ : : "ecx", "esi", "edi");
|
|
|
-+
|
|
|
-+ boot_params.screen_info.orig_x = curpos;
|
|
|
-+ boot_params.screen_info.orig_y = curpos >> 8;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void store_video_mode(void)
|
|
|
-+{
|
|
|
-+ u16 ax, page;
|
|
|
-+
|
|
|
-+ /* N.B.: the saving of the video page here is a bit silly,
|
|
|
-+ since we pretty much assume page 0 everywhere. */
|
|
|
-+ ax = 0x0f00;
|
|
|
-+ asm(INT10
|
|
|
-+ : "+a" (ax), "=b" (page)
|
|
|
-+ : : "ecx", "edx", "esi", "edi");
|
|
|
-+
|
|
|
-+ /* Not all BIOSes are clean with respect to the top bit */
|
|
|
-+ boot_params.screen_info.orig_video_mode = ax & 0x7f;
|
|
|
-+ boot_params.screen_info.orig_video_page = page;
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Store the video mode parameters for later usage by the kernel.
|
|
|
-+ * This is done by asking the BIOS except for the rows/columns
|
|
|
-+ * parameters in the default 80x25 mode -- these are set directly,
|
|
|
-+ * because some very obscure BIOSes supply insane values.
|
|
|
-+ */
|
|
|
-+static void store_mode_params(void)
|
|
|
-+{
|
|
|
-+ u16 font_size;
|
|
|
-+ int x, y;
|
|
|
-+
|
|
|
-+ /* For graphics mode, it is up to the mode-setting driver
|
|
|
-+ (currently only video-vesa.c) to store the parameters */
|
|
|
-+ if (graphic_mode)
|
|
|
-+ return;
|
|
|
-+
|
|
|
-+ store_cursor_position();
|
|
|
-+ store_video_mode();
|
|
|
-+
|
|
|
-+ if (boot_params.screen_info.orig_video_mode == 0x07) {
|
|
|
-+ /* MDA, HGC, or VGA in monochrome mode */
|
|
|
-+ video_segment = 0xb000;
|
|
|
-+ } else {
|
|
|
-+ /* CGA, EGA, VGA and so forth */
|
|
|
-+ video_segment = 0xb800;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ set_fs(0);
|
|
|
-+ font_size = rdfs16(0x485); /* Font size, BIOS area */
|
|
|
-+ boot_params.screen_info.orig_video_points = font_size;
|
|
|
-+
|
|
|
-+ x = rdfs16(0x44a);
|
|
|
-+ y = (adapter == ADAPTER_CGA) ? 25 : rdfs8(0x484)+1;
|
|
|
-+
|
|
|
-+ if (force_x)
|
|
|
-+ x = force_x;
|
|
|
-+ if (force_y)
|
|
|
-+ y = force_y;
|
|
|
-+
|
|
|
-+ boot_params.screen_info.orig_video_cols = x;
|
|
|
-+ boot_params.screen_info.orig_video_lines = y;
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Probe the video drivers and have them generate their mode lists. */
|
|
|
-+static void probe_cards(int unsafe)
|
|
|
-+{
|
|
|
-+ struct card_info *card;
|
|
|
-+ static u8 probed[2];
|
|
|
-+
|
|
|
-+ if (probed[unsafe])
|
|
|
-+ return;
|
|
|
-+
|
|
|
-+ probed[unsafe] = 1;
|
|
|
-+
|
|
|
-+ for (card = video_cards; card < video_cards_end; card++) {
|
|
|
-+ if (card->unsafe == unsafe) {
|
|
|
-+ if (card->probe)
|
|
|
-+ card->nmodes = card->probe();
|
|
|
-+ else
|
|
|
-+ card->nmodes = 0;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Test if a mode is defined */
|
|
|
-+int mode_defined(u16 mode)
|
|
|
-+{
|
|
|
-+ struct card_info *card;
|
|
|
-+ struct mode_info *mi;
|
|
|
-+ int i;
|
|
|
-+
|
|
|
-+ for (card = video_cards; card < video_cards_end; card++) {
|
|
|
-+ mi = card->modes;
|
|
|
-+ for (i = 0; i < card->nmodes; i++, mi++) {
|
|
|
-+ if (mi->mode == mode)
|
|
|
-+ return 1;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Set mode (without recalc) */
|
|
|
-+static int raw_set_mode(u16 mode)
|
|
|
-+{
|
|
|
-+ int nmode, i;
|
|
|
-+ struct card_info *card;
|
|
|
-+ struct mode_info *mi;
|
|
|
-+
|
|
|
-+ /* Drop the recalc bit if set */
|
|
|
-+ mode &= ~VIDEO_RECALC;
|
|
|
-+
|
|
|
-+ /* Scan for mode based on fixed ID, position, or resolution */
|
|
|
-+ nmode = 0;
|
|
|
-+ for (card = video_cards; card < video_cards_end; card++) {
|
|
|
-+ mi = card->modes;
|
|
|
-+ for (i = 0; i < card->nmodes; i++, mi++) {
|
|
|
-+ int visible = mi->x || mi->y;
|
|
|
-+
|
|
|
-+ if ((mode == nmode && visible) ||
|
|
|
-+ mode == mi->mode ||
|
|
|
-+ mode == (mi->y << 8)+mi->x)
|
|
|
-+ return card->set_mode(mi);
|
|
|
-+
|
|
|
-+ if (visible)
|
|
|
-+ nmode++;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Nothing found? Is it an "exceptional" (unprobed) mode? */
|
|
|
-+ for (card = video_cards; card < video_cards_end; card++) {
|
|
|
-+ if (mode >= card->xmode_first &&
|
|
|
-+ mode < card->xmode_first+card->xmode_n) {
|
|
|
-+ struct mode_info mix;
|
|
|
-+ mix.mode = mode;
|
|
|
-+ mix.x = mix.y = 0;
|
|
|
-+ return card->set_mode(&mix);
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Otherwise, failure... */
|
|
|
-+ return -1;
|
|
|
-+}
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Recalculate the vertical video cutoff (hack!)
|
|
|
-+ */
|
|
|
-+static void vga_recalc_vertical(void)
|
|
|
-+{
|
|
|
-+ unsigned int font_size, rows;
|
|
|
-+ u16 crtc;
|
|
|
-+ u8 ov;
|
|
|
-+
|
|
|
-+ set_fs(0);
|
|
|
-+ font_size = rdfs8(0x485); /* BIOS: font size (pixels) */
|
|
|
-+ rows = force_y ? force_y : rdfs8(0x484)+1; /* Text rows */
|
|
|
-+
|
|
|
-+ rows *= font_size; /* Visible scan lines */
|
|
|
-+ rows--; /* ... minus one */
|
|
|
-+
|
|
|
-+ crtc = vga_crtc();
|
|
|
-+
|
|
|
-+ out_idx((u8)rows, crtc, 0x12); /* Lower height register */
|
|
|
-+ ov = in_idx(crtc, 0x07); /* Overflow register */
|
|
|
-+ ov &= 0xbd;
|
|
|
-+ ov |= (rows >> (8-1)) & 0x02;
|
|
|
-+ ov |= (rows >> (9-6)) & 0x40;
|
|
|
-+ out_idx(ov, crtc, 0x07);
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Set mode (with recalc if specified) */
|
|
|
-+static int set_mode(u16 mode)
|
|
|
-+{
|
|
|
-+ int rv;
|
|
|
-+
|
|
|
-+ /* Very special mode numbers... */
|
|
|
-+ if (mode == VIDEO_CURRENT_MODE)
|
|
|
-+ return 0; /* Nothing to do... */
|
|
|
-+ else if (mode == NORMAL_VGA)
|
|
|
-+ mode = VIDEO_80x25;
|
|
|
-+ else if (mode == EXTENDED_VGA)
|
|
|
-+ mode = VIDEO_8POINT;
|
|
|
-+
|
|
|
-+ rv = raw_set_mode(mode);
|
|
|
-+ if (rv)
|
|
|
-+ return rv;
|
|
|
-+
|
|
|
-+ if (mode & VIDEO_RECALC)
|
|
|
-+ vga_recalc_vertical();
|
|
|
-+
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static unsigned int get_entry(void)
|
|
|
-+{
|
|
|
-+ char entry_buf[4];
|
|
|
-+ int i, len = 0;
|
|
|
-+ int key;
|
|
|
-+ unsigned int v;
|
|
|
-+
|
|
|
-+ do {
|
|
|
-+ key = getchar();
|
|
|
-+
|
|
|
-+ if (key == '\b') {
|
|
|
-+ if (len > 0) {
|
|
|
-+ puts("\b \b");
|
|
|
-+ len--;
|
|
|
-+ }
|
|
|
-+ } else if ((key >= '0' && key <= '9') ||
|
|
|
-+ (key >= 'A' && key <= 'Z') ||
|
|
|
-+ (key >= 'a' && key <= 'z')) {
|
|
|
-+ if (len < sizeof entry_buf) {
|
|
|
-+ entry_buf[len++] = key;
|
|
|
-+ putchar(key);
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ } while (key != '\r');
|
|
|
-+ putchar('\n');
|
|
|
-+
|
|
|
-+ if (len == 0)
|
|
|
-+ return VIDEO_CURRENT_MODE; /* Default */
|
|
|
-+
|
|
|
-+ v = 0;
|
|
|
-+ for (i = 0; i < len; i++) {
|
|
|
-+ v <<= 4;
|
|
|
-+ key = entry_buf[i] | 0x20;
|
|
|
-+ v += (key > '9') ? key-'a'+10 : key-'0';
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void display_menu(void)
|
|
|
-+{
|
|
|
-+ struct card_info *card;
|
|
|
-+ struct mode_info *mi;
|
|
|
-+ char ch;
|
|
|
-+ int i;
|
|
|
-+
|
|
|
-+ puts("Mode: COLSxROWS:\n");
|
|
|
-+
|
|
|
-+ ch = '0';
|
|
|
-+ for (card = video_cards; card < video_cards_end; card++) {
|
|
|
-+ mi = card->modes;
|
|
|
-+ for (i = 0; i < card->nmodes; i++, mi++) {
|
|
|
-+ int visible = mi->x && mi->y;
|
|
|
-+ u16 mode_id = mi->mode ? mi->mode :
|
|
|
-+ (mi->y << 8)+mi->x;
|
|
|
-+
|
|
|
-+ if (!visible)
|
|
|
-+ continue; /* Hidden mode */
|
|
|
-+
|
|
|
-+ printf("%c %04X %3dx%-3d %s\n",
|
|
|
-+ ch, mode_id, mi->x, mi->y, card->card_name);
|
|
|
-+
|
|
|
-+ if (ch == '9')
|
|
|
-+ ch = 'a';
|
|
|
-+ else if (ch == 'z' || ch == ' ')
|
|
|
-+ ch = ' '; /* Out of keys... */
|
|
|
-+ else
|
|
|
-+ ch++;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define H(x) ((x)-'a'+10)
|
|
|
-+#define SCAN ((H('s')<<12)+(H('c')<<8)+(H('a')<<4)+H('n'))
|
|
|
-+
|
|
|
-+static unsigned int mode_menu(void)
|
|
|
-+{
|
|
|
-+ int key;
|
|
|
-+ unsigned int sel;
|
|
|
-+
|
|
|
-+ puts("Press <ENTER> to see video modes available, "
|
|
|
-+ "<SPACE> to continue, or wait 30 sec\n");
|
|
|
-+
|
|
|
-+ kbd_flush();
|
|
|
-+ while (1) {
|
|
|
-+ key = getchar_timeout();
|
|
|
-+ if (key == ' ' || key == 0)
|
|
|
-+ return VIDEO_CURRENT_MODE; /* Default */
|
|
|
-+ if (key == '\r')
|
|
|
-+ break;
|
|
|
-+ putchar('\a'); /* Beep! */
|
|
|
-+ }
|
|
|
-+
|
|
|
-+
|
|
|
-+ for (;;) {
|
|
|
-+ display_menu();
|
|
|
-+
|
|
|
-+ puts("Enter a video mode or \"scan\" to scan for "
|
|
|
-+ "additional modes: ");
|
|
|
-+ sel = get_entry();
|
|
|
-+ if (sel != SCAN)
|
|
|
-+ return sel;
|
|
|
-+
|
|
|
-+ probe_cards(1);
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+#ifdef CONFIG_VIDEO_RETAIN
|
|
|
-+/* Save screen content to the heap */
|
|
|
-+struct saved_screen {
|
|
|
-+ int x, y;
|
|
|
-+ int curx, cury;
|
|
|
-+ u16 *data;
|
|
|
-+} saved;
|
|
|
-+
|
|
|
-+static void save_screen(void)
|
|
|
-+{
|
|
|
-+ /* Should be called after store_mode_params() */
|
|
|
-+ saved.x = boot_params.screen_info.orig_video_cols;
|
|
|
-+ saved.y = boot_params.screen_info.orig_video_lines;
|
|
|
-+ saved.curx = boot_params.screen_info.orig_x;
|
|
|
-+ saved.cury = boot_params.screen_info.orig_y;
|
|
|
-+
|
|
|
-+ if (heap_free() < saved.x*saved.y*sizeof(u16)+512)
|
|
|
-+ return; /* Not enough heap to save the screen */
|
|
|
-+
|
|
|
-+ saved.data = GET_HEAP(u16, saved.x*saved.y);
|
|
|
-+
|
|
|
-+ set_fs(video_segment);
|
|
|
-+ copy_from_fs(saved.data, 0, saved.x*saved.y*sizeof(u16));
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void restore_screen(void)
|
|
|
-+{
|
|
|
-+ /* Should be called after store_mode_params() */
|
|
|
-+ int xs = boot_params.screen_info.orig_video_cols;
|
|
|
-+ int ys = boot_params.screen_info.orig_video_lines;
|
|
|
-+ int y;
|
|
|
-+ addr_t dst = 0;
|
|
|
-+ u16 *src = saved.data;
|
|
|
-+ u16 ax, bx, dx;
|
|
|
-+
|
|
|
-+ if (graphic_mode)
|
|
|
-+ return; /* Can't restore onto a graphic mode */
|
|
|
-+
|
|
|
-+ if (!src)
|
|
|
-+ return; /* No saved screen contents */
|
|
|
-+
|
|
|
-+ /* Restore screen contents */
|
|
|
-+
|
|
|
-+ set_fs(video_segment);
|
|
|
-+ for (y = 0; y < ys; y++) {
|
|
|
-+ int npad;
|
|
|
-+
|
|
|
-+ if (y < saved.y) {
|
|
|
-+ int copy = (xs < saved.x) ? xs : saved.x;
|
|
|
-+ copy_to_fs(dst, src, copy*sizeof(u16));
|
|
|
-+ dst += copy*sizeof(u16);
|
|
|
-+ src += saved.x;
|
|
|
-+ npad = (xs < saved.x) ? 0 : xs-saved.x;
|
|
|
-+ } else {
|
|
|
-+ npad = xs;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Writes "npad" blank characters to
|
|
|
-+ video_segment:dst and advances dst */
|
|
|
-+ asm volatile("pushw %%es ; "
|
|
|
-+ "movw %2,%%es ; "
|
|
|
-+ "shrw %%cx ; "
|
|
|
-+ "jnc 1f ; "
|
|
|
-+ "stosw \n\t"
|
|
|
-+ "1: rep;stosl ; "
|
|
|
-+ "popw %%es"
|
|
|
-+ : "+D" (dst), "+c" (npad)
|
|
|
-+ : "bdSm" (video_segment),
|
|
|
-+ "a" (0x07200720));
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Restore cursor position */
|
|
|
-+ ax = 0x0200; /* Set cursor position */
|
|
|
-+ bx = 0; /* Page number (<< 8) */
|
|
|
-+ dx = (saved.cury << 8)+saved.curx;
|
|
|
-+ asm volatile(INT10
|
|
|
-+ : "+a" (ax), "+b" (bx), "+d" (dx)
|
|
|
-+ : : "ecx", "esi", "edi");
|
|
|
-+}
|
|
|
-+#else
|
|
|
-+#define save_screen() ((void)0)
|
|
|
-+#define restore_screen() ((void)0)
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+void set_video(void)
|
|
|
-+{
|
|
|
-+ u16 mode = boot_params.hdr.vid_mode;
|
|
|
-+
|
|
|
-+ RESET_HEAP();
|
|
|
-+
|
|
|
-+ store_mode_params();
|
|
|
-+ save_screen();
|
|
|
-+ probe_cards(0);
|
|
|
-+
|
|
|
-+ for (;;) {
|
|
|
-+ if (mode == ASK_VGA)
|
|
|
-+ mode = mode_menu();
|
|
|
-+
|
|
|
-+ if (!set_mode(mode))
|
|
|
-+ break;
|
|
|
-+
|
|
|
-+ printf("Undefined video mode number: %x\n", mode);
|
|
|
-+ mode = ASK_VGA;
|
|
|
-+ }
|
|
|
-+ vesa_store_edid();
|
|
|
-+ store_mode_params();
|
|
|
-+
|
|
|
-+ if (do_restore)
|
|
|
-+ restore_screen();
|
|
|
-+}
|
|
|
-diff -puN /dev/null arch/i386/boot/video.h
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/video.h
|
|
|
-@@ -0,0 +1,145 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/video.h
|
|
|
-+ *
|
|
|
-+ * Header file for the real-mode video probing code
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#ifndef BOOT_VIDEO_H
|
|
|
-+#define BOOT_VIDEO_H
|
|
|
-+
|
|
|
-+#include <linux/types.h>
|
|
|
-+
|
|
|
-+/* Enable autodetection of SVGA adapters and modes. */
|
|
|
-+#undef CONFIG_VIDEO_SVGA
|
|
|
-+
|
|
|
-+/* Enable autodetection of VESA modes */
|
|
|
-+#define CONFIG_VIDEO_VESA
|
|
|
-+
|
|
|
-+/* Retain screen contents when switching modes */
|
|
|
-+#define CONFIG_VIDEO_RETAIN
|
|
|
-+
|
|
|
-+/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
|
|
|
-+#undef CONFIG_VIDEO_400_HACK
|
|
|
-+
|
|
|
-+/* This code uses an extended set of video mode numbers. These include:
|
|
|
-+ * Aliases for standard modes
|
|
|
-+ * NORMAL_VGA (-1)
|
|
|
-+ * EXTENDED_VGA (-2)
|
|
|
-+ * ASK_VGA (-3)
|
|
|
-+ * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
|
|
|
-+ * of compatibility when extending the table. These are between 0x00 and 0xff.
|
|
|
-+ */
|
|
|
-+#define VIDEO_FIRST_MENU 0x0000
|
|
|
-+
|
|
|
-+/* Standard BIOS video modes (BIOS number + 0x0100) */
|
|
|
-+#define VIDEO_FIRST_BIOS 0x0100
|
|
|
-+
|
|
|
-+/* VESA BIOS video modes (VESA number + 0x0200) */
|
|
|
-+#define VIDEO_FIRST_VESA 0x0200
|
|
|
-+
|
|
|
-+/* Video7 special modes (BIOS number + 0x0900) */
|
|
|
-+#define VIDEO_FIRST_V7 0x0900
|
|
|
-+
|
|
|
-+/* Special video modes */
|
|
|
-+#define VIDEO_FIRST_SPECIAL 0x0f00
|
|
|
-+#define VIDEO_80x25 0x0f00
|
|
|
-+#define VIDEO_8POINT 0x0f01
|
|
|
-+#define VIDEO_80x43 0x0f02
|
|
|
-+#define VIDEO_80x28 0x0f03
|
|
|
-+#define VIDEO_CURRENT_MODE 0x0f04
|
|
|
-+#define VIDEO_80x30 0x0f05
|
|
|
-+#define VIDEO_80x34 0x0f06
|
|
|
-+#define VIDEO_80x60 0x0f07
|
|
|
-+#define VIDEO_GFX_HACK 0x0f08
|
|
|
-+#define VIDEO_LAST_SPECIAL 0x0f09
|
|
|
-+
|
|
|
-+/* Video modes given by resolution */
|
|
|
-+#define VIDEO_FIRST_RESOLUTION 0x1000
|
|
|
-+
|
|
|
-+/* The "recalculate timings" flag */
|
|
|
-+#define VIDEO_RECALC 0x8000
|
|
|
-+
|
|
|
-+/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
|
|
|
-+#ifdef CONFIG_VIDEO_RETAIN
|
|
|
-+void store_screen(void);
|
|
|
-+#define DO_STORE() store_screen()
|
|
|
-+#else
|
|
|
-+#define DO_STORE() ((void)0)
|
|
|
-+#endif /* CONFIG_VIDEO_RETAIN */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Mode table structures
|
|
|
-+ */
|
|
|
-+
|
|
|
-+struct mode_info {
|
|
|
-+ u16 mode; /* Mode number (vga= style) */
|
|
|
-+ u8 x, y; /* Width, height */
|
|
|
-+};
|
|
|
-+
|
|
|
-+struct card_info {
|
|
|
-+ const char *card_name;
|
|
|
-+ int (*set_mode)(struct mode_info *mode);
|
|
|
-+ int (*probe)(void);
|
|
|
-+ struct mode_info *modes;
|
|
|
-+ int nmodes; /* Number of probed modes so far */
|
|
|
-+ int unsafe; /* Probing is unsafe, only do after "scan" */
|
|
|
-+ u16 xmode_first; /* Unprobed modes to try to call anyway */
|
|
|
-+ u16 xmode_n; /* Size of unprobed mode range */
|
|
|
-+};
|
|
|
-+
|
|
|
-+#define __videocard struct card_info __attribute__((section(".videocards")))
|
|
|
-+extern struct card_info video_cards[], video_cards_end[];
|
|
|
-+
|
|
|
-+int mode_defined(u16 mode); /* video.c */
|
|
|
-+
|
|
|
-+/* Basic video information */
|
|
|
-+#define ADAPTER_CGA 0 /* CGA/MDA/HGC */
|
|
|
-+#define ADAPTER_EGA 1
|
|
|
-+#define ADAPTER_VGA 2
|
|
|
-+
|
|
|
-+extern int adapter;
|
|
|
-+extern u16 video_segment;
|
|
|
-+extern int force_x, force_y; /* Don't query the BIOS for cols/rows */
|
|
|
-+extern int do_restore; /* Restore screen contents */
|
|
|
-+extern int graphic_mode; /* Graphics mode with linear frame buffer */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * int $0x10 is notorious for touching registers it shouldn't.
|
|
|
-+ * gcc doesn't like %ebp being clobbered, so define it as a push/pop
|
|
|
-+ * sequence here.
|
|
|
-+ */
|
|
|
-+#define INT10 "pushl %%ebp; int $0x10; popl %%ebp"
|
|
|
-+
|
|
|
-+/* Accessing VGA indexed registers */
|
|
|
-+static inline u8 in_idx(u16 port, u8 index)
|
|
|
-+{
|
|
|
-+ outb(index, port);
|
|
|
-+ return inb(port+1);
|
|
|
-+}
|
|
|
-+
|
|
|
-+static inline void out_idx(u8 v, u16 port, u8 index)
|
|
|
-+{
|
|
|
-+ outw(index+(v << 8), port);
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Writes a value to an indexed port and then reads the port again */
|
|
|
-+static inline u8 tst_idx(u8 v, u16 port, u8 index)
|
|
|
-+{
|
|
|
-+ out_idx(port, index, v);
|
|
|
-+ return in_idx(port, index);
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Get the I/O port of the VGA CRTC */
|
|
|
-+u16 vga_crtc(void); /* video-vga.c */
|
|
|
-+
|
|
|
-+#endif /* BOOT_VIDEO_H */
|
|
|
-diff -puN /dev/null arch/i386/boot/voyager.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/boot/voyager.c
|
|
|
-@@ -0,0 +1,46 @@
|
|
|
-+/* -*- linux-c -*- ------------------------------------------------------- *
|
|
|
-+ *
|
|
|
-+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-+ * Copyright 2007 rPath, Inc. - All Rights Reserved
|
|
|
-+ *
|
|
|
-+ * This file is part of the Linux kernel, and is made available under
|
|
|
-+ * the terms of the GNU General Public License version 2.
|
|
|
-+ *
|
|
|
-+ * ----------------------------------------------------------------------- */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * arch/i386/boot/voyager.c
|
|
|
-+ *
|
|
|
-+ * Get the Voyager config information
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include "boot.h"
|
|
|
-+
|
|
|
-+#ifdef CONFIG_X86_VOYAGER
|
|
|
-+
|
|
|
-+int query_voyager(void)
|
|
|
-+{
|
|
|
-+ u8 err;
|
|
|
-+ u16 es, di;
|
|
|
-+ /* Abuse the apm_bios_info area for this */
|
|
|
-+ u8 *data_ptr = (u8 *)&boot_params.apm_bios_info;
|
|
|
-+
|
|
|
-+ data_ptr[0] = 0xff; /* Flag on config not found(?) */
|
|
|
-+
|
|
|
-+ asm("pushw %%es ; "
|
|
|
-+ "int $0x15 ; "
|
|
|
-+ "setc %0 ; "
|
|
|
-+ "movw %%es, %1 ; "
|
|
|
-+ "popw %%es"
|
|
|
-+ : "=qm" (err), "=rm" (es), "=D" (di)
|
|
|
-+ : "a" (0xffc0));
|
|
|
-+
|
|
|
-+ if (err)
|
|
|
-+ return -1; /* Not Voyager */
|
|
|
-+
|
|
|
-+ set_fs(es);
|
|
|
-+ copy_from_fs(data_ptr, di, 7); /* Table is 7 bytes apparently */
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#endif /* CONFIG_X86_VOYAGER */
|
|
|
-diff -puN arch/i386/kernel/cpu/Makefile~git-newsetup arch/i386/kernel/cpu/Makefile
|
|
|
-diff -puN /dev/null arch/i386/kernel/cpu/addon_cpuid_features.c
|
|
|
---- /dev/null
|
|
|
-+++ a/arch/i386/kernel/cpu/addon_cpuid_features.c
|
|
|
-@@ -0,0 +1,50 @@
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Routines to indentify additional cpu features that are scattered in
|
|
|
-+ * cpuid space.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include <linux/cpu.h>
|
|
|
-+
|
|
|
-+#include <asm/processor.h>
|
|
|
-+
|
|
|
-+struct cpuid_bit {
|
|
|
-+ u16 feature;
|
|
|
-+ u8 reg;
|
|
|
-+ u8 bit;
|
|
|
-+ u32 level;
|
|
|
-+};
|
|
|
-+
|
|
|
-+enum cpuid_regs {
|
|
|
-+ CR_EAX = 0,
|
|
|
-+ CR_ECX,
|
|
|
-+ CR_EDX,
|
|
|
-+ CR_EBX
|
|
|
-+};
|
|
|
-+
|
|
|
-+void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
|
|
|
-+{
|
|
|
-+ u32 max_level;
|
|
|
-+ u32 regs[4];
|
|
|
-+ const struct cpuid_bit *cb;
|
|
|
-+
|
|
|
-+ static const struct cpuid_bit cpuid_bits[] = {
|
|
|
-+ { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
|
|
|
-+ { 0, 0, 0, 0 }
|
|
|
-+ };
|
|
|
-+
|
|
|
-+ for (cb = cpuid_bits; cb->feature; cb++) {
|
|
|
-+
|
|
|
-+ /* Verify that the level is valid */
|
|
|
-+ max_level = cpuid_eax(cb->level & 0xffff0000);
|
|
|
-+ if (max_level < cb->level ||
|
|
|
-+ max_level > (cb->level | 0xffff))
|
|
|
-+ continue;
|
|
|
-+
|
|
|
-+ cpuid(cb->level, ®s[CR_EAX], ®s[CR_EBX],
|
|
|
-+ ®s[CR_ECX], ®s[CR_EDX]);
|
|
|
-+
|
|
|
-+ if (regs[cb->reg] & (1 << cb->bit))
|
|
|
-+ set_bit(cb->feature, c->x86_capability);
|
|
|
-+ }
|
|
|
-+}
|
|
|
-diff -puN arch/i386/kernel/cpu/common.c~git-newsetup arch/i386/kernel/cpu/common.c
|
|
|
---- a/arch/i386/kernel/cpu/common.c~git-newsetup
|
|
|
-+++ a/arch/i386/kernel/cpu/common.c
|
|
|
-@@ -353,6 +353,8 @@ static void __cpuinit generic_identify(s
|
|
|
- if ( xlvl >= 0x80000004 )
|
|
|
- get_model_name(c); /* Default name */
|
|
|
- }
|
|
|
-+
|
|
|
-+ init_scattered_cpuid_features(c);
|
|
|
- }
|
|
|
-
|
|
|
- early_intel_workaround(c);
|
|
|
-diff -puN arch/i386/kernel/cpu/proc.c~git-newsetup arch/i386/kernel/cpu/proc.c
|
|
|
---- a/arch/i386/kernel/cpu/proc.c~git-newsetup
|
|
|
-+++ a/arch/i386/kernel/cpu/proc.c
|
|
|
-@@ -29,7 +29,8 @@ static int show_cpuinfo(struct seq_file
|
|
|
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
- NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
|
|
|
- NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
|
|
|
-- NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext", "3dnow",
|
|
|
-+ NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm",
|
|
|
-+ "3dnowext", "3dnow",
|
|
|
-
|
|
|
- /* Transmeta-defined */
|
|
|
- "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
|
|
|
-@@ -40,8 +41,9 @@ static int show_cpuinfo(struct seq_file
|
|
|
- /* Other (Linux-defined) */
|
|
|
- "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
|
|
|
- NULL, NULL, NULL, NULL,
|
|
|
-- "constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-+ "constant_tsc", "up", NULL, "arch_perfmon",
|
|
|
-+ "pebs", "bts", NULL, "sync_rdtsc",
|
|
|
-+ "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-
|
|
|
- /* Intel-defined (#2) */
|
|
|
-@@ -57,9 +59,16 @@ static int show_cpuinfo(struct seq_file
|
|
|
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-
|
|
|
- /* AMD-defined (#2) */
|
|
|
-- "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8legacy", "abm",
|
|
|
-- "sse4a", "misalignsse",
|
|
|
-- "3dnowprefetch", "osvw", "ibs", NULL, NULL, NULL, NULL, NULL,
|
|
|
-+ "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8_legacy",
|
|
|
-+ "altmovcr8", "abm", "sse4a",
|
|
|
-+ "misalignsse", "3dnowprefetch",
|
|
|
-+ "osvw", "ibs", NULL, NULL, NULL, NULL,
|
|
|
-+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-+
|
|
|
-+ /* Auxiliary (Linux-defined) */
|
|
|
-+ "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
- };
|
|
|
-diff -puN arch/i386/kernel/e820.c~git-newsetup arch/i386/kernel/e820.c
|
|
|
---- a/arch/i386/kernel/e820.c~git-newsetup
|
|
|
-+++ a/arch/i386/kernel/e820.c
|
|
|
-@@ -766,7 +766,7 @@ void __init print_memory_map(char *who)
|
|
|
- case E820_NVS:
|
|
|
- printk("(ACPI NVS)\n");
|
|
|
- break;
|
|
|
-- default: printk("type %lu\n", e820.map[i].type);
|
|
|
-+ default: printk("type %u\n", e820.map[i].type);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-diff -puN arch/i386/kernel/setup.c~git-newsetup arch/i386/kernel/setup.c
|
|
|
---- a/arch/i386/kernel/setup.c~git-newsetup
|
|
|
-+++ a/arch/i386/kernel/setup.c
|
|
|
-@@ -102,19 +102,10 @@ static unsigned int highmem_pages = -1;
|
|
|
- /*
|
|
|
- * Setup options
|
|
|
- */
|
|
|
--struct drive_info_struct { char dummy[32]; } drive_info;
|
|
|
--#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
|
|
|
-- defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
|
|
|
--EXPORT_SYMBOL(drive_info);
|
|
|
--#endif
|
|
|
- struct screen_info screen_info;
|
|
|
- EXPORT_SYMBOL(screen_info);
|
|
|
- struct apm_info apm_info;
|
|
|
- EXPORT_SYMBOL(apm_info);
|
|
|
--struct sys_desc_table_struct {
|
|
|
-- unsigned short length;
|
|
|
-- unsigned char table[0];
|
|
|
--};
|
|
|
- struct edid_info edid_info;
|
|
|
- EXPORT_SYMBOL_GPL(edid_info);
|
|
|
- struct ist_info ist_info;
|
|
|
-@@ -134,7 +125,7 @@ unsigned long saved_videomode;
|
|
|
-
|
|
|
- static char __initdata command_line[COMMAND_LINE_SIZE];
|
|
|
-
|
|
|
--unsigned char __initdata boot_params[PARAM_SIZE];
|
|
|
-+struct boot_params __initdata boot_params;
|
|
|
-
|
|
|
- #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
|
|
|
- struct edd edd;
|
|
|
-@@ -528,7 +519,6 @@ void __init setup_arch(char **cmdline_p)
|
|
|
- #endif
|
|
|
-
|
|
|
- ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
|
|
|
-- drive_info = DRIVE_INFO;
|
|
|
- screen_info = SCREEN_INFO;
|
|
|
- edid_info = EDID_INFO;
|
|
|
- apm_info.bios = APM_BIOS_INFO;
|
|
|
-diff -puN arch/i386/kernel/verify_cpu.S~git-newsetup /dev/null
|
|
|
---- a/arch/i386/kernel/verify_cpu.S
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,94 +0,0 @@
|
|
|
--/* Check if CPU has some minimum CPUID bits
|
|
|
-- This runs in 16bit mode so that the caller can still use the BIOS
|
|
|
-- to output errors on the screen */
|
|
|
--#include <asm/cpufeature.h>
|
|
|
--#include <asm/msr.h>
|
|
|
--
|
|
|
--verify_cpu:
|
|
|
-- pushfl # Save caller passed flags
|
|
|
-- pushl $0 # Kill any dangerous flags
|
|
|
-- popfl
|
|
|
--
|
|
|
--#if CONFIG_X86_MINIMUM_CPU_MODEL >= 4
|
|
|
-- pushfl
|
|
|
-- pop %eax
|
|
|
-- orl $(1<<18),%eax # try setting AC
|
|
|
-- push %eax
|
|
|
-- popfl
|
|
|
-- pushfl
|
|
|
-- popl %eax
|
|
|
-- testl $(1<<18),%eax
|
|
|
-- jz bad
|
|
|
--#endif
|
|
|
--#if REQUIRED_MASK1 != 0
|
|
|
-- pushfl # standard way to check for cpuid
|
|
|
-- popl %eax
|
|
|
-- movl %eax,%ebx
|
|
|
-- xorl $0x200000,%eax
|
|
|
-- pushl %eax
|
|
|
-- popfl
|
|
|
-- pushfl
|
|
|
-- popl %eax
|
|
|
-- cmpl %eax,%ebx
|
|
|
-- pushfl # standard way to check for cpuid
|
|
|
-- popl %eax
|
|
|
-- movl %eax,%ebx
|
|
|
-- xorl $0x200000,%eax
|
|
|
-- pushl %eax
|
|
|
-- popfl
|
|
|
-- pushfl
|
|
|
-- popl %eax
|
|
|
-- cmpl %eax,%ebx
|
|
|
-- jz bad # REQUIRED_MASK1 != 0 requires CPUID
|
|
|
--
|
|
|
-- movl $0x0,%eax # See if cpuid 1 is implemented
|
|
|
-- cpuid
|
|
|
-- cmpl $0x1,%eax
|
|
|
-- jb bad # no cpuid 1
|
|
|
--
|
|
|
--#if REQUIRED_MASK1 & NEED_CMPXCHG64
|
|
|
-- /* Some VIA C3s need magic MSRs to enable CX64. Do this here */
|
|
|
-- cmpl $0x746e6543,%ebx # Cent
|
|
|
-- jne 1f
|
|
|
-- cmpl $0x48727561,%edx # aurH
|
|
|
-- jne 1f
|
|
|
-- cmpl $0x736c7561,%ecx # auls
|
|
|
-- jne 1f
|
|
|
-- movl $1,%eax # check model
|
|
|
-- cpuid
|
|
|
-- movl %eax,%ebx
|
|
|
-- shr $8,%ebx
|
|
|
-- andl $0xf,%ebx
|
|
|
-- cmp $6,%ebx # check family == 6
|
|
|
-- jne 1f
|
|
|
-- shr $4,%eax
|
|
|
-- andl $0xf,%eax
|
|
|
-- cmpl $6,%eax # check model >= 6
|
|
|
-- jb 1f
|
|
|
-- # assume models >= 6 all support this MSR
|
|
|
-- movl $MSR_VIA_FCR,%ecx
|
|
|
-- rdmsr
|
|
|
-- orl $((1<<1)|(1<<7)),%eax # enable CMPXCHG64 and PGE
|
|
|
-- wrmsr
|
|
|
--1:
|
|
|
--#endif
|
|
|
-- movl $0x1,%eax # Does the cpu have what it takes
|
|
|
-- cpuid
|
|
|
--
|
|
|
--#if CONFIG_X86_MINIMUM_CPU_MODEL > 4
|
|
|
--#error add proper model checking here
|
|
|
--#endif
|
|
|
--
|
|
|
-- andl $REQUIRED_MASK1,%edx
|
|
|
-- xorl $REQUIRED_MASK1,%edx
|
|
|
-- jnz bad
|
|
|
--#endif /* REQUIRED_MASK1 */
|
|
|
--
|
|
|
-- popfl
|
|
|
-- xor %eax,%eax
|
|
|
-- ret
|
|
|
--
|
|
|
--bad:
|
|
|
-- popfl
|
|
|
-- movl $1,%eax
|
|
|
-- ret
|
|
|
-diff -puN arch/x86_64/Kconfig~git-newsetup arch/x86_64/Kconfig
|
|
|
---- a/arch/x86_64/Kconfig~git-newsetup
|
|
|
-+++ a/arch/x86_64/Kconfig
|
|
|
-@@ -453,6 +453,10 @@ config NR_CPUS
|
|
|
- This is purely to save memory - each supported CPU requires
|
|
|
- memory in the static kernel configuration.
|
|
|
-
|
|
|
-+config PHYSICAL_ALIGN
|
|
|
-+ hex
|
|
|
-+ default "0x200000"
|
|
|
-+
|
|
|
- config HOTPLUG_CPU
|
|
|
- bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
|
|
|
- depends on SMP && HOTPLUG && EXPERIMENTAL
|
|
|
-diff -puN arch/x86_64/boot/Makefile~git-newsetup arch/x86_64/boot/Makefile
|
|
|
---- a/arch/x86_64/boot/Makefile~git-newsetup
|
|
|
-+++ a/arch/x86_64/boot/Makefile
|
|
|
-@@ -1,135 +1,9 @@
|
|
|
- #
|
|
|
- # arch/x86_64/boot/Makefile
|
|
|
- #
|
|
|
--# This file is subject to the terms and conditions of the GNU General Public
|
|
|
--# License. See the file "COPYING" in the main directory of this archive
|
|
|
--# for more details.
|
|
|
--#
|
|
|
--# Copyright (C) 1994 by Linus Torvalds
|
|
|
--#
|
|
|
--
|
|
|
--# ROOT_DEV specifies the default root-device when making the image.
|
|
|
--# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
|
|
|
--# the default of FLOPPY is used by 'build'.
|
|
|
--
|
|
|
--ROOT_DEV := CURRENT
|
|
|
--
|
|
|
--# If you want to preset the SVGA mode, uncomment the next line and
|
|
|
--# set SVGA_MODE to whatever number you want.
|
|
|
--# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
|
|
|
--# The number is the same as you would ordinarily press at bootup.
|
|
|
--
|
|
|
--SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
|
|
|
--
|
|
|
--# If you want the RAM disk device, define this to be the size in blocks.
|
|
|
--
|
|
|
--#RAMDISK := -DRAMDISK=512
|
|
|
--
|
|
|
--targets := vmlinux.bin bootsect bootsect.o \
|
|
|
-- setup setup.o bzImage mtools.conf
|
|
|
--
|
|
|
--EXTRA_CFLAGS := -m32
|
|
|
--
|
|
|
--hostprogs-y := tools/build
|
|
|
--HOST_EXTRACFLAGS += $(LINUXINCLUDE)
|
|
|
--subdir- := compressed/ #Let make clean descend in compressed/
|
|
|
--# ---------------------------------------------------------------------------
|
|
|
--
|
|
|
--$(obj)/bzImage: IMAGE_OFFSET := 0x100000
|
|
|
--$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
|
|
|
--$(obj)/bzImage: BUILDFLAGS := -b
|
|
|
--
|
|
|
--quiet_cmd_image = BUILD $@
|
|
|
--cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
|
|
|
-- $(obj)/vmlinux.bin $(ROOT_DEV) > $@
|
|
|
--
|
|
|
--$(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
|
|
|
-- $(obj)/vmlinux.bin $(obj)/tools/build FORCE
|
|
|
-- $(call if_changed,image)
|
|
|
-- @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
|
|
|
--
|
|
|
--$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
|
|
|
-- $(call if_changed,objcopy)
|
|
|
--
|
|
|
--LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
|
|
|
--LDFLAGS_setup := -Ttext 0x0 -s --oformat binary -e begtext
|
|
|
--
|
|
|
--$(obj)/setup $(obj)/bootsect: %: %.o FORCE
|
|
|
-- $(call if_changed,ld)
|
|
|
--
|
|
|
--$(obj)/compressed/vmlinux: FORCE
|
|
|
-- $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
|
|
|
--
|
|
|
--# Set this if you want to pass append arguments to the zdisk/fdimage/isoimage kernel
|
|
|
--FDARGS =
|
|
|
--# Set this if you want an initrd included with the zdisk/fdimage/isoimage kernel
|
|
|
--FDINITRD =
|
|
|
--
|
|
|
--image_cmdline = default linux $(FDARGS) $(if $(FDINITRD),initrd=initrd.img,)
|
|
|
--
|
|
|
--$(obj)/mtools.conf: $(src)/mtools.conf.in
|
|
|
-- sed -e 's|@OBJ@|$(obj)|g' < $< > $@
|
|
|
--
|
|
|
--# This requires write access to /dev/fd0
|
|
|
--zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
|
|
|
-- MTOOLSRC=$(obj)/mtools.conf mformat a: ; sync
|
|
|
-- syslinux /dev/fd0 ; sync
|
|
|
-- echo '$(image_cmdline)' | \
|
|
|
-- MTOOLSRC=$(obj)/mtools.conf mcopy - a:syslinux.cfg
|
|
|
-- if [ -f '$(FDINITRD)' ] ; then \
|
|
|
-- MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' a:initrd.img ; \
|
|
|
-- fi
|
|
|
-- MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux ; sync
|
|
|
--
|
|
|
--# These require being root or having syslinux 2.02 or higher installed
|
|
|
--fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf
|
|
|
-- dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440
|
|
|
-- MTOOLSRC=$(obj)/mtools.conf mformat v: ; sync
|
|
|
-- syslinux $(obj)/fdimage ; sync
|
|
|
-- echo '$(image_cmdline)' | \
|
|
|
-- MTOOLSRC=$(obj)/mtools.conf mcopy - v:syslinux.cfg
|
|
|
-- if [ -f '$(FDINITRD)' ] ; then \
|
|
|
-- MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' v:initrd.img ; \
|
|
|
-- fi
|
|
|
-- MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux ; sync
|
|
|
--
|
|
|
--fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf
|
|
|
-- dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880
|
|
|
-- MTOOLSRC=$(obj)/mtools.conf mformat w: ; sync
|
|
|
-- syslinux $(obj)/fdimage ; sync
|
|
|
-- echo '$(image_cmdline)' | \
|
|
|
-- MTOOLSRC=$(obj)/mtools.conf mcopy - w:syslinux.cfg
|
|
|
-- if [ -f '$(FDINITRD)' ] ; then \
|
|
|
-- MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' w:initrd.img ; \
|
|
|
-- fi
|
|
|
-- MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux ; sync
|
|
|
--
|
|
|
--isoimage: $(BOOTIMAGE)
|
|
|
-- -rm -rf $(obj)/isoimage
|
|
|
-- mkdir $(obj)/isoimage
|
|
|
-- for i in lib lib64 share end ; do \
|
|
|
-- if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
|
|
|
-- cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
|
|
|
-- break ; \
|
|
|
-- fi ; \
|
|
|
-- if [ $$i = end ] ; then exit 1 ; fi ; \
|
|
|
-- done
|
|
|
-- cp $(BOOTIMAGE) $(obj)/isoimage/linux
|
|
|
-- echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg
|
|
|
-- if [ -f '$(FDINITRD)' ] ; then \
|
|
|
-- cp '$(FDINITRD)' $(obj)/isoimage/initrd.img ; \
|
|
|
-- fi
|
|
|
-- mkisofs -J -r -o $(obj)/image.iso -b isolinux.bin -c boot.cat \
|
|
|
-- -no-emul-boot -boot-load-size 4 -boot-info-table \
|
|
|
-- $(obj)/isoimage
|
|
|
-- rm -rf $(obj)/isoimage
|
|
|
--
|
|
|
--zlilo: $(BOOTIMAGE)
|
|
|
-- if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
|
|
|
-- if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
|
|
|
-- cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
|
|
|
-- cp System.map $(INSTALL_PATH)/
|
|
|
-- if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
|
|
|
-+# The actual boot code is shared with i386 including the Makefile.
|
|
|
-+# So tell kbuild that we fetch the code from i386 and include the
|
|
|
-+# Makefile from i386 too.
|
|
|
-
|
|
|
--install:
|
|
|
-- sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
|
|
|
-+src := arch/i386/boot
|
|
|
-+include $(src)/Makefile
|
|
|
-diff -puN arch/x86_64/boot/bootsect.S~git-newsetup /dev/null
|
|
|
---- a/arch/x86_64/boot/bootsect.S
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,98 +0,0 @@
|
|
|
--/*
|
|
|
-- * bootsect.S Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-- *
|
|
|
-- * modified by Drew Eckhardt
|
|
|
-- * modified by Bruce Evans (bde)
|
|
|
-- * modified by Chris Noe (May 1999) (as86 -> gas)
|
|
|
-- * gutted by H. Peter Anvin (Jan 2003)
|
|
|
-- *
|
|
|
-- * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment
|
|
|
-- * addresses must be multiplied by 16 to obtain their respective linear
|
|
|
-- * addresses. To avoid confusion, linear addresses are written using leading
|
|
|
-- * hex while segment addresses are written as segment:offset.
|
|
|
-- *
|
|
|
-- */
|
|
|
--
|
|
|
--#include <asm/boot.h>
|
|
|
--
|
|
|
--SETUPSECTS = 4 /* default nr of setup-sectors */
|
|
|
--BOOTSEG = 0x07C0 /* original address of boot-sector */
|
|
|
--INITSEG = DEF_INITSEG /* we move boot here - out of the way */
|
|
|
--SETUPSEG = DEF_SETUPSEG /* setup starts here */
|
|
|
--SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */
|
|
|
--SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */
|
|
|
-- /* to be loaded */
|
|
|
--ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */
|
|
|
--SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */
|
|
|
--
|
|
|
--#ifndef SVGA_MODE
|
|
|
--#define SVGA_MODE ASK_VGA
|
|
|
--#endif
|
|
|
--
|
|
|
--#ifndef RAMDISK
|
|
|
--#define RAMDISK 0
|
|
|
--#endif
|
|
|
--
|
|
|
--#ifndef ROOT_RDONLY
|
|
|
--#define ROOT_RDONLY 1
|
|
|
--#endif
|
|
|
--
|
|
|
--.code16
|
|
|
--.text
|
|
|
--
|
|
|
--.global _start
|
|
|
--_start:
|
|
|
--
|
|
|
-- # Normalize the start address
|
|
|
-- jmpl $BOOTSEG, $start2
|
|
|
--
|
|
|
--start2:
|
|
|
-- movw %cs, %ax
|
|
|
-- movw %ax, %ds
|
|
|
-- movw %ax, %es
|
|
|
-- movw %ax, %ss
|
|
|
-- movw $0x7c00, %sp
|
|
|
-- sti
|
|
|
-- cld
|
|
|
--
|
|
|
-- movw $bugger_off_msg, %si
|
|
|
--
|
|
|
--msg_loop:
|
|
|
-- lodsb
|
|
|
-- andb %al, %al
|
|
|
-- jz die
|
|
|
-- movb $0xe, %ah
|
|
|
-- movw $7, %bx
|
|
|
-- int $0x10
|
|
|
-- jmp msg_loop
|
|
|
--
|
|
|
--die:
|
|
|
-- # Allow the user to press a key, then reboot
|
|
|
-- xorw %ax, %ax
|
|
|
-- int $0x16
|
|
|
-- int $0x19
|
|
|
--
|
|
|
-- # int 0x19 should never return. In case it does anyway,
|
|
|
-- # invoke the BIOS reset code...
|
|
|
-- ljmp $0xf000,$0xfff0
|
|
|
--
|
|
|
--
|
|
|
--bugger_off_msg:
|
|
|
-- .ascii "Direct booting from floppy is no longer supported.\r\n"
|
|
|
-- .ascii "Please use a boot loader program instead.\r\n"
|
|
|
-- .ascii "\n"
|
|
|
-- .ascii "Remove disk and press any key to reboot . . .\r\n"
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--
|
|
|
-- # Kernel attributes; used by setup
|
|
|
--
|
|
|
-- .org 497
|
|
|
--setup_sects: .byte SETUPSECTS
|
|
|
--root_flags: .word ROOT_RDONLY
|
|
|
--syssize: .word SYSSIZE
|
|
|
--swap_dev: .word SWAP_DEV
|
|
|
--ram_size: .word RAMDISK
|
|
|
--vid_mode: .word SVGA_MODE
|
|
|
--root_dev: .word ROOT_DEV
|
|
|
--boot_flag: .word 0xAA55
|
|
|
-diff -puN arch/x86_64/boot/compressed/Makefile~git-newsetup arch/x86_64/boot/compressed/Makefile
|
|
|
---- a/arch/x86_64/boot/compressed/Makefile~git-newsetup
|
|
|
-+++ a/arch/x86_64/boot/compressed/Makefile
|
|
|
-@@ -7,11 +7,12 @@
|
|
|
- #
|
|
|
-
|
|
|
- targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
|
|
|
--EXTRA_AFLAGS := -traditional
|
|
|
-
|
|
|
--# cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with
|
|
|
--# -m32
|
|
|
--CFLAGS := -m64 -D__KERNEL__ -Iinclude -O2 -fno-strict-aliasing -fPIC -mcmodel=small -fno-builtin
|
|
|
-+CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2 \
|
|
|
-+ -fno-strict-aliasing -fPIC -mcmodel=small \
|
|
|
-+ $(call cc-option, -ffreestanding) \
|
|
|
-+ $(call cc-option, -fno-stack-protector)
|
|
|
-+AFLAGS := $(CFLAGS) -D__ASSEMBLY__
|
|
|
- LDFLAGS := -m elf_x86_64
|
|
|
-
|
|
|
- LDFLAGS_vmlinux := -T
|
|
|
-diff -puN arch/x86_64/boot/compressed/head.S~git-newsetup arch/x86_64/boot/compressed/head.S
|
|
|
---- a/arch/x86_64/boot/compressed/head.S~git-newsetup
|
|
|
-+++ a/arch/x86_64/boot/compressed/head.S
|
|
|
-@@ -46,10 +46,10 @@ startup_32:
|
|
|
- * at and where we were actually loaded at. This can only be done
|
|
|
- * with a short local call on x86. Nothing else will tell us what
|
|
|
- * address we are running at. The reserved chunk of the real-mode
|
|
|
-- * data at 0x34-0x3f are used as the stack for this calculation.
|
|
|
-- * Only 4 bytes are needed.
|
|
|
-+ * data at 0x1e4 (defined as a scratch field) are used as the stack
|
|
|
-+ * for this calculation. Only 4 bytes are needed.
|
|
|
- */
|
|
|
-- leal 0x40(%esi), %esp
|
|
|
-+ leal (0x1e4+4)(%esi), %esp
|
|
|
- call 1f
|
|
|
- 1: popl %ebp
|
|
|
- subl $1b, %ebp
|
|
|
-diff -puN arch/x86_64/boot/install.sh~git-newsetup /dev/null
|
|
|
---- a/arch/x86_64/boot/install.sh
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,2 +0,0 @@
|
|
|
--#!/bin/sh
|
|
|
--. $srctree/arch/i386/boot/install.sh
|
|
|
-diff -puN arch/x86_64/boot/mtools.conf.in~git-newsetup /dev/null
|
|
|
---- a/arch/x86_64/boot/mtools.conf.in
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,17 +0,0 @@
|
|
|
--#
|
|
|
--# mtools configuration file for "make (b)zdisk"
|
|
|
--#
|
|
|
--
|
|
|
--# Actual floppy drive
|
|
|
--drive a:
|
|
|
-- file="/dev/fd0"
|
|
|
--
|
|
|
--# 1.44 MB floppy disk image
|
|
|
--drive v:
|
|
|
-- file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=18 filter
|
|
|
--
|
|
|
--# 2.88 MB floppy disk image (mostly for virtual uses)
|
|
|
--drive w:
|
|
|
-- file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=36 filter
|
|
|
--
|
|
|
--
|
|
|
-diff -puN arch/x86_64/boot/setup.S~git-newsetup /dev/null
|
|
|
---- a/arch/x86_64/boot/setup.S
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,826 +0,0 @@
|
|
|
--/*
|
|
|
-- * setup.S Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-- *
|
|
|
-- * setup.s is responsible for getting the system data from the BIOS,
|
|
|
-- * and putting them into the appropriate places in system memory.
|
|
|
-- * both setup.s and system has been loaded by the bootblock.
|
|
|
-- *
|
|
|
-- * This code asks the bios for memory/disk/other parameters, and
|
|
|
-- * puts them in a "safe" place: 0x90000-0x901FF, ie where the
|
|
|
-- * boot-block used to be. It is then up to the protected mode
|
|
|
-- * system to read them from there before the area is overwritten
|
|
|
-- * for buffer-blocks.
|
|
|
-- *
|
|
|
-- * Move PS/2 aux init code to psaux.c
|
|
|
-- * ([email protected]) 03Oct92
|
|
|
-- *
|
|
|
-- * some changes and additional features by Christoph Niemann,
|
|
|
-- * March 1993/June 1994 ([email protected])
|
|
|
-- *
|
|
|
-- * add APM BIOS checking by Stephen Rothwell, May 1994
|
|
|
-- * ([email protected])
|
|
|
-- *
|
|
|
-- * High load stuff, initrd support and position independency
|
|
|
-- * by Hans Lermen & Werner Almesberger, February 1996
|
|
|
-- * <[email protected]>, <[email protected]>
|
|
|
-- *
|
|
|
-- * Video handling moved to video.S by Martin Mares, March 1996
|
|
|
-- * <[email protected]>
|
|
|
-- *
|
|
|
-- * Extended memory detection scheme retwiddled by [email protected] (david
|
|
|
-- * parsons) to avoid loadlin confusion, July 1997
|
|
|
-- *
|
|
|
-- * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
|
|
|
-- * <[email protected]>
|
|
|
-- *
|
|
|
-- * Fix to work around buggy BIOSes which don't use carry bit correctly
|
|
|
-- * and/or report extended memory in CX/DX for e801h memory size detection
|
|
|
-- * call. As a result the kernel got wrong figures. The int15/e801h docs
|
|
|
-- * from Ralf Brown interrupt list seem to indicate AX/BX should be used
|
|
|
-- * anyway. So to avoid breaking many machines (presumably there was a reason
|
|
|
-- * to orginally use CX/DX instead of AX/BX), we do a kludge to see
|
|
|
-- * if CX/DX have been changed in the e801 call and if so use AX/BX .
|
|
|
-- * Michael Miller, April 2001 <[email protected]>
|
|
|
-- *
|
|
|
-- * Added long mode checking and SSE force. March 2003, Andi Kleen.
|
|
|
-- */
|
|
|
--
|
|
|
--#include <asm/segment.h>
|
|
|
--#include <linux/utsrelease.h>
|
|
|
--#include <linux/compile.h>
|
|
|
--#include <asm/boot.h>
|
|
|
--#include <asm/e820.h>
|
|
|
--#include <asm/page.h>
|
|
|
--#include <asm/setup.h>
|
|
|
--
|
|
|
--/* Signature words to ensure LILO loaded us right */
|
|
|
--#define SIG1 0xAA55
|
|
|
--#define SIG2 0x5A5A
|
|
|
--
|
|
|
--INITSEG = DEF_INITSEG # 0x9000, we move boot here, out of the way
|
|
|
--SYSSEG = DEF_SYSSEG # 0x1000, system loaded at 0x10000 (65536).
|
|
|
--SETUPSEG = DEF_SETUPSEG # 0x9020, this is the current segment
|
|
|
-- # ... and the former contents of CS
|
|
|
--
|
|
|
--DELTA_INITSEG = SETUPSEG - INITSEG # 0x0020
|
|
|
--
|
|
|
--.code16
|
|
|
--.globl begtext, begdata, begbss, endtext, enddata, endbss
|
|
|
--
|
|
|
--.text
|
|
|
--begtext:
|
|
|
--.data
|
|
|
--begdata:
|
|
|
--.bss
|
|
|
--begbss:
|
|
|
--.text
|
|
|
--
|
|
|
--start:
|
|
|
-- jmp trampoline
|
|
|
--
|
|
|
--# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
|
|
|
--
|
|
|
-- .ascii "HdrS" # header signature
|
|
|
-- .word 0x0206 # header version number (>= 0x0105)
|
|
|
-- # or else old loadlin-1.5 will fail)
|
|
|
--realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
|
|
|
--start_sys_seg: .word SYSSEG
|
|
|
-- .word kernel_version # pointing to kernel version string
|
|
|
-- # above section of header is compatible
|
|
|
-- # with loadlin-1.5 (header v1.5). Don't
|
|
|
-- # change it.
|
|
|
--
|
|
|
--type_of_loader: .byte 0 # = 0, old one (LILO, Loadlin,
|
|
|
-- # Bootlin, SYSLX, bootsect...)
|
|
|
-- # See Documentation/i386/boot.txt for
|
|
|
-- # assigned ids
|
|
|
--
|
|
|
--# flags, unused bits must be zero (RFU) bit within loadflags
|
|
|
--loadflags:
|
|
|
--LOADED_HIGH = 1 # If set, the kernel is loaded high
|
|
|
--CAN_USE_HEAP = 0x80 # If set, the loader also has set
|
|
|
-- # heap_end_ptr to tell how much
|
|
|
-- # space behind setup.S can be used for
|
|
|
-- # heap purposes.
|
|
|
-- # Only the loader knows what is free
|
|
|
--#ifndef __BIG_KERNEL__
|
|
|
-- .byte 0
|
|
|
--#else
|
|
|
-- .byte LOADED_HIGH
|
|
|
--#endif
|
|
|
--
|
|
|
--setup_move_size: .word 0x8000 # size to move, when setup is not
|
|
|
-- # loaded at 0x90000. We will move setup
|
|
|
-- # to 0x90000 then just before jumping
|
|
|
-- # into the kernel. However, only the
|
|
|
-- # loader knows how much data behind
|
|
|
-- # us also needs to be loaded.
|
|
|
--
|
|
|
--code32_start: # here loaders can put a different
|
|
|
-- # start address for 32-bit code.
|
|
|
--#ifndef __BIG_KERNEL__
|
|
|
-- .long 0x1000 # 0x1000 = default for zImage
|
|
|
--#else
|
|
|
-- .long 0x100000 # 0x100000 = default for big kernel
|
|
|
--#endif
|
|
|
--
|
|
|
--ramdisk_image: .long 0 # address of loaded ramdisk image
|
|
|
-- # Here the loader puts the 32-bit
|
|
|
-- # address where it loaded the image.
|
|
|
-- # This only will be read by the kernel.
|
|
|
--
|
|
|
--ramdisk_size: .long 0 # its size in bytes
|
|
|
--
|
|
|
--bootsect_kludge:
|
|
|
-- .long 0 # obsolete
|
|
|
--
|
|
|
--heap_end_ptr: .word modelist+1024 # (Header version 0x0201 or later)
|
|
|
-- # space from here (exclusive) down to
|
|
|
-- # end of setup code can be used by setup
|
|
|
-- # for local heap purposes.
|
|
|
--
|
|
|
--pad1: .word 0
|
|
|
--cmd_line_ptr: .long 0 # (Header version 0x0202 or later)
|
|
|
-- # If nonzero, a 32-bit pointer
|
|
|
-- # to the kernel command line.
|
|
|
-- # The command line should be
|
|
|
-- # located between the start of
|
|
|
-- # setup and the end of low
|
|
|
-- # memory (0xa0000), or it may
|
|
|
-- # get overwritten before it
|
|
|
-- # gets read. If this field is
|
|
|
-- # used, there is no longer
|
|
|
-- # anything magical about the
|
|
|
-- # 0x90000 segment; the setup
|
|
|
-- # can be located anywhere in
|
|
|
-- # low memory 0x10000 or higher.
|
|
|
--
|
|
|
--ramdisk_max: .long 0xffffffff
|
|
|
--kernel_alignment: .long 0x200000 # physical addr alignment required for
|
|
|
-- # protected mode relocatable kernel
|
|
|
--#ifdef CONFIG_RELOCATABLE
|
|
|
--relocatable_kernel: .byte 1
|
|
|
--#else
|
|
|
--relocatable_kernel: .byte 0
|
|
|
--#endif
|
|
|
--pad2: .byte 0
|
|
|
--pad3: .word 0
|
|
|
--
|
|
|
--cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
|
|
|
-- #added with boot protocol
|
|
|
-- #version 2.06
|
|
|
--
|
|
|
--trampoline: call start_of_setup
|
|
|
-- .align 16
|
|
|
-- # The offset at this point is 0x240
|
|
|
-- .space (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
|
|
|
--# End of setup header #####################################################
|
|
|
--
|
|
|
--start_of_setup:
|
|
|
--# Bootlin depends on this being done early
|
|
|
-- movw $0x01500, %ax
|
|
|
-- movb $0x81, %dl
|
|
|
-- int $0x13
|
|
|
--
|
|
|
--#ifdef SAFE_RESET_DISK_CONTROLLER
|
|
|
--# Reset the disk controller.
|
|
|
-- movw $0x0000, %ax
|
|
|
-- movb $0x80, %dl
|
|
|
-- int $0x13
|
|
|
--#endif
|
|
|
--
|
|
|
--# Set %ds = %cs, we know that SETUPSEG = %cs at this point
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- movw %ax, %ds
|
|
|
--# Check signature at end of setup
|
|
|
-- cmpw $SIG1, setup_sig1
|
|
|
-- jne bad_sig
|
|
|
--
|
|
|
-- cmpw $SIG2, setup_sig2
|
|
|
-- jne bad_sig
|
|
|
--
|
|
|
-- jmp good_sig1
|
|
|
--
|
|
|
--# Routine to print asciiz string at ds:si
|
|
|
--prtstr:
|
|
|
-- lodsb
|
|
|
-- andb %al, %al
|
|
|
-- jz fin
|
|
|
--
|
|
|
-- call prtchr
|
|
|
-- jmp prtstr
|
|
|
--
|
|
|
--fin: ret
|
|
|
--
|
|
|
--# Space printing
|
|
|
--prtsp2: call prtspc # Print double space
|
|
|
--prtspc: movb $0x20, %al # Print single space (note: fall-thru)
|
|
|
--
|
|
|
--prtchr:
|
|
|
-- pushw %ax
|
|
|
-- pushw %cx
|
|
|
-- movw $0007,%bx
|
|
|
-- movw $0x01, %cx
|
|
|
-- movb $0x0e, %ah
|
|
|
-- int $0x10
|
|
|
-- popw %cx
|
|
|
-- popw %ax
|
|
|
-- ret
|
|
|
--
|
|
|
--beep: movb $0x07, %al
|
|
|
-- jmp prtchr
|
|
|
--
|
|
|
--no_sig_mess: .string "No setup signature found ..."
|
|
|
--
|
|
|
--good_sig1:
|
|
|
-- jmp good_sig
|
|
|
--
|
|
|
--# We now have to find the rest of the setup code/data
|
|
|
--bad_sig:
|
|
|
-- movw %cs, %ax # SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %ax # INITSEG
|
|
|
-- movw %ax, %ds
|
|
|
-- xorb %bh, %bh
|
|
|
-- movb (497), %bl # get setup sect from bootsect
|
|
|
-- subw $4, %bx # LILO loads 4 sectors of setup
|
|
|
-- shlw $8, %bx # convert to words (1sect=2^8 words)
|
|
|
-- movw %bx, %cx
|
|
|
-- shrw $3, %bx # convert to segment
|
|
|
-- addw $SYSSEG, %bx
|
|
|
-- movw %bx, %cs:start_sys_seg
|
|
|
--# Move rest of setup code/data to here
|
|
|
-- movw $2048, %di # four sectors loaded by LILO
|
|
|
-- subw %si, %si
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- movw %ax, %es
|
|
|
-- movw $SYSSEG, %ax
|
|
|
-- movw %ax, %ds
|
|
|
-- rep
|
|
|
-- movsw
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- movw %ax, %ds
|
|
|
-- cmpw $SIG1, setup_sig1
|
|
|
-- jne no_sig
|
|
|
--
|
|
|
-- cmpw $SIG2, setup_sig2
|
|
|
-- jne no_sig
|
|
|
--
|
|
|
-- jmp good_sig
|
|
|
--
|
|
|
--no_sig:
|
|
|
-- lea no_sig_mess, %si
|
|
|
-- call prtstr
|
|
|
--
|
|
|
--no_sig_loop:
|
|
|
-- jmp no_sig_loop
|
|
|
--
|
|
|
--good_sig:
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %ax # aka INITSEG
|
|
|
-- movw %ax, %ds
|
|
|
--# Check if an old loader tries to load a big-kernel
|
|
|
-- testb $LOADED_HIGH, %cs:loadflags # Do we have a big kernel?
|
|
|
-- jz loader_ok # No, no danger for old loaders.
|
|
|
--
|
|
|
-- cmpb $0, %cs:type_of_loader # Do we have a loader that
|
|
|
-- # can deal with us?
|
|
|
-- jnz loader_ok # Yes, continue.
|
|
|
--
|
|
|
-- pushw %cs # No, we have an old loader,
|
|
|
-- popw %ds # die.
|
|
|
-- lea loader_panic_mess, %si
|
|
|
-- call prtstr
|
|
|
--
|
|
|
-- jmp no_sig_loop
|
|
|
--
|
|
|
--loader_panic_mess: .string "Wrong loader, giving up..."
|
|
|
--
|
|
|
--loader_ok:
|
|
|
-- /* check for long mode. */
|
|
|
-- /* we have to do this before the VESA setup, otherwise the user
|
|
|
-- can't see the error message. */
|
|
|
--
|
|
|
-- pushw %ds
|
|
|
-- movw %cs,%ax
|
|
|
-- movw %ax,%ds
|
|
|
--
|
|
|
-- call verify_cpu
|
|
|
-- testl %eax,%eax
|
|
|
-- jz sse_ok
|
|
|
--
|
|
|
--no_longmode:
|
|
|
-- call beep
|
|
|
-- lea long_mode_panic,%si
|
|
|
-- call prtstr
|
|
|
--no_longmode_loop:
|
|
|
-- jmp no_longmode_loop
|
|
|
--long_mode_panic:
|
|
|
-- .string "Your CPU does not support long mode. Use a 32bit distribution."
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--#include "../kernel/verify_cpu.S"
|
|
|
--sse_ok:
|
|
|
-- popw %ds
|
|
|
--
|
|
|
--# tell BIOS we want to go to long mode
|
|
|
-- movl $0xec00,%eax # declare target operating mode
|
|
|
-- movl $2,%ebx # long mode
|
|
|
-- int $0x15
|
|
|
--
|
|
|
--# Get memory size (extended mem, kB)
|
|
|
--
|
|
|
-- xorl %eax, %eax
|
|
|
-- movl %eax, (0x1e0)
|
|
|
--#ifndef STANDARD_MEMORY_BIOS_CALL
|
|
|
-- movb %al, (E820NR)
|
|
|
--# Try three different memory detection schemes. First, try
|
|
|
--# e820h, which lets us assemble a memory map, then try e801h,
|
|
|
--# which returns a 32-bit memory size, and finally 88h, which
|
|
|
--# returns 0-64m
|
|
|
--
|
|
|
--# method E820H:
|
|
|
--# the memory map from hell. e820h returns memory classified into
|
|
|
--# a whole bunch of different types, and allows memory holes and
|
|
|
--# everything. We scan through this memory map and build a list
|
|
|
--# of the first 32 memory areas, which we return at [E820MAP].
|
|
|
--# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
|
|
|
--
|
|
|
--#define SMAP 0x534d4150
|
|
|
--
|
|
|
--meme820:
|
|
|
-- xorl %ebx, %ebx # continuation counter
|
|
|
-- movw $E820MAP, %di # point into the whitelist
|
|
|
-- # so we can have the bios
|
|
|
-- # directly write into it.
|
|
|
--
|
|
|
--jmpe820:
|
|
|
-- movl $0x0000e820, %eax # e820, upper word zeroed
|
|
|
-- movl $SMAP, %edx # ascii 'SMAP'
|
|
|
-- movl $20, %ecx # size of the e820rec
|
|
|
-- pushw %ds # data record.
|
|
|
-- popw %es
|
|
|
-- int $0x15 # make the call
|
|
|
-- jc bail820 # fall to e801 if it fails
|
|
|
--
|
|
|
-- cmpl $SMAP, %eax # check the return is `SMAP'
|
|
|
-- jne bail820 # fall to e801 if it fails
|
|
|
--
|
|
|
--# cmpl $1, 16(%di) # is this usable memory?
|
|
|
--# jne again820
|
|
|
--
|
|
|
-- # If this is usable memory, we save it by simply advancing %di by
|
|
|
-- # sizeof(e820rec).
|
|
|
-- #
|
|
|
--good820:
|
|
|
-- movb (E820NR), %al # up to 128 entries
|
|
|
-- cmpb $E820MAX, %al
|
|
|
-- jae bail820
|
|
|
--
|
|
|
-- incb (E820NR)
|
|
|
-- movw %di, %ax
|
|
|
-- addw $20, %ax
|
|
|
-- movw %ax, %di
|
|
|
--again820:
|
|
|
-- cmpl $0, %ebx # check to see if
|
|
|
-- jne jmpe820 # %ebx is set to EOF
|
|
|
--bail820:
|
|
|
--
|
|
|
--
|
|
|
--# method E801H:
|
|
|
--# memory size is in 1k chunksizes, to avoid confusing loadlin.
|
|
|
--# we store the 0xe801 memory size in a completely different place,
|
|
|
--# because it will most likely be longer than 16 bits.
|
|
|
--# (use 1e0 because that's what Larry Augustine uses in his
|
|
|
--# alternative new memory detection scheme, and it's sensible
|
|
|
--# to write everything into the same place.)
|
|
|
--
|
|
|
--meme801:
|
|
|
-- stc # fix to work around buggy
|
|
|
-- xorw %cx,%cx # BIOSes which don't clear/set
|
|
|
-- xorw %dx,%dx # carry on pass/error of
|
|
|
-- # e801h memory size call
|
|
|
-- # or merely pass cx,dx though
|
|
|
-- # without changing them.
|
|
|
-- movw $0xe801, %ax
|
|
|
-- int $0x15
|
|
|
-- jc mem88
|
|
|
--
|
|
|
-- cmpw $0x0, %cx # Kludge to handle BIOSes
|
|
|
-- jne e801usecxdx # which report their extended
|
|
|
-- cmpw $0x0, %dx # memory in AX/BX rather than
|
|
|
-- jne e801usecxdx # CX/DX. The spec I have read
|
|
|
-- movw %ax, %cx # seems to indicate AX/BX
|
|
|
-- movw %bx, %dx # are more reasonable anyway...
|
|
|
--
|
|
|
--e801usecxdx:
|
|
|
-- andl $0xffff, %edx # clear sign extend
|
|
|
-- shll $6, %edx # and go from 64k to 1k chunks
|
|
|
-- movl %edx, (0x1e0) # store extended memory size
|
|
|
-- andl $0xffff, %ecx # clear sign extend
|
|
|
-- addl %ecx, (0x1e0) # and add lower memory into
|
|
|
-- # total size.
|
|
|
--
|
|
|
--# Ye Olde Traditional Methode. Returns the memory size (up to 16mb or
|
|
|
--# 64mb, depending on the bios) in ax.
|
|
|
--mem88:
|
|
|
--
|
|
|
--#endif
|
|
|
-- movb $0x88, %ah
|
|
|
-- int $0x15
|
|
|
-- movw %ax, (2)
|
|
|
--
|
|
|
--# Set the keyboard repeat rate to the max
|
|
|
-- movw $0x0305, %ax
|
|
|
-- xorw %bx, %bx
|
|
|
-- int $0x16
|
|
|
--
|
|
|
--# Check for video adapter and its parameters and allow the
|
|
|
--# user to browse video modes.
|
|
|
-- call video # NOTE: we need %ds pointing
|
|
|
-- # to bootsector
|
|
|
--
|
|
|
--# Get hd0 data...
|
|
|
-- xorw %ax, %ax
|
|
|
-- movw %ax, %ds
|
|
|
-- ldsw (4 * 0x41), %si
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %ax # aka INITSEG
|
|
|
-- pushw %ax
|
|
|
-- movw %ax, %es
|
|
|
-- movw $0x0080, %di
|
|
|
-- movw $0x10, %cx
|
|
|
-- pushw %cx
|
|
|
-- cld
|
|
|
-- rep
|
|
|
-- movsb
|
|
|
--# Get hd1 data...
|
|
|
-- xorw %ax, %ax
|
|
|
-- movw %ax, %ds
|
|
|
-- ldsw (4 * 0x46), %si
|
|
|
-- popw %cx
|
|
|
-- popw %es
|
|
|
-- movw $0x0090, %di
|
|
|
-- rep
|
|
|
-- movsb
|
|
|
--# Check that there IS a hd1 :-)
|
|
|
-- movw $0x01500, %ax
|
|
|
-- movb $0x81, %dl
|
|
|
-- int $0x13
|
|
|
-- jc no_disk1
|
|
|
--
|
|
|
-- cmpb $3, %ah
|
|
|
-- je is_disk1
|
|
|
--
|
|
|
--no_disk1:
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %ax # aka INITSEG
|
|
|
-- movw %ax, %es
|
|
|
-- movw $0x0090, %di
|
|
|
-- movw $0x10, %cx
|
|
|
-- xorw %ax, %ax
|
|
|
-- cld
|
|
|
-- rep
|
|
|
-- stosb
|
|
|
--is_disk1:
|
|
|
--
|
|
|
--# Check for PS/2 pointing device
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %ax # aka INITSEG
|
|
|
-- movw %ax, %ds
|
|
|
-- movb $0, (0x1ff) # default is no pointing device
|
|
|
-- int $0x11 # int 0x11: equipment list
|
|
|
-- testb $0x04, %al # check if mouse installed
|
|
|
-- jz no_psmouse
|
|
|
--
|
|
|
-- movb $0xAA, (0x1ff) # device present
|
|
|
--no_psmouse:
|
|
|
--
|
|
|
--#include "../../i386/boot/edd.S"
|
|
|
--
|
|
|
--# Now we want to move to protected mode ...
|
|
|
-- cmpw $0, %cs:realmode_swtch
|
|
|
-- jz rmodeswtch_normal
|
|
|
--
|
|
|
-- lcall *%cs:realmode_swtch
|
|
|
--
|
|
|
-- jmp rmodeswtch_end
|
|
|
--
|
|
|
--rmodeswtch_normal:
|
|
|
-- pushw %cs
|
|
|
-- call default_switch
|
|
|
--
|
|
|
--rmodeswtch_end:
|
|
|
--# we get the code32 start address and modify the below 'jmpi'
|
|
|
--# (loader may have changed it)
|
|
|
-- movl %cs:code32_start, %eax
|
|
|
-- movl %eax, %cs:code32
|
|
|
--
|
|
|
--# Now we move the system to its rightful place ... but we check if we have a
|
|
|
--# big-kernel. In that case we *must* not move it ...
|
|
|
-- testb $LOADED_HIGH, %cs:loadflags
|
|
|
-- jz do_move0 # .. then we have a normal low
|
|
|
-- # loaded zImage
|
|
|
-- # .. or else we have a high
|
|
|
-- # loaded bzImage
|
|
|
-- jmp end_move # ... and we skip moving
|
|
|
--
|
|
|
--do_move0:
|
|
|
-- movw $0x100, %ax # start of destination segment
|
|
|
-- movw %cs, %bp # aka SETUPSEG
|
|
|
-- subw $DELTA_INITSEG, %bp # aka INITSEG
|
|
|
-- movw %cs:start_sys_seg, %bx # start of source segment
|
|
|
-- cld
|
|
|
--do_move:
|
|
|
-- movw %ax, %es # destination segment
|
|
|
-- incb %ah # instead of add ax,#0x100
|
|
|
-- movw %bx, %ds # source segment
|
|
|
-- addw $0x100, %bx
|
|
|
-- subw %di, %di
|
|
|
-- subw %si, %si
|
|
|
-- movw $0x800, %cx
|
|
|
-- rep
|
|
|
-- movsw
|
|
|
-- cmpw %bp, %bx # assume start_sys_seg > 0x200,
|
|
|
-- # so we will perhaps read one
|
|
|
-- # page more than needed, but
|
|
|
-- # never overwrite INITSEG
|
|
|
-- # because destination is a
|
|
|
-- # minimum one page below source
|
|
|
-- jb do_move
|
|
|
--
|
|
|
--end_move:
|
|
|
--# then we load the segment descriptors
|
|
|
-- movw %cs, %ax # aka SETUPSEG
|
|
|
-- movw %ax, %ds
|
|
|
--
|
|
|
--# Check whether we need to be downward compatible with version <=201
|
|
|
-- cmpl $0, cmd_line_ptr
|
|
|
-- jne end_move_self # loader uses version >=202 features
|
|
|
-- cmpb $0x20, type_of_loader
|
|
|
-- je end_move_self # bootsect loader, we know of it
|
|
|
--
|
|
|
--# Boot loader doesnt support boot protocol version 2.02.
|
|
|
--# If we have our code not at 0x90000, we need to move it there now.
|
|
|
--# We also then need to move the params behind it (commandline)
|
|
|
--# Because we would overwrite the code on the current IP, we move
|
|
|
--# it in two steps, jumping high after the first one.
|
|
|
-- movw %cs, %ax
|
|
|
-- cmpw $SETUPSEG, %ax
|
|
|
-- je end_move_self
|
|
|
--
|
|
|
-- cli # make sure we really have
|
|
|
-- # interrupts disabled !
|
|
|
-- # because after this the stack
|
|
|
-- # should not be used
|
|
|
-- subw $DELTA_INITSEG, %ax # aka INITSEG
|
|
|
-- movw %ss, %dx
|
|
|
-- cmpw %ax, %dx
|
|
|
-- jb move_self_1
|
|
|
--
|
|
|
-- addw $INITSEG, %dx
|
|
|
-- subw %ax, %dx # this will go into %ss after
|
|
|
-- # the move
|
|
|
--move_self_1:
|
|
|
-- movw %ax, %ds
|
|
|
-- movw $INITSEG, %ax # real INITSEG
|
|
|
-- movw %ax, %es
|
|
|
-- movw %cs:setup_move_size, %cx
|
|
|
-- std # we have to move up, so we use
|
|
|
-- # direction down because the
|
|
|
-- # areas may overlap
|
|
|
-- movw %cx, %di
|
|
|
-- decw %di
|
|
|
-- movw %di, %si
|
|
|
-- subw $move_self_here+0x200, %cx
|
|
|
-- rep
|
|
|
-- movsb
|
|
|
-- ljmp $SETUPSEG, $move_self_here
|
|
|
--
|
|
|
--move_self_here:
|
|
|
-- movw $move_self_here+0x200, %cx
|
|
|
-- rep
|
|
|
-- movsb
|
|
|
-- movw $SETUPSEG, %ax
|
|
|
-- movw %ax, %ds
|
|
|
-- movw %dx, %ss
|
|
|
--end_move_self: # now we are at the right place
|
|
|
-- lidt idt_48 # load idt with 0,0
|
|
|
-- xorl %eax, %eax # Compute gdt_base
|
|
|
-- movw %ds, %ax # (Convert %ds:gdt to a linear ptr)
|
|
|
-- shll $4, %eax
|
|
|
-- addl $gdt, %eax
|
|
|
-- movl %eax, (gdt_48+2)
|
|
|
-- lgdt gdt_48 # load gdt with whatever is
|
|
|
-- # appropriate
|
|
|
--
|
|
|
--# that was painless, now we enable a20
|
|
|
-- call empty_8042
|
|
|
--
|
|
|
-- movb $0xD1, %al # command write
|
|
|
-- outb %al, $0x64
|
|
|
-- call empty_8042
|
|
|
--
|
|
|
-- movb $0xDF, %al # A20 on
|
|
|
-- outb %al, $0x60
|
|
|
-- call empty_8042
|
|
|
--
|
|
|
--#
|
|
|
--# You must preserve the other bits here. Otherwise embarrasing things
|
|
|
--# like laptops powering off on boot happen. Corrected version by Kira
|
|
|
--# Brown from Linux 2.2
|
|
|
--#
|
|
|
-- inb $0x92, %al #
|
|
|
-- orb $02, %al # "fast A20" version
|
|
|
-- outb %al, $0x92 # some chips have only this
|
|
|
--
|
|
|
--# wait until a20 really *is* enabled; it can take a fair amount of
|
|
|
--# time on certain systems; Toshiba Tecras are known to have this
|
|
|
--# problem. The memory location used here (0x200) is the int 0x80
|
|
|
--# vector, which should be safe to use.
|
|
|
--
|
|
|
-- xorw %ax, %ax # segment 0x0000
|
|
|
-- movw %ax, %fs
|
|
|
-- decw %ax # segment 0xffff (HMA)
|
|
|
-- movw %ax, %gs
|
|
|
--a20_wait:
|
|
|
-- incw %ax # unused memory location <0xfff0
|
|
|
-- movw %ax, %fs:(0x200) # we use the "int 0x80" vector
|
|
|
-- cmpw %gs:(0x210), %ax # and its corresponding HMA addr
|
|
|
-- je a20_wait # loop until no longer aliased
|
|
|
--
|
|
|
--# make sure any possible coprocessor is properly reset..
|
|
|
-- xorw %ax, %ax
|
|
|
-- outb %al, $0xf0
|
|
|
-- call delay
|
|
|
--
|
|
|
-- outb %al, $0xf1
|
|
|
-- call delay
|
|
|
--
|
|
|
--# well, that went ok, I hope. Now we mask all interrupts - the rest
|
|
|
--# is done in init_IRQ().
|
|
|
-- movb $0xFF, %al # mask all interrupts for now
|
|
|
-- outb %al, $0xA1
|
|
|
-- call delay
|
|
|
--
|
|
|
-- movb $0xFB, %al # mask all irq's but irq2 which
|
|
|
-- outb %al, $0x21 # is cascaded
|
|
|
--
|
|
|
--# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
|
|
|
--# need no steenking BIOS anyway (except for the initial loading :-).
|
|
|
--# The BIOS-routine wants lots of unnecessary data, and it's less
|
|
|
--# "interesting" anyway. This is how REAL programmers do it.
|
|
|
--#
|
|
|
--# Well, now's the time to actually move into protected mode. To make
|
|
|
--# things as simple as possible, we do no register set-up or anything,
|
|
|
--# we let the gnu-compiled 32-bit programs do that. We just jump to
|
|
|
--# absolute address 0x1000 (or the loader supplied one),
|
|
|
--# in 32-bit protected mode.
|
|
|
--#
|
|
|
--# Note that the short jump isn't strictly needed, although there are
|
|
|
--# reasons why it might be a good idea. It won't hurt in any case.
|
|
|
-- movw $1, %ax # protected mode (PE) bit
|
|
|
-- lmsw %ax # This is it!
|
|
|
-- jmp flush_instr
|
|
|
--
|
|
|
--flush_instr:
|
|
|
-- xorw %bx, %bx # Flag to indicate a boot
|
|
|
-- xorl %esi, %esi # Pointer to real-mode code
|
|
|
-- movw %cs, %si
|
|
|
-- subw $DELTA_INITSEG, %si
|
|
|
-- shll $4, %esi # Convert to 32-bit pointer
|
|
|
--# NOTE: For high loaded big kernels we need a
|
|
|
--# jmpi 0x100000,__KERNEL_CS
|
|
|
--#
|
|
|
--# but we yet haven't reloaded the CS register, so the default size
|
|
|
--# of the target offset still is 16 bit.
|
|
|
--# However, using an operand prefix (0x66), the CPU will properly
|
|
|
--# take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
|
|
|
--# Manual, Mixing 16-bit and 32-bit code, page 16-6)
|
|
|
--
|
|
|
-- .byte 0x66, 0xea # prefix + jmpi-opcode
|
|
|
--code32: .long 0x1000 # will be set to 0x100000
|
|
|
-- # for big kernels
|
|
|
-- .word __KERNEL_CS
|
|
|
--
|
|
|
--# Here's a bunch of information about your current kernel..
|
|
|
--kernel_version: .ascii UTS_RELEASE
|
|
|
-- .ascii " ("
|
|
|
-- .ascii LINUX_COMPILE_BY
|
|
|
-- .ascii "@"
|
|
|
-- .ascii LINUX_COMPILE_HOST
|
|
|
-- .ascii ") "
|
|
|
-- .ascii UTS_VERSION
|
|
|
-- .byte 0
|
|
|
--
|
|
|
--# This is the default real mode switch routine.
|
|
|
--# to be called just before protected mode transition
|
|
|
--default_switch:
|
|
|
-- cli # no interrupts allowed !
|
|
|
-- movb $0x80, %al # disable NMI for bootup
|
|
|
-- # sequence
|
|
|
-- outb %al, $0x70
|
|
|
-- lret
|
|
|
--
|
|
|
--
|
|
|
--# This routine checks that the keyboard command queue is empty
|
|
|
--# (after emptying the output buffers)
|
|
|
--#
|
|
|
--# Some machines have delusions that the keyboard buffer is always full
|
|
|
--# with no keyboard attached...
|
|
|
--#
|
|
|
--# If there is no keyboard controller, we will usually get 0xff
|
|
|
--# to all the reads. With each IO taking a microsecond and
|
|
|
--# a timeout of 100,000 iterations, this can take about half a
|
|
|
--# second ("delay" == outb to port 0x80). That should be ok,
|
|
|
--# and should also be plenty of time for a real keyboard controller
|
|
|
--# to empty.
|
|
|
--#
|
|
|
--
|
|
|
--empty_8042:
|
|
|
-- pushl %ecx
|
|
|
-- movl $100000, %ecx
|
|
|
--
|
|
|
--empty_8042_loop:
|
|
|
-- decl %ecx
|
|
|
-- jz empty_8042_end_loop
|
|
|
--
|
|
|
-- call delay
|
|
|
--
|
|
|
-- inb $0x64, %al # 8042 status port
|
|
|
-- testb $1, %al # output buffer?
|
|
|
-- jz no_output
|
|
|
--
|
|
|
-- call delay
|
|
|
-- inb $0x60, %al # read it
|
|
|
-- jmp empty_8042_loop
|
|
|
--
|
|
|
--no_output:
|
|
|
-- testb $2, %al # is input buffer full?
|
|
|
-- jnz empty_8042_loop # yes - loop
|
|
|
--empty_8042_end_loop:
|
|
|
-- popl %ecx
|
|
|
-- ret
|
|
|
--
|
|
|
--# Read the cmos clock. Return the seconds in al
|
|
|
--gettime:
|
|
|
-- pushw %cx
|
|
|
-- movb $0x02, %ah
|
|
|
-- int $0x1a
|
|
|
-- movb %dh, %al # %dh contains the seconds
|
|
|
-- andb $0x0f, %al
|
|
|
-- movb %dh, %ah
|
|
|
-- movb $0x04, %cl
|
|
|
-- shrb %cl, %ah
|
|
|
-- aad
|
|
|
-- popw %cx
|
|
|
-- ret
|
|
|
--
|
|
|
--# Delay is needed after doing I/O
|
|
|
--delay:
|
|
|
-- outb %al,$0x80
|
|
|
-- ret
|
|
|
--
|
|
|
--# Descriptor tables
|
|
|
--gdt:
|
|
|
-- .word 0, 0, 0, 0 # dummy
|
|
|
--
|
|
|
-- .word 0, 0, 0, 0 # unused
|
|
|
--
|
|
|
-- .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
|
|
|
-- .word 0 # base address = 0
|
|
|
-- .word 0x9A00 # code read/exec
|
|
|
-- .word 0x00CF # granularity = 4096, 386
|
|
|
-- # (+5th nibble of limit)
|
|
|
--
|
|
|
-- .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
|
|
|
-- .word 0 # base address = 0
|
|
|
-- .word 0x9200 # data read/write
|
|
|
-- .word 0x00CF # granularity = 4096, 386
|
|
|
-- # (+5th nibble of limit)
|
|
|
--gdt_end:
|
|
|
--idt_48:
|
|
|
-- .word 0 # idt limit = 0
|
|
|
-- .word 0, 0 # idt base = 0L
|
|
|
--gdt_48:
|
|
|
-- .word gdt_end-gdt-1 # gdt limit
|
|
|
-- .word 0, 0 # gdt base (filled in later)
|
|
|
--
|
|
|
--# Include video setup & detection code
|
|
|
--
|
|
|
--#include "../../i386/boot/video.S"
|
|
|
--
|
|
|
--# Setup signature -- must be last
|
|
|
--setup_sig1: .word SIG1
|
|
|
--setup_sig2: .word SIG2
|
|
|
--
|
|
|
--# After this point, there is some free space which is used by the video mode
|
|
|
--# handling code to store the temporary mode table (not used by the kernel).
|
|
|
--
|
|
|
--modelist:
|
|
|
--
|
|
|
--.text
|
|
|
--endtext:
|
|
|
--.data
|
|
|
--enddata:
|
|
|
--.bss
|
|
|
--endbss:
|
|
|
-diff -puN arch/x86_64/boot/tools/build.c~git-newsetup /dev/null
|
|
|
---- a/arch/x86_64/boot/tools/build.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,185 +0,0 @@
|
|
|
--/*
|
|
|
-- * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
-- * Copyright (C) 1997 Martin Mares
|
|
|
-- */
|
|
|
--
|
|
|
--/*
|
|
|
-- * This file builds a disk-image from three different files:
|
|
|
-- *
|
|
|
-- * - bootsect: compatibility mbr which prints an error message if
|
|
|
-- * someone tries to boot the kernel directly.
|
|
|
-- * - setup: 8086 machine code, sets up system parm
|
|
|
-- * - system: 80386 code for actual system
|
|
|
-- *
|
|
|
-- * It does some checking that all files are of the correct type, and
|
|
|
-- * just writes the result to stdout, removing headers and padding to
|
|
|
-- * the right amount. It also writes some system data to stderr.
|
|
|
-- */
|
|
|
--
|
|
|
--/*
|
|
|
-- * Changes by tytso to allow root device specification
|
|
|
-- * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
|
|
|
-- * Cross compiling fixes by Gertjan van Wingerde, July 1996
|
|
|
-- * Rewritten by Martin Mares, April 1997
|
|
|
-- */
|
|
|
--
|
|
|
--#include <stdio.h>
|
|
|
--#include <string.h>
|
|
|
--#include <stdlib.h>
|
|
|
--#include <stdarg.h>
|
|
|
--#include <sys/types.h>
|
|
|
--#include <sys/stat.h>
|
|
|
--#include <sys/sysmacros.h>
|
|
|
--#include <unistd.h>
|
|
|
--#include <fcntl.h>
|
|
|
--#include <asm/boot.h>
|
|
|
--
|
|
|
--typedef unsigned char byte;
|
|
|
--typedef unsigned short word;
|
|
|
--typedef unsigned long u32;
|
|
|
--
|
|
|
--#define DEFAULT_MAJOR_ROOT 0
|
|
|
--#define DEFAULT_MINOR_ROOT 0
|
|
|
--
|
|
|
--/* Minimal number of setup sectors (see also bootsect.S) */
|
|
|
--#define SETUP_SECTS 4
|
|
|
--
|
|
|
--byte buf[1024];
|
|
|
--int fd;
|
|
|
--int is_big_kernel;
|
|
|
--
|
|
|
--void die(const char * str, ...)
|
|
|
--{
|
|
|
-- va_list args;
|
|
|
-- va_start(args, str);
|
|
|
-- vfprintf(stderr, str, args);
|
|
|
-- fputc('\n', stderr);
|
|
|
-- exit(1);
|
|
|
--}
|
|
|
--
|
|
|
--void file_open(const char *name)
|
|
|
--{
|
|
|
-- if ((fd = open(name, O_RDONLY, 0)) < 0)
|
|
|
-- die("Unable to open `%s': %m", name);
|
|
|
--}
|
|
|
--
|
|
|
--void usage(void)
|
|
|
--{
|
|
|
-- die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
|
|
|
--}
|
|
|
--
|
|
|
--int main(int argc, char ** argv)
|
|
|
--{
|
|
|
-- unsigned int i, c, sz, setup_sectors;
|
|
|
-- u32 sys_size;
|
|
|
-- byte major_root, minor_root;
|
|
|
-- struct stat sb;
|
|
|
--
|
|
|
-- if (argc > 2 && !strcmp(argv[1], "-b"))
|
|
|
-- {
|
|
|
-- is_big_kernel = 1;
|
|
|
-- argc--, argv++;
|
|
|
-- }
|
|
|
-- if ((argc < 4) || (argc > 5))
|
|
|
-- usage();
|
|
|
-- if (argc > 4) {
|
|
|
-- if (!strcmp(argv[4], "CURRENT")) {
|
|
|
-- if (stat("/", &sb)) {
|
|
|
-- perror("/");
|
|
|
-- die("Couldn't stat /");
|
|
|
-- }
|
|
|
-- major_root = major(sb.st_dev);
|
|
|
-- minor_root = minor(sb.st_dev);
|
|
|
-- } else if (strcmp(argv[4], "FLOPPY")) {
|
|
|
-- if (stat(argv[4], &sb)) {
|
|
|
-- perror(argv[4]);
|
|
|
-- die("Couldn't stat root device.");
|
|
|
-- }
|
|
|
-- major_root = major(sb.st_rdev);
|
|
|
-- minor_root = minor(sb.st_rdev);
|
|
|
-- } else {
|
|
|
-- major_root = 0;
|
|
|
-- minor_root = 0;
|
|
|
-- }
|
|
|
-- } else {
|
|
|
-- major_root = DEFAULT_MAJOR_ROOT;
|
|
|
-- minor_root = DEFAULT_MINOR_ROOT;
|
|
|
-- }
|
|
|
-- fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
|
|
|
--
|
|
|
-- file_open(argv[1]);
|
|
|
-- i = read(fd, buf, sizeof(buf));
|
|
|
-- fprintf(stderr,"Boot sector %d bytes.\n",i);
|
|
|
-- if (i != 512)
|
|
|
-- die("Boot block must be exactly 512 bytes");
|
|
|
-- if (buf[510] != 0x55 || buf[511] != 0xaa)
|
|
|
-- die("Boot block hasn't got boot flag (0xAA55)");
|
|
|
-- buf[508] = minor_root;
|
|
|
-- buf[509] = major_root;
|
|
|
-- if (write(1, buf, 512) != 512)
|
|
|
-- die("Write call failed");
|
|
|
-- close (fd);
|
|
|
--
|
|
|
-- file_open(argv[2]); /* Copy the setup code */
|
|
|
-- for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
|
|
|
-- if (write(1, buf, c) != c)
|
|
|
-- die("Write call failed");
|
|
|
-- if (c != 0)
|
|
|
-- die("read-error on `setup'");
|
|
|
-- close (fd);
|
|
|
--
|
|
|
-- setup_sectors = (i + 511) / 512; /* Pad unused space with zeros */
|
|
|
-- /* for compatibility with ancient versions of LILO. */
|
|
|
-- if (setup_sectors < SETUP_SECTS)
|
|
|
-- setup_sectors = SETUP_SECTS;
|
|
|
-- fprintf(stderr, "Setup is %d bytes.\n", i);
|
|
|
-- memset(buf, 0, sizeof(buf));
|
|
|
-- while (i < setup_sectors * 512) {
|
|
|
-- c = setup_sectors * 512 - i;
|
|
|
-- if (c > sizeof(buf))
|
|
|
-- c = sizeof(buf);
|
|
|
-- if (write(1, buf, c) != c)
|
|
|
-- die("Write call failed");
|
|
|
-- i += c;
|
|
|
-- }
|
|
|
--
|
|
|
-- file_open(argv[3]);
|
|
|
-- if (fstat (fd, &sb))
|
|
|
-- die("Unable to stat `%s': %m", argv[3]);
|
|
|
-- sz = sb.st_size;
|
|
|
-- fprintf (stderr, "System is %d kB\n", sz/1024);
|
|
|
-- sys_size = (sz + 15) / 16;
|
|
|
-- if (!is_big_kernel && sys_size > DEF_SYSSIZE)
|
|
|
-- die("System is too big. Try using bzImage or modules.");
|
|
|
-- while (sz > 0) {
|
|
|
-- int l, n;
|
|
|
--
|
|
|
-- l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
|
|
|
-- if ((n=read(fd, buf, l)) != l) {
|
|
|
-- if (n < 0)
|
|
|
-- die("Error reading %s: %m", argv[3]);
|
|
|
-- else
|
|
|
-- die("%s: Unexpected EOF", argv[3]);
|
|
|
-- }
|
|
|
-- if (write(1, buf, l) != l)
|
|
|
-- die("Write failed");
|
|
|
-- sz -= l;
|
|
|
-- }
|
|
|
-- close(fd);
|
|
|
--
|
|
|
-- if (lseek(1, 497, SEEK_SET) != 497) /* Write sizes to the bootsector */
|
|
|
-- die("Output: seek failed");
|
|
|
-- buf[0] = setup_sectors;
|
|
|
-- if (write(1, buf, 1) != 1)
|
|
|
-- die("Write of setup sector count failed");
|
|
|
-- if (lseek(1, 500, SEEK_SET) != 500)
|
|
|
-- die("Output: seek failed");
|
|
|
-- buf[0] = (sys_size & 0xff);
|
|
|
-- buf[1] = ((sys_size >> 8) & 0xff);
|
|
|
-- buf[2] = ((sys_size >> 16) & 0xff);
|
|
|
-- buf[3] = ((sys_size >> 24) & 0xff);
|
|
|
-- if (write(1, buf, 4) != 4)
|
|
|
-- die("Write of image length failed");
|
|
|
--
|
|
|
-- return 0; /* Everything is OK */
|
|
|
--}
|
|
|
-diff -puN arch/x86_64/kernel/Makefile~git-newsetup arch/x86_64/kernel/Makefile
|
|
|
---- a/arch/x86_64/kernel/Makefile~git-newsetup
|
|
|
-+++ a/arch/x86_64/kernel/Makefile
|
|
|
-@@ -45,6 +45,7 @@ obj-$(CONFIG_PCI) += early-quirks.o
|
|
|
-
|
|
|
- obj-y += topology.o
|
|
|
- obj-y += intel_cacheinfo.o
|
|
|
-+obj-y += addon_cpuid_features.o
|
|
|
- obj-y += pcspeaker.o
|
|
|
-
|
|
|
- CFLAGS_vsyscall.o := $(PROFILING) -g0
|
|
|
-@@ -58,6 +59,7 @@ cpuid-$(subst m,y,$(CONFIG_X86_CPUID))
|
|
|
- topology-y += ../../i386/kernel/topology.o
|
|
|
- microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o
|
|
|
- intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o
|
|
|
-+addon_cpuid_features-y += ../../i386/kernel/cpu/addon_cpuid_features.o
|
|
|
- quirks-y += ../../i386/kernel/quirks.o
|
|
|
- i8237-y += ../../i386/kernel/i8237.o
|
|
|
- msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o
|
|
|
-diff -puN arch/x86_64/kernel/setup.c~git-newsetup arch/x86_64/kernel/setup.c
|
|
|
---- a/arch/x86_64/kernel/setup.c~git-newsetup
|
|
|
-+++ a/arch/x86_64/kernel/setup.c
|
|
|
-@@ -855,6 +855,8 @@ void __cpuinit identify_cpu(struct cpuin
|
|
|
- c->x86_capability[2] = cpuid_edx(0x80860001);
|
|
|
- }
|
|
|
-
|
|
|
-+ init_scattered_cpuid_features(c);
|
|
|
-+
|
|
|
- c->apicid = phys_pkg_id(0);
|
|
|
-
|
|
|
- /*
|
|
|
-@@ -940,7 +942,7 @@ static int show_cpuinfo(struct seq_file
|
|
|
- "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
|
|
|
- "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
|
|
|
- "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
|
|
|
-- "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
|
|
|
-+ "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
|
|
|
-
|
|
|
- /* AMD-defined */
|
|
|
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-@@ -956,10 +958,11 @@ static int show_cpuinfo(struct seq_file
|
|
|
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-
|
|
|
- /* Other (Linux-defined) */
|
|
|
-- "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL,
|
|
|
-- "constant_tsc", NULL, NULL,
|
|
|
-- "up", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-+ "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
|
|
|
-+ NULL, NULL, NULL, NULL,
|
|
|
-+ "constant_tsc", "up", NULL, "arch_perfmon",
|
|
|
-+ "pebs", "bts", NULL, "sync_rdtsc",
|
|
|
-+ "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-
|
|
|
- /* Intel-defined (#2) */
|
|
|
-@@ -970,7 +973,7 @@ static int show_cpuinfo(struct seq_file
|
|
|
-
|
|
|
- /* VIA/Cyrix/Centaur-defined */
|
|
|
- NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
|
|
|
-- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-+ "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
|
|
|
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-
|
|
|
-@@ -981,6 +984,12 @@ static int show_cpuinfo(struct seq_file
|
|
|
- "osvw", "ibs", NULL, NULL, NULL, NULL,
|
|
|
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-+
|
|
|
-+ /* Auxiliary (Linux-defined) */
|
|
|
-+ "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
-+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
|
- };
|
|
|
- static char *x86_power_flags[] = {
|
|
|
- "ts", /* temperature sensor */
|
|
|
-diff -puN arch/x86_64/kernel/verify_cpu.S~git-newsetup arch/x86_64/kernel/verify_cpu.S
|
|
|
---- a/arch/x86_64/kernel/verify_cpu.S~git-newsetup
|
|
|
-+++ a/arch/x86_64/kernel/verify_cpu.S
|
|
|
-@@ -37,20 +37,6 @@ verify_cpu:
|
|
|
- pushl $0 # Kill any dangerous flags
|
|
|
- popfl
|
|
|
-
|
|
|
-- /* minimum CPUID flags for x86-64 as defined by AMD */
|
|
|
--#define M(x) (1<<(x))
|
|
|
--#define M2(a,b) M(a)|M(b)
|
|
|
--#define M4(a,b,c,d) M(a)|M(b)|M(c)|M(d)
|
|
|
--
|
|
|
--#define SSE_MASK \
|
|
|
-- (M2(X86_FEATURE_XMM,X86_FEATURE_XMM2))
|
|
|
--#define REQUIRED_MASK1 \
|
|
|
-- (M4(X86_FEATURE_FPU,X86_FEATURE_PSE,X86_FEATURE_TSC,X86_FEATURE_MSR)|\
|
|
|
-- M4(X86_FEATURE_PAE,X86_FEATURE_CX8,X86_FEATURE_PGE,X86_FEATURE_CMOV)|\
|
|
|
-- M(X86_FEATURE_FXSR))
|
|
|
--#define REQUIRED_MASK2 \
|
|
|
-- (M(X86_FEATURE_LM - 32))
|
|
|
--
|
|
|
- pushfl # standard way to check for cpuid
|
|
|
- popl %eax
|
|
|
- movl %eax,%ebx
|
|
|
-@@ -79,8 +65,8 @@ verify_cpu:
|
|
|
- verify_cpu_noamd:
|
|
|
- movl $0x1,%eax # Does the cpu have what it takes
|
|
|
- cpuid
|
|
|
-- andl $REQUIRED_MASK1,%edx
|
|
|
-- xorl $REQUIRED_MASK1,%edx
|
|
|
-+ andl $REQUIRED_MASK0,%edx
|
|
|
-+ xorl $REQUIRED_MASK0,%edx
|
|
|
- jnz verify_cpu_no_longmode
|
|
|
-
|
|
|
- movl $0x80000000,%eax # See if extended cpuid is implemented
|
|
|
-@@ -90,8 +76,8 @@ verify_cpu_noamd:
|
|
|
-
|
|
|
- movl $0x80000001,%eax # Does the cpu have what it takes
|
|
|
- cpuid
|
|
|
-- andl $REQUIRED_MASK2,%edx
|
|
|
-- xorl $REQUIRED_MASK2,%edx
|
|
|
-+ andl $REQUIRED_MASK1,%edx
|
|
|
-+ xorl $REQUIRED_MASK1,%edx
|
|
|
- jnz verify_cpu_no_longmode
|
|
|
-
|
|
|
- verify_cpu_sse_test:
|
|
|
-diff -puN drivers/ide/legacy/hd.c~git-newsetup drivers/ide/legacy/hd.c
|
|
|
---- a/drivers/ide/legacy/hd.c~git-newsetup
|
|
|
-+++ a/drivers/ide/legacy/hd.c
|
|
|
-@@ -718,74 +718,25 @@ static int __init hd_init(void)
|
|
|
- device_timer.function = hd_times_out;
|
|
|
- blk_queue_hardsect_size(hd_queue, 512);
|
|
|
-
|
|
|
--#ifdef __i386__
|
|
|
- if (!NR_HD) {
|
|
|
-- extern struct drive_info drive_info;
|
|
|
-- unsigned char *BIOS = (unsigned char *) &drive_info;
|
|
|
-- unsigned long flags;
|
|
|
-- int cmos_disks;
|
|
|
--
|
|
|
-- for (drive=0 ; drive<2 ; drive++) {
|
|
|
-- hd_info[drive].cyl = *(unsigned short *) BIOS;
|
|
|
-- hd_info[drive].head = *(2+BIOS);
|
|
|
-- hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
|
|
|
-- hd_info[drive].ctl = *(8+BIOS);
|
|
|
-- hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
|
|
|
-- hd_info[drive].sect = *(14+BIOS);
|
|
|
--#ifdef does_not_work_for_everybody_with_scsi_but_helps_ibm_vp
|
|
|
-- if (hd_info[drive].cyl && NR_HD == drive)
|
|
|
-- NR_HD++;
|
|
|
--#endif
|
|
|
-- BIOS += 16;
|
|
|
-- }
|
|
|
--
|
|
|
-- /*
|
|
|
-- We query CMOS about hard disks : it could be that
|
|
|
-- we have a SCSI/ESDI/etc controller that is BIOS
|
|
|
-- compatible with ST-506, and thus showing up in our
|
|
|
-- BIOS table, but not register compatible, and therefore
|
|
|
-- not present in CMOS.
|
|
|
--
|
|
|
-- Furthermore, we will assume that our ST-506 drives
|
|
|
-- <if any> are the primary drives in the system, and
|
|
|
-- the ones reflected as drive 1 or 2.
|
|
|
--
|
|
|
-- The first drive is stored in the high nibble of CMOS
|
|
|
-- byte 0x12, the second in the low nibble. This will be
|
|
|
-- either a 4 bit drive type or 0xf indicating use byte 0x19
|
|
|
-- for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.
|
|
|
--
|
|
|
-- Needless to say, a non-zero value means we have
|
|
|
-- an AT controller hard disk for that drive.
|
|
|
--
|
|
|
-- Currently the rtc_lock is a bit academic since this
|
|
|
-- driver is non-modular, but someday... ? Paul G.
|
|
|
-- */
|
|
|
--
|
|
|
-- spin_lock_irqsave(&rtc_lock, flags);
|
|
|
-- cmos_disks = CMOS_READ(0x12);
|
|
|
-- spin_unlock_irqrestore(&rtc_lock, flags);
|
|
|
--
|
|
|
-- if (cmos_disks & 0xf0) {
|
|
|
-- if (cmos_disks & 0x0f)
|
|
|
-- NR_HD = 2;
|
|
|
-- else
|
|
|
-- NR_HD = 1;
|
|
|
-- }
|
|
|
-- }
|
|
|
--#endif /* __i386__ */
|
|
|
--#ifdef __arm__
|
|
|
-- if (!NR_HD) {
|
|
|
-- /* We don't know anything about the drive. This means
|
|
|
-+ /*
|
|
|
-+ * We don't know anything about the drive. This means
|
|
|
- * that you *MUST* specify the drive parameters to the
|
|
|
- * kernel yourself.
|
|
|
-+ *
|
|
|
-+ * If we were on an i386, we used to read this info from
|
|
|
-+ * the BIOS or CMOS. This doesn't work all that well,
|
|
|
-+ * since this assumes that this is a primary or secondary
|
|
|
-+ * drive, and if we're using this legacy driver, it's
|
|
|
-+ * probably an auxilliary controller added to recover
|
|
|
-+ * legacy data off an ST-506 drive. Either way, it's
|
|
|
-+ * definitely safest to have the user explicitly specify
|
|
|
-+ * the information.
|
|
|
- */
|
|
|
- printk("hd: no drives specified - use hd=cyl,head,sectors"
|
|
|
- " on kernel command line\n");
|
|
|
-- }
|
|
|
--#endif
|
|
|
-- if (!NR_HD)
|
|
|
- goto out;
|
|
|
-+ }
|
|
|
-
|
|
|
- for (drive=0 ; drive < NR_HD ; drive++) {
|
|
|
- struct gendisk *disk = alloc_disk(64);
|
|
|
-diff -puN include/asm-i386/boot.h~git-newsetup include/asm-i386/boot.h
|
|
|
---- a/include/asm-i386/boot.h~git-newsetup
|
|
|
-+++ a/include/asm-i386/boot.h
|
|
|
-@@ -1,5 +1,5 @@
|
|
|
--#ifndef _LINUX_BOOT_H
|
|
|
--#define _LINUX_BOOT_H
|
|
|
-+#ifndef _ASM_BOOT_H
|
|
|
-+#define _ASM_BOOT_H
|
|
|
-
|
|
|
- /* Don't touch these, unless you really know what you're doing. */
|
|
|
- #define DEF_INITSEG 0x9000
|
|
|
-@@ -17,4 +17,4 @@
|
|
|
- + (CONFIG_PHYSICAL_ALIGN - 1)) \
|
|
|
- & ~(CONFIG_PHYSICAL_ALIGN - 1))
|
|
|
-
|
|
|
--#endif /* _LINUX_BOOT_H */
|
|
|
-+#endif /* _ASM_BOOT_H */
|
|
|
-diff -puN /dev/null include/asm-i386/bootparam.h
|
|
|
---- /dev/null
|
|
|
-+++ a/include/asm-i386/bootparam.h
|
|
|
-@@ -0,0 +1,85 @@
|
|
|
-+#ifndef _ASM_BOOTPARAM_H
|
|
|
-+#define _ASM_BOOTPARAM_H
|
|
|
-+
|
|
|
-+#include <linux/types.h>
|
|
|
-+#include <linux/screen_info.h>
|
|
|
-+#include <linux/apm_bios.h>
|
|
|
-+#include <asm/e820.h>
|
|
|
-+#include <linux/edd.h>
|
|
|
-+#include <video/edid.h>
|
|
|
-+
|
|
|
-+struct setup_header {
|
|
|
-+ u8 setup_sects;
|
|
|
-+ u16 root_flags;
|
|
|
-+ u32 syssize;
|
|
|
-+ u16 ram_size;
|
|
|
-+ u16 vid_mode;
|
|
|
-+ u16 root_dev;
|
|
|
-+ u16 boot_flag;
|
|
|
-+ u16 jump;
|
|
|
-+ u32 header;
|
|
|
-+ u16 version;
|
|
|
-+ u32 realmode_swtch;
|
|
|
-+ u16 start_sys;
|
|
|
-+ u16 kernel_version;
|
|
|
-+ u8 type_of_loader;
|
|
|
-+ u8 loadflags;
|
|
|
-+#define LOADED_HIGH 0x01
|
|
|
-+#define CAN_USE_HEAP 0x80
|
|
|
-+ u16 setup_move_size;
|
|
|
-+ u32 code32_start;
|
|
|
-+ u32 ramdisk_image;
|
|
|
-+ u32 ramdisk_size;
|
|
|
-+ u32 bootsect_kludge;
|
|
|
-+ u16 heap_end_ptr;
|
|
|
-+ u16 _pad1;
|
|
|
-+ u32 cmd_line_ptr;
|
|
|
-+ u32 initrd_addr_max;
|
|
|
-+ u32 kernel_alignment;
|
|
|
-+ u8 relocatable_kernel;
|
|
|
-+} __attribute__((packed));
|
|
|
-+
|
|
|
-+struct sys_desc_table {
|
|
|
-+ u16 length;
|
|
|
-+ u8 table[14];
|
|
|
-+};
|
|
|
-+
|
|
|
-+struct efi_info {
|
|
|
-+ u32 _pad1;
|
|
|
-+ u32 efi_systab;
|
|
|
-+ u32 efi_memdesc_size;
|
|
|
-+ u32 efi_memdec_version;
|
|
|
-+ u32 efi_memmap;
|
|
|
-+ u32 fi_memmap_size;
|
|
|
-+ u32 _pad2[2];
|
|
|
-+};
|
|
|
-+
|
|
|
-+/* The so-called "zeropage" */
|
|
|
-+struct boot_params {
|
|
|
-+ struct screen_info screen_info; /* 0x000 */
|
|
|
-+ struct apm_bios_info apm_bios_info; /* 0x040 */
|
|
|
-+ u8 _pad2[12]; /* 0x054 */
|
|
|
-+ u32 speedstep_info[4]; /* 0x060 */
|
|
|
-+ u8 _pad3[16]; /* 0x070 */
|
|
|
-+ u8 hd0_info[16]; /* obsolete! */ /* 0x080 */
|
|
|
-+ u8 hd1_info[16]; /* obsolete! */ /* 0x090 */
|
|
|
-+ struct sys_desc_table sys_desc_table; /* 0x0a0 */
|
|
|
-+ u8 _pad4[144]; /* 0x0b0 */
|
|
|
-+ struct edid_info edid_info; /* 0x140 */
|
|
|
-+ struct efi_info efi_info; /* 0x1c0 */
|
|
|
-+ u32 alt_mem_k; /* 0x1e0 */
|
|
|
-+ u32 scratch; /* Scratch field! */ /* 0x1e4 */
|
|
|
-+ u8 e820_entries; /* 0x1e8 */
|
|
|
-+ u8 eddbuf_entries; /* 0x1e9 */
|
|
|
-+ u8 edd_mbr_sig_buf_entries; /* 0x1ea */
|
|
|
-+ u8 _pad6[6]; /* 0x1eb */
|
|
|
-+ struct setup_header hdr; /* setup header */ /* 0x1f1 */
|
|
|
-+ u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
|
|
|
-+ u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */
|
|
|
-+ struct e820entry e820_map[E820MAX]; /* 0x2d0 */
|
|
|
-+ u8 _pad8[48]; /* 0xcd0 */
|
|
|
-+ struct edd_info eddbuf[EDDMAXNR]; /* 0xd00 */
|
|
|
-+ u8 _pad9[276]; /* 0xeec */
|
|
|
-+} __attribute__((packed));
|
|
|
-+
|
|
|
-+#endif /* _ASM_BOOTPARAM_H */
|
|
|
-diff -puN include/asm-i386/cpufeature.h~git-newsetup include/asm-i386/cpufeature.h
|
|
|
---- a/include/asm-i386/cpufeature.h~git-newsetup
|
|
|
-+++ a/include/asm-i386/cpufeature.h
|
|
|
-@@ -12,7 +12,7 @@
|
|
|
- #endif
|
|
|
- #include <asm/required-features.h>
|
|
|
-
|
|
|
--#define NCAPINTS 7 /* N 32-bit words worth of info */
|
|
|
-+#define NCAPINTS 8 /* N 32-bit words worth of info */
|
|
|
-
|
|
|
- /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
|
|
|
- #define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */
|
|
|
-@@ -81,6 +81,7 @@
|
|
|
- #define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */
|
|
|
- #define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */
|
|
|
- #define X86_FEATURE_SYNC_RDTSC (3*32+15) /* RDTSC synchronizes the CPU */
|
|
|
-+#define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */
|
|
|
-
|
|
|
- /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
|
|
|
- #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
|
|
|
-@@ -108,11 +109,24 @@
|
|
|
- #define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */
|
|
|
- #define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */
|
|
|
-
|
|
|
--#define cpu_has(c, bit) \
|
|
|
-- ((__builtin_constant_p(bit) && (bit) < 32 && \
|
|
|
-- (1UL << (bit)) & REQUIRED_MASK1) ? \
|
|
|
-- 1 : \
|
|
|
-- test_bit(bit, (c)->x86_capability))
|
|
|
-+/*
|
|
|
-+ * Auxiliary flags: Linux defined - For features scattered in various
|
|
|
-+ * CPUID levels like 0x6, 0xA etc
|
|
|
-+ */
|
|
|
-+#define X86_FEATURE_IDA (7*32+ 0) /* Intel Dynamic Acceleration */
|
|
|
-+
|
|
|
-+#define cpu_has(c, bit) \
|
|
|
-+ (__builtin_constant_p(bit) && \
|
|
|
-+ ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) || \
|
|
|
-+ (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) || \
|
|
|
-+ (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) || \
|
|
|
-+ (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) || \
|
|
|
-+ (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) || \
|
|
|
-+ (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) || \
|
|
|
-+ (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) || \
|
|
|
-+ (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) ) \
|
|
|
-+ ? 1 : \
|
|
|
-+ test_bit(bit, (c)->x86_capability))
|
|
|
- #define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit)
|
|
|
-
|
|
|
- #define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU)
|
|
|
-diff -puN include/asm-i386/e820.h~git-newsetup include/asm-i386/e820.h
|
|
|
---- a/include/asm-i386/e820.h~git-newsetup
|
|
|
-+++ a/include/asm-i386/e820.h
|
|
|
-@@ -25,13 +25,15 @@
|
|
|
-
|
|
|
- #ifndef __ASSEMBLY__
|
|
|
-
|
|
|
-+struct e820entry {
|
|
|
-+ u64 addr; /* start of memory segment */
|
|
|
-+ u64 size; /* size of memory segment */
|
|
|
-+ u32 type; /* type of memory segment */
|
|
|
-+} __attribute__((packed));
|
|
|
-+
|
|
|
- struct e820map {
|
|
|
-- int nr_map;
|
|
|
-- struct e820entry {
|
|
|
-- unsigned long long addr; /* start of memory segment */
|
|
|
-- unsigned long long size; /* size of memory segment */
|
|
|
-- unsigned long type; /* type of memory segment */
|
|
|
-- } map[E820MAX];
|
|
|
-+ u32 nr_map;
|
|
|
-+ struct e820entry map[E820MAX];
|
|
|
- };
|
|
|
-
|
|
|
- extern struct e820map e820;
|
|
|
-diff -puN include/asm-i386/processor.h~git-newsetup include/asm-i386/processor.h
|
|
|
---- a/include/asm-i386/processor.h~git-newsetup
|
|
|
-+++ a/include/asm-i386/processor.h
|
|
|
-@@ -118,6 +118,7 @@ void __init cpu_detect(struct cpuinfo_x8
|
|
|
- extern void identify_boot_cpu(void);
|
|
|
- extern void identify_secondary_cpu(struct cpuinfo_x86 *);
|
|
|
- extern void print_cpu_info(struct cpuinfo_x86 *);
|
|
|
-+extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
|
|
|
- extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
|
|
|
- extern unsigned short num_cache_leaves;
|
|
|
-
|
|
|
-diff -puN include/asm-i386/required-features.h~git-newsetup include/asm-i386/required-features.h
|
|
|
---- a/include/asm-i386/required-features.h~git-newsetup
|
|
|
-+++ a/include/asm-i386/required-features.h
|
|
|
-@@ -3,7 +3,7 @@
|
|
|
-
|
|
|
- /* Define minimum CPUID feature set for kernel These bits are checked
|
|
|
- really early to actually display a visible error message before the
|
|
|
-- kernel dies. Only add word 0 bits here
|
|
|
-+ kernel dies. Make sure to assign features to the proper mask!
|
|
|
-
|
|
|
- Some requirements that are not in CPUID yet are also in the
|
|
|
- CONFIG_X86_MINIMUM_CPU mode which is checked too.
|
|
|
-@@ -11,24 +11,45 @@
|
|
|
- The real information is in arch/i386/Kconfig.cpu, this just converts
|
|
|
- the CONFIGs into a bitmask */
|
|
|
-
|
|
|
-+#ifndef CONFIG_MATH_EMULATION
|
|
|
-+# define NEED_FPU (1<<(X86_FEATURE_FPU & 31))
|
|
|
-+#else
|
|
|
-+# define NEED_FPU 0
|
|
|
-+#endif
|
|
|
-+
|
|
|
- #ifdef CONFIG_X86_PAE
|
|
|
--#define NEED_PAE (1<<X86_FEATURE_PAE)
|
|
|
-+# define NEED_PAE (1<<(X86_FEATURE_PAE & 31))
|
|
|
- #else
|
|
|
--#define NEED_PAE 0
|
|
|
-+# define NEED_PAE 0
|
|
|
- #endif
|
|
|
-
|
|
|
- #ifdef CONFIG_X86_CMOV
|
|
|
--#define NEED_CMOV (1<<X86_FEATURE_CMOV)
|
|
|
-+# define NEED_CMOV (1<<(X86_FEATURE_CMOV & 31))
|
|
|
- #else
|
|
|
--#define NEED_CMOV 0
|
|
|
-+# define NEED_CMOV 0
|
|
|
- #endif
|
|
|
-
|
|
|
- #ifdef CONFIG_X86_CMPXCHG64
|
|
|
--#define NEED_CMPXCHG64 (1<<X86_FEATURE_CX8)
|
|
|
-+# define NEED_CX8 (1<<(X86_FEATURE_CX8 & 31))
|
|
|
-+#else
|
|
|
-+# define NEED_CX8 0
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#define REQUIRED_MASK0 (NEED_FPU|NEED_PAE|NEED_CMOV|NEED_CX8)
|
|
|
-+
|
|
|
-+#ifdef CONFIG_X86_USE_3DNOW
|
|
|
-+# define NEED_3DNOW (1<<(X86_FEATURE_3DNOW & 31))
|
|
|
- #else
|
|
|
--#define NEED_CMPXCHG64 0
|
|
|
-+# define NEED_3DNOW 0
|
|
|
- #endif
|
|
|
-
|
|
|
--#define REQUIRED_MASK1 (NEED_PAE|NEED_CMOV|NEED_CMPXCHG64)
|
|
|
-+#define REQUIRED_MASK1 (NEED_3DNOW)
|
|
|
-+
|
|
|
-+#define REQUIRED_MASK2 0
|
|
|
-+#define REQUIRED_MASK3 0
|
|
|
-+#define REQUIRED_MASK4 0
|
|
|
-+#define REQUIRED_MASK5 0
|
|
|
-+#define REQUIRED_MASK6 0
|
|
|
-+#define REQUIRED_MASK7 0
|
|
|
-
|
|
|
- #endif
|
|
|
-diff -puN include/asm-i386/setup.h~git-newsetup include/asm-i386/setup.h
|
|
|
---- a/include/asm-i386/setup.h~git-newsetup
|
|
|
-+++ a/include/asm-i386/setup.h
|
|
|
-@@ -26,12 +26,15 @@
|
|
|
- #define NEW_CL_POINTER 0x228 /* Relative to real mode data */
|
|
|
-
|
|
|
- #ifndef __ASSEMBLY__
|
|
|
-+
|
|
|
-+#include <asm/bootparam.h>
|
|
|
-+
|
|
|
- /*
|
|
|
- * This is set up by the setup-routine at boot-time
|
|
|
- */
|
|
|
--extern unsigned char boot_params[PARAM_SIZE];
|
|
|
-+extern struct boot_params boot_params;
|
|
|
-
|
|
|
--#define PARAM (boot_params)
|
|
|
-+#define PARAM ((char *)&boot_params)
|
|
|
- #define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
|
|
|
- #define EXT_MEM_K (*(unsigned short *) (PARAM+2))
|
|
|
- #define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
|
|
|
-@@ -39,8 +42,7 @@ extern unsigned char boot_params[PARAM_S
|
|
|
- #define E820_MAP ((struct e820entry *) (PARAM+E820MAP))
|
|
|
- #define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
|
|
|
- #define IST_INFO (*(struct ist_info *) (PARAM+0x60))
|
|
|
--#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
|
|
|
--#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
|
|
|
-+#define SYS_DESC_TABLE (*(struct sys_desc_table *)(PARAM+0xa0))
|
|
|
- #define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4)))
|
|
|
- #define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8)))
|
|
|
- #define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc)))
|
|
|
-diff -puN include/asm-x86_64/alternative.h~git-newsetup include/asm-x86_64/alternative.h
|
|
|
---- a/include/asm-x86_64/alternative.h~git-newsetup
|
|
|
-+++ a/include/asm-x86_64/alternative.h
|
|
|
-@@ -5,6 +5,41 @@
|
|
|
-
|
|
|
- #include <linux/types.h>
|
|
|
- #include <linux/stddef.h>
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Alternative inline assembly for SMP.
|
|
|
-+ *
|
|
|
-+ * The LOCK_PREFIX macro defined here replaces the LOCK and
|
|
|
-+ * LOCK_PREFIX macros used everywhere in the source tree.
|
|
|
-+ *
|
|
|
-+ * SMP alternatives use the same data structures as the other
|
|
|
-+ * alternatives and the X86_FEATURE_UP flag to indicate the case of a
|
|
|
-+ * UP system running a SMP kernel. The existing apply_alternatives()
|
|
|
-+ * works fine for patching a SMP kernel for UP.
|
|
|
-+ *
|
|
|
-+ * The SMP alternative tables can be kept after boot and contain both
|
|
|
-+ * UP and SMP versions of the instructions to allow switching back to
|
|
|
-+ * SMP at runtime, when hotplugging in a new CPU, which is especially
|
|
|
-+ * useful in virtualized environments.
|
|
|
-+ *
|
|
|
-+ * The very common lock prefix is handled as special case in a
|
|
|
-+ * separate table which is a pure address list without replacement ptr
|
|
|
-+ * and size information. That keeps the table sizes small.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#ifdef CONFIG_SMP
|
|
|
-+#define LOCK_PREFIX \
|
|
|
-+ ".section .smp_locks,\"a\"\n" \
|
|
|
-+ " .align 8\n" \
|
|
|
-+ " .quad 661f\n" /* address */ \
|
|
|
-+ ".previous\n" \
|
|
|
-+ "661:\n\tlock; "
|
|
|
-+
|
|
|
-+#else /* ! CONFIG_SMP */
|
|
|
-+#define LOCK_PREFIX ""
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+/* This must be included *after* the definition of LOCK_PREFIX */
|
|
|
- #include <asm/cpufeature.h>
|
|
|
-
|
|
|
- struct alt_instr {
|
|
|
-@@ -108,39 +143,6 @@ static inline void alternatives_smp_swit
|
|
|
- */
|
|
|
- #define ASM_OUTPUT2(a, b) a, b
|
|
|
-
|
|
|
--/*
|
|
|
-- * Alternative inline assembly for SMP.
|
|
|
-- *
|
|
|
-- * The LOCK_PREFIX macro defined here replaces the LOCK and
|
|
|
-- * LOCK_PREFIX macros used everywhere in the source tree.
|
|
|
-- *
|
|
|
-- * SMP alternatives use the same data structures as the other
|
|
|
-- * alternatives and the X86_FEATURE_UP flag to indicate the case of a
|
|
|
-- * UP system running a SMP kernel. The existing apply_alternatives()
|
|
|
-- * works fine for patching a SMP kernel for UP.
|
|
|
-- *
|
|
|
-- * The SMP alternative tables can be kept after boot and contain both
|
|
|
-- * UP and SMP versions of the instructions to allow switching back to
|
|
|
-- * SMP at runtime, when hotplugging in a new CPU, which is especially
|
|
|
-- * useful in virtualized environments.
|
|
|
-- *
|
|
|
-- * The very common lock prefix is handled as special case in a
|
|
|
-- * separate table which is a pure address list without replacement ptr
|
|
|
-- * and size information. That keeps the table sizes small.
|
|
|
-- */
|
|
|
--
|
|
|
--#ifdef CONFIG_SMP
|
|
|
--#define LOCK_PREFIX \
|
|
|
-- ".section .smp_locks,\"a\"\n" \
|
|
|
-- " .align 8\n" \
|
|
|
-- " .quad 661f\n" /* address */ \
|
|
|
-- ".previous\n" \
|
|
|
-- "661:\n\tlock; "
|
|
|
--
|
|
|
--#else /* ! CONFIG_SMP */
|
|
|
--#define LOCK_PREFIX ""
|
|
|
--#endif
|
|
|
--
|
|
|
- struct paravirt_patch;
|
|
|
- #ifdef CONFIG_PARAVIRT
|
|
|
- void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end);
|
|
|
-diff -puN include/asm-x86_64/boot.h~git-newsetup include/asm-x86_64/boot.h
|
|
|
---- a/include/asm-x86_64/boot.h~git-newsetup
|
|
|
-+++ a/include/asm-x86_64/boot.h
|
|
|
-@@ -1,15 +1 @@
|
|
|
--#ifndef _LINUX_BOOT_H
|
|
|
--#define _LINUX_BOOT_H
|
|
|
--
|
|
|
--/* Don't touch these, unless you really know what you're doing. */
|
|
|
--#define DEF_INITSEG 0x9000
|
|
|
--#define DEF_SYSSEG 0x1000
|
|
|
--#define DEF_SETUPSEG 0x9020
|
|
|
--#define DEF_SYSSIZE 0x7F00
|
|
|
--
|
|
|
--/* Internal svga startup constants */
|
|
|
--#define NORMAL_VGA 0xffff /* 80x25 mode */
|
|
|
--#define EXTENDED_VGA 0xfffe /* 80x50 mode */
|
|
|
--#define ASK_VGA 0xfffd /* ask for it at bootup */
|
|
|
--
|
|
|
--#endif
|
|
|
-+#include <asm-i386/boot.h>
|
|
|
-diff -puN /dev/null include/asm-x86_64/bootparam.h
|
|
|
---- /dev/null
|
|
|
-+++ a/include/asm-x86_64/bootparam.h
|
|
|
-@@ -0,0 +1 @@
|
|
|
-+#include <asm-i386/bootparam.h>
|
|
|
-diff -puN include/asm-x86_64/cpufeature.h~git-newsetup include/asm-x86_64/cpufeature.h
|
|
|
---- a/include/asm-x86_64/cpufeature.h~git-newsetup
|
|
|
-+++ a/include/asm-x86_64/cpufeature.h
|
|
|
-@@ -7,115 +7,24 @@
|
|
|
- #ifndef __ASM_X8664_CPUFEATURE_H
|
|
|
- #define __ASM_X8664_CPUFEATURE_H
|
|
|
-
|
|
|
--#define NCAPINTS 7 /* N 32-bit words worth of info */
|
|
|
-+#include <asm-i386/cpufeature.h>
|
|
|
-
|
|
|
--/* Intel-defined CPU features, CPUID level 0x00000001, word 0 */
|
|
|
--#define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */
|
|
|
--#define X86_FEATURE_VME (0*32+ 1) /* Virtual Mode Extensions */
|
|
|
--#define X86_FEATURE_DE (0*32+ 2) /* Debugging Extensions */
|
|
|
--#define X86_FEATURE_PSE (0*32+ 3) /* Page Size Extensions */
|
|
|
--#define X86_FEATURE_TSC (0*32+ 4) /* Time Stamp Counter */
|
|
|
--#define X86_FEATURE_MSR (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
|
|
|
--#define X86_FEATURE_PAE (0*32+ 6) /* Physical Address Extensions */
|
|
|
--#define X86_FEATURE_MCE (0*32+ 7) /* Machine Check Architecture */
|
|
|
--#define X86_FEATURE_CX8 (0*32+ 8) /* CMPXCHG8 instruction */
|
|
|
--#define X86_FEATURE_APIC (0*32+ 9) /* Onboard APIC */
|
|
|
--#define X86_FEATURE_SEP (0*32+11) /* SYSENTER/SYSEXIT */
|
|
|
--#define X86_FEATURE_MTRR (0*32+12) /* Memory Type Range Registers */
|
|
|
--#define X86_FEATURE_PGE (0*32+13) /* Page Global Enable */
|
|
|
--#define X86_FEATURE_MCA (0*32+14) /* Machine Check Architecture */
|
|
|
--#define X86_FEATURE_CMOV (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
|
|
|
--#define X86_FEATURE_PAT (0*32+16) /* Page Attribute Table */
|
|
|
--#define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */
|
|
|
--#define X86_FEATURE_PN (0*32+18) /* Processor serial number */
|
|
|
--#define X86_FEATURE_CLFLSH (0*32+19) /* Supports the CLFLUSH instruction */
|
|
|
--#define X86_FEATURE_DS (0*32+21) /* Debug Store */
|
|
|
--#define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */
|
|
|
--#define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */
|
|
|
--#define X86_FEATURE_FXSR (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
|
|
|
-- /* of FPU context), and CR4.OSFXSR available */
|
|
|
--#define X86_FEATURE_XMM (0*32+25) /* Streaming SIMD Extensions */
|
|
|
--#define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */
|
|
|
--#define X86_FEATURE_SELFSNOOP (0*32+27) /* CPU self snoop */
|
|
|
--#define X86_FEATURE_HT (0*32+28) /* Hyper-Threading */
|
|
|
--#define X86_FEATURE_ACC (0*32+29) /* Automatic clock control */
|
|
|
--#define X86_FEATURE_IA64 (0*32+30) /* IA-64 processor */
|
|
|
--
|
|
|
--/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
|
|
|
--/* Don't duplicate feature flags which are redundant with Intel! */
|
|
|
--#define X86_FEATURE_SYSCALL (1*32+11) /* SYSCALL/SYSRET */
|
|
|
--#define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */
|
|
|
--#define X86_FEATURE_FXSR_OPT (1*32+25) /* FXSR optimizations */
|
|
|
--#define X86_FEATURE_RDTSCP (1*32+27) /* RDTSCP */
|
|
|
--#define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */
|
|
|
--#define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */
|
|
|
--#define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */
|
|
|
--
|
|
|
--/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
|
|
|
--#define X86_FEATURE_RECOVERY (2*32+ 0) /* CPU in recovery mode */
|
|
|
--#define X86_FEATURE_LONGRUN (2*32+ 1) /* Longrun power control */
|
|
|
--#define X86_FEATURE_LRTI (2*32+ 3) /* LongRun table interface */
|
|
|
--
|
|
|
--/* Other features, Linux-defined mapping, word 3 */
|
|
|
--/* This range is used for feature bits which conflict or are synthesized */
|
|
|
--#define X86_FEATURE_CXMMX (3*32+ 0) /* Cyrix MMX extensions */
|
|
|
--#define X86_FEATURE_K6_MTRR (3*32+ 1) /* AMD K6 nonstandard MTRRs */
|
|
|
--#define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */
|
|
|
--#define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */
|
|
|
--#define X86_FEATURE_REP_GOOD (3*32+ 4) /* rep microcode works well on this CPU */
|
|
|
--#define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */
|
|
|
--#define X86_FEATURE_SYNC_RDTSC (3*32+6) /* RDTSC syncs CPU core */
|
|
|
--#define X86_FEATURE_FXSAVE_LEAK (3*32+7) /* FIP/FOP/FDP leaks through FXSAVE */
|
|
|
--#define X86_FEATURE_UP (3*32+8) /* SMP kernel running on UP */
|
|
|
--#define X86_FEATURE_ARCH_PERFMON (3*32+9) /* Intel Architectural PerfMon */
|
|
|
--#define X86_FEATURE_PEBS (3*32+10) /* Precise-Event Based Sampling */
|
|
|
--#define X86_FEATURE_BTS (3*32+11) /* Branch Trace Store */
|
|
|
--
|
|
|
--/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
|
|
|
--#define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
|
|
|
--#define X86_FEATURE_MWAIT (4*32+ 3) /* Monitor/Mwait support */
|
|
|
--#define X86_FEATURE_DSCPL (4*32+ 4) /* CPL Qualified Debug Store */
|
|
|
--#define X86_FEATURE_EST (4*32+ 7) /* Enhanced SpeedStep */
|
|
|
--#define X86_FEATURE_TM2 (4*32+ 8) /* Thermal Monitor 2 */
|
|
|
--#define X86_FEATURE_CID (4*32+10) /* Context ID */
|
|
|
--#define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */
|
|
|
--#define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */
|
|
|
--
|
|
|
--/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
|
|
|
--#define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */
|
|
|
--#define X86_FEATURE_XSTORE_EN (5*32+ 3) /* on-CPU RNG enabled */
|
|
|
--#define X86_FEATURE_XCRYPT (5*32+ 6) /* on-CPU crypto (xcrypt insn) */
|
|
|
--#define X86_FEATURE_XCRYPT_EN (5*32+ 7) /* on-CPU crypto enabled */
|
|
|
--
|
|
|
--/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
|
|
|
--#define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */
|
|
|
--#define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */
|
|
|
--
|
|
|
--#define cpu_has(c, bit) test_bit(bit, (c)->x86_capability)
|
|
|
--#define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability)
|
|
|
--
|
|
|
--#define cpu_has_fpu 1
|
|
|
-+#undef cpu_has_vme
|
|
|
- #define cpu_has_vme 0
|
|
|
--#define cpu_has_de 1
|
|
|
--#define cpu_has_pse 1
|
|
|
--#define cpu_has_tsc 1
|
|
|
-+
|
|
|
-+#undef cpu_has_pae
|
|
|
- #define cpu_has_pae ___BUG___
|
|
|
--#define cpu_has_pge 1
|
|
|
--#define cpu_has_apic boot_cpu_has(X86_FEATURE_APIC)
|
|
|
--#define cpu_has_mtrr 1
|
|
|
--#define cpu_has_mmx 1
|
|
|
--#define cpu_has_fxsr 1
|
|
|
--#define cpu_has_xmm 1
|
|
|
--#define cpu_has_xmm2 1
|
|
|
--#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3)
|
|
|
--#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT)
|
|
|
-+
|
|
|
-+#undef cpu_has_mp
|
|
|
- #define cpu_has_mp 1 /* XXX */
|
|
|
-+
|
|
|
-+#undef cpu_has_k6_mtrr
|
|
|
- #define cpu_has_k6_mtrr 0
|
|
|
-+
|
|
|
-+#undef cpu_has_cyrix_arr
|
|
|
- #define cpu_has_cyrix_arr 0
|
|
|
-+
|
|
|
-+#undef cpu_has_centaur_mcr
|
|
|
- #define cpu_has_centaur_mcr 0
|
|
|
--#define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH)
|
|
|
--#define cpu_has_ds boot_cpu_has(X86_FEATURE_DS)
|
|
|
--#define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS)
|
|
|
--#define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS)
|
|
|
-
|
|
|
- #endif /* __ASM_X8664_CPUFEATURE_H */
|
|
|
-diff -puN include/asm-x86_64/e820.h~git-newsetup include/asm-x86_64/e820.h
|
|
|
---- a/include/asm-x86_64/e820.h~git-newsetup
|
|
|
-+++ a/include/asm-x86_64/e820.h
|
|
|
-@@ -11,7 +11,9 @@
|
|
|
- #ifndef __E820_HEADER
|
|
|
- #define __E820_HEADER
|
|
|
-
|
|
|
--#include <linux/mmzone.h>
|
|
|
-+#ifndef _SETUP
|
|
|
-+# include <linux/mmzone.h>
|
|
|
-+#endif
|
|
|
-
|
|
|
- #define E820MAP 0x2d0 /* our map */
|
|
|
- #define E820MAX 128 /* number of entries in E820MAP */
|
|
|
-@@ -30,7 +32,7 @@ struct e820entry {
|
|
|
- } __attribute__((packed));
|
|
|
-
|
|
|
- struct e820map {
|
|
|
-- int nr_map;
|
|
|
-+ u32 nr_map;
|
|
|
- struct e820entry map[E820MAX];
|
|
|
- };
|
|
|
-
|
|
|
-diff -puN include/asm-x86_64/processor.h~git-newsetup include/asm-x86_64/processor.h
|
|
|
---- a/include/asm-x86_64/processor.h~git-newsetup
|
|
|
-+++ a/include/asm-x86_64/processor.h
|
|
|
-@@ -99,6 +99,7 @@ extern char ignore_irq13;
|
|
|
-
|
|
|
- extern void identify_cpu(struct cpuinfo_x86 *);
|
|
|
- extern void print_cpu_info(struct cpuinfo_x86 *);
|
|
|
-+extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
|
|
|
- extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
|
|
|
- extern unsigned short num_cache_leaves;
|
|
|
-
|
|
|
-@@ -367,8 +368,6 @@ static inline void sync_core(void)
|
|
|
- asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
|
|
|
- }
|
|
|
-
|
|
|
--#define cpu_has_fpu 1
|
|
|
--
|
|
|
- #define ARCH_HAS_PREFETCH
|
|
|
- static inline void prefetch(void *x)
|
|
|
- {
|
|
|
-diff -puN /dev/null include/asm-x86_64/required-features.h
|
|
|
---- /dev/null
|
|
|
-+++ a/include/asm-x86_64/required-features.h
|
|
|
-@@ -0,0 +1,46 @@
|
|
|
-+#ifndef _ASM_REQUIRED_FEATURES_H
|
|
|
-+#define _ASM_REQUIRED_FEATURES_H 1
|
|
|
-+
|
|
|
-+/* Define minimum CPUID feature set for kernel These bits are checked
|
|
|
-+ really early to actually display a visible error message before the
|
|
|
-+ kernel dies. Make sure to assign features to the proper mask!
|
|
|
-+
|
|
|
-+ The real information is in arch/x86_64/Kconfig.cpu, this just converts
|
|
|
-+ the CONFIGs into a bitmask */
|
|
|
-+
|
|
|
-+/* x86-64 baseline features */
|
|
|
-+#define NEED_FPU (1<<(X86_FEATURE_FPU & 31))
|
|
|
-+#define NEED_PSE (1<<(X86_FEATURE_PSE & 31))
|
|
|
-+#define NEED_MSR (1<<(X86_FEATURE_MSR & 31))
|
|
|
-+#define NEED_PAE (1<<(X86_FEATURE_PAE & 31))
|
|
|
-+#define NEED_CX8 (1<<(X86_FEATURE_CX8 & 31))
|
|
|
-+#define NEED_PGE (1<<(X86_FEATURE_PGE & 31))
|
|
|
-+#define NEED_FXSR (1<<(X86_FEATURE_FXSR & 31))
|
|
|
-+#define NEED_CMOV (1<<(X86_FEATURE_CMOV & 31))
|
|
|
-+#define NEED_XMM (1<<(X86_FEATURE_XMM & 31))
|
|
|
-+#define NEED_XMM2 (1<<(X86_FEATURE_XMM2 & 31))
|
|
|
-+
|
|
|
-+#define REQUIRED_MASK0 (NEED_FPU|NEED_PSE|NEED_MSR|NEED_PAE|\
|
|
|
-+ NEED_CX8|NEED_PGE|NEED_FXSR|NEED_CMOV|\
|
|
|
-+ NEED_XMM|NEED_XMM2)
|
|
|
-+#define SSE_MASK (NEED_XMM|NEED_XMM2)
|
|
|
-+
|
|
|
-+/* x86-64 baseline features */
|
|
|
-+#define NEED_LM (1<<(X86_FEATURE_LM & 31))
|
|
|
-+
|
|
|
-+#ifdef CONFIG_X86_USE_3DNOW
|
|
|
-+# define NEED_3DNOW (1<<(X86_FEATURE_3DNOW & 31))
|
|
|
-+#else
|
|
|
-+# define NEED_3DNOW 0
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#define REQUIRED_MASK1 (NEED_LM|NEED_3DNOW)
|
|
|
-+
|
|
|
-+#define REQUIRED_MASK2 0
|
|
|
-+#define REQUIRED_MASK3 0
|
|
|
-+#define REQUIRED_MASK4 0
|
|
|
-+#define REQUIRED_MASK5 0
|
|
|
-+#define REQUIRED_MASK6 0
|
|
|
-+#define REQUIRED_MASK7 0
|
|
|
-+
|
|
|
-+#endif
|
|
|
-diff -puN include/asm-x86_64/segment.h~git-newsetup include/asm-x86_64/segment.h
|
|
|
---- a/include/asm-x86_64/segment.h~git-newsetup
|
|
|
-+++ a/include/asm-x86_64/segment.h
|
|
|
-@@ -3,6 +3,14 @@
|
|
|
-
|
|
|
- #include <asm/cache.h>
|
|
|
-
|
|
|
-+/* Simple and small GDT entries for booting only */
|
|
|
-+
|
|
|
-+#define GDT_ENTRY_BOOT_CS 2
|
|
|
-+#define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8)
|
|
|
-+
|
|
|
-+#define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1)
|
|
|
-+#define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8)
|
|
|
-+
|
|
|
- #define __KERNEL_CS 0x10
|
|
|
- #define __KERNEL_DS 0x18
|
|
|
-
|
|
|
-diff -puN include/linux/edd.h~git-newsetup include/linux/edd.h
|
|
|
---- a/include/linux/edd.h~git-newsetup
|
|
|
-+++ a/include/linux/edd.h
|
|
|
-@@ -49,10 +49,6 @@
|
|
|
- #define EDD_MBR_SIG_MAX 16 /* max number of signatures to store */
|
|
|
- #define EDD_MBR_SIG_NR_BUF 0x1ea /* addr of number of MBR signtaures at EDD_MBR_SIG_BUF
|
|
|
- in boot_params - treat this as 1 byte */
|
|
|
--#define EDD_CL_EQUALS 0x3d646465 /* "edd=" */
|
|
|
--#define EDD_CL_OFF 0x666f /* "of" for off */
|
|
|
--#define EDD_CL_SKIP 0x6b73 /* "sk" for skipmbr */
|
|
|
--#define EDD_CL_ON 0x6e6f /* "on" for on */
|
|
|
-
|
|
|
- #ifndef __ASSEMBLY__
|
|
|
-
|
|
|
-diff -puN include/linux/screen_info.h~git-newsetup include/linux/screen_info.h
|
|
|
---- a/include/linux/screen_info.h~git-newsetup
|
|
|
-+++ a/include/linux/screen_info.h
|
|
|
-@@ -10,7 +10,7 @@
|
|
|
- struct screen_info {
|
|
|
- u8 orig_x; /* 0x00 */
|
|
|
- u8 orig_y; /* 0x01 */
|
|
|
-- u16 dontuse1; /* 0x02 -- EXT_MEM_K sits here */
|
|
|
-+ u16 ext_mem_k; /* 0x02 */
|
|
|
- u16 orig_video_page; /* 0x04 */
|
|
|
- u8 orig_video_mode; /* 0x06 */
|
|
|
- u8 orig_video_cols; /* 0x07 */
|
|
|
-@@ -27,7 +27,7 @@ struct screen_info {
|
|
|
- u16 lfb_depth; /* 0x16 */
|
|
|
- u32 lfb_base; /* 0x18 */
|
|
|
- u32 lfb_size; /* 0x1c */
|
|
|
-- u16 dontuse2, dontuse3; /* 0x20 -- CL_MAGIC and CL_OFFSET here */
|
|
|
-+ u16 cl_magic, cl_offset; /* 0x20 */
|
|
|
- u16 lfb_linelength; /* 0x24 */
|
|
|
- u8 red_size; /* 0x26 */
|
|
|
- u8 red_pos; /* 0x27 */
|
|
|
-@@ -42,9 +42,8 @@ struct screen_info {
|
|
|
- u16 pages; /* 0x32 */
|
|
|
- u16 vesa_attributes; /* 0x34 */
|
|
|
- u32 capabilities; /* 0x36 */
|
|
|
-- /* 0x3a -- 0x3b reserved for future expansion */
|
|
|
-- /* 0x3c -- 0x3f micro stack for relocatable kernels */
|
|
|
--};
|
|
|
-+ u8 _reserved[6]; /* 0x3a */
|
|
|
-+} __attribute__((packed));
|
|
|
-
|
|
|
- extern struct screen_info screen_info;
|
|
|
-
|
|
|
-_
|