OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [mips/] [malta/] [current/] [src/] [platform.S] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
##
2
#=============================================================================
3
##      platform.S
4
##
5
##      MIPS Malta platform code
6
##
7
##=============================================================================
8
## ####ECOSGPLCOPYRIGHTBEGIN####
9
## -------------------------------------------
10
## This file is part of eCos, the Embedded Configurable Operating System.
11
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
12
##
13
## eCos is free software; you can redistribute it and/or modify it under
14
## the terms of the GNU General Public License as published by the Free
15
## Software Foundation; either version 2 or (at your option) any later
16
## version.
17
##
18
## eCos is distributed in the hope that it will be useful, but WITHOUT
19
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21
## for more details.
22
##
23
## You should have received a copy of the GNU General Public License
24
## along with eCos; if not, write to the Free Software Foundation, Inc.,
25
## 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26
##
27
## As a special exception, if other files instantiate templates or use
28
## macros or inline functions from this file, or you compile this file
29
## and link it with other works to produce a work based on this file,
30
## this file does not by itself cause the resulting work to be covered by
31
## the GNU General Public License. However the source code for this file
32
## must still be made available in accordance with section (3) of the GNU
33
## General Public License v2.
34
##
35
## This exception does not invalidate any other reasons why a work based
36
## on this file might be covered by the GNU General Public License.
37
## -------------------------------------------
38
## ####ECOSGPLCOPYRIGHTEND####
39
##=============================================================================
40
#######DESCRIPTIONBEGIN####
41
##
42
## Author(s):   dmoseley
43
## Contributors:dmoseley, jskov
44
## Date:        2001-03-20
45
## Purpose:     MIPS Malta platform code
46
## Description: Platform specific code for Malta board.
47
##
48
##
49
##
50
##
51
######DESCRIPTIONEND####
52
##
53
##=============================================================================
54
 
55
#include 
56
#include 
57
 
58
#ifdef CYGPKG_KERNEL
59
# include 
60
#endif
61
 
62
#include 
63
#include 
64
#include 
65
#include 
66
#include CYGBLD_HAL_PLATFORM_H
67
 
68
##-----------------------------------------------------------------------------
69
 
70
##-----------------------------------------------------------------------------
71
# Platform Initialization.
72
# This code performs platform specific initialization.
73
 
74
##-----------------------------------------------------------------------------
75
## I2C accessors - these need to delay after accessing the controller.
76
// Need to delay between clocking the serial bits since the CPU is way too
77
// fast for the I2C interface. CPU runs at CYGHWR_HAL_MIPS_MALTA_CPU_CLOCK
78
// and the I2C no fasten than 1.7MHz. We want to delay the CPU for half
79
// an I2C cycle and two instructions are executed per loop, hence:
80
 
81
#define PAUSE                                                      \
82
    li     t0, (20*(CYGHWR_HAL_MIPS_MALTA_CPU_CLOCK/1700000/2/2)); \
83
99: bne    t0, zero, 99b;                                          \
84
     addiu t0, -1
85
 
86
 
87
#define I2C_OE(v)              \
88
    li  t0,v;                  \
89
    sw  t0,HAL_I2CFPGA_OE(a1); \
90
    PAUSE
91
 
92
#define I2C_OUT(v)              \
93
    li  t0,v;                   \
94
    sw  t0,HAL_I2CFPGA_OUT(a1); \
95
    PAUSE
96
 
97
#define I2C_IN(v)                      \
98
    lw   v,HAL_I2CFPGA_INP(a1);        \
99
    andi v,v,HAL_I2CFPGA_IN_SDA_MASK;  \
100
    PAUSE
101
 
102
#define I2C_ENABLE                \
103
    I2C_OE(HAL_I2C_CIN_DIN);      \
104
    I2C_OUT(HAL_I2C_CHIGH_DHIGH); \
105
    li  t0,HAL_I2CFPGA_SEL_FPGA;  \
106
    sw  t0,HAL_I2CFPGA_SEL(a1);   \
107
    PAUSE
108
 
109
##-----------------------------------------------------------------------------
110
## MEMC initialization.
111
##
112
 
113
#if defined(CYG_HAL_STARTUP_ROM)
114
 
115
        .text
116
        .set    noreorder
117
 
118
.macro MASK_WRITE_PCI_REG regnum, devnum, mask
119
        .set noreorder
120
        # First, read the appropriate register
121
        li      t0, HAL_GALILEO_PCI0_CONFIG_ADDR_ConfigEn | \regnum | \devnum
122
        sw      t0, HAL_GALILEO_PCI0_CONFIG_ADDR_OFFSET(s7)
123
        lw      t1, HAL_GALILEO_PCI0_CONFIG_DATA_OFFSET(s7)
124
 
125
        # Now, mask in the appropriate bits
126
        li      t2, \mask
127
        or      t1, t2
128
 
129
        # Write the updated value
130
        li      t0, HAL_GALILEO_PCI0_CONFIG_ADDR_ConfigEn | \regnum | \devnum
131
        sw      t0, HAL_GALILEO_PCI0_CONFIG_ADDR_OFFSET(s7)
132
        sw      t1, HAL_GALILEO_PCI0_CONFIG_DATA_OFFSET(s7)
133
.endm
134
 
135
.macro WRITE_PCI_REG regnum, devnum, base
136
        .set noreorder
137
        li      t0, HAL_GALILEO_PCI0_CONFIG_ADDR_ConfigEn | \regnum | \devnum
138
        li      t1, \base
139
        sw      t0, HAL_GALILEO_PCI0_CONFIG_ADDR_OFFSET(s7)
140
        sw      t1, HAL_GALILEO_PCI0_CONFIG_DATA_OFFSET(s7)
141
.endm
142
 
143
#define NO_MASK        0
144
#define NO_ERROR_CHECK 0
145
#define ERROR_CHECK    1
146
.macro READ_SPD_VALUE func, mask, ret_reg, err_check
147
    .set noreorder
148
    jal   read_spd_value
149
     li   a0, \func                      # delay slot
150
.if \err_check
151
    beq   v0, zero, error
152
     nop
153
.endif
154
    move  \ret_reg, v0
155
.if \mask
156
    and   \ret_reg, \mask
157
.endif
158
.endm
159
 
160
##-----------------------------------------------------------------------------
161
##
162
## Initialize the RAM.
163
##
164
## To do that, we need to first initialize the Galileo PCI stuff to gain access
165
## to the SAA9730.
166
## From there, use the I2C bus of the SAA9730 to read the SPD SDRAM
167
## config data. We then setup the Galileo SDRAM configuration
168
##
169
##  Returns
170
##  v0 = Error Code
171
##  v1 = SDRAM size
172
##
173
FUNC_START(hal_malta_init_sdram)
174
 
175
        .set noreorder
176
 
177
        # Save the return address
178
        move    s8, ra
179
 
180
        # Setup the base address registers
181
        li      s7, CYGARC_UNCACHED_ADDRESS(HAL_GALILEO_REGISTER_BASE)
182
        #
183
        # Change the Galileo Base address to HAL_MALTA_CONTROLLER_BASE
184
        #
185
        li      t0, HAL_MALTA_CONTROLLER_BASE_ISD_CONFIG
186
        sw      t0, HAL_GALILEO_INT_SPACE_DECODE_OFFSET(s7)
187
        li      s7, CYGARC_UNCACHED_ADDRESS(HAL_MALTA_CONTROLLER_BASE)
188
 
189
        # Setup the Galileo controller Endian configuration
190
        li      t0, (HAL_GALILEO_BYTE_SWAP)
191
        sw      t0, HAL_GALILEO_PCI_INTERNAL_COMMAND_OFFSET(s7)
192
 
193
        # Setup the PCI_0 Timeout and retry configuration
194
        li      t0, HAL_GALILEO_PCI0_TIMEOUT_RETRY_VALUE
195
        sw      t0, HAL_GALILEO_PCI0_TIMEOUT_RETRY_OFFSET(s7)
196
 
197
        # Setup Galileo as PCI Master
198
        MASK_WRITE_PCI_REG HAL_GALILEO_PCI0_STATUS_COMMAND_REGNUM, HAL_MALTA_NULL_DEVNUM, \
199
                           (HAL_GALILEO_PCI0_CONFIG_MEMEn | HAL_GALILEO_PCI0_CONFIG_MasEn | HAL_GALILEO_PCI0_CONFIG_SErrEn)
200
 
201
        # Setup Galileo PCI latency timer
202
        MASK_WRITE_PCI_REG HAL_GALILEO_PCI0_BIST_REGNUM, HAL_MALTA_NULL_DEVNUM, \
203
                           HAL_GALILEO_PCI0_LAT_TIMER_VAL
204
 
205
        # Enable FPGA I2C
206
        li      a1, CYGARC_UNCACHED_ADDRESS(HAL_I2CFPGA_BASE)
207
        I2C_ENABLE
208
 
209
        ##=====================================================================================
210
        ##
211
        ## Read the SPD device parameters and determine memory size
212
        ##
213
 
214
        READ_SPD_VALUE HAL_SPD_GET_NUM_ROW_BITS, 0xf, s0, ERROR_CHECK
215
        READ_SPD_VALUE HAL_SPD_GET_NUM_COL_BITS, 0xf, s1, ERROR_CHECK
216
 
217
        READ_SPD_VALUE HAL_SPD_GET_NUM_DEVICE_BANKS, NO_MASK, s2, ERROR_CHECK
218
 
219
        READ_SPD_VALUE HAL_SPD_GET_SDRAM_WIDTH, 0x7f, s3, ERROR_CHECK
220
        READ_SPD_VALUE HAL_SPD_GET_NUM_MODULE_BANKS, NO_MASK, s4, ERROR_CHECK
221
        READ_SPD_VALUE HAL_SPD_GET_ROW_DENSITY, NO_MASK, s5, ERROR_CHECK
222
 
223
        READ_SPD_VALUE HAL_SPD_GET_BURST_LENGTH, NO_MASK, s6, ERROR_CHECK
224
 
225
        #
226
        # Determine Size in Mbit
227
        #     SIZE = SDRAM_WIDTH * NUM_DEVICE_BANKS * 2 ^ (NUM_ROW_BITS + NUM_COL_BITS)
228
        #
229
        addu    t0, s0, s1              # t0 = (NUM_ROW_BITS + NUM_COL_BITS)
230
        li      t1, 1                   # t1 = 2 ^ 0
231
        sll     t1, t0                  # t1 = 2 ^ (NUM_ROW_BITS + NUM_COL_BITS)
232
        multu   s2, t1
233
        mflo    s6                      # s6 = NUM_DEVICE_BANKS * 2 ^ (NUM_ROW_BITS + NUM_COL_BITS)
234
        nop
235
        nop
236
        nop
237
        multu   s6, s3
238
        mflo    s6                      # s6 = SDRAM_WIDTH * NUM_DEVICE_BANKS * 2 ^ (NUM_ROW_BITS + NUM_COL_BITS)
239
        nop
240
        nop
241
        nop
242
 
243
        #
244
        # Determine size of Bank 0
245
        # SPD Density of Each Row on Module value is used. Bit 7 represents
246
        # 512MB, bit 6 256MB, etc. Highest set bit is size of bank 0.
247
        # If there are two banks and these have different sizes, an extra
248
        # bit will be set. If the sizes are the same, only the one bit is set.
249
        # Note, at the exit of this loop, the size-bit of bank 0 will have been
250
        # shifted out, allowing an easy check for multiple sizes below
251
        #
252
        li      s0, SZ_512M
253
0:
254
        and     t1, s5, BIT7
255
        bnez    t1, 8f
256
         sll    s5, 1
257
        b       0b
258
         srl    s0, 1
259
8:
260
 
261
        #
262
        # Determine if Bank 1 exists
263
        #
264
        li      t0, 1
265
        beq     s4, t0, 8f
266
         move   s1, zero
267
        #
268
        # Determine if Bank 1 is different than Bank 0. If no additional bits
269
        # set, size is the same.
270
        #
271
        and     t1, s5, 0xFF
272
        beq     t1, zero, 8f
273
         move   s1, s0
274
        #
275
        # Determine size of Bank 1. It will be at least one factor smaller
276
        # than that of bank 0.
277
        #
278
        sll     s1,1
279
0:
280
        and     t1, s5, BIT7
281
        bnez    t1, 8f
282
         sll    s5, 1
283
        b       0b
284
         srl    s1, 1
285
8:
286
 
287
        #
288
        # FIXME: We should probably do some validation on the various
289
        #        memory parameters here at some point.
290
        #
291
 
292
        #
293
        # Set the base SDRAM bank configuration value.
294
        # All other fields are zero, and the proper value is masked
295
        # in when they are known
296
        #
297
        li      s5, HAL_GALILEO_SDRAM_SRAS_TO_SCAS_DELAY_3C | \
298
                    HAL_GALILEO_SDRAM_WIDTH_64BIT | \
299
                    HAL_GALILEO_SDRAM_SRAS_PRECHARGE_3C
300
 
301
        #
302
        # Setup the CASLAT value.
303
        # Support only CASLAT = 2
304
        #
305
        READ_SPD_VALUE HAL_SPD_GET_CAS_LAT, NO_MASK, v0, NO_ERROR_CHECK
306
        and     t0, v0, 2
307
        beqz    t0, error
308
         nop
309
        ori     s5, HAL_GALILEO_SDRAM_BANK0_CASLAT_2
310
 
311
        #
312
        # Setup SDRAM device size
313
        #
314
        li      t0, SZ_16M
315
        beq     s6, t0, 8f
316
         nop
317
        ori     s5, HAL_GALILEO_SDRAM_BANK0_SZ_64M
318
8:
319
 
320
        #
321
        # Setup burst length: Support only 8
322
        #
323
        READ_SPD_VALUE HAL_SPD_GET_BURST_LENGTH, NO_MASK, v0, NO_ERROR_CHECK
324
        and     t0, v0, 8
325
        beqz    t0, error
326
         nop
327
 
328
        #
329
        # Setup Parity.
330
        # Only support Parity/Noparity.  Don't support ECC.
331
        #
332
        READ_SPD_VALUE HAL_SPD_GET_CONFIG_TYPE, NO_MASK, v0, NO_ERROR_CHECK
333
        li      t0, HAL_SPD_CONFIG_TYPE_PARITY
334
        beq     t0, v0, 0f
335
        nop
336
        li      t0, HAL_SPD_CONFIG_TYPE_ECC
337
        beq     t0, v0, error
338
        nop
339
        b       8f
340
        li      v1, 0
341
0:
342
        ori     s5, HAL_GALILEO_SDRAM_BANK0_PARITY
343
        li      v1, 1
344
8:
345
 
346
        #
347
        # Setup number of device banks
348
        # Only support 2 or 4 banks
349
        #
350
        li      t0, 2
351
        beq     s2, t0, 8f
352
        nop
353
        li      t0, 4
354
        beq     s2, t0, 0f
355
        nop
356
        b       error
357
        nop
358
0:
359
        ori     s5, HAL_GALILEO_SDRAM_NUM_BANKS_4
360
8:
361
 
362
        #
363
        # Now actually store the bank config register
364
        #
365
        sw      s5, HAL_GALILEO_SDRAM_BANK0_OFFSET(s7)
366
        sw      s5, HAL_GALILEO_SDRAM_BANK2_OFFSET(s7)
367
 
368
        #
369
        # Setup the SDRAM configuration register
370
        # All other fields are zero, and the proper value is masked
371
        # in when they are known
372
        #
373
        li      s5, HAL_GALILEO_SDRAM_DUPLICATE_BANK_ADDR | HAL_GALILEO_SDRAM_BANK_INTERLEAVE_DIS
374
 
375
        #
376
        # Setup the Refresh Rate
377
        #
378
        READ_SPD_VALUE HAL_SPD_GET_REFRESH_RATE, 0x7f, v0, NO_ERROR_CHECK
379
 
380
        li      t0, HAL_SPD_REFRESH_RATE_125
381
        beq     t0, v0, 8f
382
        li      t0, HAL_SPD_REFRESH_COUNTER_125
383
 
384
        li      t0, HAL_SPD_REFRESH_RATE_62_5
385
        beq     t0, v0, 8f
386
        li      t0, HAL_SPD_REFRESH_COUNTER_62_5
387
 
388
        li      t0, HAL_SPD_REFRESH_RATE_31_3
389
        beq     t0, v0, 8f
390
        li      t0, HAL_SPD_REFRESH_COUNTER_31_3
391
 
392
        li      t0, HAL_SPD_REFRESH_RATE_15_625
393
        beq     t0, v0, 8f
394
        li      t0, HAL_SPD_REFRESH_COUNTER_15_625
395
 
396
        li      t0, HAL_SPD_REFRESH_RATE_7_8
397
        beq     t0, v0, 8f
398
        li      t0, HAL_SPD_REFRESH_COUNTER_7_8
399
 
400
        # Unknown: assume 3.9 microseconds
401
        li      t0, HAL_SPD_REFRESH_COUNTER_3_9
402
8:
403
 
404
        or      s5, t0
405
 
406
#if 0   // FIXME: Dunno what this is supposed to do, but it changes the RMW flag,
407
        // not anything related to RAM width.
408
        #
409
        # Setup RAM_WIDTH
410
        #
411
        beqz    v1, 8f
412
        nop
413
        READ_SPD_VALUE HAL_SPD_GET_ERROR_CHECK_WIDTH, 0x7f, v0, NO_ERROR_CHECK
414
        beq     v0, zero, 8f
415
        nop
416
        ori     s5, HAL_GALILEO_SDRAM_CFG_RAM_WIDTH
417
8:
418
#endif
419
 
420
        #
421
        # Store the SDRAM configuration register
422
        #
423
        sw      s5, HAL_GALILEO_SDRAM_CONFIG_OFFSET(s7)
424
 
425
        #
426
        # Setup SDRAM Bank 0 Address Decoding
427
        #
428
        li      a0, CYGARC_PHYSICAL_ADDRESS(HAL_MALTA_RAM_BASE)          # Physical bottom of Bank 0
429
        add     a1, s0, a0
430
        subu    a1, 1                                                    # Physical top of Bank 0
431
 
432
        srl     t0, a0, HAL_GALILEO_CPU_DECODE_SHIFT                     # Setup SCS[1:0]
433
        srl     t1, a1, HAL_GALILEO_CPU_DECODE_SHIFT                     #   First level decoding
434
        sw      t0, HAL_GALILEO_SCS10_LD_OFFSET(s7)                      #   (ie Processor Decode Region)
435
        sw      t1, HAL_GALILEO_SCS10_HD_OFFSET(s7)                      #
436
 
437
        srl     t0, a0, HAL_GALILEO_DEV_DECODE_SHIFT                     # Setup SCS0
438
        srl     t1, a1, HAL_GALILEO_DEV_DECODE_SHIFT                     #   Second level decoding
439
        sw      t0, HAL_GALILEO_SCS0_LD_OFFSET(s7)                       #   (ie Device Sub-decode Region)
440
        sw      t1, HAL_GALILEO_SCS0_HD_OFFSET(s7)                       #
441
 
442
        #
443
        # Setup SDRAM Bank 1 Address Decoding
444
        #
445
        add     a0, s0, CYGARC_PHYSICAL_ADDRESS(HAL_MALTA_RAM_BASE)      # Physical bottom of Bank 1
446
        add     a1, a0, s1
447
        subu    a1, 1                                                    # Physical top of Bank 1
448
 
449
        srl     t0, a0, HAL_GALILEO_CPU_DECODE_SHIFT                     # Setup SCS[3:2]
450
        srl     t1, a1, HAL_GALILEO_CPU_DECODE_SHIFT                     #   First level decoding
451
        sw      t0, HAL_GALILEO_SCS32_LD_OFFSET(s7)                      #   (ie Processor Decode Region)
452
        sw      t1, HAL_GALILEO_SCS32_HD_OFFSET(s7)                      #
453
 
454
        srl     t0, a0, HAL_GALILEO_DEV_DECODE_SHIFT                     # Setup SCS2
455
        srl     t1, a1, HAL_GALILEO_DEV_DECODE_SHIFT                     #   Second level decoding
456
        sw      t0, HAL_GALILEO_SCS2_LD_OFFSET(s7)                       #   (ie Device Sub-decode Region)
457
        sw      t1, HAL_GALILEO_SCS2_HD_OFFSET(s7)                       #
458
 
459
        #
460
        # Setup PCI windows
461
        #
462
        li      a0, CYGARC_PHYSICAL_ADDRESS(HAL_MALTA_PCI_MEM0_BASE)
463
        add     a1, a0, HAL_MALTA_PCI_MEM0_SIZE
464
        subu    a1, 1                                                    # Physical top of Mem Bank 0
465
        srl     t0, a0, HAL_GALILEO_CPU_DECODE_SHIFT
466
        srl     t1, a1, HAL_GALILEO_CPU_DECODE_SHIFT
467
        sw      t0, HAL_GALILEO_PCIMEM0_LD_OFFSET(s7)
468
        sw      t1, HAL_GALILEO_PCIMEM0_HD_OFFSET(s7)
469
 
470
 
471
        li      a0, CYGARC_PHYSICAL_ADDRESS(HAL_MALTA_PCI_MEM1_BASE)
472
        add     a1, a0, HAL_MALTA_PCI_MEM1_SIZE
473
        subu    a1, 1                                                    # Physical top of Mem Bank 1
474
        srl     t0, a0, HAL_GALILEO_CPU_DECODE_SHIFT
475
        srl     t1, a1, HAL_GALILEO_CPU_DECODE_SHIFT
476
        sw      t0, HAL_GALILEO_PCIMEM1_LD_OFFSET(s7)
477
        sw      t1, HAL_GALILEO_PCIMEM1_HD_OFFSET(s7)
478
 
479
        li      a0, CYGARC_PHYSICAL_ADDRESS(HAL_MALTA_PCI_IO_BASE)
480
        add     a1, a0, HAL_MALTA_PCI_IO_SIZE
481
        subu    a1, 1                                                    # Physical top of IO Bank
482
        srl     t0, a0, HAL_GALILEO_CPU_DECODE_SHIFT
483
        srl     t1, a1, HAL_GALILEO_CPU_DECODE_SHIFT
484
        sw      t0, HAL_GALILEO_PCIIO_LD_OFFSET(s7)
485
        sw      t1, HAL_GALILEO_PCIIO_HD_OFFSET(s7)
486
 
487
        # Here's a nice gotcha. The Intel southbridge *must* see IO
488
        # starting from 0.
489
        sw      zero,HAL_GALILEO_PCI_IO_REMAP(s7)
490
 
491
        #
492
        # Setup FLASH Address Decoding
493
        #
494
        li      a0, CYGARC_PHYSICAL_ADDRESS(HAL_MALTA_FLASH_BASE)        # Physical bottom of Flash Bank
495
        add     a1, a0, HAL_MALTA_FLASH_SIZE
496
        subu    a1, 1                                                    # Physical top of Flash Bank
497
 
498
        srl     t0, a0, HAL_GALILEO_CPU_DECODE_SHIFT                     # Setup CS[2:0]
499
        srl     t1, a1, HAL_GALILEO_CPU_DECODE_SHIFT                     #   First level decoding
500
        sw      t0, HAL_GALILEO_CS20_LD_OFFSET(s7)                       #   (ie Processor Decode Region)
501
        sw      t1, HAL_GALILEO_CS20_HD_OFFSET(s7)                       #
502
 
503
        srl     t0, a0, HAL_GALILEO_DEV_DECODE_SHIFT                     # Setup CS0
504
        srl     t1, a1, HAL_GALILEO_DEV_DECODE_SHIFT                     #   Second level decoding
505
        sw      t0, HAL_GALILEO_CS0_LD_OFFSET(s7)                        #   (ie Device Sub-decode Region)
506
        sw      t1, HAL_GALILEO_CS0_HD_OFFSET(s7)                        #
507
 
508
        #
509
        #  Now disable all unused decodes
510
        #  (SCS1, SCS3, PCI1xx, CS1, CS2)
511
        #
512
        li      t0, 0xffff
513
        move    t1, zero
514
        sw      t0, HAL_GALILEO_SCS1_LD_OFFSET(s7)
515
        sw      t1, HAL_GALILEO_SCS1_HD_OFFSET(s7)
516
        sw      t0, HAL_GALILEO_SCS3_LD_OFFSET(s7)
517
        sw      t1, HAL_GALILEO_SCS3_HD_OFFSET(s7)
518
        sw      t0, HAL_GALILEO_PCI1IO_LD_OFFSET(s7)
519
        sw      t1, HAL_GALILEO_PCI1IO_HD_OFFSET(s7)
520
        sw      t0, HAL_GALILEO_PCI1MEM0_LD_OFFSET(s7)
521
        sw      t1, HAL_GALILEO_PCI1MEM0_HD_OFFSET(s7)
522
        sw      t0, HAL_GALILEO_PCI1MEM1_LD_OFFSET(s7)
523
        sw      t1, HAL_GALILEO_PCI1MEM1_HD_OFFSET(s7)
524
        sw      t0, HAL_GALILEO_CS1_LD_OFFSET(s7)
525
        sw      t1, HAL_GALILEO_CS1_HD_OFFSET(s7)
526
        sw      t0, HAL_GALILEO_CS2_LD_OFFSET(s7)
527
        sw      t1, HAL_GALILEO_CS2_HD_OFFSET(s7)
528
 
529
noerror:
530
        move    v0, zero
531
        add     v1, s0, s1
532
        move    ra, s8
533
        jr      ra
534
        nop
535
 
536
error:
537
        li      v0, HAL_MALTA_MEMERROR
538
        move    ra, s8
539
        jr      ra
540
        nop
541
 
542
FUNC_END(hal_malta_init_sdram)
543
 
544
    .macro i2c_start
545
    # Start: SDA low -> high with SLC high
546
    I2C_OE(HAL_I2C_COUT_DOUT)
547
    I2C_OUT(HAL_I2C_CHIGH_DHIGH)
548
    I2C_OUT(HAL_I2C_CHIGH_DLOW)
549
    I2C_OUT(HAL_I2C_CLOW_DLOW)
550
    .endm
551
 
552
    .macro i2c_stop
553
    # Stop: SDA high -> low with SLC high
554
    I2C_OE(HAL_I2C_COUT_DOUT)
555
    I2C_OUT(HAL_I2C_CLOW_DLOW)
556
    I2C_OUT(HAL_I2C_CHIGH_DLOW)
557
    I2C_OUT(HAL_I2C_CHIGH_DHIGH)
558
    I2C_OUT(HAL_I2C_CLOW_DHIGH)
559
    .endm
560
 
561
    .macro i2c_write
562
    # Value to write in t1.
563
    # Writes happen by clocking SCL low->high->low while SDA defines
564
    # the bit to be sent (MSB first).
565
    I2C_OE(HAL_I2C_COUT_DOUT)
566
    li      t2, 7
567
1:  srlv    t3, t1, t2
568
    andi    t3, 1
569
    beq     t3, zero, 2f
570
     nop
571
    # Send 1
572
    I2C_OUT(HAL_I2C_CLOW_DHIGH)
573
    I2C_OUT(HAL_I2C_CHIGH_DHIGH)
574
    I2C_OUT(HAL_I2C_CLOW_DHIGH)
575
    b       3f
576
     nop
577
 
578
2:  # Send 0
579
    I2C_OUT(HAL_I2C_CLOW_DLOW)
580
    I2C_OUT(HAL_I2C_CHIGH_DLOW)
581
    I2C_OUT(HAL_I2C_CLOW_DLOW)
582
 
583
3:  bne     t2, zero, 1b
584
     addiu   t2, -1
585
 
586
    # Now tristate the SDA and pulse the clock. Receiver will
587
    # ack the transfer by pulling SDA low.
588
    # Read by pulsing clock. Leave result in t1
589
    I2C_OE(HAL_I2C_COUT_DIN)
590
    I2C_OUT(HAL_I2C_CHIGH_DHIGH)
591
    I2C_IN(t1)
592
    I2C_OUT(HAL_I2C_CLOW_DHIGH)
593
    .endm
594
 
595
    .macro i2c_read
596
    # Value read is returned in t1
597
    # Reads happen by clocking SCL high->low while reading SDA
598
    I2C_OE(HAL_I2C_COUT_DIN)
599
    move    t1,zero
600
    li      t2, 7
601
1:  I2C_OUT(HAL_I2C_CHIGH_DHIGH)
602
    I2C_IN(t3)
603
    sll     t1,1
604
    or      t1,t1,t3
605
    I2C_OUT(HAL_I2C_CLOW_DHIGH)
606
 
607
    bne     t2, zero, 1b
608
     addiu   t2, -1
609
 
610
    // Send ack by clocking with SDA low.
611
    I2C_OUT(HAL_I2C_CLOW_DHIGH)
612
    I2C_OE(HAL_I2C_COUT_DOUT)
613
    I2C_OUT(HAL_I2C_CHIGH_DHIGH)
614
    I2C_OUT(HAL_I2C_CLOW_DHIGH)
615
    .endm
616
 
617
##
618
## Read a value from the SDRAM SPD device.
619
##
620
## Parameters:   a0 = subaddress
621
## Returns:      v0 = SPD value read
622
##
623
FUNC_START(read_spd_value)
624
        .set noreorder
625
        # Setup a base address register
626
        li      a1, CYGARC_UNCACHED_ADDRESS(HAL_I2CFPGA_BASE)
627
 
628
        i2c_start
629
 
630
        # Write address of SDRAM sense controller
631
        li      t1,( HAL_I2C_SPD_ADDRESS | HAL_I2C_WRITE )
632
        i2c_write
633
        li      t0,HAL_I2CFPGA_OUT_SDA_NACK
634
        beq     t0,t1,i2c_error
635
         move   v0,zero
636
 
637
        # Write address of data wanted
638
        move    t1,a0
639
        i2c_write
640
        li      t0,HAL_I2CFPGA_OUT_SDA_NACK
641
        beq     t0,t1,i2c_error
642
         move   v0,zero
643
 
644
        i2c_start
645
 
646
        # Write address of SDRAM sense controller
647
        li      t1,( HAL_I2C_SPD_ADDRESS | HAL_I2C_READ )
648
        i2c_write
649
        li      t0,HAL_I2CFPGA_OUT_SDA_NACK
650
        beq     t0,t1,i2c_error
651
         move   v0,zero
652
 
653
        # Read data
654
        i2c_read
655
        move    v0,t1
656
 
657
        i2c_stop
658
 
659
i2c_error:
660
        jr      ra
661
         nop
662
 
663
FUNC_END(read_spd_value)
664
#endif // defined(CYG_HAL_STARTUP_ROM)
665
 
666
##-----------------------------------------------------------------------------
667
## ISR springboard.
668
## This routine decodes the interrupt from the southbridge and vectors to it.
669
 
670
        # On entry:
671
        # a0 = MIPS status register interrupt number (1,2 or 3)
672
        # a1 = ISR data value (= interrupt controller reg address)
673
        # a2 = saved reg dump ptr
674
        # s0 = saved reg dump ptr
675
        # s1 = vector table offset
676
        # s2 = interrupt number
677
        # a3,v0,v1 etc available for use
678
 
679
        .text
680
 
681
FUNC_START(hal_isr_springboard_southbridge)
682
        .set noreorder
683
        # Get req bits of controller 1
684
        lb      v0,0(a1)
685
        lb      v1,1(a1)             # apply mask
686
        xori    v1,v1,0xffff
687
        and     v0,v0,v1
688
        andi    v1,v0,0xffff&~(1<<(CYGNUM_HAL_INTERRUPT_CASCADE-CYGNUM_HAL_INTERRUPT_CTRL1_BASE))
689
        bne     v1,zero,1f
690
         ori    a2,zero,CYGNUM_HAL_INTERRUPT_CTRL1_BASE
691
        # If cascade is set, check controller 2
692
        andi    v0,v0,(1<<(CYGNUM_HAL_INTERRUPT_CASCADE-CYGNUM_HAL_INTERRUPT_CTRL1_BASE))
693
        beq     v0,zero,2f
694
         lb     v0,HAL_PIIX4_MASTER_SLAVE_OFFSET(a1)
695
        lb      v1,HAL_PIIX4_MASTER_SLAVE_OFFSET+1(a1)   # apply mask
696
        xori    v1,v1,0xffff
697
        and     v0,v0,v1
698
        bne     v0,zero,1f
699
         ori    a2,zero,CYGNUM_HAL_INTERRUPT_CTRL2_BASE
700
        # Spurious interrupt, return to VSR
701
2:      jr      ra
702
         move   v0,zero
703
1:
704
 
705
        # FIXME: May want to rewrite this to do ls bit on byte
706
        #        to save a few cycles.
707
        # The following code implements an ls bit index algorithm similar
708
        # to that in hal_lsbit_index() in hal_misc.c.
709
        negu    v1,v0                           # v1 = -v0
710
        and     v1,v1,v0                        # v1 &= v0 [isolate ls bit]
711
        sll     v0,v1,16                        # v0 = v1<<16
712
        subu    v1,v0,v1                        # v1 = v0 - v1
713
        sll     a0,v1,6                         # a0 = v1<<6
714
        addu    v1,v1,a0                        # v1 += a0
715
        sll     a1,v1,4                         # a1 = v1<<4
716
        addu    v1,v1,a1                        # v1 += a1
717
        la      v0,hal_isr_springboard_table    # v0 = table address
718
        srl     v1,v1,26                        # v1 = v1>>26
719
        addu    v1,v1,v0                        # v1 = table entry address
720
        lb      a0,0(v1)                        # a0 = intc isr number
721
 
722
        add     s2,a0,a2                        # s2 = eCos isr number
723
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
724
hal_isr_springboard_chaining:
725
        # This serves as the __default_interrupt_isr entry-point in
726
        # chaning mode, thus ensuring that all interrupts from
727
        # vectors 0-5 eventually end up on the special CHAINING vector.
728
        # (See the hal_interrupt_handlers table)
729
        ori     s1,zero,CYGNUM_HAL_INTERRUPT_CHAINING*4 # s1 = chaining isr ix
730
#else
731
        sll     s1,s2,2                         # s1 = isr table index
732
#endif
733
 
734
        la      v1,hal_interrupt_handlers
735
        add     v1,v1,s1                        # v1 = isr handler address
736
        lw      v1,0(v1)                        # v1 = isr handler
737
 
738
        la      a1,hal_interrupt_data
739
        add     a1,a1,s1                        # a1 = address of data ptr
740
        lw      a1,0(a1)                        # a1 = data pointer
741
 
742
        move    a0,s2                           # pass interrupt number
743
 
744
        jr      v1                              # jump to handler, return is to
745
         nop                                    # default vsr already in ra
746
 
747
FUNC_END(hal_isr_springboard_southbridge)
748
 
749
 
750
hal_isr_springboard_table:
751
        .byte  -1,  0,  1, 12,  2,  6,  0, 13
752
        .byte   3,  0,  7,  0,  0,  0,  0, 14
753
        .byte  10,  4,  0,  0,  8,  0,  0, 25
754
        .byte   0,  0,  0,  0,  0, 21, 27, 15
755
        .byte  31, 11,  5,  0,  0,  0,  0,  0
756
        .byte   9,  0,  0, 24,  0,  0, 20, 26
757
        .byte  30,  0,  0,  0,  0, 23,  0, 19
758
        .byte  29,  0, 22, 18, 28, 17, 16,  0
759
 
760
##-----------------------------------------------------------------------------
761
# Interrupt vector tables.
762
# These tables contain the isr, data and object pointers used to deliver
763
# interrupts to user code.
764
 
765
        .extern hal_default_isr
766
 
767
        .data
768
 
769
        .globl  hal_interrupt_handlers
770
hal_interrupt_handlers:
771
        .long   hal_isr_springboard_southbridge
772
        .rept   CYGNUM_HAL_ISR_COUNT-1
773
        .long   hal_default_isr
774
        .endr
775
 
776
        .globl  hal_interrupt_data
777
hal_interrupt_data:
778
        .long   HAL_PIIX4_MASTER_OCW3
779
        .rept   CYGNUM_HAL_ISR_COUNT-1
780
        .long   0
781
        .endr
782
 
783
        .globl  hal_interrupt_objects
784
hal_interrupt_objects:
785
        .rept   CYGNUM_HAL_ISR_COUNT
786
        .long   0
787
        .endr
788
 
789
 
790
##-----------------------------------------------------------------------------
791
## end of platform.S

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.