Commit 816d6073 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] i386 probe_roms(): preparation

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

The i386 probe_roms() function has a fair number of problems currently:

- When you actually have an adapter ROM in the machine, your video ROM
  disappears.  This is due to the pc9800 subarch merge that split it up in
  probe_video_rom(int roms) and probe_extension_roms(int roms), but expects a
  "roms++" in probe_video_roms() to have an effect outside of that function.

- The majority of VGA adapters these days host a ROM larger then 32K, yet
  the current code hardcodes a 32K ROM.  The VGA BIOS "length" byte is
  normally valid (it in fact needs to be for a regular mainboard BIOS to
  accept it) and I've verified on a few dozen very new to very old VGAs that
  it is.  However, assuming someone actually did not check for the length and
  checksum there for a reason, the safe thing to do here is accept the length
  byte when we also get a valid checksum.

- The current code scans 0xc0000 to 0xdffff for a video ROM while the
  standard PC thing to do (that which the BIOS does) is only scan for a video
  ROM starting between 0xc0000 and 0xc7fff.  This means that on a headless-
  (or BIOS-less monochrome adapter-) box, the first adapter ROM found
  triggers the registration of a 32K "Video ROM" at hardcoded address
  0xc0000, even when _nothing_ is present between 0xc0000 and 0xc7fff.

- The current adapter ROM scan stops at 0xdffff, whether or not an
  extension ROM is present at 0xe0000.  The PC thing to do is scan 0xc8000
  upto 0xdffff if an extension ROM is present, and upto 0xeffff when it's not
  (it's not/hardly ever).

- Adapter ROMs are called "Extension ROM", but the latter term is really
  better reserved for a motherboard extension ROM.

- Currently, the code happily starts scanning through a ROM it just
  registered looking for the next one (just does += 2048, even when that's
  inside the previous ROM) which is at least silly.

Unfortunately, this code is "subarched" between mach-default and
mach-pc9800, meaning the patch got a bit involved. Currently all this
code, and gobs of data, is defined (not just declared) in the header:

   include/asm-i386/mach-{default,pc9800}/mach_resources.h

which isn't nice. That .h really wants to be a .c. The first patch, in
the next message, does not change any code but only undoes the
probe_video_rom / probe_extension_roms split and moves the code to a new
file

   arch/i386/mach-{default,pc9800}/std_resources.c

with a header

   include/asm-i386/std_resources.h

for the prototypes only. The second patch overhauls the code itself for
mach-default. Please see comments on top of that patch for (yet more)
comments. It's tested on various machines, with and without adapter ROMs.

I haven't touched pc9800. Nothing should have changed though. The pc9800
author, as given in the code, is CCed.

Also, x86-64 inherits the probe_roms() code from 2.4, and while it
doesn't have the subarch specific problems, it has all others. I'll
convert it to if this i386 version is deemed desirable.



This patch doesn't change any code, just moves stuff from the
"mach_resources.h" header to a "std_resources.c" subarch specific file, and
introduces a "std_resources.h" header for the prototypes.
parent a1fa32d7
...@@ -47,8 +47,8 @@ ...@@ -47,8 +47,8 @@
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/io_apic.h> #include <asm/io_apic.h>
#include <asm/ist.h> #include <asm/ist.h>
#include <asm/std_resources.h>
#include "setup_arch_pre.h" #include "setup_arch_pre.h"
#include "mach_resources.h"
/* This value is set up by the early boot code to point to the value /* This value is set up by the early boot code to point to the value
immediately after the boot time page tables. It contains a *physical* immediately after the boot time page tables. It contains a *physical*
...@@ -135,19 +135,6 @@ unsigned char __initdata boot_params[PARAM_SIZE]; ...@@ -135,19 +135,6 @@ unsigned char __initdata boot_params[PARAM_SIZE];
static struct resource code_resource = { "Kernel code", 0x100000, 0 }; static struct resource code_resource = { "Kernel code", 0x100000, 0 };
static struct resource data_resource = { "Kernel data", 0, 0 }; static struct resource data_resource = { "Kernel data", 0, 0 };
static void __init probe_roms(void)
{
int roms = 1;
request_resource(&iomem_resource, rom_resources+0);
/* Video ROM is standard at C000:0000 - C7FF:0000, check signature */
probe_video_rom(roms);
/* Extension roms */
probe_extension_roms(roms);
}
static void __init limit_regions(unsigned long long size) static void __init limit_regions(unsigned long long size)
{ {
unsigned long long current_addr = 0; unsigned long long current_addr = 0;
...@@ -951,19 +938,17 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat ...@@ -951,19 +938,17 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
static void __init register_memory(unsigned long max_low_pfn) static void __init register_memory(unsigned long max_low_pfn)
{ {
unsigned long low_mem_size; unsigned long low_mem_size;
int i;
if (efi_enabled) if (efi_enabled)
efi_initialize_iomem_resources(&code_resource, &data_resource); efi_initialize_iomem_resources(&code_resource, &data_resource);
else else
legacy_init_iomem_resources(&code_resource, &data_resource); legacy_init_iomem_resources(&code_resource, &data_resource);
/* EFI systems may still have VGA */ /* EFI systems may still have VGA */
request_graphics_resource(); request_graphics_resource();
/* request I/O space for devices used on all i[345]86 PCs */ /* request I/O space for devices used on all i[345]86 PCs */
for (i = 0; i < STANDARD_IO_RESOURCES; i++) request_standard_io_resources();
request_resource(&ioport_resource, standard_io_resources+i);
/* Tell the PCI layer not to allocate too close to the RAM area.. */ /* Tell the PCI layer not to allocate too close to the RAM area.. */
low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff; low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
......
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
# Makefile for the linux kernel. # Makefile for the linux kernel.
# #
obj-y := setup.o topology.o obj-y := setup.o topology.o std_resources.o
/* /*
* include/asm-i386/mach-default/mach_resources.h
*
* Machine specific resource allocation for generic. * Machine specific resource allocation for generic.
* Split out from setup.c by Osamu Tomita <tomita@cinet.co.jp> * Split out from setup.c by Osamu Tomita <tomita@cinet.co.jp>
*/ */
#ifndef _MACH_RESOURCES_H
#define _MACH_RESOURCES_H
struct resource standard_io_resources[] = { #include <linux/ioport.h>
#include <asm/io.h>
#include <asm/std_resources.h>
static struct resource standard_io_resources[] = {
{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY }, { "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
{ "pic1", 0x20, 0x21, IORESOURCE_BUSY }, { "pic1", 0x20, 0x21, IORESOURCE_BUSY },
{ "timer", 0x40, 0x5f, IORESOURCE_BUSY }, { "timer", 0x40, 0x5f, IORESOURCE_BUSY },
...@@ -31,11 +31,13 @@ static struct resource rom_resources[MAXROMS] = { ...@@ -31,11 +31,13 @@ static struct resource rom_resources[MAXROMS] = {
#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) #define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
static inline void probe_video_rom(int roms) void __init probe_roms(void)
{ {
unsigned long base; unsigned long base;
unsigned char *romstart; unsigned char *romstart;
int roms = 1;
request_resource(&iomem_resource, rom_resources+0);
/* Video ROM is standard at C000:0000 - C7FF:0000, check signature */ /* Video ROM is standard at C000:0000 - C7FF:0000, check signature */
for (base = 0xC0000; base < 0xE0000; base += 2048) { for (base = 0xC0000; base < 0xE0000; base += 2048) {
...@@ -46,12 +48,6 @@ static inline void probe_video_rom(int roms) ...@@ -46,12 +48,6 @@ static inline void probe_video_rom(int roms)
roms++; roms++;
break; break;
} }
}
static inline void probe_extension_roms(int roms)
{
unsigned long base;
unsigned char *romstart;
/* Extension roms at C800:0000 - DFFF:0000 */ /* Extension roms at C800:0000 - DFFF:0000 */
for (base = 0xC8000; base < 0xE0000; base += 2048) { for (base = 0xC8000; base < 0xE0000; base += 2048) {
...@@ -98,9 +94,15 @@ static inline void probe_extension_roms(int roms) ...@@ -98,9 +94,15 @@ static inline void probe_extension_roms(int roms)
} }
} }
static inline void request_graphics_resource(void) void __init request_graphics_resource(void)
{ {
request_resource(&iomem_resource, &vram_resource); request_resource(&iomem_resource, &vram_resource);
} }
#endif /* !_MACH_RESOURCES_H */ void __init request_standard_io_resources(void)
{
int i;
for (i = 0; i < STANDARD_IO_RESOURCES; i++)
request_resource(&ioport_resource, standard_io_resources+i);
}
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
# Makefile for the linux kernel. # Makefile for the linux kernel.
# #
obj-y := setup.o topology.o obj-y := setup.o topology.o std_resources.o
/* /*
* include/asm-i386/mach-pc9800/mach_resources.h
*
* Machine specific resource allocation for PC-9800. * Machine specific resource allocation for PC-9800.
* Written by Osamu Tomita <tomita@cinet.co.jp> * Written by Osamu Tomita <tomita@cinet.co.jp>
*/ */
#ifndef _MACH_RESOURCES_H
#define _MACH_RESOURCES_H #include <linux/ioport.h>
#include <asm/io.h>
#include <asm/std_resources.h>
static char str_pic1[] = "pic1"; static char str_pic1[] = "pic1";
static char str_dma[] = "dma"; static char str_dma[] = "dma";
...@@ -120,15 +120,13 @@ static struct resource rom_resources[MAXROMS] = { ...@@ -120,15 +120,13 @@ static struct resource rom_resources[MAXROMS] = {
{ "System ROM", 0xe8000, 0xfffff, IORESOURCE_BUSY } { "System ROM", 0xe8000, 0xfffff, IORESOURCE_BUSY }
}; };
static inline void probe_video_rom(int roms) void __init probe_roms(void)
{
/* PC-9800 has no video ROM */
}
static inline void probe_extension_roms(int roms)
{ {
int i; int i;
__u8 *xrom_id; __u8 *xrom_id;
int roms = 1;
request_resource(&iomem_resource, rom_resources+0);
xrom_id = (__u8 *) isa_bus_to_virt(PC9800SCA_XROM_ID + 0x10); xrom_id = (__u8 *) isa_bus_to_virt(PC9800SCA_XROM_ID + 0x10);
...@@ -151,7 +149,7 @@ static inline void probe_extension_roms(int roms) ...@@ -151,7 +149,7 @@ static inline void probe_extension_roms(int roms)
} }
} }
static inline void request_graphics_resource(void) void __init request_graphics_resource(void)
{ {
int i; int i;
...@@ -188,4 +186,10 @@ static inline void request_graphics_resource(void) ...@@ -188,4 +186,10 @@ static inline void request_graphics_resource(void)
} }
} }
#endif /* !_MACH_RESOURCES_H */ void __init request_standard_io_resources(void)
{
int i;
for (i = 0; i < STANDARD_IO_RESOURCES; i++)
request_resource(&ioport_resource, standard_io_resources+i);
}
/*
* include/asm-i386/std_resources.h
*/
#ifndef __ASM_I386_STD_RESOURCES_H
#define __ASM_I386_STD_RESOURCES_H
#include <linux/init.h>
void probe_roms(void) __init;
void request_graphics_resource(void) __init;
void request_standard_io_resources(void) __init;
#endif
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