2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted (subject to the limitations in the
7 * disclaimer below) provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
17 * * Neither the name of Qualcomm Atheros nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
22 * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
23 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 /*************************************************************************/
36 /* Copyright (c) 2008 Atheros Communications, Inc., All Rights Reserved */
38 /* Module Name : cmnos_rompatch.c */
41 /* This file contains rom code patch mechanism, patch code is */
42 /* offline generated, and replace the indirect table function as we */
48 /*************************************************************************/
52 #include "athos_api.h"
54 #if SYSTEM_MODULE_ROM_PATCH
57 LOCAL BOOLEAN _patch_dump( struct rom_patch_st *patch);
58 LOCAL BOOLEAN _read_rom_patch(struct rom_patch_st *patch);
61 // the patch install entry
62 void (*patch_start)(void);
64 // the eep redirect addr
65 struct eep_redir_addr patch_addr = {0x0, 0x0};
69 BOOLEAN _patch_dump( struct rom_patch_st *patch)
71 // A_PRINTF("\tCRC: 0x%04x\n\r", patch->crc16);
72 A_PRINTF("\tsize: %d bytes\n\r", patch->len);
73 A_PRINTF("\tld_addr: 0x%08x\n\r", (uint32_t)patch->ld_addr);
74 A_PRINTF("\tfun_addr: 0x%08x\n\r", (uint32_t)patch->fun_addr);
80 BOOLEAN _read_rom_patch(struct rom_patch_st *patch)
82 BOOLEAN retVal = FALSE;
85 uint8_t *buf = ((uint8_t*)(patch)+(sizeof(struct rom_patch_st)-4)); //assign the patch code buffer, last 4 bytes is the data
87 /*! assign the load address of the patch
89 * - convert the address to dport address 0x4exxxx or 0x5xxxxx
91 //addr = (uint32_t *)((patch->ld_addr&(~0xc00000))|(0x400000));
92 addr = (uint8_t *)(patch->ld_addr);
93 if( (uint32_t)addr < SYS_D_RAM_REGION_0_BASE || (uint32_t)addr >= (SYS_D_RAM_REGION_0_BASE + SYS_RAM_SZIE) )
95 A_PRINTF("!address should be dport in ram's address, 0x%08x\n\r", (uint32_t)addr);
101 A_PRINTF("copy %d bytes from 0x%08x to 0x%08x", patch->len, (uint32_t)buf, (uint32_t)addr);
102 for(i=0; i<patch->len; i+=4) // word access
105 addr[i+2] = buf[i+1];
106 addr[i+1] = buf[i+2];
118 * decode and parse the rompatch code
120 * addr: the buffer in ram stored the downloaded buffer
123 BOOLEAN cmnos_romp_decode(uint32_t addr)
126 BOOLEAN retVal = FALSE;
127 struct rom_patch_st *patch;
130 A_PRINTF("[%s+]\n\r", __FUNCTION__ );
133 * check the integrity of the buffer
135 uint32_t *mData = (uint32_t *)addr;
136 uint32_t CheckSum = 0;
138 // size at here is a half-word based, divide by 2 set it to a word
139 for(i=0; i<(patch_addr.size/2); i++, mData++)
140 CheckSum = CheckSum ^ *mData;
142 A_PRINTF("CheckSum: 0x%08x\n\r", CheckSum);
147 /*********************************************/
149 patch = (struct rom_patch_st *)addr;
151 func_addr = (uint8_t *)patch->fun_addr;
153 if( _read_rom_patch(patch) )
155 //A_PRINTF("\n\r patch to 0x%08x, func at 0x%08x\n\r", (uint32_t)patch->ld_addr, (uint32_t)func_addr);
157 // the patch function entry, call install later
158 patch_start = (void *)func_addr;
160 // install the patch here
165 A_PRINTF("patch decode fail!\n\r");
173 A_PRINTF("[%s-]\n\r", __FUNCTION__ );
177 // if crc checking is ok, move code the where it belong according to it's ld_addr
186 LOCAL BOOLEAN cmnos_romp_install(void)
188 /* TBD: to be removed! */
190 /*! call the patch function,
192 * - left the patch install did by the patch code,
193 * so that we sould build the patch code with entry function is the install process
194 * e.g void install_patch(void), which update the function table
197 //A_PRINTF("[%s+]\n\r", __FUNCTION__);
199 //A_PRINTF("[%s-]\n\r", __FUNCTION__);
205 * offset: the offset of the eeprom redirect header(offset, size)
208 LOCAL BOOLEAN cmnos_romp_download(uint16_t offset)
210 BOOLEAN retVal = FALSE;
213 uint16_t eep_start_ofst = EEPROM_START_OFFSET;
214 uint16_t eep_end_ofst = EEPROM_END_OFFSET;
216 A_PRINTF("[%s+]\n\r", __FUNCTION__ );
218 /* TBD: to be removed! */
219 /* read the patch from EEPROM, if there is an EEPROM exist and patch code stored inside */
222 * 1. read the fixed offset address of 0xfc and find the exactly patch code is
223 * 2. read the patch code from eeprom and write to buffer ram
224 * ------------------- leave it to decode operation ------------------
225 * 3. and check the integrity of it, if the integrity is ok, goto 4
226 * 4. decode the patch pack and decode each patch code and write them to the RAM
231 * read the eep redirect(offset, size) from the offset
233 if( RET_SUCCESS != A_EEP_READ(offset, sizeof(struct eep_redir_addr)/sizeof(uint16_t), buf) )
236 A_PRINTF("patch.offset: 0x%04x, patch.size : 0x%04x\n\r", buf[0], buf[1]);
238 patch_addr.offset = buf[0];
239 patch_addr.size = buf[1];
241 // ATHR : 0x41544852, ((uint32_t)patch_addr == 0x41544852) ||
242 // size == 0, offset > 0x3fff or offset < 0x2000, eeprom offset is between 0x2000~0x3fff
243 if( (patch_addr.size == 0x0) ||(patch_addr.offset < eep_start_ofst ) \
244 || (patch_addr.offset > eep_end_ofst) || ((patch_addr.offset+patch_addr.size) > eep_end_ofst))
247 // read the patch code to ROM_PATCH_BUF_ADDR: 0x51E000,
248 A_EEP_READ(patch_addr.offset, patch_addr.size, (uint16_t *)ROM_PATCH_BUF_ADDR);
250 if( A_ROMP_DECODE(ROM_PATCH_BUF_ADDR) )
259 A_PRINTF("[%s-]\n\r", __FUNCTION__ );
267 LOCAL void cmnos_romp_init(void)
269 /* TBD: to be removed! */
270 //A_PRINTF("CMNOS_ROMP_INIT!\n\r");
274 cmnos_romp_module_install(struct romp_api *tbl)
276 tbl->_romp_init = cmnos_romp_init;
277 tbl->_romp_download = cmnos_romp_download;
278 tbl->_romp_install = cmnos_romp_install;
279 tbl->_romp_decode = cmnos_romp_decode;