1
/******************************************************************************
2
* Copyright (c) 2004, 2008 IBM Corporation
4
* This program and the accompanying materials
5
* are made available under the terms of the BSD License
6
* which accompanies this distribution, and is available at
7
* http://www.opensource.org/licenses/bsd-license.php
10
* IBM Corporation - initial implementation
11
*****************************************************************************/
14
#include <southbridge.h>
16
#if !defined(DISABLE_NVRAM) && !defined(RTAS_NVRAM)
18
// detect overflow: if(a<b) return a else return 0
19
#define NVRAM_LOG_DATA_OVERFLOW( a, b) \
25
// get Pointer(pointer) to next byte in NVRAM data section
26
// and size of this data sechtion (modulo)
27
// modifies register pointer, modulo
28
#define NVRAM_POINTER_DATASIZE_BE0(pointer, modulo, address) \
29
LOAD64( modulo, LLFW_LOG_BE0_LENGTH); \
30
lwz pointer, LLFW_LOG_POS_POINTER(address); \
31
sldi modulo, modulo, 4; \
32
addi modulo, modulo,-LLFW_LOG_BE0_DATA_OFFSET
33
#define NVRAM_POINTER_DATASIZE_BE1(pointer, modulo, address) \
34
LOAD64( modulo, LLFW_LOG_BE1_LENGTH); \
35
lwz pointer, LLFW_LOG_POS_POINTER(address); \
36
sldi modulo, modulo, 4; \
37
addi modulo, modulo,-LLFW_LOG_BE1_DATA_OFFSET
39
/****************************************************************************
41
* compare the fixed values in the header if any change was done since
42
* last initialisation.
43
* Flags are not checked!
45
* Retrun 0 if no manimulation was found 1 else
48
* r3 - NVRAM Base Address
51
* r3 - status: 0 = ok, 1 = corrupt
52
* r4 - NVRAM Base Address
54
***************************************************************************/
55
ASM_ENTRY(checkLogHeaderData)
56
li r4, 0 // init error flag
57
lbz r5, 0(r3) // check signature
58
addi r5, r5, -LLFW_LOG_BE0_SIGNATURE
61
lhz r5, LLFW_LOG_POS_LENGTH(r3) // check length
62
addi r5, r5, -LLFW_LOG_BE0_LENGTH
65
lwz r5, LLFW_LOG_POS_NAME(r3) // check name prefix
66
LOAD64( r6, LLFW_LOG_BE0_NAME_PREFIX)
70
ld r5, (LLFW_LOG_POS_NAME+4)(r3) // check name
71
LOAD64( r6, LLFW_LOG_BE0_NAME)
75
lhz r5, LLFW_LOG_POS_DATA_OFFSET(r3) //check data offset
76
addi r5, r5, -LLFW_LOG_BE0_DATA_OFFSET
79
lhz r5, LLFW_LOG_POS_FLAGS(r3) //check flags
80
addi r5, r5, -LLFW_LOG_BE0_FLAGS
91
/*****************************************************************************
92
* checkLogPartition: check Partition Header entries and Checksum
93
* check also the NVRAM-Log-Partition CRC
94
* if Partition is not ok set the following bits to 1
95
* bit 1: if Partiton Header Checksum is corrupt
96
* bit 2: if CRC is corrupt
97
* bit 3: if Header entries are corrupt
100
* r3 - NVRAM log address (BASE + NVRAM_LOG_OFFSET)
104
* r4 - NVRAM log address
106
* Modifies Register: R3, R4, R5, R6, R7, R8, R9
107
****************************************************************************/
108
ASM_ENTRY(.checkLogPartition)
110
mr r4, r3 // emulate "bl updateCRC_NVRAM"
111
li r3, 0 // with successful CRC check
118
bl .calPartitionHeaderChecksum // r3=checksum, r4=NVARM addr
119
lbz r6, LLFW_LOG_POS_CHECKSUM(r4)
121
beq+ 7, 0f // cal checksum must eq checksum
126
ori r7, r7, 1 // 0 as checksum is invalid
129
bl checkLogHeaderData
137
/*****************************************************************************
138
* checkinitLog: check the NVRAM Log Partition Header
139
* initialize the NVRAM if the Header was modified
142
* r3 - NVRAM BASE address
145
* r3 - 0 = check ok, no new header written
146
* r3 - 1 = check not ok, header and NVRAM initialized
147
* r4 - NVRAM log address
149
* Modifies Register: R3, R4, R5, R6, R7, r8, r9
150
****************************************************************************/
151
// init is done if checkLogPartiton returns not 0 (= check failed)
152
ASM_ENTRY(.checkinitLog)
153
ASM_ENTRY(checkinitLog)
155
bl .checkLogPartition //r3..r8, r4_out = r3_in
159
mr r3, r4 // r3=NVRAM_LOG address
160
bne- 7, .initLog // if header is not ok, init header
162
blr // header OK, return 0
165
/* this is basically just a copy of .initLog
166
registers used: r3, r4, r5, r6, r7, r9*/
169
li r6, LLFW_LOG_BE0_LENGTH
172
li r5, LLFW_LOG_BE1_SIGNATURE
173
li r4, LLFW_LOG_BE1_LENGTH
175
sth r4, LLFW_LOG_POS_LENGTH(r6)
176
li r5, LLFW_LOG_BE1_DATA_OFFSET
177
li r4, LLFW_LOG_BE1_FLAGS
178
sth r5, LLFW_LOG_POS_DATA_OFFSET(r6)
179
sth r4, LLFW_LOG_POS_FLAGS(r6)
182
LOAD32( r4, LLFW_LOG_BE1_NAME_PREFIX)
183
stw r5, LLFW_LOG_POS_POINTER(r6)
184
stw r4, (LLFW_LOG_POS_NAME+0x00)(r6)
185
LOAD64( r5, LLFW_LOG_BE1_NAME)
186
std r5, (LLFW_LOG_POS_NAME+0x04)(r6)
188
bl .calPartitionHeaderChecksum
189
stb r3, LLFW_LOG_POS_CHECKSUM(r6)
192
/*****************************************************************************
193
* initLog: initialize the NVRAM with 0
194
* write a new NVRAM Log-Partition-Header
197
* r3 - NVRAM BASE address
200
* r3 - 0 = check ok, no new header written
201
* r3 - 1 = check not ok, header and NVRAM initialized
202
* r4 - NVRAM log address
204
* Modifies Register: R3, R4, R5, R6, R7, r8, r9
205
****************************************************************************/
212
li r5, LLFW_LOG_BE0_SIGNATURE
213
li r4, LLFW_LOG_BE0_LENGTH
215
sth r4, LLFW_LOG_POS_LENGTH(r7)
216
li r5, LLFW_LOG_BE0_DATA_OFFSET
217
li r4, LLFW_LOG_BE0_FLAGS
218
sth r5, LLFW_LOG_POS_DATA_OFFSET(r7)
219
sth r4, LLFW_LOG_POS_FLAGS(r7)
222
LOAD32( r4, LLFW_LOG_BE0_NAME_PREFIX)
223
stw r5, LLFW_LOG_POS_POINTER(r7)
224
stw r4, (LLFW_LOG_POS_NAME+0x00)(r7)
225
LOAD64( r5, LLFW_LOG_BE0_NAME)
226
std r5, (LLFW_LOG_POS_NAME+0x04)(r7)
227
bl .calPartitionHeaderChecksum
228
stb r3, LLFW_LOG_POS_CHECKSUM(r7)
229
bl init_log_2nd_be // create a second log partition for BE1
234
/*****************************************************************************
235
* clearNVRAM: set all not used NVRAM memory to zero
239
* R3 - NVRAM BASE ADDRESS
242
* R3 - NVARM END ADDRESS
244
* Modifies Register: r4, r5
245
****************************************************************************/
246
ASM_ENTRY(clearNVRAM)
247
LOAD64( r4, NVRAM_LENGTH)
251
LOAD64( r4, NVRAM_EMPTY_PATTERN)
257
/*****************************************************************************
258
* writeNVRAMbyte: write next log into NVRAM
262
* R3 - byte to be written
263
* R4 - NVRAM Base Address
266
* R3 - byte that was written
267
* R4 - NVRAM Base Address
269
* Modifies Register: R3, R4, R5, R6
270
****************************************************************************/
271
ASM_ENTRY(.writeNVRAMbyte)
273
NVRAM_POINTER_DATASIZE_BE0( r5, r6, r4) // get pointer,size of data
274
NVRAM_LOG_DATA_OVERFLOW( r5, r6) // check for overflow
275
addi r5, r5, 1 // increment pointer
276
stw r5, LLFW_LOG_POS_POINTER(r4) // store pointer
277
addi r5, r5, -1 // restore old pointer
278
add r6, r4, r5 // byte address in data section
280
stb r3, LLFW_LOG_BE0_DATA_OFFSET(r6)
283
/*****************************************************************************
284
* writeNVRAMbyte: write next log into NVRAM
288
* R3 - byte to be written
289
* R4 - NVRAM Base Address
292
* R3 - byte that was written
293
* R4 - NVRAM Base Address
295
* Modifies Register: R3, R4, R5, R6
296
****************************************************************************/
297
ENTRY(writeLogByteBE1)
298
li r6, LLFW_LOG_BE0_LENGTH
301
NVRAM_POINTER_DATASIZE_BE1( r5, r6, r4) // get pointer,size of data
302
NVRAM_LOG_DATA_OVERFLOW( r5, r6) // check for overflow
303
addi r5, r5, 1 // increment pointer
304
stw r5, LLFW_LOG_POS_POINTER(r4) // store pointer
305
addi r5, r5, -1 // restore old pointer
306
add r6, r4, r5 // byte address in data section
308
stb r3, LLFW_LOG_BE1_DATA_OFFSET(r6)
311
/*****************************************************************************
312
* calPartitionHeaderChecksum: calculate the Checksum of the
313
* Partition Header as described in ....
315
* input: r3 - NVRAM BASE adresse
317
* output: R3 - the calculated checksum as 8 bit value
318
* R4 - NVRAM log address
320
* Modifies Register: R3, R4, R5, R6
321
****************************************************************************/
322
ASM_ENTRY(.calPartitionHeaderChecksum)
324
lbz r3,0(r6) // load first byte
325
LOAD64( r4, LLFW_LOG_POS_LENGTH) // load position of 3rd byte
327
lbzx r5, r4, r6 // r5 nexed byte
328
addi r4, r4, 1 // r4++ (index)
329
add r5, r5, r3 // r5 new sum =sum + nexed byte
332
cmpldi 6, r4, LLFW_LOG_POS_DATA_OFFSET
333
bge+ 7,.L5 // if new sum > sum
334
addi r5, r5, 1 // new sum ++
337
mr r3,r5 // sum = new sum
343
#else /* defined(DISABLE_NVRAM) || defined(RTAS_NVRAM) */
345
ASM_ENTRY(.writeNVRAMbyte)