1*0044c42eSStefan Roese /* 2*0044c42eSStefan Roese * (C) Copyright 2010-2012 3*0044c42eSStefan Roese * Stefan Roese, DENX Software Engineering, sr@denx.de. 4*0044c42eSStefan Roese * 5*0044c42eSStefan Roese * See file CREDITS for list of people who contributed to this 6*0044c42eSStefan Roese * project. 7*0044c42eSStefan Roese * 8*0044c42eSStefan Roese * This program is free software; you can redistribute it and/or 9*0044c42eSStefan Roese * modify it under the terms of the GNU General Public License as 10*0044c42eSStefan Roese * published by the Free Software Foundation; either version 2 of 11*0044c42eSStefan Roese * the License, or (at your option) any later version. 12*0044c42eSStefan Roese * 13*0044c42eSStefan Roese * This program is distributed in the hope that it will be useful, 14*0044c42eSStefan Roese * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*0044c42eSStefan Roese * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*0044c42eSStefan Roese * GNU General Public License for more details. 17*0044c42eSStefan Roese * 18*0044c42eSStefan Roese * You should have received a copy of the GNU General Public License 19*0044c42eSStefan Roese * along with this program; if not, write to the Free Software 20*0044c42eSStefan Roese * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21*0044c42eSStefan Roese * MA 02111-1307 USA 22*0044c42eSStefan Roese */ 23*0044c42eSStefan Roese 24*0044c42eSStefan Roese #include <bootcount.h> 25*0044c42eSStefan Roese #include <linux/compiler.h> 26*0044c42eSStefan Roese 27*0044c42eSStefan Roese /* 28*0044c42eSStefan Roese * Only override CONFIG_SYS_BOOTCOUNT_ADDR if not already defined. This 29*0044c42eSStefan Roese * way, some boards can define it directly in their config header. 30*0044c42eSStefan Roese */ 31*0044c42eSStefan Roese #if !defined(CONFIG_SYS_BOOTCOUNT_ADDR) 32*0044c42eSStefan Roese 33*0044c42eSStefan Roese #if defined(CONFIG_MPC5xxx) 34*0044c42eSStefan Roese #define CONFIG_SYS_BOOTCOUNT_ADDR (MPC5XXX_CDM_BRDCRMB) 35*0044c42eSStefan Roese #define CONFIG_SYS_BOOTCOUNT_SINGLEWORD 36*0044c42eSStefan Roese #endif /* defined(CONFIG_MPC5xxx) */ 37*0044c42eSStefan Roese 38*0044c42eSStefan Roese #if defined(CONFIG_MPC512X) 39*0044c42eSStefan Roese #define CONFIG_SYS_BOOTCOUNT_ADDR (&((immap_t *)CONFIG_SYS_IMMR)->clk.bcr) 40*0044c42eSStefan Roese #define CONFIG_SYS_BOOTCOUNT_SINGLEWORD 41*0044c42eSStefan Roese #endif /* defined(CONFIG_MPC512X) */ 42*0044c42eSStefan Roese 43*0044c42eSStefan Roese #if defined(CONFIG_8xx) 44*0044c42eSStefan Roese #define CONFIG_SYS_BOOTCOUNT_ADDR (((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_dpmem + \ 45*0044c42eSStefan Roese CPM_BOOTCOUNT_ADDR) 46*0044c42eSStefan Roese #endif /* defined(CONFIG_8xx) */ 47*0044c42eSStefan Roese 48*0044c42eSStefan Roese #if defined(CONFIG_MPC8260) 49*0044c42eSStefan Roese #include <asm/cpm_8260.h> 50*0044c42eSStefan Roese 51*0044c42eSStefan Roese #define CONFIG_SYS_BOOTCOUNT_ADDR (CONFIG_SYS_IMMR + CPM_BOOTCOUNT_ADDR) 52*0044c42eSStefan Roese #endif /* defined(CONFIG_MPC8260) */ 53*0044c42eSStefan Roese 54*0044c42eSStefan Roese #if defined(CONFIG_QE) 55*0044c42eSStefan Roese #include <asm/immap_qe.h> 56*0044c42eSStefan Roese 57*0044c42eSStefan Roese #define CONFIG_SYS_BOOTCOUNT_ADDR (CONFIG_SYS_IMMR + 0x110000 + \ 58*0044c42eSStefan Roese QE_MURAM_SIZE - 2 * sizeof(u32)) 59*0044c42eSStefan Roese #endif /* defined(CONFIG_MPC8360) */ 60*0044c42eSStefan Roese 61*0044c42eSStefan Roese #if defined(CONFIG_4xx) 62*0044c42eSStefan Roese #define CONFIG_SYS_BOOTCOUNT_ADDR (CONFIG_SYS_OCM_DATA_ADDR + \ 63*0044c42eSStefan Roese CONFIG_SYS_BOOTCOUNT_ADDR) 64*0044c42eSStefan Roese #endif /* defined(CONFIG_4xx) */ 65*0044c42eSStefan Roese 66*0044c42eSStefan Roese #endif /* !defined(CONFIG_SYS_BOOTCOUNT_ADDR) */ 67*0044c42eSStefan Roese 68*0044c42eSStefan Roese /* Now implement the generic default functions */ 69*0044c42eSStefan Roese #if defined(CONFIG_SYS_BOOTCOUNT_ADDR) 70*0044c42eSStefan Roese __weak void bootcount_store(ulong a) 71*0044c42eSStefan Roese { 72*0044c42eSStefan Roese void *reg = (void *)CONFIG_SYS_BOOTCOUNT_ADDR; 73*0044c42eSStefan Roese 74*0044c42eSStefan Roese #if defined(CONFIG_SYS_BOOTCOUNT_SINGLEWORD) 75*0044c42eSStefan Roese raw_bootcount_store(reg, (BOOTCOUNT_MAGIC & 0xffff0000) | a); 76*0044c42eSStefan Roese #else 77*0044c42eSStefan Roese raw_bootcount_store(reg, a); 78*0044c42eSStefan Roese raw_bootcount_store(reg + 4, BOOTCOUNT_MAGIC); 79*0044c42eSStefan Roese #endif 80*0044c42eSStefan Roese } 81*0044c42eSStefan Roese 82*0044c42eSStefan Roese __weak ulong bootcount_load(void) 83*0044c42eSStefan Roese { 84*0044c42eSStefan Roese void *reg = (void *)CONFIG_SYS_BOOTCOUNT_ADDR; 85*0044c42eSStefan Roese 86*0044c42eSStefan Roese #if defined(CONFIG_SYS_BOOTCOUNT_SINGLEWORD) 87*0044c42eSStefan Roese u32 tmp = raw_bootcount_load(reg); 88*0044c42eSStefan Roese 89*0044c42eSStefan Roese if ((tmp & 0xffff0000) != (BOOTCOUNT_MAGIC & 0xffff0000)) 90*0044c42eSStefan Roese return 0; 91*0044c42eSStefan Roese else 92*0044c42eSStefan Roese return (tmp & 0x0000ffff); 93*0044c42eSStefan Roese #else 94*0044c42eSStefan Roese if (raw_bootcount_load(reg + 4) != BOOTCOUNT_MAGIC) 95*0044c42eSStefan Roese return 0; 96*0044c42eSStefan Roese else 97*0044c42eSStefan Roese return raw_bootcount_load(reg); 98*0044c42eSStefan Roese #endif 99*0044c42eSStefan Roese } 100*0044c42eSStefan Roese #endif 101