-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[PATCH] i386: i386 create e820.c to handle standard io/mem resources
This patch creates new file named e820.c to hanle standard io/mem resources, moving request_standard_resources function from setup.c to e820.c. Also this patch modifies Makfile to compile file e820.c. Signed-off-by: bibo,mao <bibo.mao@intel.com> Signed-off-by: Andi Kleen <ak@suse.de> Makefile | 2 arch/i386/kernel/Makefile | 2 arch/i386/kernel/e820.c | 289 ++++++++++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 276 ------------------------------------------- 3 files changed, 293 insertions(+), 274 deletions(-)
- Loading branch information
bibo,mao
authored and
Andi Kleen
committed
Dec 7, 2006
1 parent
8e3de53
commit 269c2d8
Showing
3 changed files
with
293 additions
and
274 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,289 @@ | ||
#include <linux/kernel.h> | ||
#include <linux/types.h> | ||
#include <linux/init.h> | ||
#include <linux/bootmem.h> | ||
#include <linux/ioport.h> | ||
#include <linux/string.h> | ||
#include <linux/kexec.h> | ||
#include <linux/module.h> | ||
#include <linux/mm.h> | ||
#include <linux/efi.h> | ||
|
||
#include <asm/pgtable.h> | ||
#include <asm/page.h> | ||
#include <asm/e820.h> | ||
|
||
#ifdef CONFIG_EFI | ||
int efi_enabled = 0; | ||
EXPORT_SYMBOL(efi_enabled); | ||
#endif | ||
|
||
struct e820map e820; | ||
struct resource data_resource = { | ||
.name = "Kernel data", | ||
.start = 0, | ||
.end = 0, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_MEM | ||
}; | ||
|
||
struct resource code_resource = { | ||
.name = "Kernel code", | ||
.start = 0, | ||
.end = 0, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_MEM | ||
}; | ||
|
||
static struct resource system_rom_resource = { | ||
.name = "System ROM", | ||
.start = 0xf0000, | ||
.end = 0xfffff, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
}; | ||
|
||
static struct resource extension_rom_resource = { | ||
.name = "Extension ROM", | ||
.start = 0xe0000, | ||
.end = 0xeffff, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
}; | ||
|
||
static struct resource adapter_rom_resources[] = { { | ||
.name = "Adapter ROM", | ||
.start = 0xc8000, | ||
.end = 0, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
}, { | ||
.name = "Adapter ROM", | ||
.start = 0, | ||
.end = 0, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
}, { | ||
.name = "Adapter ROM", | ||
.start = 0, | ||
.end = 0, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
}, { | ||
.name = "Adapter ROM", | ||
.start = 0, | ||
.end = 0, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
}, { | ||
.name = "Adapter ROM", | ||
.start = 0, | ||
.end = 0, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
}, { | ||
.name = "Adapter ROM", | ||
.start = 0, | ||
.end = 0, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
} }; | ||
|
||
static struct resource video_rom_resource = { | ||
.name = "Video ROM", | ||
.start = 0xc0000, | ||
.end = 0xc7fff, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
}; | ||
|
||
static struct resource video_ram_resource = { | ||
.name = "Video RAM area", | ||
.start = 0xa0000, | ||
.end = 0xbffff, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_MEM | ||
}; | ||
|
||
static struct resource standard_io_resources[] = { { | ||
.name = "dma1", | ||
.start = 0x0000, | ||
.end = 0x001f, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
}, { | ||
.name = "pic1", | ||
.start = 0x0020, | ||
.end = 0x0021, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
}, { | ||
.name = "timer0", | ||
.start = 0x0040, | ||
.end = 0x0043, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
}, { | ||
.name = "timer1", | ||
.start = 0x0050, | ||
.end = 0x0053, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
}, { | ||
.name = "keyboard", | ||
.start = 0x0060, | ||
.end = 0x006f, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
}, { | ||
.name = "dma page reg", | ||
.start = 0x0080, | ||
.end = 0x008f, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
}, { | ||
.name = "pic2", | ||
.start = 0x00a0, | ||
.end = 0x00a1, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
}, { | ||
.name = "dma2", | ||
.start = 0x00c0, | ||
.end = 0x00df, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
}, { | ||
.name = "fpu", | ||
.start = 0x00f0, | ||
.end = 0x00ff, | ||
.flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
} }; | ||
|
||
#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) | ||
|
||
static int __init romchecksum(unsigned char *rom, unsigned long length) | ||
{ | ||
unsigned char *p, sum = 0; | ||
|
||
for (p = rom; p < rom + length; p++) | ||
sum += *p; | ||
return sum == 0; | ||
} | ||
|
||
static void __init probe_roms(void) | ||
{ | ||
unsigned long start, length, upper; | ||
unsigned char *rom; | ||
int i; | ||
|
||
/* video rom */ | ||
upper = adapter_rom_resources[0].start; | ||
for (start = video_rom_resource.start; start < upper; start += 2048) { | ||
rom = isa_bus_to_virt(start); | ||
if (!romsignature(rom)) | ||
continue; | ||
|
||
video_rom_resource.start = start; | ||
|
||
/* 0 < length <= 0x7f * 512, historically */ | ||
length = rom[2] * 512; | ||
|
||
/* if checksum okay, trust length byte */ | ||
if (length && romchecksum(rom, length)) | ||
video_rom_resource.end = start + length - 1; | ||
|
||
request_resource(&iomem_resource, &video_rom_resource); | ||
break; | ||
} | ||
|
||
start = (video_rom_resource.end + 1 + 2047) & ~2047UL; | ||
if (start < upper) | ||
start = upper; | ||
|
||
/* system rom */ | ||
request_resource(&iomem_resource, &system_rom_resource); | ||
upper = system_rom_resource.start; | ||
|
||
/* check for extension rom (ignore length byte!) */ | ||
rom = isa_bus_to_virt(extension_rom_resource.start); | ||
if (romsignature(rom)) { | ||
length = extension_rom_resource.end - extension_rom_resource.start + 1; | ||
if (romchecksum(rom, length)) { | ||
request_resource(&iomem_resource, &extension_rom_resource); | ||
upper = extension_rom_resource.start; | ||
} | ||
} | ||
|
||
/* check for adapter roms on 2k boundaries */ | ||
for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { | ||
rom = isa_bus_to_virt(start); | ||
if (!romsignature(rom)) | ||
continue; | ||
|
||
/* 0 < length <= 0x7f * 512, historically */ | ||
length = rom[2] * 512; | ||
|
||
/* but accept any length that fits if checksum okay */ | ||
if (!length || start + length > upper || !romchecksum(rom, length)) | ||
continue; | ||
|
||
adapter_rom_resources[i].start = start; | ||
adapter_rom_resources[i].end = start + length - 1; | ||
request_resource(&iomem_resource, &adapter_rom_resources[i]); | ||
|
||
start = adapter_rom_resources[i++].end & ~2047UL; | ||
} | ||
} | ||
|
||
/* | ||
* Request address space for all standard RAM and ROM resources | ||
* and also for regions reported as reserved by the e820. | ||
*/ | ||
static void __init | ||
legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource) | ||
{ | ||
int i; | ||
|
||
probe_roms(); | ||
for (i = 0; i < e820.nr_map; i++) { | ||
struct resource *res; | ||
#ifndef CONFIG_RESOURCES_64BIT | ||
if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) | ||
continue; | ||
#endif | ||
res = kzalloc(sizeof(struct resource), GFP_ATOMIC); | ||
switch (e820.map[i].type) { | ||
case E820_RAM: res->name = "System RAM"; break; | ||
case E820_ACPI: res->name = "ACPI Tables"; break; | ||
case E820_NVS: res->name = "ACPI Non-volatile Storage"; break; | ||
default: res->name = "reserved"; | ||
} | ||
res->start = e820.map[i].addr; | ||
res->end = res->start + e820.map[i].size - 1; | ||
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
if (request_resource(&iomem_resource, res)) { | ||
kfree(res); | ||
continue; | ||
} | ||
if (e820.map[i].type == E820_RAM) { | ||
/* | ||
* We don't know which RAM region contains kernel data, | ||
* so we try it repeatedly and let the resource manager | ||
* test it. | ||
*/ | ||
request_resource(res, code_resource); | ||
request_resource(res, data_resource); | ||
#ifdef CONFIG_KEXEC | ||
request_resource(res, &crashk_res); | ||
#endif | ||
} | ||
} | ||
} | ||
|
||
/* | ||
* Request address space for all standard resources | ||
* | ||
* This is called just before pcibios_init(), which is also a | ||
* subsys_initcall, but is linked in later (in arch/i386/pci/common.c). | ||
*/ | ||
static int __init request_standard_resources(void) | ||
{ | ||
int i; | ||
|
||
printk("Setting up standard PCI resources\n"); | ||
if (efi_enabled) | ||
efi_initialize_iomem_resources(&code_resource, &data_resource); | ||
else | ||
legacy_init_iomem_resources(&code_resource, &data_resource); | ||
|
||
/* EFI systems may still have VGA */ | ||
request_resource(&iomem_resource, &video_ram_resource); | ||
|
||
/* request I/O space for devices used on all i[345]86 PCs */ | ||
for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) | ||
request_resource(&ioport_resource, &standard_io_resources[i]); | ||
return 0; | ||
} | ||
|
||
subsys_initcall(request_standard_resources); |
Oops, something went wrong.