Commit 31a359d2 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] i386 probe_roms(): fixes

From: Rene Herman <rene.herman@keyaccess.nl>

This patch tries to improve the i386/mach-default probe_roms().  This also
c99ifies the data, adds an IORESOURCE_IO flag for the I/O port resources,
an IORESOURCE_MEM flag for the VRAM resource, IORESOURCE_READONLY |
IORESOURCE_MEM for the ROM resources and adds two additional "adapter ROM
slots" (for a total of 6) since it now also scans the 0xe0000 segment.
parent 816d6073
/* /*
* Machine specific resource allocation for generic. * Machine specific resource allocation for generic.
* Split out from setup.c by Osamu Tomita <tomita@cinet.co.jp>
*/ */
#include <linux/ioport.h> #include <linux/ioport.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/std_resources.h> #include <asm/std_resources.h>
static struct resource standard_io_resources[] = { #define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
{ "pic1", 0x20, 0x21, IORESOURCE_BUSY }, static struct resource system_rom_resource = {
{ "timer", 0x40, 0x5f, IORESOURCE_BUSY }, .name = "System ROM",
{ "keyboard", 0x60, 0x6f, IORESOURCE_BUSY }, .start = 0xf0000,
{ "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY }, .end = 0xfffff,
{ "pic2", 0xa0, 0xa1, IORESOURCE_BUSY }, .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
{ "fpu", 0xf0, 0xff, IORESOURCE_BUSY }
}; };
#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource)) static struct resource extension_rom_resource = {
.name = "Extension ROM",
.start = 0xe0000,
.end = 0xeffff,
.flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
};
static struct resource vram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_BUSY }; 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
} };
#define ADAPTER_ROM_RESOURCES \
(sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
static struct resource video_rom_resource = {
.name = "Video ROM",
.start = 0xc0000,
.end = 0xc7fff,
.flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
};
/* System ROM resources */ static struct resource vram_resource = {
#define MAXROMS 6 .name = "Video RAM area",
static struct resource rom_resources[MAXROMS] = { .start = 0xa0000,
{ "System ROM", 0xF0000, 0xFFFFF, IORESOURCE_BUSY }, .end = 0xbffff,
{ "Video ROM", 0xc0000, 0xc7fff, IORESOURCE_BUSY } .flags = IORESOURCE_BUSY | IORESOURCE_MEM
}; };
#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) 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 = "timer",
.start = 0x0040,
.end = 0x005f,
.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 STANDARD_IO_RESOURCES \
(sizeof standard_io_resources / sizeof standard_io_resources[0])
static int __init checksum(unsigned char *rom, unsigned long length)
{
unsigned char *p, sum = 0;
for (p = rom; p < rom + length; p++)
sum += *p;
return sum == 0;
}
void __init probe_roms(void) void __init probe_roms(void)
{ {
unsigned long base; unsigned long start, length, upper;
unsigned char *romstart; unsigned char *rom;
int roms = 1; int i;
request_resource(&iomem_resource, rom_resources+0);
/* Video ROM is standard at C000:0000 - C7FF:0000, check signature */ /* video rom */
for (base = 0xC0000; base < 0xE0000; base += 2048) { upper = adapter_rom_resources[0].start;
romstart = isa_bus_to_virt(base); for (start = video_rom_resource.start; start < upper; start += 2048) {
if (!romsignature(romstart)) rom = isa_bus_to_virt(start);
if (!romsignature(rom))
continue; continue;
request_resource(&iomem_resource, rom_resources + roms);
roms++;
break;
}
/* Extension roms at C800:0000 - DFFF:0000 */ video_rom_resource.start = start;
for (base = 0xC8000; base < 0xE0000; base += 2048) {
unsigned long length;
romstart = isa_bus_to_virt(base); /* 0 < length <= 0x7f * 512, historically */
if (!romsignature(romstart)) length = rom[2] * 512;
continue;
length = romstart[2] * 512; /* if checksum okay, trust length byte */
if (length) { if (length && checksum(rom, length))
unsigned int i; video_rom_resource.end = start + length - 1;
unsigned char chksum;
request_resource(&iomem_resource, &video_rom_resource);
chksum = 0; break;
for (i = 0; i < length; i++)
chksum += romstart[i];
/* Good checksum? */
if (!chksum) {
rom_resources[roms].start = base;
rom_resources[roms].end = base + length - 1;
rom_resources[roms].name = "Extension ROM";
rom_resources[roms].flags = IORESOURCE_BUSY;
request_resource(&iomem_resource, rom_resources + roms);
roms++;
if (roms >= MAXROMS)
return;
} }
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 (checksum(rom, length)) {
request_resource(&iomem_resource, &extension_rom_resource);
upper = extension_rom_resource.start;
} }
} }
/* Final check for motherboard extension rom at E000:0000 */ /* check for adapter roms on 2k boundaries */
base = 0xE0000; for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) {
romstart = isa_bus_to_virt(base); 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 || !checksum(rom, length))
continue;
if (romsignature(romstart)) { adapter_rom_resources[i].start = start;
rom_resources[roms].start = base; adapter_rom_resources[i].end = start + length - 1;
rom_resources[roms].end = base + 65535; request_resource(&iomem_resource, &adapter_rom_resources[i]);
rom_resources[roms].name = "Extension ROM";
rom_resources[roms].flags = IORESOURCE_BUSY;
request_resource(&iomem_resource, rom_resources + roms); start = adapter_rom_resources[i++].end & ~2047UL;
} }
} }
...@@ -104,5 +200,5 @@ void __init request_standard_io_resources(void) ...@@ -104,5 +200,5 @@ void __init request_standard_io_resources(void)
int i; int i;
for (i = 0; i < STANDARD_IO_RESOURCES; i++) for (i = 0; i < STANDARD_IO_RESOURCES; i++)
request_resource(&ioport_resource, standard_io_resources+i); request_resource(&ioport_resource, &standard_io_resources[i]);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment