Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9655ad03af2d232c3b26e7562ab4f8c29b107e49
Commit:     9655ad03af2d232c3b26e7562ab4f8c29b107e49
Parent:     e08f457c7c0cc7720f28349f8780ea752c063441
Author:     Paul Mundt <[EMAIL PROTECTED]>
AuthorDate: Mon May 14 15:59:09 2007 +0900
Committer:  Paul Mundt <[EMAIL PROTECTED]>
CommitDate: Fri Jun 8 02:43:37 2007 +0000

    sh: Fixup machvec support.
    
    This fixes up much of the machvec handling, allowing for it to be
    overloaded on boot. Making practical use of this still requires
    some Kconfig munging, however.
    
    Signed-off-by: Paul Mundt <[EMAIL PROTECTED]>
---
 arch/sh/kernel/Makefile       |    2 +-
 arch/sh/kernel/machvec.c      |  105 ++++++++++++++++++++++++++
 arch/sh/kernel/setup.c        |  162 ++++-------------------------------------
 arch/sh/kernel/vmlinux.lds.S  |    3 +-
 include/asm-sh/machvec_init.h |   34 ---------
 include/asm-sh/sections.h     |    2 +
 include/asm-sh/setup.h        |    1 +
 7 files changed, 125 insertions(+), 184 deletions(-)

diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index fb623e5..1f141a8 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -4,7 +4,7 @@
 
 extra-y        := head.o init_task.o vmlinux.lds
 
-obj-y  := debugtraps.o io.o io_generic.o irq.o process.o ptrace.o \
+obj-y  := debugtraps.o io.o io_generic.o irq.o machvec.o process.o ptrace.o \
           semaphore.o setup.o signal.o sys_sh.o syscalls.o \
           time.o topology.o traps.o
 
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
new file mode 100644
index 0000000..1e78191
--- /dev/null
+++ b/arch/sh/kernel/machvec.c
@@ -0,0 +1,105 @@
+/*
+ * arch/sh/kernel/machvec.c
+ *
+ * The SuperH machine vector setup handlers, yanked from setup.c
+ *
+ *  Copyright (C) 1999  Niibe Yutaka
+ *  Copyright (C) 2002 - 2007 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/machvec.h>
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#define MV_NAME_SIZE 32
+
+#define for_each_mv(mv) \
+       for ((mv) = (struct sh_machine_vector *)&__machvec_start; \
+            (mv) && (unsigned long)(mv) < (unsigned long)&__machvec_end; \
+            (mv)++)
+
+static struct sh_machine_vector * __init get_mv_byname(const char *name)
+{
+       struct sh_machine_vector *mv;
+
+       for_each_mv(mv)
+               if (strcasecmp(name, get_system_type()) == 0)
+                       return mv;
+
+       return NULL;
+}
+
+static int __init early_parse_mv(char *from)
+{
+       char mv_name[MV_NAME_SIZE] = "";
+       char *mv_end;
+       char *mv_comma;
+       int mv_len;
+       struct sh_machine_vector *mvp;
+
+       mv_end = strchr(from, ' ');
+       if (mv_end == NULL)
+               mv_end = from + strlen(from);
+
+       mv_comma = strchr(from, ',');
+       mv_len = mv_end - from;
+       if (mv_len > (MV_NAME_SIZE-1))
+               mv_len = MV_NAME_SIZE-1;
+       memcpy(mv_name, from, mv_len);
+       mv_name[mv_len] = '\0';
+       from = mv_end;
+
+       if (strcmp(sh_mv.mv_name, mv_name) != 0) {
+               mvp = get_mv_byname(mv_name);
+               if (unlikely(!mvp)) {
+                       printk("Available vectors:\n\n\t");
+                       for_each_mv(mvp)
+                               printk("'%s', ", mvp->mv_name);
+                       printk("\n\n");
+                       panic("Failed to select machvec '%s' -- halting.\n",
+                             mv_name);
+               } else
+                       sh_mv = *mvp;
+       }
+
+       printk(KERN_NOTICE "Booting machvec: %s\n", sh_mv.mv_name);
+       return 0;
+}
+early_param("sh_mv", early_parse_mv);
+
+void __init sh_mv_setup(void)
+{
+       /*
+        * Manually walk the vec, fill in anything that the board hasn't yet
+        * by hand, wrapping to the generic implementation.
+        */
+#define mv_set(elem) do { \
+       if (!sh_mv.mv_##elem) \
+               sh_mv.mv_##elem = generic_##elem; \
+} while (0)
+
+       mv_set(inb);    mv_set(inw);    mv_set(inl);
+       mv_set(outb);   mv_set(outw);   mv_set(outl);
+
+       mv_set(inb_p);  mv_set(inw_p);  mv_set(inl_p);
+       mv_set(outb_p); mv_set(outw_p); mv_set(outl_p);
+
+       mv_set(insb);   mv_set(insw);   mv_set(insl);
+       mv_set(outsb);  mv_set(outsw);  mv_set(outsl);
+
+       mv_set(readb);  mv_set(readw);  mv_set(readl);
+       mv_set(writeb); mv_set(writew); mv_set(writel);
+
+       mv_set(ioport_map);
+       mv_set(ioport_unmap);
+       mv_set(irq_demux);
+
+       if (!sh_mv.mv_nr_irqs)
+               sh_mv.mv_nr_irqs = NR_IRQS;
+}
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 61152b4..0ad7158 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -46,16 +46,8 @@ struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, };
 struct screen_info screen_info;
 #endif
 
-#if defined(CONFIG_SH_UNKNOWN)
-struct sh_machine_vector sh_mv;
-#endif
-
 extern int root_mountflags;
 
-#define MV_NAME_SIZE 32
-
-static struct sh_machine_vector* __init get_mv_byname(const char* name);
-
 /*
  * This is set up by the setup-routine at boot-time
  */
@@ -81,131 +73,17 @@ static struct resource data_resource = { .name = "Kernel 
data", };
 
 unsigned long memory_start, memory_end;
 
-static inline void parse_cmdline (char ** cmdline_p, char 
mv_name[MV_NAME_SIZE],
-                                 struct sh_machine_vector** mvp,
-                                 unsigned long *mv_io_base)
+static int __init early_parse_mem(char *p)
 {
-       char c = ' ', *to = command_line, *from = COMMAND_LINE;
-       int len = 0;
-
-       /* Save unparsed command line copy for /proc/cmdline */
-       memcpy(boot_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
-       boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
+       unsigned long size;
 
        memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START;
-       memory_end = memory_start + __MEMORY_SIZE;
-
-       for (;;) {
-               /*
-                * "mem=XXX[kKmM]" defines a size of memory.
-                */
-               if (c == ' ' && !memcmp(from, "mem=", 4)) {
-                       if (to != command_line)
-                               to--;
-                       {
-                               unsigned long mem_size;
-
-                               mem_size = memparse(from+4, &from);
-                               memory_end = memory_start + mem_size;
-                       }
-               }
-
-               if (c == ' ' && !memcmp(from, "sh_mv=", 6)) {
-                       char* mv_end;
-                       char* mv_comma;
-                       int mv_len;
-                       if (to != command_line)
-                               to--;
-                       from += 6;
-                       mv_end = strchr(from, ' ');
-                       if (mv_end == NULL)
-                               mv_end = from + strlen(from);
-
-                       mv_comma = strchr(from, ',');
-                       if ((mv_comma != NULL) && (mv_comma < mv_end)) {
-                               int ints[3];
-                               get_options(mv_comma+1, ARRAY_SIZE(ints), ints);
-                               *mv_io_base = ints[1];
-                               mv_len = mv_comma - from;
-                       } else {
-                               mv_len = mv_end - from;
-                       }
-                       if (mv_len > (MV_NAME_SIZE-1))
-                               mv_len = MV_NAME_SIZE-1;
-                       memcpy(mv_name, from, mv_len);
-                       mv_name[mv_len] = '\0';
-                       from = mv_end;
-
-                       *mvp = get_mv_byname(mv_name);
-               }
-
-               c = *(from++);
-               if (!c)
-                       break;
-               if (COMMAND_LINE_SIZE <= ++len)
-                       break;
-               *(to++) = c;
-       }
-       *to = '\0';
-       *cmdline_p = command_line;
-}
-
-static int __init sh_mv_setup(char **cmdline_p)
-{
-#ifdef CONFIG_SH_UNKNOWN
-       extern struct sh_machine_vector mv_unknown;
-#endif
-       struct sh_machine_vector *mv = NULL;
-       char mv_name[MV_NAME_SIZE] = "";
-       unsigned long mv_io_base = 0;
-
-       parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base);
-
-#ifdef CONFIG_SH_UNKNOWN
-       if (mv == NULL) {
-               mv = &mv_unknown;
-               if (*mv_name != '\0') {
-                       printk("Warning: Unsupported machine %s, using 
unknown\n",
-                              mv_name);
-               }
-       }
-       sh_mv = *mv;
-#endif
-
-       /*
-        * Manually walk the vec, fill in anything that the board hasn't yet
-        * by hand, wrapping to the generic implementation.
-        */
-#define mv_set(elem) do { \
-       if (!sh_mv.mv_##elem) \
-               sh_mv.mv_##elem = generic_##elem; \
-} while (0)
-
-       mv_set(inb);    mv_set(inw);    mv_set(inl);
-       mv_set(outb);   mv_set(outw);   mv_set(outl);
-
-       mv_set(inb_p);  mv_set(inw_p);  mv_set(inl_p);
-       mv_set(outb_p); mv_set(outw_p); mv_set(outl_p);
-
-       mv_set(insb);   mv_set(insw);   mv_set(insl);
-       mv_set(outsb);  mv_set(outsw);  mv_set(outsl);
-
-       mv_set(readb);  mv_set(readw);  mv_set(readl);
-       mv_set(writeb); mv_set(writew); mv_set(writel);
-
-       mv_set(ioport_map);
-       mv_set(ioport_unmap);
-       mv_set(irq_demux);
-
-#ifdef CONFIG_SH_UNKNOWN
-       __set_io_port_base(mv_io_base);
-#endif
-
-       if (!sh_mv.mv_nr_irqs)
-               sh_mv.mv_nr_irqs = NR_IRQS;
+       size = memparse(p, &p);
+       memory_end = memory_start + size;
 
        return 0;
 }
+early_param("mem", early_parse_mem);
 
 /*
  * Register fully available low RAM pages with the bootmem allocator.
@@ -340,9 +218,17 @@ void __init setup_arch(char **cmdline_p)
        data_resource.start = virt_to_phys(_etext);
        data_resource.end = virt_to_phys(_edata)-1;
 
+       memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START;
+       memory_end = memory_start + __MEMORY_SIZE;
+
+       /* Save unparsed command line copy for /proc/cmdline */
+       strlcpy(boot_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
+
+       *cmdline_p = command_line;
+
        parse_early_param();
 
-       sh_mv_setup(cmdline_p);
+       sh_mv_setup();
 
        /*
         * Find the highest page frame number we have available
@@ -369,26 +255,6 @@ void __init setup_arch(char **cmdline_p)
                sh_mv.mv_setup(cmdline_p);
 }
 
-struct sh_machine_vector* __init get_mv_byname(const char* name)
-{
-       extern long __machvec_start, __machvec_end;
-       struct sh_machine_vector *all_vecs =
-               (struct sh_machine_vector *)&__machvec_start;
-
-       int i, n = ((unsigned long)&__machvec_end
-                   - (unsigned long)&__machvec_start)/
-               sizeof(struct sh_machine_vector);
-
-       for (i = 0; i < n; ++i) {
-               struct sh_machine_vector *mv = &all_vecs[i];
-               if (mv == NULL)
-                       continue;
-               if (strcasecmp(name, get_system_type()) == 0) {
-                       return mv;
-               }
-       }
-       return NULL;
-}
 
 static const char *cpu_name[] = {
        [CPU_SH7206]    = "SH7206",     [CPU_SH7619]    = "SH7619",
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 4c5b57e..f437a4f 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -98,8 +98,9 @@ SECTIONS
 #endif
 
   __machvec_start = .;
-  .init.machvec : { *(.init.machvec) }
+  .machvec.init : { *(.machvec.init) }
   __machvec_end = .;
+
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
 
diff --git a/include/asm-sh/machvec_init.h b/include/asm-sh/machvec_init.h
index e397798..88a973e 100644
--- a/include/asm-sh/machvec_init.h
+++ b/include/asm-sh/machvec_init.h
@@ -12,42 +12,8 @@
 #ifndef __SH_MACHVEC_INIT_H
 #define __SH_MACHVEC_INIT_H
 
-
-/*
- * In a GENERIC kernel, we have lots of these vectors floating about,
- * all but one of which we want to go away.  In a non-GENERIC kernel,
- * we want only one, ever.
- *
- * Accomplish this in the GENERIC kernel by puting all of the vectors
- * in the .init.data section where they'll go away.  We'll copy the
- * one we want to the real alpha_mv vector in setup_arch.
- *
- * Accomplish this in a non-GENERIC kernel by ifdef'ing out all but
- * one of the vectors, which will not reside in .init.data.  We then
- * alias this one vector to alpha_mv, so no copy is needed.
- *
- * Upshot: set __initdata to nothing for non-GENERIC kernels.
- *
- * Note we do the same thing for the UNKNOWN kernel, as we need to write
- * to the machine vector while setting it up.
- */
-
-#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_UNKNOWN)
 #define __initmv __attribute__((unused,__section__ (".machvec.init")))
-#define ALIAS_MV(x)
-#else
-#define __initmv
-
-/* GCC actually has a syntax for defining aliases, but is under some
-   delusion that you shouldn't be able to declare it extern somewhere
-   else beforehand.  Fine.  We'll do it ourselves.  */
-#if 0
-#define ALIAS_MV(system) \
-  struct sh_machine_vector sh_mv __attribute__((alias("mv_"#system)));
-#else
 #define ALIAS_MV(system) \
   asm(".global sh_mv\nsh_mv = mv_"#system );
-#endif
-#endif /* GENERIC */
 
 #endif /* __SH_MACHVEC_INIT_H */
diff --git a/include/asm-sh/sections.h b/include/asm-sh/sections.h
index 44c06c0..2a696b8 100644
--- a/include/asm-sh/sections.h
+++ b/include/asm-sh/sections.h
@@ -3,5 +3,7 @@
 
 #include <asm-generic/sections.h>
 
+extern long __machvec_start, __machvec_end;
+
 #endif /* __ASM_SH_SECTIONS_H */
 
diff --git a/include/asm-sh/setup.h b/include/asm-sh/setup.h
index 1583c6b..586a971 100644
--- a/include/asm-sh/setup.h
+++ b/include/asm-sh/setup.h
@@ -6,6 +6,7 @@
 #ifdef __KERNEL__
 
 int setup_early_printk(char *);
+void sh_mv_setup(void);
 
 #endif /* __KERNEL__ */
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to