1 /* 2 * Copyright 2008-2010 Freescale Semiconductor, Inc. 3 * 4 * See file CREDITS for list of people who contributed to this 5 * project. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of 10 * the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 * MA 02111-1307 USA 21 */ 22 23 #include <common.h> 24 #include <asm/processor.h> 25 #include <asm/mmu.h> 26 #include <ioports.h> 27 #include <lmb.h> 28 #include <asm/io.h> 29 #include <asm/mp.h> 30 31 DECLARE_GLOBAL_DATA_PTR; 32 33 int cpu_reset(int nr) 34 { 35 /* dummy function so common/cmd_mp.c will build 36 * should be implemented in the future, when cpu_release() 37 * is supported. Be aware there may be a similiar bug 38 * as exists on MPC85xx w/its PIC having a timing window 39 * associated to resetting the core */ 40 return 1; 41 } 42 43 int cpu_status(int nr) 44 { 45 /* dummy function so common/cmd_mp.c will build */ 46 return 0; 47 } 48 49 int cpu_disable(int nr) 50 { 51 volatile immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR; 52 volatile ccsr_gur_t *gur = &immap->im_gur; 53 54 switch (nr) { 55 case 0: 56 setbits_be32(&gur->devdisr, MPC86xx_DEVDISR_CPU0); 57 break; 58 case 1: 59 setbits_be32(&gur->devdisr, MPC86xx_DEVDISR_CPU1); 60 break; 61 default: 62 printf("Invalid cpu number for disable %d\n", nr); 63 return 1; 64 } 65 66 return 0; 67 } 68 69 int cpu_release(int nr, int argc, char *argv[]) 70 { 71 /* dummy function so common/cmd_mp.c will build 72 * should be implemented in the future */ 73 return 1; 74 } 75 76 u32 determine_mp_bootpg(void) 77 { 78 /* if we have 4G or more of memory, put the boot page at 4Gb-1M */ 79 if ((u64)gd->ram_size > 0xfffff000) 80 return (0xfff00000); 81 82 return (gd->ram_size - (1024 * 1024)); 83 } 84 85 void cpu_mp_lmb_reserve(struct lmb *lmb) 86 { 87 u32 bootpg = determine_mp_bootpg(); 88 89 /* tell u-boot we stole a page */ 90 lmb_reserve(lmb, bootpg, 4096); 91 } 92 93 /* 94 * Copy the code for other cpus to execute into an 95 * aligned location accessible via BPTR 96 */ 97 void setup_mp(void) 98 { 99 extern ulong __secondary_start_page; 100 ulong fixup = (ulong)&__secondary_start_page; 101 u32 bootpg = determine_mp_bootpg(); 102 u32 bootpg_va; 103 104 if (bootpg >= CONFIG_SYS_MAX_DDR_BAT_SIZE) { 105 /* We're not covered by the DDR mapping, set up BAT */ 106 write_bat(DBAT7, CONFIG_SYS_SCRATCH_VA | BATU_BL_128K | 107 BATU_VS | BATU_VP, 108 bootpg | BATL_PP_RW | BATL_MEMCOHERENCE); 109 bootpg_va = CONFIG_SYS_SCRATCH_VA; 110 } else { 111 bootpg_va = bootpg; 112 } 113 114 memcpy((void *)bootpg_va, (void *)fixup, 4096); 115 flush_cache(bootpg_va, 4096); 116 117 /* remove the temporary BAT mapping */ 118 if (bootpg >= CONFIG_SYS_MAX_DDR_BAT_SIZE) 119 write_bat(DBAT7, 0, 0); 120 121 /* If the physical location of bootpg is not at fff00000, set BPTR */ 122 if (bootpg != 0xfff00000) 123 out_be32((uint *)(CONFIG_SYS_CCSRBAR + 0x20), 0x80000000 | 124 (bootpg >> 12)); 125 } 126