diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-05-07 02:55:41 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-05-07 02:55:41 +0000 |
commit | dcec8a13bf565e47942a1751a9cec21bec5648fe (patch) | |
tree | 548b69625b18cc2e88c3e68d0923be546c9ebb03 /arch/i386/mm | |
parent | 2e0f55e79c49509b7ff70ff1a10e1e9e90a3dfd4 (diff) |
o Merge with Linux 2.1.99.
o Fix ancient bug in the ELF loader making ldd crash.
o Fix ancient bug in the keyboard code for SGI, SNI and Jazz.
Diffstat (limited to 'arch/i386/mm')
-rw-r--r-- | arch/i386/mm/init.c | 86 |
1 files changed, 65 insertions, 21 deletions
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index ef3ac57f4..c33c53b9a 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -90,7 +90,6 @@ void show_mem(void) shared += atomic_read(&mem_map[i].count) - 1; } printk("%d pages of RAM\n",total); - printk("%d free pages\n",free); printk("%d reserved pages\n",reserved); printk("%d pages shared\n",shared); printk("%d pages swap cached\n",cached); @@ -174,29 +173,29 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_ * It may also hold the MP configuration table when we are booting SMP. */ #ifdef __SMP__ - if (!smp_scan_config(0x0,0x400)) /* Scan the bottom 1K for a signature */ - { + /* + * FIXME: Linux assumes you have 640K of base ram.. + * this continues the error... + * + * 1) Scan the bottom 1K for a signature + * 2) Scan the top 1K of base RAM + * 3) Scan the 64K of bios + */ + if (!smp_scan_config(0x0,0x400) && + !smp_scan_config(639*0x400,0x400) && + !smp_scan_config(0xF0000,0x10000)) { /* - * FIXME: Linux assumes you have 640K of base ram.. this continues - * the error... + * If it is an SMP machine we should know now, unless the + * configuration is in an EISA/MCA bus machine with an + * extended bios data area. + * + * there is a real-mode segmented pointer pointing to the + * 4K EBDA area at 0x40E, calculate and scan it here: */ - if (!smp_scan_config(639*0x400,0x400)) /* Scan the top 1K of base RAM */ - { - if(!smp_scan_config(0xF0000,0x10000)) /* Scan the 64K of bios */ - { - /* - * If it is an SMP machine we should know now, unless the configuration - * is in an EISA/MCA bus machine with an extended bios data area. - */ - - address = *(unsigned short *)phys_to_virt(0x40E); /* EBDA */ - address<<=4; /* Real mode segments to physical */ - smp_scan_config(address, 0x1000); /* Scan the EBDA */ - } - } + address = *(unsigned short *)phys_to_virt(0x40E); + address<<=4; + smp_scan_config(address, 0x1000); } - -/* smp_alloc_memory(8192); */ #endif start_mem = PAGE_ALIGN(start_mem); address = PAGE_OFFSET; @@ -255,7 +254,52 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_ address += PAGE_SIZE; } } +#ifdef __SMP__ +{ + extern unsigned long mp_lapic_addr; + pte_t pte; + unsigned long apic_area = (unsigned long)APIC_BASE; + + pg_dir = swapper_pg_dir + ((apic_area) >> PGDIR_SHIFT); + memset((void *)start_mem, 0, PAGE_SIZE); + pgd_val(*pg_dir) = _PAGE_TABLE | __pa(start_mem); + start_mem += PAGE_SIZE; + + if (smp_found_config) { + /* + * Map the local APIC to FEE00000. (it's only the default + * value, thanks to Steve Hsieh for finding this out. We + * now save the real local-APIC physical address in smp_scan(), + * and use it here) + */ + pg_table = pte_offset((pmd_t *)pg_dir, apic_area); + pte = mk_pte(__va(mp_lapic_addr), PAGE_KERNEL); + set_pte(pg_table, pte); + + /* + * Map the IO-APIC to FEC00000. + */ + apic_area = 0xFEC00000; /*(unsigned long)IO_APIC_BASE;*/ + pg_table = pte_offset((pmd_t *)pg_dir, apic_area); + pte = mk_pte(__va(apic_area), PAGE_KERNEL); + set_pte(pg_table, pte); + } else { + /* + * No local APIC but we are compiled SMP ... set up a + * fake all zeroes page to simulate the local APIC. + */ + pg_table = pte_offset((pmd_t *)pg_dir, apic_area); + pte = mk_pte(start_mem, PAGE_KERNEL); + memset((void *)start_mem, 0, PAGE_SIZE); + start_mem += PAGE_SIZE; + set_pte(pg_table, pte); + } + + local_flush_tlb(); +} +#endif local_flush_tlb(); + return free_area_init(start_mem, end_mem); } |