diff -b -u -r -N linux-1.3.95-orig/Documentation/Configure.help linux-1.3.95/Documentation/Configure.help --- linux-1.3.95-orig/Documentation/Configure.help Tue Apr 23 06:20:20 1996 +++ linux-1.3.95/Documentation/Configure.help Fri Apr 26 20:58:59 1996 @@ -603,6 +603,14 @@ say "386" or "486" here even if running on a Pentium or PPro machine. If you don't know what to do, say "386". +Support for big physical area reservation +CONFIG_BIGPHYS_AREA + Enables kernel support for reserving large areas of physical memory + at boot-time for use by certain device drivers (such as video + framegrabbers, etc.) which require it. To use this feature, boot + the kernel with the boot-time option 'bigphysarea=nnn' where + 'nnn' is the number of pages (a page is usually 4K) to reserve. + Compile the kernel into the ELF object format CONFIG_ELF_KERNEL ELF (Executable and Linkable Format) is a format for libraries and diff -b -u -r -N linux-1.3.95-orig/arch/i386/config.in linux-1.3.95/arch/i386/config.in --- linux-1.3.95-orig/arch/i386/config.in Mon Feb 26 04:58:03 1996 +++ linux-1.3.95/arch/i386/config.in Fri Apr 26 20:58:59 1996 @@ -34,6 +34,8 @@ 486 CONFIG_M486 \ Pentium CONFIG_M586 \ PPro CONFIG_M686" Pentium +# Added by M. Welsh +bool 'Support for big physical area reservation' CONFIG_BIGPHYS_AREA endmenu source drivers/block/Config.in diff -b -u -r -N linux-1.3.95-orig/include/linux/bigphysarea.h linux-1.3.95/include/linux/bigphysarea.h --- linux-1.3.95-orig/include/linux/bigphysarea.h Wed Dec 31 19:00:00 1969 +++ linux-1.3.95/include/linux/bigphysarea.h Fri Apr 26 20:58:59 1996 @@ -0,0 +1,25 @@ +/* linux/mm/bigphysarea.h, M. Welsh (mdw@cs.cornell.edu) + * Copyright (c) 1996 by Matt Welsh. + * + * This is a set of routines which allow you to reserve a large (?) + * amount of physical memory at boot-time, which can be allocated/deallocated + * by drivers. This memory is intended to be used for devices such as + * video framegrabbers which need a lot of physical RAM (above the amount + * allocated by kmalloc). This is by no means efficient or recommended; + * to be used only in extreme circumstances. + * + */ + +#ifndef __LINUX_BIGPHYSAREA_H +#define __LINUX_BIGPHYSAREA_H + +#include + +extern caddr_t bigphysarea; + +extern void bigphysarea_setup(char *str, int *ints); +extern unsigned long bigphysarea_init(unsigned long mem_start, unsigned long mem_end); +extern caddr_t bigphysarea_alloc(int size); +extern void bigphysarea_free(caddr_t addr, int size); + +#endif __LINUX_BIGPHYSAREA_H diff -b -u -r -N linux-1.3.95-orig/init/main.c linux-1.3.95/init/main.c --- linux-1.3.95-orig/init/main.c Mon Apr 22 08:12:29 1996 +++ linux-1.3.95/init/main.c Fri Apr 26 21:13:31 1996 @@ -142,10 +142,12 @@ extern void riscom8_setup(char *str, int *ints); #endif - #if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD) extern void ipc_init(void); #endif +#ifdef CONFIG_BIGPHYS_AREA +extern void bigphysarea_setup(char *str, int *ints); +#endif /* * Boot command-line arguments @@ -352,6 +354,9 @@ #ifdef CONFIG_RISCOM8 { "riscom8=", riscom8_setup }, #endif +#ifdef CONFIG_BIGPHYS_AREA + { "bigphysarea=", bigphysarea_setup }, +#endif { 0, 0 } }; @@ -735,6 +740,9 @@ memory_start = console_init(memory_start,memory_end); #ifdef CONFIG_PCI memory_start = pci_init(memory_start,memory_end); +#endif +#ifdef CONFIG_BIGPHYS_AREA + memory_start = bigphysarea_init(memory_start,memory_end); #endif memory_start = kmalloc_init(memory_start,memory_end); sti(); diff -b -u -r -N linux-1.3.95-orig/kernel/ksyms.c linux-1.3.95/kernel/ksyms.c --- linux-1.3.95-orig/kernel/ksyms.c Fri Apr 12 02:49:47 1996 +++ linux-1.3.95/kernel/ksyms.c Fri Apr 26 20:59:00 1996 @@ -62,6 +62,9 @@ #ifdef __SMP__ #include #endif +#ifdef CONFIG_BIGPHYS_AREA +#include +#endif extern char *get_options(char *str, int *ints); extern void set_device_ro(int dev,int flag); @@ -133,6 +136,13 @@ X(remap_page_range), X(high_memory), X(update_vm_cache), + +#ifdef CONFIG_BIGPHYS_AREA + /* Large physical area memory management */ + X(bigphysarea_alloc), + X(bigphysarea_free), + X(bigphysarea), +#endif /* filesystem internal functions */ X(getname), diff -b -u -r -N linux-1.3.95-orig/mm/Makefile linux-1.3.95/mm/Makefile --- linux-1.3.95-orig/mm/Makefile Fri Mar 22 05:56:56 1996 +++ linux-1.3.95/mm/Makefile Fri Apr 26 20:59:00 1996 @@ -12,4 +12,8 @@ kmalloc.o vmalloc.o \ swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o +ifeq ($(CONFIG_BIGPHYS_AREA),y) + O_OBJS += bigphysarea.o +endif + include $(TOPDIR)/Rules.make diff -b -u -r -N linux-1.3.95-orig/mm/bigphysarea.c linux-1.3.95/mm/bigphysarea.c --- linux-1.3.95-orig/mm/bigphysarea.c Wed Dec 31 19:00:00 1969 +++ linux-1.3.95/mm/bigphysarea.c Fri Apr 26 20:59:00 1996 @@ -0,0 +1,113 @@ +/* linux/mm/bigphysarea.c, M. Welsh (mdw@cs.cornell.edu) + * Copyright (c) 1996 by Matt Welsh. + * + * This is a set of routines which allow you to reserve a large (?) + * amount of physical memory at boot-time, which can be allocated/deallocated + * by drivers. This memory is intended to be used for devices such as + * video framegrabbers which need a lot of physical RAM (above the amount + * allocated by kmalloc). This is by no means efficient or recommended; + * to be used only in extreme circumstances. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int bigphysarea_pages = 0; +static unsigned char *bigphysarea_map; +caddr_t bigphysarea; + +#define BIGPHYS_FREE 0 +#define BIGPHYS_INUSE 1 + +void bigphysarea_setup(char *str, int *ints) { + if (ints[0] != 1) { + printk("bigphysarea_setup: Usage: bigphysarea=\n"); + } else { + bigphysarea_pages = ints[1]; + } +} + +unsigned long bigphysarea_init(unsigned long mem_start, unsigned long mem_end) { + int ncp, i; + + if (bigphysarea_pages == 0) return mem_start; + + ncp = (bigphysarea_pages / PAGE_SIZE) + 1; + bigphysarea_map = (caddr_t)((mem_start + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1)); + bigphysarea = bigphysarea_map + (ncp * PAGE_SIZE); + + printk("bigphysarea: Allocated %d pages at 0x%lx.\n", + bigphysarea_pages, (unsigned long)bigphysarea); + + for (i = 0; i < bigphysarea_pages; i++) { + bigphysarea_map[i] = BIGPHYS_FREE; + } + + return (unsigned long)(bigphysarea + (bigphysarea_pages * PAGE_SIZE)); +} + +caddr_t bigphysarea_alloc(int size) { + int i, j, n; + + n = (size / PAGE_SIZE) + 1; + + i = 0; + +try_again: + /* Get the first unallocated page */ + for (; i < bigphysarea_pages; i++) { + if (bigphysarea_map[i] == BIGPHYS_FREE) break; + } + if (i == bigphysarea_pages) return NULL; + + /* Check out the region */ + for (j = i; (j < bigphysarea_pages) && (j < (i + n)); j++) { + if (bigphysarea_map[i] != BIGPHYS_FREE) break; + } + + if (j == (i + n)) { + /* Got it */ + for (j = i; (j < (i + n)); j++) { + bigphysarea_map[j] = BIGPHYS_INUSE; + } + return bigphysarea + (i * PAGE_SIZE); + } + + /* Try again ... */ + i = j; + goto try_again; + +} + +void bigphysarea_free(caddr_t addr, int size) { + int i, j; + int n = (size / PAGE_SIZE) + 1; + + i = (((unsigned int)addr - (unsigned int)bigphysarea)/PAGE_SIZE); + for (j = 0; j < n; j++) { + if (bigphysarea_map[i+j] != BIGPHYS_INUSE) return; + bigphysarea_map[i+j] = BIGPHYS_FREE; + } +}