2008-06-20 20:31:01 +04:00
/* Kernel module help for powerpc.
Copyright ( C ) 2001 , 2003 Rusty Russell IBM Corporation .
Copyright ( C ) 2008 Freescale Semiconductor , Inc .
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 . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include <linux/elf.h>
# include <linux/moduleloader.h>
# include <linux/err.h>
# include <linux/vmalloc.h>
# include <linux/bug.h>
# include <asm/module.h>
# include <asm/uaccess.h>
# include <asm/firmware.h>
# include <linux/sort.h>
# include "setup.h"
LIST_HEAD ( module_bug_list ) ;
static const Elf_Shdr * find_section ( const Elf_Ehdr * hdr ,
const Elf_Shdr * sechdrs ,
const char * name )
{
char * secstrings ;
unsigned int i ;
secstrings = ( char * ) hdr + sechdrs [ hdr - > e_shstrndx ] . sh_offset ;
for ( i = 1 ; i < hdr - > e_shnum ; i + + )
if ( strcmp ( secstrings + sechdrs [ i ] . sh_name , name ) = = 0 )
return & sechdrs [ i ] ;
return NULL ;
}
int module_finalize ( const Elf_Ehdr * hdr ,
const Elf_Shdr * sechdrs , struct module * me )
{
const Elf_Shdr * sect ;
/* Apply feature fixups */
sect = find_section ( hdr , sechdrs , " __ftr_fixup " ) ;
if ( sect ! = NULL )
do_feature_fixups ( cur_cpu_spec - > cpu_features ,
( void * ) sect - > sh_addr ,
( void * ) sect - > sh_addr + sect - > sh_size ) ;
2008-12-18 22:13:32 +03:00
sect = find_section ( hdr , sechdrs , " __mmu_ftr_fixup " ) ;
if ( sect ! = NULL )
do_feature_fixups ( cur_cpu_spec - > mmu_features ,
( void * ) sect - > sh_addr ,
( void * ) sect - > sh_addr + sect - > sh_size ) ;
2008-06-20 20:31:01 +04:00
# ifdef CONFIG_PPC64
sect = find_section ( hdr , sechdrs , " __fw_ftr_fixup " ) ;
if ( sect ! = NULL )
do_feature_fixups ( powerpc_firmware_features ,
( void * ) sect - > sh_addr ,
( void * ) sect - > sh_addr + sect - > sh_size ) ;
# endif
2008-07-01 19:16:40 +04:00
sect = find_section ( hdr , sechdrs , " __lwsync_fixup " ) ;
if ( sect ! = NULL )
do_lwsync_fixups ( cur_cpu_spec - > cpu_features ,
( void * ) sect - > sh_addr ,
( void * ) sect - > sh_addr + sect - > sh_size ) ;
2008-06-20 20:31:01 +04:00
return 0 ;
}