|
From: Kenn H. <ke...@us...> - 2004-09-30 08:27:04
|
Update of /cvsroot/linux-vax/kernel-2.5/arch/vax/boot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27333/arch/vax/boot Modified Files: cpu_sel.c Log Message: Stuff the actual contents of the machvec_match structures into the relevant section, rather than pointers to them (simplifies the code). Also need to be careful about pointers to things in the kernel at this early stage of boot. In code, we've got MOVAx instructions with PC-relative addressing that are nicely position independent, but pointers embedded in data structures by the linker (such as machvec_match.mv) will always have S0-space addresses (such as 0x80123456). So, the new id_cpu function needs to correct for this before returning to the boot code. Was the first-cut matching stuff boot tested on KA46? I can't see how it would have worked :-) Index: cpu_sel.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.5/arch/vax/boot/cpu_sel.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- cpu_sel.c 29 Sep 2004 10:47:57 -0000 1.12 +++ cpu_sel.c 30 Sep 2004 08:26:55 -0000 1.13 @@ -5,14 +5,26 @@ * $Id$ */ -#include <asm/mtpr.h> /* Processor register definitions */ -#include <asm/mv.h> /* machine vector definitions */ -#include <asm/system.h> /* for HALT */ -#include <asm/vaxcpu.h> /* CPU type definitions */ - +#include <asm/mtpr.h> /* Processor register definitions */ +#include <asm/mv.h> /* machine vector definitions */ +#include <linux/mm.h> /* for PAGE_OFFSET and KERNEL_START_PHYS */ +#include <asm/system.h> /* for HALT */ +#include <asm/vaxcpu.h> /* CPU type definitions */ #ifdef USE_NEW_VECTORS -extern struct machvec_match __init_vecmatch_start, __init_vecmatch_end; + +/* + * Given a virtual address in the final kernel image (i.e. an S0 + * address like 0x80123456, convert it to the corresponding address + * in the loaded kernel before we relocate (which depends on the + * exact load address) + */ +void * +s0vmaddr_to_load_addr(void *vaddr) +{ + extern char _stext; + return (char *)vaddr - PAGE_OFFSET - KERNEL_START_PHYS + (unsigned int) &_stext; +} struct vax_mv * idcpu (void) @@ -20,10 +32,20 @@ unsigned long sid; unsigned long sidex; struct machvec_match *mvm; + unsigned int i; + unsigned int num_matches; + struct vax_mv *retmv; + + extern struct machvec_match __init_vecmatch_start, __init_vecmatch_end; sid = __mfpr (PR_SID); - for (mvm = &__init_vecmatch_start; mvm < &__init_vecmatch_end; mvm++) { + num_matches = &__init_vecmatch_end - &__init_vecmatch_start; + + for (i = 0; i < num_matches; i++) { + + mvm = &__init_vecmatch_start + i; + if ((sid & mvm->sid_mask) == mvm->sid_match) { /* * No sidex known? Accept the vector. @@ -32,15 +54,16 @@ * entries with weaker/shorter masks */ if (!mvm->sidex_addr) - return mvm->mv; + return s0vmaddr_to_load_addr(mvm->mv); /* * If a SIDEX match was supplied, too, check it! */ sidex = * ((unsigned long *) mvm->sidex_addr); if ((sidex & mvm->sidex_mask) == mvm->sidex_match) { - mvm->mv->sidex = sidex; - return mvm->mv; + retmv = s0vmaddr_to_load_addr(mvm->mv); + retmv->sidex = sidex; + return retmv; } } } |