1 /*************************************************************************/
2 /* Copyright (c) 2008 Atheros Communications, Inc., All Rights Reserved */
4 /* Module Name : cmnos_rompatch.c */
7 /* This file contains rom code patch mechanism, patch code is */
8 /* offline generated, and replace the indirect table function as we */
14 /*************************************************************************/
18 #include "athos_api.h"
20 #if SYSTEM_MODULE_ROM_PATCH
23 LOCAL BOOLEAN _patch_dump( struct rom_patch_st *patch);
24 LOCAL BOOLEAN _read_rom_patch(struct rom_patch_st *patch);
27 // the patch install entry
28 void (*patch_start)(void);
30 // the eep redirect addr
31 struct eep_redir_addr patch_addr = {0x0, 0x0};
35 BOOLEAN _patch_dump( struct rom_patch_st *patch)
37 // A_PRINTF("\tCRC: 0x%04x\n\r", patch->crc16);
38 A_PRINTF("\tsize: %d bytes\n\r", patch->len);
39 A_PRINTF("\tld_addr: 0x%08x\n\r", (uint32_t)patch->ld_addr);
40 A_PRINTF("\tfun_addr: 0x%08x\n\r", (uint32_t)patch->fun_addr);
46 BOOLEAN _read_rom_patch(struct rom_patch_st *patch)
48 BOOLEAN retVal = FALSE;
51 uint8_t *buf = ((uint8_t*)(patch)+(sizeof(struct rom_patch_st)-4)); //assign the patch code buffer, last 4 bytes is the data
53 /*! assign the load address of the patch
55 * - convert the address to dport address 0x4exxxx or 0x5xxxxx
57 //addr = (uint32_t *)((patch->ld_addr&(~0xc00000))|(0x400000));
58 addr = (uint8_t *)(patch->ld_addr);
59 if( (uint32_t)addr < SYS_D_RAM_REGION_0_BASE || (uint32_t)addr >= (SYS_D_RAM_REGION_0_BASE + SYS_RAM_SZIE) )
61 A_PRINTF("!address should be dport in ram's address, 0x%08x\n\r", (uint32_t)addr);
67 A_PRINTF("copy %d bytes from 0x%08x to 0x%08x", patch->len, (uint32_t)buf, (uint32_t)addr);
68 for(i=0; i<patch->len; i+=4) // word access
84 * decode and parse the rompatch code
86 * addr: the buffer in ram stored the downloaded buffer
89 BOOLEAN cmnos_romp_decode(uint32_t addr)
92 BOOLEAN retVal = FALSE;
93 struct rom_patch_st *patch;
96 A_PRINTF("[%s+]\n\r", __FUNCTION__ );
99 * check the integrity of the buffer
101 uint32_t *mData = (uint32_t *)addr;
102 uint32_t CheckSum = 0;
104 // size at here is a half-word based, divide by 2 set it to a word
105 for(i=0; i<(patch_addr.size/2); i++, mData++)
106 CheckSum = CheckSum ^ *mData;
108 A_PRINTF("CheckSum: 0x%08x\n\r", CheckSum);
113 /*********************************************/
115 patch = (struct rom_patch_st *)addr;
117 func_addr = (uint8_t *)patch->fun_addr;
119 if( _read_rom_patch(patch) )
121 //A_PRINTF("\n\r patch to 0x%08x, func at 0x%08x\n\r", (uint32_t)patch->ld_addr, (uint32_t)func_addr);
123 // the patch function entry, call install later
124 patch_start = (void *)func_addr;
126 // install the patch here
131 A_PRINTF("patch decode fail!\n\r");
139 A_PRINTF("[%s-]\n\r", __FUNCTION__ );
143 // if crc checking is ok, move code the where it belong according to it's ld_addr
152 LOCAL BOOLEAN cmnos_romp_install(void)
154 /* TBD: to be removed! */
156 /*! call the patch function,
158 * - left the patch install did by the patch code,
159 * so that we sould build the patch code with entry function is the install process
160 * e.g void install_patch(void), which update the function table
163 //A_PRINTF("[%s+]\n\r", __FUNCTION__);
165 //A_PRINTF("[%s-]\n\r", __FUNCTION__);
171 * offset: the offset of the eeprom redirect header(offset, size)
174 LOCAL BOOLEAN cmnos_romp_download(uint16_t offset)
176 BOOLEAN retVal = FALSE;
179 uint16_t eep_start_ofst = EEPROM_START_OFFSET;
180 uint16_t eep_end_ofst = EEPROM_END_OFFSET;
182 A_PRINTF("[%s+]\n\r", __FUNCTION__ );
184 /* TBD: to be removed! */
185 /* read the patch from EEPROM, if there is an EEPROM exist and patch code stored inside */
188 * 1. read the fixed offset address of 0xfc and find the exactly patch code is
189 * 2. read the patch code from eeprom and write to buffer ram
190 * ------------------- leave it to decode operation ------------------
191 * 3. and check the integrity of it, if the integrity is ok, goto 4
192 * 4. decode the patch pack and decode each patch code and write them to the RAM
197 * read the eep redirect(offset, size) from the offset
199 if( RET_SUCCESS != A_EEP_READ(offset, sizeof(struct eep_redir_addr)/sizeof(uint16_t), buf) )
202 A_PRINTF("patch.offset: 0x%04x, patch.size : 0x%04x\n\r", buf[0], buf[1]);
204 patch_addr.offset = buf[0];
205 patch_addr.size = buf[1];
207 // ATHR : 0x41544852, ((uint32_t)patch_addr == 0x41544852) ||
208 // size == 0, offset > 0x3fff or offset < 0x2000, eeprom offset is between 0x2000~0x3fff
209 if( (patch_addr.size == 0x0) ||(patch_addr.offset < eep_start_ofst ) \
210 || (patch_addr.offset > eep_end_ofst) || ((patch_addr.offset+patch_addr.size) > eep_end_ofst))
213 // read the patch code to ROM_PATCH_BUF_ADDR: 0x51E000,
214 A_EEP_READ(patch_addr.offset, patch_addr.size, (uint16_t *)ROM_PATCH_BUF_ADDR);
216 if( A_ROMP_DECODE(ROM_PATCH_BUF_ADDR) )
225 A_PRINTF("[%s-]\n\r", __FUNCTION__ );
233 LOCAL void cmnos_romp_init(void)
235 /* TBD: to be removed! */
236 //A_PRINTF("CMNOS_ROMP_INIT!\n\r");
240 cmnos_romp_module_install(struct romp_api *tbl)
242 tbl->_romp_init = cmnos_romp_init;
243 tbl->_romp_download = cmnos_romp_download;
244 tbl->_romp_install = cmnos_romp_install;
245 tbl->_romp_decode = cmnos_romp_decode;