static void vecAlignSpTaskCreateHook (WIND_TCB *tcb) { unsigned long new_sp; new_sp = tcb->regs.spReg; /* Note: that the stack chain that runs through the internal */ /* kernel routines at the start of the task is 16 byte unaligned, */ /* so we need to unalign the stack here rather than align it so */ /* that it is correctly 16 aligned when we enter our user code. */ /* Also, note that the manual advises using taskRegsGet/Set to */ /* access a task's regs in a safe fashion, but I think it is safe */ /* to ignore that advice at this point as the task is not actually */ /* up and running yet, so there are no MT issues to worry about. */ if (bsp_do_align) new_sp = (new_sp & ~0x0000000F) | 8; tcb->regs.spReg = new_sp; /* This is also where we might malloc some memory for saving altivec regs */ /* when we get around to making the compiler suitable for multitasking */ /* altivec applications. */ } static void vecAddBspTaskHooks (void) { /* Add a task hook so that new tasks are created with their stack */ /* pointers aligned to 16-bytes as required by the altivec */ /* extensions to the EABI spec */ taskCreateHookAdd ((FUNCPTR)vecAlignSpTaskCreateHook); } static inline unsigned int ppcArchMsrGet (void) { unsigned int result; asm volatile ("mfmsr %0" : "=r" (result) ); return(result); } static inline void ppcArchMsrSet (unsigned int val) { asm volatile ("mtmsr %0" : : "r" (val) ); } void vecInitAltivec (void) { /* Set MSR bit 6 (0=MSB) to enable the altivec unit */ ppcArchMsrSet (ppcArchMsrGet () | (1 << (31-6))); /* And add the task create hook to align the stack */ vecAddBspTaskHooks (); return; }