lkml.org 
[lkml]   [1999]   [Aug]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
SubjectA bios patch
Date
Hi, Alan,

This patch from David Parsons for 2.2.11 is needed for some Intel
440ZX MBs.

Thanks.


--
H.J. Lu (hjl@gnu.org)
-----
diff -Naur linux-2.2.10-orig/arch/i386/boot/setup.S linux-2.2.10/arch/i386/boot/setup.S
--- linux-2.2.10-orig/arch/i386/boot/setup.S Mon Jun 7 16:13:07 1999
+++ linux-2.2.10/arch/i386/boot/setup.S Fri Jun 18 02:14:22 1999
@@ -37,6 +37,7 @@
#include <linux/version.h>
#include <linux/compile.h>
#include <asm/boot.h>
+#include <asm/e820.h>

! Signature words to ensure LILO loaded us right
#define SIG1 0xAA55
@@ -59,7 +60,7 @@

entry start
start:
- jmp start_of_setup
+ jmp trampoline
! ------------------------ start of header --------------------------------
!
! SETUP-header, must start at CS:2 (old 0x9020:2)
@@ -119,6 +120,8 @@
heap_end_ptr: .word modelist+1024 ! space from here (exclusive) down to
! end of setup code can be used by setup
! for local heap purposes.
+trampoline: call start_of_setup
+ .space 1024
! ------------------------ end of header ----------------------------------

start_of_setup:
@@ -245,37 +248,100 @@
loader_ok:
! Get memory size (extended mem, kB)

+ xor eax, eax
+ mov dword ptr [0x1e0], eax
#ifndef STANDARD_MEMORY_BIOS_CALL
- push ebx

- xor ebx,ebx ! preload new memory slot with 0k
- mov [0x1e0], ebx
+ mov dword ptr [E820MEM], eax
+ mov dword ptr [E820NR], eax
+
+! 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 available memory areas, which we return at [0xC20].
+! We also make a stab at the memory size by the somewhat gross approach
+! of setting memsize to the address+size of the LAST available memory
+! we picked up. This assumes that e820 returns memory regions in strictly
+! increasing order; if a bios returns those memory regions in any other
+! order, we will be in for a world of pain.
+!
+
+meme820:
+ mov edx, #0x534d4150 ! ascii `SMAP'
+ xor ebx, ebx ! continuation counter
+
+jmpe820:
+ mov eax, #0x0000e820 ! e820, upper word zeroed
+ mov ecx, #20 ! size of the e820rec
+
+ mov dword ptr [E820+16], #42
+ mov di, #E820 ! es:di points at the
+ push ds ! data record.
+ pop es
+ int 0x15 ! make the call
+ jc meme801 ! fall to e801 if it fails
+
+ cmp eax, #0x534d4150 ! check the return is `SMAP'
+ jne meme801 ! fall to e801 if it fails
+
+ cmp dword ptr [E820+16], #1 ! is this usable memory?
+ jne again820
+
+ ! usable memory: add it to the whitelist
+ !
+good820:
+ mov al, byte ptr [E820NR]
+ cmp al, #E820MAX
+ jnl again820
+ inc byte ptr [E820NR]
+ and ax, #0xff ! clear sign extend
+ shl ax, 3 ! double dword alignment
+ mov si, ax
+ mov ecx, dword ptr [E820+8] ! pick up low dword of memsize
+ mov eax, dword ptr [E820+0] ! pick up low dword of address
+ mov E820MAP(si), eax ! store address in whitelist
+ mov E820MAP+4(si), ecx ! store size in whitelist
+
+ add eax, ecx ! set end_mem to address + memsize
+ mov [E820MEM], eax
+
+again820:
+ cmp ebx, #0 ! check to see if ebx is
+ jne jmpe820 ! set to EOF

- mov ax,#0xe801
- int 0x15
- jc oldstylemem

-! Memory size is in 1 k chunksizes, to avoid confusing loadlin.
-! We store the 0xe801 memory size in a completely different place,
+
+! 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.)

- and ebx, #0xffff ! clear sign extend
- shl ebx, 6 ! and go from 64k to 1k chunks
- mov [0x1e0],ebx ! store extended memory size
-
- and eax, #0xffff ! clear sign extend
- add [0x1e0],eax ! and add lower memory into total size.
-
- ! and fall into the old memory detection code to populate the
- ! compatibility slot.
+meme801:
+
+ mov ax,#0xe801
+ int 0x15
+ jc mem88
+
+ and edx, #0xffff ! clear sign extend
+ shl edx, 6 ! and go from 64k to 1k chunks
+ mov [0x1e0],edx ! store extended memory size
+
+ and ecx, #0xffff ! clear sign extend
+ add [0x1e0],ecx ! 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:

-oldstylemem:
- pop ebx
-#else
- mov dword ptr [0x1e0], #0
#endif
mov ah,#0x88
int 0x15
diff -Naur linux-2.2.10-orig/arch/i386/kernel/setup.c linux-2.2.10/arch/i386/kernel/setup.c
--- linux-2.2.10-orig/arch/i386/kernel/setup.c Tue Jun 8 10:43:21 1999
+++ linux-2.2.10/arch/i386/kernel/setup.c Fri Jun 18 02:53:05 1999
@@ -49,6 +49,7 @@
#include <asm/smp.h>
#include <asm/cobalt.h>
#include <asm/msr.h>
+#include <asm/e820.h>

/*
* Machine setup..
@@ -82,6 +83,8 @@
unsigned char table[0];
};

+struct e820map e820 = { 0 };
+
unsigned char aux_device_present;

#ifdef CONFIG_BLK_DEV_RAM
@@ -101,6 +104,9 @@
#define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
#define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
+#define E820_MEM (*(unsigned long *) (PARAM+E820MEM))
+#define E820_MAP_NR (*(char*) (PARAM+E820NR))
+#define E820_MAP ((unsigned long *) (PARAM+E820MAP))
#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
@@ -277,9 +283,27 @@
#ifndef STANDARD_MEMORY_BIOS_CALL
{
unsigned long memory_alt_end = (1<<20) + (ALT_MEM_K<<10);
- /* printk(KERN_DEBUG "Memory sizing: %08x %08x\n", memory_end, memory_alt_end); */
+ unsigned long *mem = E820_MAP;
+
if (memory_alt_end > memory_end)
memory_end = memory_alt_end;
+
+ if (E820_MEM > memory_end)
+ memory_end = E820_MEM;
+
+ if ((e820.nr_map = E820_MAP_NR) > 0) {
+ int x;
+
+ if (e820.nr_map > E820MAX)
+ e820.nr_map = 0;
+ else for (x = 0; x < e820.nr_map; x++) {
+ e820.map[x].addr = *(mem++);
+ e820.map[x].size = *(mem++);
+ /*printk("E820: region %d, %lu bytes @ %08lx\n",
+ x, e820.map[x].size, e820.map[x].addr);*/
+ }
+ }
+
}
#endif

diff -Naur linux-2.2.10-orig/arch/i386/mm/init.c linux-2.2.10/arch/i386/mm/init.c
--- linux-2.2.10-orig/arch/i386/mm/init.c Thu Jan 21 11:28:40 1999
+++ linux-2.2.10/arch/i386/mm/init.c Fri Jun 18 02:55:43 1999
@@ -27,6 +27,7 @@
#include <asm/pgtable.h>
#include <asm/dma.h>
#include <asm/fixmap.h>
+#include <asm/e820.h>

extern void show_net_buffers(void);
extern unsigned long init_smp_mappings(unsigned long);
@@ -390,6 +391,18 @@
int datapages = 0;
int initpages = 0;
unsigned long tmp;
+ unsigned long start_seg = 0;
+ unsigned long size_seg = ~0;
+ int nr_map = 0;
+
+ if (nr_map < e820.nr_map) {
+ start_seg = e820.map[nr_map].addr + PAGE_OFFSET;
+ size_seg = e820.map[nr_map].size;
+ printk("region %d: %lu bytes @ %08lx\n",
+ nr_map, size_seg, start_seg - PAGE_OFFSET);
+ nr_map++;
+ }
+

end_mem &= PAGE_MASK;
high_memory = (void *) end_mem;
@@ -424,7 +437,23 @@
}

while (start_mem < end_mem) {
- clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
+ if (start_mem > start_seg) {
+ if (start_mem < start_seg + size_seg)
+ clear_bit(PG_reserved,
+ &mem_map[MAP_NR(start_mem)].flags);
+ else if (nr_map < e820.nr_map) {
+ start_seg = e820.map[nr_map].addr + PAGE_OFFSET;
+ size_seg = e820.map[nr_map].size;
+ printk("region %d: %lu bytes @ %08lx\n",
+ nr_map, size_seg, start_seg - PAGE_OFFSET);
+ nr_map++;
+ continue; /* be paranoid in case the */
+ /* e820 code hasn't collapsed */
+ /* adjacent usable memory */
+ }
+ else
+ break; /* no more valid memory */
+ }
start_mem += PAGE_SIZE;
}
for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
diff -Naur linux-2.2.10-orig/include/asm-i386/e820.h linux-2.2.10/include/asm-i386/e820.h
--- linux-2.2.10-orig/include/asm-i386/e820.h Wed Dec 31 16:00:00 1969
+++ linux-2.2.10/include/asm-i386/e820.h Fri Jun 18 02:12:12 1999
@@ -0,0 +1,34 @@
+/*
+ * structures and definitions for the int 15, ax=e820 memory map
+ * scheme.
+ *
+ * In a nutshell, arch/i386/boot/setup.S populates a scratch table
+ * in the empty_zero_block that contains a list of usable address/size
+ * duples. In arch/i386/kernel/setup.c, this information is
+ * transferred into the e820map, and in arch/i386/mm/init.c, that
+ * new information is used to mark pages reserved or not.
+ *
+ */
+#ifndef __E820_HEADER
+#define __E820_HEADER
+
+#define E820 0x2d0 /* scratch area */
+#define E820MAP 0x300 /* our map */
+#define E820MAX 32 /* number of entries in E820MAP */
+#define E820MEM 0x1e4 /* memtop from e820 calls */
+#define E820NR 0x1e8 /* # entries in E820MAP */
+
+#ifndef __ASSEMBLY__
+
+struct e820map {
+ int nr_map;
+ struct {
+ unsigned long addr;
+ unsigned long size;
+ } map[E820MAX];
+};
+
+extern struct e820map e820;
+#endif/*!__ASSEMBLY__*/
+
+#endif/*__E820_HEADER*/


--
H.J. Lu (hjl@gnu.org)

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:53    [W:0.108 / U:0.032 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site