|
From: NIIBE Y. <gn...@ch...> - 2000-08-03 08:19:38
|
NIIBE Yutaka wrote:
> Besides, I think that it is better to use some linker magic for
> `all_vecs' handling. Currently, when people want to add another
> system, he has to touch setup.c for the inclusion. I think that we
> can add our own ELF section for the machine vector, then all that he
> need is adding the specific file and modify Makefile. No need to
> touch other files. Sounds good?
Like this one. Any comments are appreciated. If it's OK, I will add
ChangeLog entries and commit this over the changes by Stuart.
Index: arch/sh/vmlinux.lds.S
===================================================================
RCS file: /cvsroot/linuxsh/kernel/arch/sh/vmlinux.lds.S,v
retrieving revision 1.5
diff -u -r1.5 vmlinux.lds.S
--- arch/sh/vmlinux.lds.S 2000/07/20 06:50:06 1.5
+++ arch/sh/vmlinux.lds.S 2000/08/03 08:11:21
@@ -61,6 +61,9 @@
__initcall_start = .;
.initcall.init : { *(.initcall.init) }
__initcall_end = .;
+ __machvec_start = .;
+ .machvec.init : { *(.machvec.init) }
+ __machvec_end = .;
. = ALIGN(4096);
__init_end = .;
Index: include/asm-sh/machvec_init.h
===================================================================
RCS file: /cvsroot/linuxsh/kernel/include/asm-sh/machvec_init.h,v
retrieving revision 1.1
diff -u -r1.1 machvec_init.h
--- include/asm-sh/machvec_init.h 2000/07/31 12:31:12 1.1
+++ include/asm-sh/machvec_init.h 2000/08/03 08:11:30
@@ -26,11 +26,15 @@
* 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.
*/
-#ifdef CONFIG_SH_GENERIC
+#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_UNKNOWN)
#define __initmv __initdata
#define ALIAS_MV(x)
+#define REGISTER_MV(x) long pointer_to_##x __attribute__((unused,__section__ (".machvec.init"))) = (long)&mv_##x;
#else
#define __initmv
@@ -44,6 +48,7 @@
#define ALIAS_MV(system) \
asm(".global sh_mv\nsh_mv = mv_"#system );
#endif
+#define REGISTER_MV(x)
#endif /* GENERIC */
#endif /* __SH_MACHVEC_INIT_H */
Index: arch/sh/kernel/mach_hp600.c
===================================================================
RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/mach_hp600.c,v
retrieving revision 1.3
diff -u -r1.3 mach_hp600.c
--- arch/sh/kernel/mach_hp600.c 2000/08/01 03:18:38 1.3
+++ arch/sh/kernel/mach_hp600.c 2000/08/03 08:11:21
@@ -61,3 +61,4 @@
mv_hw_hd64461: 1,
};
ALIAS_MV(hp600)
+REGISTER_MV(hp600)
Index: arch/sh/kernel/mach_se.c
===================================================================
RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/mach_se.c,v
retrieving revision 1.1
diff -u -r1.1 mach_se.c
--- arch/sh/kernel/mach_se.c 2000/07/31 12:30:17 1.1
+++ arch/sh/kernel/mach_se.c 2000/08/03 08:11:21
@@ -78,3 +78,4 @@
mv_hw_se: 1,
};
ALIAS_MV(se)
+REGISTER_MV(se)
Index: arch/sh/kernel/mach_unknown.c
===================================================================
RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/mach_unknown.c,v
retrieving revision 1.1
diff -u -r1.1 mach_unknown.c
--- arch/sh/kernel/mach_unknown.c 2000/07/31 12:30:36 1.1
+++ arch/sh/kernel/mach_unknown.c 2000/08/03 08:11:21
@@ -66,3 +66,4 @@
mv_isa_port2addr: unknown_isa_port2addr,
};
ALIAS_MV(unknown)
+REGISTER_MV(unknown)
Index: arch/sh/kernel/setup.c
===================================================================
RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/setup.c,v
retrieving revision 1.10
diff -u -r1.10 setup.c
--- arch/sh/kernel/setup.c 2000/08/01 03:18:38 1.10
+++ arch/sh/kernel/setup.c 2000/08/03 08:11:21
@@ -63,16 +64,6 @@
extern int root_mountflags;
extern int _text, _etext, _edata, _end;
-/* __attribute__(weak) doesn't appear to do anything */
-#define WEAK(X) \
- extern struct sh_machine_vector X; \
- asm(".weak "#X)
-
-WEAK(mv_unknown);
-WEAK(mv_hp600);
-WEAK(mv_od);
-WEAK(mv_se);
-
#define MV_NAME_SIZE 32
static struct sh_machine_vector* __init get_mv_byname(const char* name);
@@ -426,14 +471,11 @@
struct sh_machine_vector* __init get_mv_byname(const char* name)
{
extern int strcasecmp(const char *, const char *);
- static struct sh_machine_vector *all_vecs[] __initlocaldata =
- {
- &mv_hp600,
- &mv_od,
- &mv_se,
- };
+ extern long __machvec_start, __machvec_end;
+ struct sh_machine_vector **all_vecs =
+ (struct sh_machine_vector **)&__machvec_start;
- int i, n = sizeof(all_vecs)/sizeof(*all_vecs);
+ int i, n = (&__machvec_end - &__machvec_start);
for (i = 0; i < n; ++i) {
struct sh_machine_vector *mv = all_vecs[i];
Index: arch/sh/overdrive/mach.c
===================================================================
RCS file: /cvsroot/linuxsh/kernel/arch/sh/overdrive/mach.c,v
retrieving revision 1.1
diff -u -r1.1 mach.c
--- arch/sh/overdrive/mach.c 2000/07/31 12:38:20 1.1
+++ arch/sh/overdrive/mach.c 2000/08/03 08:11:21
@@ -71,3 +71,4 @@
};
ALIAS_MV(od)
+REGISTER_MV(od)
|