diff -urN linux-2.1.119/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c --- linux-2.1.119/arch/i386/kernel/mtrr.c Sat Aug 29 23:41:22 1998 +++ linux/arch/i386/kernel/mtrr.c Tue Sep 1 15:26:01 1998 @@ -117,6 +117,11 @@ 19980611 Richard Gooch Always define . v1.22 + 19980901 Richard Gooch + Removed module support in order to tidy up code. + Added sanity check for / before . + Created addition queue for prior to SMP commence. + v1.23 */ #include #include @@ -149,7 +154,7 @@ #include #include -#define MTRR_VERSION "1.22 (19980611)" +#define MTRR_VERSION "1.23 (19980901)" #define TRUE 1 #define FALSE 0 @@ -177,6 +182,7 @@ # define MTRR_CHANGE_MASK_FIXED 0x01 # define MTRR_CHANGE_MASK_VARIABLE 0x02 # define MTRR_CHANGE_MASK_DEFTYPE 0x04 +# define MAX_QUEUE_SIZE 16 #endif /* In the processor's MTRR interface, the MTRR type is always held in @@ -658,13 +664,8 @@ } /* End Function set_mtrr_smp */ -/* A warning that is common to the module and non-module cases. */ /* Some BIOS's are fucked and don't set all MTRRs the same! */ -#ifdef MODULE -static void mtrr_state_warn (unsigned long mask) -#else __initfunc(static void mtrr_state_warn (unsigned long mask)) -#endif { if (!mask) return; if (mask & MTRR_CHANGE_MASK_FIXED) @@ -676,37 +677,47 @@ printk ("mtrr: probably your BIOS does not setup all CPUs\n"); } /* End Function mtrr_state_warn */ -#ifdef MODULE -/* As a module, copy the MTRR state using an IPI handler. */ +struct mtrr_queue_struct +{ + unsigned long base; + unsigned long size; + unsigned int type; + char increment; +}; -static volatile unsigned long smp_changes_mask = 0; +/* For SMP, we need a queue of requests for when additions are made before + is called. +*/ +static struct mtrr_queue_struct mtrr_queue[MAX_QUEUE_SIZE] __initdata = {}; +static unsigned int mtrr_queue_size __initdata = 0; +static char mtrr_smp_safe = FALSE; /* Permanent data */ + +__initfunc(static int mtrr_add_to_queue (unsigned long base, + unsigned long size, unsigned int type, + char increment)) +{ + if (mtrr_queue_size >= MAX_QUEUE_SIZE) return -ENOSPC; + mtrr_queue[mtrr_queue_size].base = base; + mtrr_queue[mtrr_queue_size].size = size; + mtrr_queue[mtrr_queue_size].type = type; + mtrr_queue[mtrr_queue_size].increment = increment; + ++mtrr_queue_size; + return 0; +} /* End Function mtrr_add_to_queue */ -static void copy_mtrr_state_handler (struct set_mtrr_context *ctxt, void *info) +__initfunc (void mtrr_after_smp_commenced (void)) { - unsigned long mask, count; - struct mtrr_state *smp_mtrr_state = info; + unsigned int count; - mask = set_mtrr_state (smp_mtrr_state, ctxt); - /* Use the atomic bitops to update the global mask */ - for (count = 0; count < sizeof mask * 8; ++count) + mtrr_smp_safe = TRUE; /* Must do this first */ + for (count = 0; count < mtrr_queue_size; ++count) { - if (mask & 0x01) set_bit (count, &smp_changes_mask); - mask >>= 1; + mtrr_add (mtrr_queue[count].base, mtrr_queue[count].size, + mtrr_queue[count].type, mtrr_queue[count].increment); } -} /* End Function copy_mtrr_state_handler */ - -/* Copies the entire MTRR state of this CPU to all the others. */ -static void copy_mtrr_state (void) -{ - struct mtrr_state ms; - - get_mtrr_state (&ms); - do_all_cpus (copy_mtrr_state_handler, &ms, FALSE); - finalize_mtrr_state (&ms); - mtrr_state_warn (smp_changes_mask); -} /* End Function copy_mtrr_state */ + if (mtrr_queue_size > 0) printk ("mtrr: processed queue\n"); +} /* End Function mtrr_after_smp_commenced */ -#endif /* MODULE */ #endif /* __SMP__ */ static char *attrib_to_str (int x) @@ -755,6 +766,11 @@ unsigned long lbase, lsize, last; if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return -ENODEV; + if (usage_table == NULL) + { + printk ("mtrr: add before mtrr_init() called!\n"); + return -EBUSY; + } if ( (base & 0xfff) || (size & 0xfff) ) { printk ("mtrr: size and base must be multiples of 4kB\n"); @@ -789,6 +805,9 @@ printk ("mtrr: your processor doesn't support write-combining\n"); return -ENOSYS; } +#ifdef __SMP__ + if (!mtrr_smp_safe) return mtrr_add_to_queue (base, size, type, increment); +#endif increment = increment ? 1 : 0; max = get_num_var_ranges (); /* Search for existing MTRR */ @@ -852,6 +871,18 @@ unsigned long lbase, lsize; if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return -ENODEV; + if (usage_table == NULL) + { + printk ("mtrr: del before mtrr_init() called!\n"); + return -EBUSY; + } +#ifdef __SMP__ + if (!mtrr_smp_safe) + { + printk ("mtrr: cannot delete entries yet\n"); + return -EBUSY; + } +#endif max = get_num_var_ranges (); spin_lock (&main_lock); if (reg < 0) @@ -1163,7 +1194,7 @@ EXPORT_SYMBOL(mtrr_add); EXPORT_SYMBOL(mtrr_del); -#if defined(__SMP__) && !defined(MODULE) +#ifdef __SMP__ static volatile unsigned long smp_changes_mask __initdata = 0; static struct mtrr_state smp_mtrr_state __initdata = {0, 0}; @@ -1196,26 +1227,18 @@ } } /* End Function mtrr_init_secondary_cpu */ -#endif +#endif /* __SMP__ */ -#ifdef MODULE -int init_module (void) -#else __initfunc(int mtrr_init(void)) -#endif { if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return 0; -# if !defined(__SMP__) || defined(MODULE) +# ifndef __SMP__ printk("mtrr: v%s Richard Gooch (rgooch@atnf.csiro.au)\n", MTRR_VERSION); # endif # ifdef __SMP__ -# ifdef MODULE - copy_mtrr_state (); -# else /* MODULE */ finalize_mtrr_state (&smp_mtrr_state); mtrr_state_warn (smp_changes_mask); -# endif /* MODULE */ # endif /* __SMP__ */ # ifdef CONFIG_PROC_FS @@ -1224,17 +1247,4 @@ init_table (); return 0; -} - -#ifdef MODULE -void cleanup_module (void) -{ - if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return; -# ifdef CONFIG_PROC_FS - proc_unregister (&proc_root, PROC_MTRR); -# endif -# ifdef __SMP__ - mtrr_hook = NULL; -# endif -} -#endif +} /* End Function mtrr_init */ diff -urN linux-2.1.119/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c --- linux-2.1.119/arch/i386/kernel/smp.c Sat Aug 29 23:41:30 1998 +++ linux/arch/i386/kernel/smp.c Tue Sep 1 11:54:40 1998 @@ -637,6 +637,9 @@ */ SMP_PRINTK(("Setting commenced=1, go go go\n")); smp_commenced=1; +#ifdef CONFIG_MTRR + mtrr_after_smp_commenced (); +#endif } __initfunc(void enable_local_APIC(void)) diff -urN linux-2.1.119/include/asm-alpha/init_steps.h linux/include/asm-alpha/init_steps.h --- linux-2.1.119/include/asm-alpha/init_steps.h Thu Jan 1 10:00:00 1970 +++ linux/include/asm-alpha/init_steps.h Tue Sep 1 15:16:06 1998 @@ -0,0 +1,21 @@ +/* include/asm-alpha/init_steps.h + + Copyright (C) 1998 Richard Gooch + Licenced under the GPL. + + This file contains architecture-specific setup code required during the + initialisation process. Multiple sequence points are defined. + +*/ +#ifndef _alpha_INIT_STEPS_H +#define _alpha_INIT_STEPS_H + +__initfunc(static void arch_pre_bus_init(void)) +{ +} /* End Function arch_pre_bus_init */ + +__initfunc(static void arch_post_bus_init(void)) +{ +} /* End Function arch_post_bus_init */ + +#endif /* _alpha_INIT_STEPS_H */ diff -urN linux-2.1.119/include/asm-arm/init_steps.h linux/include/asm-arm/init_steps.h --- linux-2.1.119/include/asm-arm/init_steps.h Thu Jan 1 10:00:00 1970 +++ linux/include/asm-arm/init_steps.h Tue Sep 1 15:16:06 1998 @@ -0,0 +1,21 @@ +/* include/asm-arm/init_steps.h + + Copyright (C) 1998 Richard Gooch + Licenced under the GPL. + + This file contains architecture-specific setup code required during the + initialisation process. Multiple sequence points are defined. + +*/ +#ifndef _arm_INIT_STEPS_H +#define _arm_INIT_STEPS_H + +__initfunc(static void arch_pre_bus_init(void)) +{ +} /* End Function arch_pre_bus_init */ + +__initfunc(static void arch_post_bus_init(void)) +{ +} /* End Function arch_post_bus_init */ + +#endif /* _arm_INIT_STEPS_H */ diff -urN linux-2.1.119/include/asm-i386/init_steps.h linux/include/asm-i386/init_steps.h --- linux-2.1.119/include/asm-i386/init_steps.h Thu Jan 1 10:00:00 1970 +++ linux/include/asm-i386/init_steps.h Tue Sep 1 15:21:16 1998 @@ -0,0 +1,28 @@ +/* include/asm-i386/init_steps.h + + Copyright (C) 1998 Richard Gooch + Licenced under the GPL. + + This file contains architecture-specific setup code required during the + initialisation process. Multiple sequence points are defined. + +*/ +#ifndef _i386_INIT_STEPS_H +#define _i386_INIT_STEPS_H + +#ifdef CONFIG_MTRR +# include +#endif + +__initfunc(static void arch_pre_bus_init(void)) +{ +#ifdef CONFIG_MTRR + mtrr_init (); +#endif +} /* End Function arch_pre_bus_init */ + +__initfunc(static void arch_post_bus_init(void)) +{ +} /* End Function arch_post_bus_init */ + +#endif /* _i386_INIT_STEPS_H */ diff -urN linux-2.1.119/include/asm-i386/mtrr.h linux/include/asm-i386/mtrr.h --- linux-2.1.119/include/asm-i386/mtrr.h Thu Apr 30 15:46:59 1998 +++ linux/include/asm-i386/mtrr.h Tue Sep 1 15:21:16 1998 @@ -96,6 +96,7 @@ # if defined(__SMP__) && defined(CONFIG_MTRR) extern void mtrr_init_boot_cpu (void); extern void mtrr_init_secondary_cpu (void); +extern void mtrr_after_smp_commenced (void); # endif #endif diff -urN linux-2.1.119/include/asm-m68k/init_steps.h linux/include/asm-m68k/init_steps.h --- linux-2.1.119/include/asm-m68k/init_steps.h Thu Jan 1 10:00:00 1970 +++ linux/include/asm-m68k/init_steps.h Tue Sep 1 15:16:06 1998 @@ -0,0 +1,21 @@ +/* include/asm-m68k/init_steps.h + + Copyright (C) 1998 Richard Gooch + Licenced under the GPL. + + This file contains architecture-specific setup code required during the + initialisation process. Multiple sequence points are defined. + +*/ +#ifndef _m68k_INIT_STEPS_H +#define _m68k_INIT_STEPS_H + +__initfunc(static void arch_pre_bus_init(void)) +{ +} /* End Function arch_pre_bus_init */ + +__initfunc(static void arch_post_bus_init(void)) +{ +} /* End Function arch_post_bus_init */ + +#endif /* _m68k_INIT_STEPS_H */ diff -urN linux-2.1.119/include/asm-mips/init_steps.h linux/include/asm-mips/init_steps.h --- linux-2.1.119/include/asm-mips/init_steps.h Thu Jan 1 10:00:00 1970 +++ linux/include/asm-mips/init_steps.h Tue Sep 1 15:16:06 1998 @@ -0,0 +1,21 @@ +/* include/asm-mips/init_steps.h + + Copyright (C) 1998 Richard Gooch + Licenced under the GPL. + + This file contains architecture-specific setup code required during the + initialisation process. Multiple sequence points are defined. + +*/ +#ifndef _mips_INIT_STEPS_H +#define _mips_INIT_STEPS_H + +__initfunc(static void arch_pre_bus_init(void)) +{ +} /* End Function arch_pre_bus_init */ + +__initfunc(static void arch_post_bus_init(void)) +{ +} /* End Function arch_post_bus_init */ + +#endif /* _mips_INIT_STEPS_H */ diff -urN linux-2.1.119/include/asm-ppc/init_steps.h linux/include/asm-ppc/init_steps.h --- linux-2.1.119/include/asm-ppc/init_steps.h Thu Jan 1 10:00:00 1970 +++ linux/include/asm-ppc/init_steps.h Tue Sep 1 15:16:06 1998 @@ -0,0 +1,21 @@ +/* include/asm-ppc/init_steps.h + + Copyright (C) 1998 Richard Gooch + Licenced under the GPL. + + This file contains architecture-specific setup code required during the + initialisation process. Multiple sequence points are defined. + +*/ +#ifndef _ppc_INIT_STEPS_H +#define _ppc_INIT_STEPS_H + +__initfunc(static void arch_pre_bus_init(void)) +{ +} /* End Function arch_pre_bus_init */ + +__initfunc(static void arch_post_bus_init(void)) +{ +} /* End Function arch_post_bus_init */ + +#endif /* _ppc_INIT_STEPS_H */ diff -urN linux-2.1.119/include/asm-sparc/init_steps.h linux/include/asm-sparc/init_steps.h --- linux-2.1.119/include/asm-sparc/init_steps.h Thu Jan 1 10:00:00 1970 +++ linux/include/asm-sparc/init_steps.h Tue Sep 1 15:16:06 1998 @@ -0,0 +1,21 @@ +/* include/asm-sparc/init_steps.h + + Copyright (C) 1998 Richard Gooch + Licenced under the GPL. + + This file contains architecture-specific setup code required during the + initialisation process. Multiple sequence points are defined. + +*/ +#ifndef _sparc_INIT_STEPS_H +#define _sparc_INIT_STEPS_H + +__initfunc(static void arch_pre_bus_init(void)) +{ +} /* End Function arch_pre_bus_init */ + +__initfunc(static void arch_post_bus_init(void)) +{ +} /* End Function arch_post_bus_init */ + +#endif /* _sparc_INIT_STEPS_H */ diff -urN linux-2.1.119/include/asm-sparc64/init_steps.h linux/include/asm-sparc64/init_steps.h --- linux-2.1.119/include/asm-sparc64/init_steps.h Thu Jan 1 10:00:00 1970 +++ linux/include/asm-sparc64/init_steps.h Tue Sep 1 15:16:06 1998 @@ -0,0 +1,21 @@ +/* include/asm-sparc64/init_steps.h + + Copyright (C) 1998 Richard Gooch + Licenced under the GPL. + + This file contains architecture-specific setup code required during the + initialisation process. Multiple sequence points are defined. + +*/ +#ifndef _sparc64_INIT_STEPS_H +#define _sparc64_INIT_STEPS_H + +__initfunc(static void arch_pre_bus_init(void)) +{ +} /* End Function arch_pre_bus_init */ + +__initfunc(static void arch_post_bus_init(void)) +{ +} /* End Function arch_post_bus_init */ + +#endif /* _sparc64_INIT_STEPS_H */ diff -urN linux-2.1.119/init/main.c linux/init/main.c --- linux-2.1.119/init/main.c Sat Aug 29 23:41:27 1998 +++ linux/init/main.c Tue Sep 1 15:20:13 1998 @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -48,10 +49,6 @@ #include #endif -#ifdef CONFIG_MTRR -# include -#endif - /* * Versions of gcc older than that listed below may actually compile * and link okay, but the end product can have subtle run time bugs. @@ -1120,15 +1117,6 @@ check_bugs(); -#if defined(CONFIG_MTRR) /* Do this after SMP initialization */ -/* - * We should probably create some architecture-dependent "fixup after - * everything is up" style function where this would belong better - * than in init/main.c.. - */ - mtrr_init (); -#endif - sock_init(); #ifdef CONFIG_SYSCTL sysctl_init(); @@ -1141,6 +1129,7 @@ * Ok, at this point all CPU's should be initialized, so * we can start looking into devices.. */ + arch_pre_bus_init(); #ifdef CONFIG_PCI pci_init(); #endif @@ -1156,6 +1145,7 @@ #ifdef CONFIG_ARCH_ACORN ecard_init(); #endif + arch_post_bus_init(); /* * We count on the initial thread going ok