~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/SLOF/llfw/nvramlog.S

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 * Copyright (c) 2004, 2008 IBM Corporation
 
3
 * All rights reserved.
 
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
 
8
 *
 
9
 * Contributors:
 
10
 *     IBM Corporation - initial implementation
 
11
 *****************************************************************************/
 
12
#include <macros.h>
 
13
#include <nvramlog.h>
 
14
#include <southbridge.h>
 
15
 
 
16
#if !defined(DISABLE_NVRAM) && !defined(RTAS_NVRAM)
 
17
 
 
18
// detect overflow: if(a<b)  return a else return 0
 
19
#define NVRAM_LOG_DATA_OVERFLOW( a, b) \
 
20
        cmpd    7, a, b; \
 
21
        blt+    7, 0f; \
 
22
        li      a, 0; \
 
23
        0:
 
24
 
 
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
 
38
 
 
39
/****************************************************************************
 
40
 *      checkLogHeaderData
 
41
 *      compare the fixed values in the header if any change was done since
 
42
 *      last initialisation.
 
43
 *      Flags are not checked!
 
44
 *
 
45
 *      Retrun 0 if no manimulation was found 1 else
 
46
 *
 
47
 *      input:
 
48
 *                      r3 - NVRAM Base Address 
 
49
 *
 
50
 *      output:
 
51
 *                      r3 - status: 0 = ok, 1 = corrupt
 
52
 *                      r4 - NVRAM Base Address
 
53
 *
 
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
 
59
        add     r4, r4, r5
 
60
 
 
61
        lhz     r5, LLFW_LOG_POS_LENGTH(r3)             // check length
 
62
        addi    r5, r5, -LLFW_LOG_BE0_LENGTH
 
63
        add     r4, r4, r5
 
64
 
 
65
        lwz     r5, LLFW_LOG_POS_NAME(r3)               // check name prefix
 
66
        LOAD64( r6, LLFW_LOG_BE0_NAME_PREFIX)
 
67
        subf    r5, r6, r5
 
68
        add     r4, r4, r5
 
69
 
 
70
        ld      r5, (LLFW_LOG_POS_NAME+4)(r3)           // check name
 
71
        LOAD64( r6, LLFW_LOG_BE0_NAME)
 
72
        subf    r5, r6, r5
 
73
        add     r4, r4, r5
 
74
        
 
75
        lhz     r5, LLFW_LOG_POS_DATA_OFFSET(r3)        //check data offset
 
76
        addi    r5, r5, -LLFW_LOG_BE0_DATA_OFFSET
 
77
        add     r4, r4, r5
 
78
 
 
79
        lhz     r5, LLFW_LOG_POS_FLAGS(r3)              //check flags
 
80
        addi    r5, r5, -LLFW_LOG_BE0_FLAGS
 
81
        add     r4, r4, r5
 
82
 
 
83
        cmpldi  7, r4, 0
 
84
        beq+    7, 0f
 
85
        li      r4, 1
 
86
0:
 
87
        mr      r5, r3
 
88
        mr      r3, r4
 
89
        mr      r4, r5
 
90
        blr
 
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
 
98
 *                                              
 
99
 *      input:  
 
100
 *              r3 - NVRAM log address (BASE + NVRAM_LOG_OFFSET)
 
101
 *
 
102
 *      output: 
 
103
 *              r3 - CRC status  
 
104
 *              r4 - NVRAM log address
 
105
 *
 
106
 *      Modifies Register:      R3, R4, R5, R6, R7, R8, R9
 
107
 ****************************************************************************/
 
108
ASM_ENTRY(.checkLogPartition)
 
109
        mflr    r8
 
110
        mr      r4, r3                  // emulate "bl updateCRC_NVRAM"
 
111
        li      r3, 0                   // with successful CRC check
 
112
        li      r7, 0
 
113
        cmpwi   7, r3, 0
 
114
        beq+    7, 0f
 
115
        li      r7, 2
 
116
0:
 
117
        mr      r3, r4
 
118
        bl      .calPartitionHeaderChecksum     // r3=checksum, r4=NVARM addr
 
119
        lbz     r6, LLFW_LOG_POS_CHECKSUM(r4)
 
120
        cmpw    7, r3, r6
 
121
        beq+    7, 0f                   // cal checksum must eq checksum
 
122
        ori     r7, r7, 1
 
123
0:
 
124
        cmpwi   7, r3, 0
 
125
        bne+    7, 0f
 
126
        ori     r7, r7, 1               // 0 as checksum is invalid
 
127
0:
 
128
        mr      r3, r4
 
129
        bl      checkLogHeaderData      
 
130
        cmpdi   7, r3, 0
 
131
        beq+    7, 0f
 
132
        ori     r7, r7, 4
 
133
0:
 
134
        mr      r3, r7
 
135
        mtlr    r8
 
136
        blr
 
137
/*****************************************************************************
 
138
 * checkinitLog:        check the NVRAM Log Partition Header 
 
139
 *                      initialize the NVRAM if the Header was modified
 
140
 *                                      
 
141
 *      input:  
 
142
 *              r3 - NVRAM BASE address 
 
143
 *
 
144
 *      output: 
 
145
 *              r3 - 0 = check ok, no new header written
 
146
 *              r3 - 1 = check not ok, header and NVRAM initialized
 
147
 *              r4 - NVRAM log address
 
148
 *
 
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)
 
154
        mflr    r9
 
155
        bl      .checkLogPartition              //r3..r8, r4_out = r3_in   
 
156
        mtlr    r9
 
157
        
 
158
        cmpwi   7, r3, 0
 
159
        mr      r3, r4                  // r3=NVRAM_LOG address
 
160
        bne-    7, .initLog             // if header is not ok, init header
 
161
        li      r3, 0
 
162
        blr                             // header OK, return 0                  
 
163
 
 
164
 
 
165
/* this is basically just a copy of .initLog 
 
166
   registers used: r3, r4, r5, r6, r7, r9*/
 
167
init_log_2nd_be:
 
168
        mflr    r9      
 
169
        li      r6, LLFW_LOG_BE0_LENGTH
 
170
        mulli   r6, r6, 0x10
 
171
        add     r6, r7, r6
 
172
        li      r5, LLFW_LOG_BE1_SIGNATURE
 
173
        li      r4, LLFW_LOG_BE1_LENGTH
 
174
        stb     r5, 0(r6)
 
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)
 
180
        li      r5, 1
 
181
 
 
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)
 
187
        mr      r3, r6
 
188
        bl      .calPartitionHeaderChecksum
 
189
        stb     r3, LLFW_LOG_POS_CHECKSUM(r6)
 
190
        mtlr    r9
 
191
        blr
 
192
/*****************************************************************************
 
193
 * initLog:     initialize the NVRAM with 0
 
194
 *              write a new NVRAM Log-Partition-Header
 
195
 *                                      
 
196
 *      input:  
 
197
 *              r3 - NVRAM BASE address 
 
198
 *
 
199
 *      output: 
 
200
 *              r3 - 0 = check ok, no new header written
 
201
 *              r3 - 1 = check not ok, header and NVRAM initialized
 
202
 *              r4 - NVRAM log address
 
203
 *
 
204
 *      Modifies Register:      R3, R4, R5, R6, R7, r8, r9
 
205
 ****************************************************************************/
 
206
ASM_ENTRY(.initLog)
 
207
        mflr    r8
 
208
        mr      r7, r3
 
209
 
 
210
        bl clearNVRAM
 
211
0:
 
212
        li      r5, LLFW_LOG_BE0_SIGNATURE
 
213
        li      r4, LLFW_LOG_BE0_LENGTH
 
214
        stb     r5, 0(r7)
 
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)
 
220
        li      r5, 1
 
221
 
 
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
 
230
        mr      r4, r7
 
231
        li      r3, 1
 
232
        mtlr    r8
 
233
        blr
 
234
/*****************************************************************************
 
235
 *      clearNVRAM:     set all not used NVRAM memory to zero
 
236
 *
 
237
 *
 
238
 *      input:  
 
239
 *              R3 - NVRAM BASE ADDRESS
 
240
 *
 
241
 *      output: 
 
242
 *              R3 - NVARM END ADDRESS
 
243
 *
 
244
 *      Modifies Register: r4, r5
 
245
 ****************************************************************************/
 
246
ASM_ENTRY(clearNVRAM)
 
247
        LOAD64( r4, NVRAM_LENGTH)
 
248
        srdi    r4, r4, 3
 
249
        mtctr   r4
 
250
        li      r5, 0x0
 
251
        LOAD64( r4, NVRAM_EMPTY_PATTERN)
 
252
0:
 
253
        stdx    r4, r3,r5
 
254
        addi    r5, r5, 8
 
255
        bdnz+   0b
 
256
        blr     
 
257
/*****************************************************************************
 
258
 * writeNVRAMbyte:      write next log into NVRAM
 
259
 *                                      
 
260
 *
 
261
 *      input:  
 
262
 *              R3 - byte to be written
 
263
 *              R4 - NVRAM Base Address
 
264
 *
 
265
 *      output: 
 
266
 *              R3 - byte that was written
 
267
 *              R4 - NVRAM Base Address 
 
268
 *
 
269
 *      Modifies Register:      R3, R4, R5, R6
 
270
 ****************************************************************************/
 
271
ASM_ENTRY(.writeNVRAMbyte)
 
272
ENTRY(writeLogByte)
 
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 
 
279
 
 
280
        stb     r3, LLFW_LOG_BE0_DATA_OFFSET(r6)        
 
281
        blr
 
282
 
 
283
/*****************************************************************************
 
284
 * writeNVRAMbyte:      write next log into NVRAM
 
285
 *                                      
 
286
 *
 
287
 *      input:  
 
288
 *              R3 - byte to be written
 
289
 *              R4 - NVRAM Base Address
 
290
 *
 
291
 *      output: 
 
292
 *              R3 - byte that was written
 
293
 *              R4 - NVRAM Base Address 
 
294
 *
 
295
 *      Modifies Register:      R3, R4, R5, R6
 
296
 ****************************************************************************/
 
297
ENTRY(writeLogByteBE1)
 
298
        li      r6, LLFW_LOG_BE0_LENGTH
 
299
        mulli   r6, r6, 0x10
 
300
        add     r4, r6, r4
 
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 
 
307
 
 
308
        stb     r3, LLFW_LOG_BE1_DATA_OFFSET(r6)        
 
309
        blr
 
310
 
 
311
/*****************************************************************************
 
312
 * calPartitionHeaderChecksum:  calculate the Checksum of the 
 
313
 *      Partition Header as described in ....
 
314
 *
 
315
 *      input: r3 - NVRAM BASE adresse
 
316
 *
 
317
 *      output: R3 - the calculated checksum as 8 bit value 
 
318
 *                      R4 - NVRAM log address
 
319
 *
 
320
 *      Modifies Register:      R3, R4, R5, R6
 
321
 ****************************************************************************/
 
322
ASM_ENTRY(.calPartitionHeaderChecksum)
 
323
        mr      r6, r3
 
324
        lbz     r3,0(r6)                        // load first byte
 
325
        LOAD64( r4, LLFW_LOG_POS_LENGTH)        // load position of 3rd byte
 
326
.L6:
 
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
 
330
        rldicl  r5, r5, 0, 56
 
331
        cmpld   7, r5, r3                                       
 
332
        cmpldi  6, r4, LLFW_LOG_POS_DATA_OFFSET
 
333
        bge+    7,.L5                           // if new sum > sum 
 
334
        addi    r5, r5, 1                       // new sum ++
 
335
        rldicl  r5, r5, 0, 56
 
336
.L5:
 
337
        mr      r3,r5                           // sum = new sum
 
338
        blt+    6,.L6
 
339
 
 
340
        mr r4, r6
 
341
        blr
 
342
 
 
343
#else   /* defined(DISABLE_NVRAM) || defined(RTAS_NVRAM) */
 
344
 
 
345
ASM_ENTRY(.writeNVRAMbyte)
 
346
        ENTRY(writeLogByte)
 
347
        blr
 
348
 
 
349
#endif