Working SPD reading in fwstart.img
This commit is contained in:
parent
a1efcc79d3
commit
7517048135
8 changed files with 321 additions and 12 deletions
|
@ -80,11 +80,11 @@ grub_cs5536_smbus_wait (grub_port_t smbbase)
|
|||
{
|
||||
grub_uint8_t status;
|
||||
status = grub_inb (smbbase + GRUB_CS5536_SMB_REG_STATUS);
|
||||
if (status & (1 << 6))
|
||||
if (status & GRUB_CS5536_SMB_REG_STATUS_SDAST)
|
||||
return GRUB_ERR_NONE;
|
||||
if (status & (1 << 5))
|
||||
if (status & GRUB_CS5536_SMB_REG_STATUS_BER)
|
||||
return grub_error (GRUB_ERR_IO, "SM bus error");
|
||||
if (status & (1 << 4))
|
||||
if (status & GRUB_CS5536_SMB_REG_STATUS_NACK)
|
||||
return grub_error (GRUB_ERR_IO, "NACK received");
|
||||
if (grub_get_time_ms () > start + 40)
|
||||
return grub_error (GRUB_ERR_IO, "SM stalled");
|
||||
|
|
|
@ -30,6 +30,14 @@ kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \
|
|||
-Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic
|
||||
kernel_img_FORMAT = binary
|
||||
|
||||
pkglib_IMAGES += fwstart.img
|
||||
fwstart_img_SOURCES = kern/$(target_cpu)/$(target_machine)/fwstart.S
|
||||
fwstart_img_CFLAGS = $(COMMON_CFLAGS)
|
||||
fwstart_img_ASFLAGS = $(COMMON_ASFLAGS)
|
||||
fwstart_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \
|
||||
-Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic
|
||||
fwstart_img_FORMAT = binary
|
||||
|
||||
# For ata.mod.
|
||||
pkglib_MODULES += ata.mod
|
||||
ata_mod_SOURCES = disk/ata.c
|
||||
|
|
|
@ -19,17 +19,23 @@
|
|||
#ifndef GRUB_CS5536_HEADER
|
||||
#define GRUB_CS5536_HEADER 1
|
||||
|
||||
#ifndef ASM_FILE
|
||||
#include <grub/pci.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/smbus.h>
|
||||
#endif
|
||||
|
||||
#define GRUB_CS5536_PCIID 0x208f1022
|
||||
#define GRUB_CS5536_MSR_MAILBOX_ADDR 0xf4
|
||||
#define GRUB_CS5536_MSR_MAILBOX_DATA0 0xf8
|
||||
#define GRUB_CS5536_MSR_MAILBOX_DATA1 0xfc
|
||||
#define GRUB_CS5536_MSR_SMB_BAR 0x8000000b
|
||||
#define GRUB_CS5536_MSR_GPIO_BAR 0x8000000c
|
||||
#define GRUB_CS5536_SMB_REG_DATA 0x0
|
||||
#define GRUB_CS5536_SMB_REG_STATUS 0x1
|
||||
#define GRUB_CS5536_SMB_REG_STATUS_SDAST (1 << 6)
|
||||
#define GRUB_CS5536_SMB_REG_STATUS_BER (1 << 5)
|
||||
#define GRUB_CS5536_SMB_REG_STATUS_NACK (1 << 4)
|
||||
#define GRUB_CS5536_SMB_REG_CTRL1 0x3
|
||||
#define GRUB_CS5536_SMB_REG_CTRL1_START 0x01
|
||||
#define GRUB_CS5536_SMB_REG_CTRL1_STOP 0x02
|
||||
|
@ -41,11 +47,19 @@
|
|||
#define GRUB_CS5536_SMB_REG_CTRL3 0x6
|
||||
|
||||
#define GRUB_CS5536_LBAR_ADDR_MASK 0x000000000000fff8ULL
|
||||
#define GRUB_CS5536_LBAR_ADDR_OFF 3
|
||||
#define GRUB_CS5536_LBAR_ENABLE 0x0000000100000000ULL
|
||||
#define GRUB_SMB_RAM_START_ADDR 0x50
|
||||
#define GRUB_SMB_RAM_NUM_MAX 0x08
|
||||
|
||||
/* PMON-compatible LBARs. */
|
||||
#define GRUB_CS5536_LBAR_GPIO 0x0b000
|
||||
#define GRUB_CS5536_LBAR_SMBUS 0x0b390
|
||||
|
||||
#define GRUB_GPIO_SMBUS_PINS ((1 << 14) | (1 << 15))
|
||||
#define GRUB_GPIO_REG_OUT_EN 0x4
|
||||
#define GRUB_GPIO_REG_OUT_AUX1 0x10
|
||||
#define GRUB_GPIO_REG_IN_EN 0x20
|
||||
#define GRUB_GPIO_REG_IN_AUX1 0x34
|
||||
|
||||
#ifndef ASM_FILE
|
||||
int grub_cs5536_find (grub_pci_device_t *devp);
|
||||
|
||||
grub_uint64_t grub_cs5536_read_msr (grub_pci_device_t dev, grub_uint32_t addr);
|
||||
|
@ -58,5 +72,6 @@ grub_err_t grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev,
|
|||
grub_err_t grub_cs5536_smbus_wait (grub_port_t smbbase);
|
||||
grub_err_t grub_cs5536_init_smbus (grub_pci_device_t dev, grub_uint16_t divisor,
|
||||
grub_port_t *smbbase);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_BOOT_MACHINE_HEADER
|
||||
#define GRUB_BOOT_MACHINE_HEADER 1
|
||||
|
||||
#define GRUB_MACHINE_FLASH_START 0xbfc00000
|
||||
#define GRUB_MACHINE_FLASH_TLB_REFILL 0xbfc00200
|
||||
#define GRUB_MACHINE_FLASH_CACHE_ERROR 0xbfc00300
|
||||
#define GRUB_MACHINE_FLASH_OTHER_EXCEPTION 0xbfc00380
|
||||
|
||||
#endif
|
|
@ -19,16 +19,24 @@
|
|||
#ifndef GRUB_MACHINE_PCI_H
|
||||
#define GRUB_MACHINE_PCI_H 1
|
||||
|
||||
#ifndef ASM_FILE
|
||||
#include <grub/types.h>
|
||||
#include <grub/cpu/io.h>
|
||||
#endif
|
||||
|
||||
#define GRUB_PCI_NUM_BUS 1
|
||||
#define GRUB_PCI_NUM_DEVICES 16
|
||||
|
||||
#define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000
|
||||
#define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000
|
||||
|
||||
#ifndef ASM_FILE
|
||||
#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00118)
|
||||
#define GRUB_MACHINE_PCI_IO_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00110)
|
||||
#else
|
||||
#define GRUB_MACHINE_PCI_CONF_CTRL_REG_HI 0xbfe0
|
||||
#define GRUB_MACHINE_PCI_CONF_CTRL_REG_LO 0x0118
|
||||
#endif
|
||||
#define GRUB_MACHINE_PCI_WIN_MASK_SIZE 6
|
||||
#define GRUB_MACHINE_PCI_WIN_MASK ((1 << GRUB_MACHINE_PCI_WIN_MASK_SIZE) - 1)
|
||||
|
||||
|
@ -46,6 +54,7 @@
|
|||
#define GRUB_MACHINE_PCI_WIN2_ADDR 0xb4000000
|
||||
#define GRUB_MACHINE_PCI_WIN3_ADDR 0xb8000000
|
||||
|
||||
#ifndef ASM_FILE
|
||||
static inline grub_uint32_t
|
||||
grub_pci_read (grub_pci_address_t addr)
|
||||
{
|
||||
|
@ -101,5 +110,6 @@ void
|
|||
grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)),
|
||||
volatile void *mem,
|
||||
grub_size_t size __attribute__ ((unused)));
|
||||
#endif
|
||||
|
||||
#endif /* GRUB_MACHINE_PCI_H */
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
#ifndef GRUB_PCI_H
|
||||
#define GRUB_PCI_H 1
|
||||
|
||||
#ifndef ASM_FILE
|
||||
#include <grub/types.h>
|
||||
#include <grub/symbol.h>
|
||||
#endif
|
||||
|
||||
#define GRUB_PCI_ADDR_SPACE_MASK 0x01
|
||||
#define GRUB_PCI_ADDR_SPACE_MEMORY 0x00
|
||||
|
@ -66,6 +68,7 @@
|
|||
#define GRUB_PCI_REG_MIN_GNT 0x3e
|
||||
#define GRUB_PCI_REG_MAX_LAT 0x3f
|
||||
|
||||
#ifndef ASM_FILE
|
||||
typedef grub_uint32_t grub_pci_id_t;
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
|
@ -106,5 +109,6 @@ grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev,
|
|||
int reg);
|
||||
|
||||
void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook);
|
||||
#endif
|
||||
|
||||
#endif /* GRUB_PCI_H */
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
#ifndef GRUB_SMBUS_HEADER
|
||||
#define GRUB_SMBUS_HEADER 1
|
||||
|
||||
#define GRUB_SMB_RAM_START_ADDR 0x50
|
||||
#define GRUB_SMB_RAM_NUM_MAX 0x08
|
||||
|
||||
struct grub_smbus_spd
|
||||
{
|
||||
grub_uint8_t written_size;
|
||||
|
|
|
@ -17,17 +17,107 @@
|
|||
*/
|
||||
|
||||
#include <grub/mips/yeeloong/serial.h>
|
||||
#include <grub/mips/yeeloong/pci.h>
|
||||
#include <grub/mips/yeeloong/boot.h>
|
||||
#include <grub/pci.h>
|
||||
#include <grub/serial.h>
|
||||
#include <grub/cs5536.h>
|
||||
|
||||
.set noreorder
|
||||
.set noat
|
||||
.set nomacro
|
||||
|
||||
.global start,_start,__start
|
||||
start:
|
||||
_start:
|
||||
__start:
|
||||
bal serial_hw_init
|
||||
nop
|
||||
self:
|
||||
b self
|
||||
nop
|
||||
/* Find CS5536 controller. */
|
||||
/* $t4 chooses device in priority encoding. */
|
||||
/* Resulting value is kept in GRUB_MACHINE_PCI_CONF_CTRL_REG.
|
||||
This way we don't need to sacrifice a register for it. */
|
||||
/* We have only one bus (0). Function is 0. */
|
||||
lui $t0, GRUB_MACHINE_PCI_CONF_CTRL_REG_HI
|
||||
lui $t1, %hi(GRUB_MACHINE_PCI_CONFSPACE)
|
||||
lui $t3, %hi(GRUB_CS5536_PCIID)
|
||||
addiu $t3, $t3, %lo(GRUB_CS5536_PCIID)
|
||||
ori $t4, $zero, 1
|
||||
lui $a0, %hi(no_cs5536)
|
||||
1:
|
||||
andi $t4, $t4, 0xffff
|
||||
beql $t4, $zero, fatal
|
||||
addiu $a0, $a0, %lo(no_cs5536)
|
||||
sw $t4, GRUB_MACHINE_PCI_CONF_CTRL_REG_LO($t0)
|
||||
lw $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_PCI_REG_PCI_ID) ($t1)
|
||||
bnel $t2, $t3, 1b
|
||||
sll $t4, $t4, 1
|
||||
|
||||
bal message
|
||||
addiu $a0, $a0, %lo(cs5536_found)
|
||||
bal printhex
|
||||
move $a0, $t4
|
||||
|
||||
/* Initialise SMBus controller. */
|
||||
/* Set GPIO LBAR. */
|
||||
lui $a0, %hi(GRUB_CS5536_MSR_GPIO_BAR)
|
||||
addiu $a0, $a0, %lo(GRUB_CS5536_MSR_GPIO_BAR)
|
||||
ori $a1, $zero, GRUB_CS5536_LBAR_GPIO
|
||||
/* Set mask to 0xf and enabled bit to 1. */
|
||||
bal wrmsr
|
||||
ori $a2, $zero, 0xf001
|
||||
|
||||
/* Set SMBUS LBAR. */
|
||||
lui $a0, %hi(GRUB_CS5536_MSR_SMB_BAR)
|
||||
addiu $a0, $a0, %lo(GRUB_CS5536_MSR_SMB_BAR)
|
||||
ori $a1, $zero, GRUB_CS5536_LBAR_SMBUS
|
||||
/* Set mask to 0xf and enabled bit to 1. */
|
||||
bal wrmsr
|
||||
ori $a2, $zero, 0xf001
|
||||
|
||||
lui $a0, %hi(smbus_enabled)
|
||||
bal message
|
||||
addiu $a0, $a0, %lo(smbus_enabled)
|
||||
|
||||
/* Enable SMBus controller pins. */
|
||||
lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO)
|
||||
ori $t1, $zero, GRUB_GPIO_SMBUS_PINS
|
||||
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_EN) ($t0)
|
||||
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_AUX1) ($t0)
|
||||
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_EN) ($t0)
|
||||
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_AUX1) ($t0)
|
||||
|
||||
lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS)
|
||||
|
||||
/* Disable SMB. */
|
||||
sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0)
|
||||
|
||||
/* Disable interrupts. */
|
||||
sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1) ($t0)
|
||||
|
||||
/* Set as master. */
|
||||
sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_ADDR) ($t0)
|
||||
|
||||
/* Launch SMBus controller at slowest speed possible. */
|
||||
ori $t1, $zero, 0xff
|
||||
sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL3) ($t0)
|
||||
sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0)
|
||||
|
||||
ori $a0, $zero, 0x50
|
||||
bal read_spd
|
||||
move $a1, $zero
|
||||
bal printhex
|
||||
move $a0, $v0
|
||||
|
||||
ori $a0, $zero, 0x50
|
||||
bal read_spd
|
||||
ori $a1, $zero, 2
|
||||
bal printhex
|
||||
move $a0, $v0
|
||||
|
||||
lui $a0, %hi(not_implemented)
|
||||
b fatal
|
||||
addiu $a0, $a0, %lo(not_implemented)
|
||||
|
||||
/* Same as similarly named C function but in asm since
|
||||
we need it early. */
|
||||
|
@ -70,12 +160,164 @@ serial_hw_init:
|
|||
/* In: $a0 = asciiz message. Out: none. Clobbered: $t0, $t1, $a0. */
|
||||
message:
|
||||
lui $t0, GRUB_MACHINE_SERIAL_PORT_HI
|
||||
1:
|
||||
1:
|
||||
lb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_LSR)($t0)
|
||||
andi $t1, $t1, UART_EMPTY_TRANSMITTER
|
||||
beq $t1, $zero, 1b
|
||||
nop
|
||||
lb $t1, 0($a0)
|
||||
addiu $a0, $a0, 1
|
||||
sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_TX)($t0)
|
||||
bne $t1, $zero, 1b
|
||||
sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_TX)($t0)
|
||||
addiu $a0, $a0, 1
|
||||
jr $ra
|
||||
nop
|
||||
|
||||
/* Print 32-bit hexadecimal on serial.
|
||||
In: $a0. Out: None. Clobbered: $a0, $t0, $t1, $t2
|
||||
*/
|
||||
printhex:
|
||||
lui $t0, GRUB_MACHINE_SERIAL_PORT_HI
|
||||
ori $t2, $zero, 8
|
||||
1:
|
||||
lb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_LSR)($t0)
|
||||
andi $t1, $t1, UART_EMPTY_TRANSMITTER
|
||||
beq $t1, $zero, 1b
|
||||
nop
|
||||
srl $t1, $a0, 28
|
||||
addiu $t1, $t1, -10
|
||||
blt $t1, $zero, 2f
|
||||
sll $a0, $a0, 4
|
||||
addiu $t1, $t1, 'A'-10-'0'
|
||||
2: addiu $t1, $t1, '0'+10
|
||||
sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_TX)($t0)
|
||||
addiu $t2, $t2, -1
|
||||
bne $t2, $zero, 1b
|
||||
nop
|
||||
jr $ra
|
||||
nop
|
||||
|
||||
fatal:
|
||||
bal message
|
||||
nop
|
||||
self:
|
||||
b self
|
||||
nop
|
||||
|
||||
. = start + GRUB_MACHINE_FLASH_TLB_REFILL - GRUB_MACHINE_FLASH_START
|
||||
tlb_refill:
|
||||
lui $a0, %hi(unhandled_tlb_refill)
|
||||
b fatal
|
||||
addiu $a0, $a0, %lo(unhandled_tlb_refill)
|
||||
|
||||
. = start + GRUB_MACHINE_FLASH_CACHE_ERROR - GRUB_MACHINE_FLASH_START
|
||||
cache_error:
|
||||
lui $a0, %hi(unhandled_cache_error)
|
||||
b fatal
|
||||
addiu $a0, $a0, %lo(unhandled_cache_error)
|
||||
|
||||
. = start + GRUB_MACHINE_FLASH_OTHER_EXCEPTION - GRUB_MACHINE_FLASH_START
|
||||
other_exception:
|
||||
lui $a0, %hi(unhandled_exception)
|
||||
b fatal
|
||||
addiu $a0, $a0, %lo(unhandled_exception)
|
||||
|
||||
/* Write CS5536 MSR.
|
||||
In: $a0 address, $a1 lower word, $a2 upper word.
|
||||
Out: None
|
||||
Clobbered: $t0
|
||||
*/
|
||||
wrmsr:
|
||||
lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE)
|
||||
sw $a0, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_ADDR) ($t0)
|
||||
sw $a1, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_DATA0) ($t0)
|
||||
jr $ra
|
||||
sw $a2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_DATA1) ($t0)
|
||||
|
||||
/* Wait for SMBus data or empty transmitter. */
|
||||
/* In: $a0 = exception handler. Out: none. Clobbered: $t0, $t1 */
|
||||
smbus_wait:
|
||||
1:
|
||||
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE)
|
||||
lb $t0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE) ($t0)
|
||||
andi $t1, $t0, GRUB_CS5536_SMB_REG_STATUS_SDAST
|
||||
bne $t1, $zero, return
|
||||
nop
|
||||
andi $t1, $t0, (GRUB_CS5536_SMB_REG_STATUS_BER | GRUB_CS5536_SMB_REG_STATUS_NACK)
|
||||
beq $t1, $zero, 1b
|
||||
nop
|
||||
jr $a0
|
||||
nop
|
||||
return:
|
||||
jr $ra
|
||||
nop
|
||||
|
||||
/* Read SPD byte. In: $a0 device, $a1 byte. Out: $v0 read byte (0x100 on failure).
|
||||
Clobbered: $t0, $t1, $t2, $t3, $a0. */
|
||||
read_spd:
|
||||
move $t2, $a0
|
||||
move $t3, $ra
|
||||
lui $a0, %hi(read_spd_fail)
|
||||
addiu $a0, $a0, %hi(read_spd_fail)
|
||||
|
||||
/* Send START. */
|
||||
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
|
||||
lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
|
||||
ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_START
|
||||
bal smbus_wait
|
||||
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
|
||||
|
||||
/* Send device address. */
|
||||
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
|
||||
sll $t1, $t2, 1
|
||||
bal smbus_wait
|
||||
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
|
||||
|
||||
/* Send ACK. */
|
||||
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
|
||||
lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
|
||||
ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_ACK
|
||||
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
|
||||
|
||||
/* Send byte address. */
|
||||
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
|
||||
bal smbus_wait
|
||||
sb $a1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
|
||||
|
||||
/* Send START. */
|
||||
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
|
||||
lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
|
||||
ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_START
|
||||
bal smbus_wait
|
||||
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
|
||||
|
||||
/* Send device address. */
|
||||
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
|
||||
sll $t1, $t2, 1
|
||||
ori $t1, $t1, 1
|
||||
bal smbus_wait
|
||||
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
|
||||
|
||||
/* Send STOP. */
|
||||
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
|
||||
lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
|
||||
ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_STOP
|
||||
bal smbus_wait
|
||||
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
|
||||
|
||||
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
|
||||
lb $v0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
|
||||
jr $t3
|
||||
andi $v0, $v0, 0xff
|
||||
read_spd_fail:
|
||||
jr $t3
|
||||
ori $v0, $v0, 0x100
|
||||
|
||||
notification_string: .asciz "GRUB "
|
||||
no_cs5536: .asciz "No CS5536 found.\n\r"
|
||||
cs5536_found: .asciz "CS5536 at "
|
||||
sm_failed: .asciz "SM transaction failed.\n\r"
|
||||
not_implemented: .asciz "Nothing more is implemented. Bye.\n\r"
|
||||
unhandled_tlb_refill: .asciz "Unhandled TLB refill.\n\r"
|
||||
unhandled_cache_error: .asciz "Unhandled cache error.\n\r"
|
||||
unhandled_exception: .asciz "Unhandled exception.\n\r"
|
||||
smbus_enabled: .asciz "SMBus controller enabled.\n\r"
|
||||
|
|
Loading…
Reference in a new issue