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) |