~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to boot/mips/yeeloong/fwstart.S

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  GRUB  --  GRand Unified Bootloader
3
 
 *  Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010  Free Software Foundation, Inc.
4
 
 *
5
 
 *  GRUB is free software: you can redistribute it and/or modify
6
 
 *  it under the terms of the GNU General Public License as published by
7
 
 *  the Free Software Foundation, either version 3 of the License, or
8
 
 *  (at your option) any later version.
9
 
 *
10
 
 *  GRUB is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
17
 
 */
18
 
 
19
 
#include <grub/mips/yeeloong/serial.h>
20
 
#include <grub/mips/yeeloong/pci.h>
21
 
#include <grub/mips/loongson.h>
22
 
#include <grub/pci.h>
23
 
#include <grub/serial.h>
24
 
#include <grub/cs5536.h>
25
 
#include <grub/smbus.h>
26
 
 
27
 
        .set noreorder
28
 
        .set noat
29
 
        .set nomacro
30
 
 
31
 
        .global start,_start,__start
32
 
start:
33
 
_start:
34
 
__start:        
35
 
        bal serial_hw_init
36
 
         nop
37
 
        /* Find CS5536 controller.  */
38
 
        /* $t4 chooses device in priority encoding.  */
39
 
        /* Resulting value is kept in GRUB_MACHINE_PCI_CONF_CTRL_REG.
40
 
           This way we don't need to sacrifice a register for it.  */
41
 
        /* We have only one bus (0). Function is 0.  */
42
 
        lui $t0, %hi(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR)
43
 
        lui $t1, %hi(GRUB_MACHINE_PCI_CONFSPACE)
44
 
        lui $t3, %hi(GRUB_CS5536_PCIID)
45
 
        addiu $t3, $t3, %lo(GRUB_CS5536_PCIID)
46
 
        ori $t4, $zero, 1
47
 
        lui $a0, %hi(no_cs5536)
48
 
1:
49
 
        andi $t4, $t4, ((1 << GRUB_PCI_NUM_DEVICES) - 1)
50
 
        beql  $t4, $zero, fatal
51
 
         addiu $a0, $a0, %lo(no_cs5536)
52
 
        sw   $t4, %lo(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) ($t0)
53
 
        lw   $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_PCI_REG_PCI_ID) ($t1)
54
 
        bnel  $t2, $t3, 1b
55
 
         sll $t4, $t4, 1
56
 
 
57
 
        bal message
58
 
         addiu $a0, $a0, %lo(cs5536_found)
59
 
        bal printhex
60
 
         move $a0, $t4
61
 
 
62
 
        /* Initialise SMBus controller.  */
63
 
        /* Set GPIO LBAR.  */
64
 
        lui $a0, %hi(GRUB_CS5536_MSR_GPIO_BAR)
65
 
        addiu $a0, $a0, %lo(GRUB_CS5536_MSR_GPIO_BAR)
66
 
        ori $a1, $zero, GRUB_CS5536_LBAR_GPIO
67
 
        /* Set mask to 0xf and enabled bit to 1.  */
68
 
        bal wrmsr
69
 
         ori $a2, $zero, ((GRUB_CS5536_LBAR_MASK_MASK \
70
 
                          | GRUB_CS5536_LBAR_ENABLE) >> 32)
71
 
 
72
 
        /* Set SMBUS LBAR.  */
73
 
        lui $a0, %hi(GRUB_CS5536_MSR_SMB_BAR)
74
 
        addiu $a0, $a0, %lo(GRUB_CS5536_MSR_SMB_BAR)
75
 
        ori $a1, $zero, GRUB_CS5536_LBAR_SMBUS
76
 
        /* Set mask to 0xf and enabled bit to 1.  */
77
 
        bal wrmsr
78
 
         ori $a2, $zero, ((GRUB_CS5536_LBAR_MASK_MASK \
79
 
                           | GRUB_CS5536_LBAR_ENABLE) >> 32)
80
 
 
81
 
        lui $a0, %hi(smbus_enabled)
82
 
        bal message
83
 
          addiu $a0, $a0, %lo(smbus_enabled)
84
 
 
85
 
        /* Enable SMBus controller pins.  */
86
 
        lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO)
87
 
        ori $t1, $zero, GRUB_GPIO_SMBUS_PINS
88
 
        sw  $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_EN) ($t0)
89
 
        sw  $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_AUX1) ($t0)
90
 
        sw  $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_EN) ($t0)
91
 
        sw  $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_AUX1) ($t0)
92
 
 
93
 
        lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS)
94
 
 
95
 
        /* Disable SMB.  */
96
 
        sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0)
97
 
 
98
 
        /* Disable interrupts.  */
99
 
        sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1) ($t0)
100
 
 
101
 
        /* Set as master.  */
102
 
        sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_ADDR) ($t0)
103
 
 
104
 
        /* Launch SMBus controller at slowest speed possible.  */
105
 
        ori $t1, $zero, 0xff
106
 
        sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL3) ($t0)
107
 
        sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0)
108
 
 
109
 
        /* Yeeloong has only one memory slot.  */
110
 
        /* Output first byte on serial for debugging.  */
111
 
        ori $a1, $zero, GRUB_SMB_RAM_START_ADDR
112
 
        bal read_spd
113
 
         move $a0, $zero
114
 
        bal printhex
115
 
         move $a0, $v0
116
 
 
117
 
        bal read_spd
118
 
         ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_ADDR
119
 
        ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2
120
 
        lui $a0, %hi(unimplemented_memory_type)
121
 
        bne $t0, $v0, fatal
122
 
         addiu $a0, $a0, %hi(unimplemented_memory_type)
123
 
 
124
 
        /* And here is our goal: DDR2 controller initialisation.  */
125
 
        lui     $t0, %hi(GRUB_CPU_LOONGSON_CORECFG)
126
 
        ld      $t1, %lo(GRUB_CPU_LOONGSON_CORECFG) ($t0)
127
 
        /* Use addiu for sign-extension.  */
128
 
        addiu   $t2, $zero, ~(GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE|GRUB_CPU_LOONGSON_CORECFG_BUFFER_CPU)
129
 
        and     $t1, $t1, $t2
130
 
        sd      $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0)
131
 
 
132
 
        b continue
133
 
 
134
 
        . = start + GRUB_CPU_LOONGSON_FLASH_TLB_REFILL - GRUB_CPU_LOONGSON_FLASH_START
135
 
tlb_refill:     
136
 
        mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC
137
 
        mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR
138
 
        move $s3, $ra
139
 
        lui $a0, %hi(epc)
140
 
        bal message
141
 
         addiu $a0, $a0, %lo(epc)
142
 
 
143
 
        bal printhex
144
 
         move $a0, $s1
145
 
 
146
 
        lui $a0, %hi(badvaddr)
147
 
        bal message
148
 
         addiu $a0, $a0, %lo(badvaddr)
149
 
 
150
 
        bal printhex
151
 
         move $a0, $s2
152
 
 
153
 
        lui $a0, %hi(return_msg)
154
 
        bal message
155
 
         addiu $a0, $a0, %lo(return_msg)
156
 
 
157
 
        bal printhex
158
 
         move $a0, $s3
159
 
        
160
 
        lui $a0, %hi(newline)
161
 
        bal message
162
 
         addiu $a0, $a0, %lo(newline)
163
 
 
164
 
        lui $a0, %hi(unhandled_tlb_refill)
165
 
        b fatal
166
 
         addiu $a0, $a0, %lo(unhandled_tlb_refill)
167
 
 
168
 
        . = start + GRUB_CPU_LOONGSON_FLASH_CACHE_ERROR - GRUB_CPU_LOONGSON_FLASH_START
169
 
cache_error:
170
 
        lui $a0, %hi(unhandled_cache_error)
171
 
        b fatal
172
 
         addiu $a0, $a0, %lo(unhandled_cache_error)
173
 
 
174
 
        . = start + GRUB_CPU_LOONGSON_FLASH_OTHER_EXCEPTION - GRUB_CPU_LOONGSON_FLASH_START
175
 
other_exception:
176
 
        mfc0 $s0, GRUB_CPU_LOONGSON_COP0_CAUSE
177
 
        mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC
178
 
        mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR
179
 
        lui $a0, %hi(cause)
180
 
        bal message
181
 
         addiu $a0, $a0, %lo(cause)
182
 
 
183
 
        bal printhex
184
 
         move $a0, $s0
185
 
 
186
 
        lui $a0, %hi(epc)
187
 
        bal message
188
 
         addiu $a0, $a0, %lo(epc)
189
 
 
190
 
        bal printhex
191
 
         move $a0, $s1
192
 
 
193
 
        lui $a0, %hi(badvaddr)
194
 
        bal message
195
 
         addiu $a0, $a0, %lo(badvaddr)
196
 
 
197
 
        bal printhex
198
 
         move $a0, $s2
199
 
        
200
 
        lui $a0, %hi(newline)
201
 
        bal message
202
 
         addiu $a0, $a0, %lo(newline)
203
 
        
204
 
        lui $a0, %hi(unhandled_exception)
205
 
        b fatal
206
 
         addiu $a0, $a0, %lo(unhandled_exception)
207
 
 
208
 
        /* Same as similarly named C function but in asm since
209
 
           we need it early.  */
210
 
        /* In: none. Out: none. Clobbered: $t0, $t1, $a0.  */
211
 
serial_hw_init:
212
 
        lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT)
213
 
 
214
 
        /* Turn off the interrupt.  */
215
 
        sb $zero, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_IER)($t0)
216
 
 
217
 
        /* Set DLAB.  */
218
 
        ori $t1, $zero, UART_DLAB
219
 
        sb  $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LCR)($t0)
220
 
 
221
 
        /* Set the baud rate 115200.  */
222
 
        ori $t1, $zero, GRUB_MACHINE_SERIAL_DIVISOR_115200
223
 
        sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLL)($t0) 
224
 
        sb $zero, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLH)($t0) 
225
 
 
226
 
        /* Set the line status.  */
227
 
        ori $t1, $zero, (UART_NO_PARITY | UART_8BITS_WORD | UART_1_STOP_BIT)
228
 
        sb  $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LCR)($t0)
229
 
 
230
 
        /* Enable the FIFO.  */
231
 
        ori $t1, $zero, UART_ENABLE_FIFO_TRIGGER1
232
 
        sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_FCR)($t0)
233
 
 
234
 
        /* Turn on DTR and RTS.  */
235
 
        ori $t1, $zero, UART_ENABLE_DTRRTS
236
 
        sb  $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_MCR)($t0)
237
 
 
238
 
        /* Let message return to original caller.  */
239
 
        lui  $a0, %hi(notification_string)
240
 
        addiu $a0, $a0, %lo(notification_string)
241
 
 
242
 
        /* Print message on serial console.  */
243
 
        /* In: $a0 = asciiz message. Out: none. Clobbered: $t0, $t1, $a0.  */
244
 
message:
245
 
        lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT)
246
 
1:
247
 
        lb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LSR)($t0)
248
 
        andi $t1, $t1, UART_EMPTY_TRANSMITTER
249
 
        beq $t1, $zero, 1b
250
 
         nop
251
 
        lb  $t1, 0($a0)
252
 
        sb  $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_TX)($t0)
253
 
        bne $t1, $zero, 1b
254
 
         addiu $a0, $a0, 1
255
 
        jr  $ra
256
 
         nop
257
 
        
258
 
        /* Print 32-bit hexadecimal on serial.
259
 
           In:  $a0. Out: None. Clobbered: $a0, $t0, $t1, $t2
260
 
        */
261
 
printhex:
262
 
        lui $t0, %hi  (GRUB_MACHINE_SERIAL_PORT)
263
 
        ori $t2, $zero, 8
264
 
1:
265
 
        lb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LSR)($t0)
266
 
        andi $t1, $t1, UART_EMPTY_TRANSMITTER
267
 
        beq $t1, $zero, 1b
268
 
         nop
269
 
        srl  $t1, $a0, 28
270
 
        addiu $t1, $t1, -10
271
 
        blt  $t1, $zero, 2f
272
 
         sll  $a0, $a0, 4
273
 
        addiu $t1, $t1, 'A'-10-'0' 
274
 
2:      addiu $t1, $t1, '0'+10
275
 
        sb  $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_TX)($t0)
276
 
        addiu $t2, $t2, -1
277
 
        bne $t2, $zero, 1b
278
 
         nop
279
 
        jr  $ra
280
 
         nop
281
 
 
282
 
fatal:
283
 
        bal message
284
 
         nop
285
 
self:
286
 
        b self
287
 
         nop
288
 
        
289
 
        /* Write CS5536 MSR.
290
 
           In:   $a0 address, $a1 lower word, $a2 upper word.
291
 
           Out:  None
292
 
           Clobbered:    $t0
293
 
        */
294
 
wrmsr:
295
 
        lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE)
296
 
        sw  $a0, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_ADDR) ($t0)
297
 
        sw  $a1, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_DATA0) ($t0)
298
 
        jr $ra
299
 
         sw  $a2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_DATA1) ($t0)
300
 
 
301
 
        /* Wait for SMBus data or empty transmitter.  */
302
 
        /* In: $a0 = exception handler. Out: none. Clobbered: $t0, $t1  */
303
 
smbus_wait:
304
 
1:      
305
 
        lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE)
306
 
        lb $t0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE) ($t0)
307
 
        andi $t1, $t0, GRUB_CS5536_SMB_REG_STATUS_SDAST
308
 
        bne $t1, $zero, return
309
 
         nop
310
 
        andi $t1, $t0, (GRUB_CS5536_SMB_REG_STATUS_BER | GRUB_CS5536_SMB_REG_STATUS_NACK)
311
 
        beq $t1, $zero, 1b
312
 
         nop
313
 
        jr $a0
314
 
         nop
315
 
return:
316
 
        jr $ra
317
 
         nop
318
 
        
319
 
        /* Read SPD byte. In: $a0 byte, $a1 device. Out: $v0 read byte (0x100 on failure).
320
 
           Clobbered: $t0, $t1, $t2, $t3, $a0. */
321
 
read_spd:
322
 
        move $t2, $a0
323
 
        move $t3, $ra
324
 
        lui $a0, %hi(read_spd_fail)
325
 
        addiu $a0, $a0, %hi(read_spd_fail)
326
 
 
327
 
        /* Send START.  */
328
 
        lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
329
 
        lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
330
 
        ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_START
331
 
        bal smbus_wait
332
 
         sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
333
 
        
334
 
        /* Send device address.  */
335
 
        lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
336
 
        sll $t1, $a1, 1
337
 
        bal smbus_wait
338
 
         sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
339
 
 
340
 
        /* Send ACK.  */
341
 
        lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
342
 
        lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
343
 
        ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_ACK
344
 
        sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
345
 
 
346
 
        /* Send byte address.  */
347
 
        lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
348
 
        bal smbus_wait
349
 
         sb $t2, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
350
 
 
351
 
        /* Send START.  */
352
 
        lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
353
 
        lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
354
 
        ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_START
355
 
        bal smbus_wait
356
 
         sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
357
 
 
358
 
        /* Send device address.  */
359
 
        lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
360
 
        sll $t1, $a1, 1
361
 
        ori $t1, $t1, 1
362
 
        bal smbus_wait
363
 
         sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
364
 
 
365
 
        /* Send STOP.  */
366
 
        lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
367
 
        lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
368
 
        ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_STOP
369
 
        bal smbus_wait
370
 
         sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
371
 
 
372
 
        lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
373
 
        lb $v0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
374
 
        jr $t3
375
 
         andi $v0, $v0, 0xff
376
 
read_spd_fail:
377
 
        jr $t3
378
 
         ori $v0, $v0, 0x100
379
 
 
380
 
notification_string:    .asciz "GRUB "
381
 
no_cs5536:      .asciz "No CS5536 found.\n\r"
382
 
cs5536_found:   .asciz "CS5536 at "
383
 
sm_failed: .asciz "SM transaction failed.\n\r"
384
 
unhandled_tlb_refill:   .asciz "Unhandled TLB refill.\n\r"
385
 
unhandled_cache_error:  .asciz "Unhandled cache error.\n\r"
386
 
unhandled_exception:    .asciz "Unhandled exception.\n\r"
387
 
smbus_enabled:  .asciz "SMBus controller enabled.\n\r"
388
 
unimplemented_memory_type:      .asciz "non-DDR2 memory isn't supported.\n\r"
389
 
no_cas_latency:         .asciz "Couldn't determine CAS latency.\n\r"
390
 
cause:   .asciz "Cause: "
391
 
epc:    .asciz "\n\rEPC: "
392
 
badvaddr:       .asciz "\n\rBadVaddr: "
393
 
newline:        .asciz "\n\r"
394
 
return_msg:       .asciz "\n\rReturn address: "
395
 
caches_enabled: .asciz "Caches enabled\n\r"
396
 
 
397
 
        .p2align 3
398
 
 
399
 
regdump:
400
 
        .quad 0x0100010000000101 /* 0 */
401
 
        .quad 0x0100010100000000 /* 2 */
402
 
        .quad 0x0101000001000000 /* 3 */
403
 
        .quad 0x0100020200010101 /* 4 */
404
 
        .quad 0x0a04030603050203 /* 6 */
405
 
        .quad 0x0f0e040000010a0b /* 7 */
406
 
        .quad 0x0000010200000102 /* 8 */
407
 
        .quad 0x0000060c00000000 /* 9 */
408
 
        .quad 0x2323233f3f1f0200 /* a */
409
 
        .quad 0x5f7f232323232323 /* b */
410
 
        .quad 0x002a3c0615000000 /* c */
411
 
        .quad 0x002a002a002a002a /* d */
412
 
        .quad 0x002a002a002a002a /* e */
413
 
        .quad 0x00b40020006d0004 /* f */
414
 
        .quad 0x070007ff00000087 /* 10 */
415
 
        .quad 0x000000000016101f /* 11 */
416
 
        .quad 0x001c000000000000 /* 12 */
417
 
        .quad 0x28e1000200c8006b /* 13 */
418
 
        .quad 0x0000204200c8002f /* 14 */
419
 
        .quad 0x0000000000030d40 /* 15 */
420
 
        .quad 0 /* 16 */
421
 
        .quad 0 /* 17 */
422
 
        .quad 0 /* 18 */
423
 
        .quad 0 /* 19 */
424
 
        .quad 0 /* 1a */
425
 
        .quad 0 /* 1b */
426
 
        .quad 0 /* 1c */
427
 
 
428
 
        .p2align
429
 
 
430
 
write_dumpreg:  
431
 
        ld $t2, 0($t6)
432
 
        sd $t2, 0($t4)
433
 
        addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP
434
 
        jr $ra
435
 
         addiu $t6, $t6, GRUB_CPU_LOONGSON_DDR2_REG_SIZE
436
 
 
437
 
continue:
438
 
        lui $t4, %hi(GRUB_CPU_LOONGSON_DDR2_BASE)
439
 
        addiu $t4, $t4, %lo(GRUB_CPU_LOONGSON_DDR2_BASE)
440
 
        lui $t6, %hi(regdump)
441
 
 
442
 
        /* 0 */
443
 
        bal write_dumpreg
444
 
         addiu $t6, $t6, %lo(regdump)
445
 
 
446
 
        /* 1 */
447
 
        ori $a1, $a1, GRUB_SMB_RAM_START_ADDR
448
 
        move $t8, $zero
449
 
        lui  $t5, 0x0001
450
 
        bal read_spd
451
 
         ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_BANKS_ADDR
452
 
        ori $t7, $zero, 8
453
 
        bne $v0, $t7, 1f
454
 
         ori $t5, $t5, 0x0001
455
 
        ori $t8, $t8, GRUB_CPU_LOONGSON_DDR2_REG1_HI_8BANKS
456
 
1:
457
 
        dsll $t8, $t8, 32
458
 
        or $t5, $t5, $t8
459
 
        sd  $t5, 0 ($t4)
460
 
        addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP
461
 
 
462
 
        /* 2 */
463
 
        bal write_dumpreg
464
 
         nop
465
 
 
466
 
        /* 3 */
467
 
        bal write_dumpreg
468
 
         nop
469
 
 
470
 
        /* 4 */
471
 
        bal write_dumpreg
472
 
         nop
473
 
 
474
 
        /* 5 */
475
 
        /* FIXME: figure termination resistance.  */
476
 
        ori $t5, $zero, 0x2
477
 
        bal read_spd
478
 
         ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_ROWS_ADDR
479
 
        /* $v0 = 15 - $v0.  */
480
 
        xori $v0, $v0, 0xf
481
 
        andi $v0, $v0, 0x7
482
 
        sll $v0, $v0, 8
483
 
        or $t5, $t5, $v0
484
 
 
485
 
        /* Find the fastest supported CAS latency.  */
486
 
        bal read_spd
487
 
         ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_ADDR
488
 
        ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE
489
 
        ori $t1, $zero, (1 << GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE)
490
 
2:      
491
 
        and $t2, $t1, $v0
492
 
        bne $t2, $zero, 1f
493
 
         ori $t3, $zero, 8
494
 
        lui $a0, %hi(no_cas_latency)
495
 
        beq $t0, $t3, fatal
496
 
         addiu $a0, $a0, %lo(no_cas_latency)
497
 
        addiu $t0, $t0, 1
498
 
        b 2b
499
 
         sll $t1, $t1, 1
500
 
1:
501
 
        sll $t0, $t0, 16
502
 
        or $t5, $t5, $t0
503
 
        
504
 
        bal read_spd
505
 
         ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_COLUMNS_ADDR
506
 
        /* $v0 = 15 - ($v0 + 1) = 14 - $v0.  */
507
 
        addiu $v0, $v0, 1
508
 
        xori $v0, $v0, 0xf
509
 
        andi $v0, $v0, 0x7
510
 
        sll $v0, 24
511
 
        or $t5, $t5, $v0
512
 
        sd  $t5, 0 ($t4)
513
 
 
514
 
        addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP
515
 
        
516
 
        ori $t7, $zero, 0x16
517
 
 
518
 
1:      
519
 
        ld $t2, 0($t6)
520
 
        sd $t2, 0($t4)
521
 
        addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP
522
 
        addiu $t7, $t7, -1
523
 
        bne $t7, $zero, 1b
524
 
         addiu $t6, $t6, GRUB_CPU_LOONGSON_DDR2_REG_SIZE
525
 
        
526
 
        lui $t4, %hi(GRUB_CPU_LOONGSON_DDR2_BASE)
527
 
        ld  $t5, (%lo(GRUB_CPU_LOONGSON_DDR2_BASE) + 0x30) ($t4)
528
 
        ori $t0, $zero, 1
529
 
        dsll $t0, $t0, 40
530
 
        or $t5, $t5, $t0
531
 
        sd  $t5, (%lo(GRUB_CPU_LOONGSON_DDR2_BASE) + 0x30) ($t4)
532
 
 
533
 
        /* Desactivate DDR2 registers.  */
534
 
        lui     $t0, %hi (GRUB_CPU_LOONGSON_CORECFG)
535
 
        ld      $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0)
536
 
        ori     $t1, $t1, GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE
537
 
        sd      $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0)
538
 
 
539
 
        /* Enable cache.  */
540
 
        mfc0    $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
541
 
        addiu   $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK
542
 
        and     $t0, $t1, $t1
543
 
        /* Set line size to 32 bytes and disabled cache.  */
544
 
        ori     $t0, $t0, (GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE \
545
 
                           | GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE \
546
 
                           | GRUB_CPU_LOONGSON_CACHE_ACCELERATED)
547
 
        mtc0    $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
548
 
 
549
 
        /* Invalidate all I-cache entries.  */
550
 
        srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_ISIZE_SHIFT
551
 
        andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK
552
 
        ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \
553
 
                               - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
554
 
                               - GRUB_CPU_LOONGSON_I_CACHE_LOG_WAYS))
555
 
        sll $t1, $t2, $t1
556
 
        lui $t2, 0x8000
557
 
 
558
 
1:      
559
 
        cache GRUB_CPU_LOONGSON_COP0_I_INDEX_INVALIDATE, 0($t2)
560
 
        addiu $t1, $t1, -1
561
 
        bne $t1, $zero, 1b
562
 
         addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_I_INDEX_BIT_OFFSET)
563
 
 
564
 
        /* Invalidate all D-cache entries.  */
565
 
        srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT
566
 
        andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK
567
 
        ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \
568
 
                               - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
569
 
                               - GRUB_CPU_LOONGSON_D_CACHE_LOG_WAYS))
570
 
        sll $t1, $t2, $t1
571
 
        lui $t2, 0x8000
572
 
        mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO
573
 
        mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI
574
 
1:
575
 
        /* All four ways.  */
576
 
        cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 0($t2)
577
 
        cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 1($t2)
578
 
        cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 2($t2)
579
 
        cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 3($t2)
580
 
        addiu $t1, $t1, -1
581
 
        bne $t1, $zero, 1b
582
 
         addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET)
583
 
 
584
 
        /* Invalidate all S-cache entries.  */
585
 
        ori $t1, $zero, (1 << (GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE \
586
 
                               - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
587
 
                               - GRUB_CPU_LOONGSON_S_CACHE_LOG_WAYS))
588
 
        lui $t2, 0x8000
589
 
        mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO
590
 
        mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI
591
 
1:
592
 
        /* All four ways.  */
593
 
        cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 0($t2)
594
 
        cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 1($t2)
595
 
        cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 2($t2)
596
 
        cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 3($t2)
597
 
        addiu $t1, $t1, -1
598
 
        bne $t1, $zero, 1b
599
 
         addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET)
600
 
        
601
 
        /* Finally enable cache.  */
602
 
        mfc0    $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
603
 
        addiu   $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK
604
 
        and     $t0, $t1, $t1
605
 
        ori     $t0, $t0, GRUB_CPU_LOONGSON_CACHE_CACHED
606
 
        mtc0    $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
607
 
 
608
 
        lui $a0, %hi(caches_enabled)
609
 
        bal message
610
 
          addiu $a0, $a0, %lo(caches_enabled)
611
 
 
612
 
        /* Set ROM delay cycles to 1.  */
613
 
        lui $t0, %hi(GRUB_CPU_LOONGSON_LIOCFG)
614
 
        lw  $t1, %lo(GRUB_CPU_LOONGSON_LIOCFG) ($t0)
615
 
        addiu $t2, $zero, ~(GRUB_CPU_LOONGSON_ROM_DELAY_MASK \
616
 
                            << GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET)
617
 
        and $t1, $t1, $t2
618
 
        ori $t1, $t1, (1 << GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET)
619
 
        sw  $t1, %lo(GRUB_CPU_LOONGSON_LIOCFG) ($t0)
620
 
        
621
 
        addiu $a0, $zero, -1
622
 
        addiu $a1, $zero, -1
623
 
 
624
 
        /* Take advantage of cache.  */
625
 
        lui $t0, %hi(cached_continue - 0x20000000)
626
 
        addiu $t0, $t0, %lo(cached_continue - 0x20000000)
627
 
        jr $t0
628
 
         addiu $a2, $zero, -1
629
 
 
630
 
cached_continue:
 
 
b'\\ No newline at end of file'