diff --git a/ChangeLog b/ChangeLog index 04a0dc082..70572f940 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,80 @@ +2010-07-01 Vladimir Serbinenko + + Yeeloong firmware port. + + * boot/mips/yeeloong/fwstart.S: New file. + * bus/cs5536.c (gpiodump): New const. + (set_io_space): New function. + (set_iod): Likewise. + (set_p2d): Likewise. + (grub_cs5536_init_geode): Likewise. + * commands/mips/yeeloong/lsspd.c: New file. + * conf/mips-qemu-mips.rmk (pkglib_MODULES): Add serial.mod. + (serial_mod_SOURCES): New variable. + (serial_mod_CFLAGS): Likewise. + (serial_mod_LDFLAGS): Likewise. + * conf/mips-yeeloong.rmk (kernel_img_SOURCES): Add term/serial.c, + term/terminfo.c and term/tparm.c. + (pkglib_IMAGES): Add fwstart.img. + (fwstart_img_SOURCES): New variable. + (fwstart_img_CFLAGS): Likewise. + (fwstart_img_ASFLAGS): Likewise. + (fwstart_img_LDFLAGS): Likewise. + (fwstart_img_FORMAT): Likewise. + (pkglib_MODULES): Add lsspd.mod. + (lsspd_mod_SOURCES): New variable. + (lsspd_mod_CFLAGS): Likewise. + (lsspd_mod_LDFLAGS): Likewise. + (pkglib_MODULES): Add halt.mod. + (halt_mod_SOURCES): New variable. + (halt_mod_CFLAGS): Likewise. + (halt_mod_LDFLAGS): Likewise. + * conf/mips.rmk (pkglib_MODULES): Remove serial.mod. + (serial_mod_SOURCES): Removed. + (serial_mod_CFLAGS): Likewise. + (serial_mod_LDFLAGS): Likewise. + * disk/ata.c (check_device): New function. + (grub_ata_device_initialize): Use check_device. + (grub_ata_iterate): Recheck devices. + (grub_ata_open): Likewise. + (grub_atapi_iterate): Likewise. + (grub_atapi_open): Likewise. + * include/grub/ata.h (GRUB_ATA_CH0_PORT1): New macro. + (GRUB_ATA_CH1_PORT1): Likewise. + (GRUB_ATA_CH0_PORT2): Likewise. + (GRUB_ATA_CH1_PORT2): Likewise. + * include/grub/mips/loongson.h: New file. + * include/grub/mips/yeeloong/ec.h: Likewise. + * include/grub/mips/yeeloong/serial.h (GRUB_MACHINE_SERIAL_PORT): New definition. + (GRUB_MACHINE_SERIAL_DIVISOR_115200): Likewise. + (GRUB_MACHINE_SERIAL_PORTS) [ASM_FILE]: Remove. + * include/grub/misc.h (grub_halt): Declare as noreturn. + * include/grub/serial.h (UART_ENABLE_FIFO): Renamed to ... + (UART_ENABLE_FIFO_TRIGGER14): ... this. All users updated. + (UART_ENABLE_FIFO_TRIGGER1): New definition. + (UART_ENABLE_DTRRTS): Likewise. + (UART_ENABLE_MODEM): Removed. + (UART_ENABLE_OUT2): New const. + * include/grub/term.h (grub_term_register_input_active): New function. + (grub_term_register_output_active): Likewise. + * kern/mips/startup.S [GRUB_MACHINE_MIPS_YEELOONG]: Handle 0xffffffff + argument. + * kern/mips/yeeloong/init.c (grub_get_rtc): Macroify. + (init_pci): New function. + (grub_machine_init): Execute platform init when firmware. Init serial. + (grub_halt): Implement. + (grub_exit): Likewise. + (grub_reboot): Likewise. + * term/serial.c (serial_hw_init): Update macros. + [GRUB_MACHINE_MIPS_YEELOONG]: Init on startup. + * util/grub-mkimage.c (image_target_desc): New id IMAGE_YEELOONG_FLASH. + (image_targets): New target mipsel-yeeloong-flash. + (generate_image): Support IMAGE_YEELOONG_FLASH. + * video/sm712.c (GRUB_SM712_TOTAL_MEMORY_SPACE): New definition. + (grub_video_sm712_setup): Init card. + (grub_video_sm712_set_palette): Removed. + * video/sm712_init.c: New file. + 2010-06-30 Colin Watson * Makefile.in (install-local): Temporarily prepend $(builddir) to diff --git a/boot/mips/yeeloong/fwstart.S b/boot/mips/yeeloong/fwstart.S new file mode 100644 index 000000000..7fe5d7ac2 --- /dev/null +++ b/boot/mips/yeeloong/fwstart.S @@ -0,0 +1,630 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,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 . + */ + +#include +#include +#include +#include +#include +#include +#include + + .set noreorder + .set noat + .set nomacro + + .global start,_start,__start +start: +_start: +__start: + bal serial_hw_init + 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, %hi(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) + 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, ((1 << GRUB_PCI_NUM_DEVICES) - 1) + beql $t4, $zero, fatal + addiu $a0, $a0, %lo(no_cs5536) + sw $t4, %lo(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) ($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, ((GRUB_CS5536_LBAR_MASK_MASK \ + | GRUB_CS5536_LBAR_ENABLE) >> 32) + + /* 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, ((GRUB_CS5536_LBAR_MASK_MASK \ + | GRUB_CS5536_LBAR_ENABLE) >> 32) + + 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) + + /* Yeeloong has only one memory slot. */ + /* Output first byte on serial for debugging. */ + ori $a1, $zero, GRUB_SMB_RAM_START_ADDR + bal read_spd + move $a0, $zero + bal printhex + move $a0, $v0 + + bal read_spd + ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_ADDR + ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2 + lui $a0, %hi(unimplemented_memory_type) + bne $t0, $v0, fatal + addiu $a0, $a0, %hi(unimplemented_memory_type) + + /* And here is our goal: DDR2 controller initialisation. */ + lui $t0, %hi(GRUB_CPU_LOONGSON_CORECFG) + ld $t1, %lo(GRUB_CPU_LOONGSON_CORECFG) ($t0) + /* Use addiu for sign-extension. */ + addiu $t2, $zero, ~(GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE|GRUB_CPU_LOONGSON_CORECFG_BUFFER_CPU) + and $t1, $t1, $t2 + sd $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0) + + b continue + + . = start + GRUB_CPU_LOONGSON_FLASH_TLB_REFILL - GRUB_CPU_LOONGSON_FLASH_START +tlb_refill: + mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC + mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR + move $s3, $ra + lui $a0, %hi(epc) + bal message + addiu $a0, $a0, %lo(epc) + + bal printhex + move $a0, $s1 + + lui $a0, %hi(badvaddr) + bal message + addiu $a0, $a0, %lo(badvaddr) + + bal printhex + move $a0, $s2 + + lui $a0, %hi(return_msg) + bal message + addiu $a0, $a0, %lo(return_msg) + + bal printhex + move $a0, $s3 + + lui $a0, %hi(newline) + bal message + addiu $a0, $a0, %lo(newline) + + lui $a0, %hi(unhandled_tlb_refill) + b fatal + addiu $a0, $a0, %lo(unhandled_tlb_refill) + + . = start + GRUB_CPU_LOONGSON_FLASH_CACHE_ERROR - GRUB_CPU_LOONGSON_FLASH_START +cache_error: + lui $a0, %hi(unhandled_cache_error) + b fatal + addiu $a0, $a0, %lo(unhandled_cache_error) + + . = start + GRUB_CPU_LOONGSON_FLASH_OTHER_EXCEPTION - GRUB_CPU_LOONGSON_FLASH_START +other_exception: + mfc0 $s0, GRUB_CPU_LOONGSON_COP0_CAUSE + mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC + mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR + lui $a0, %hi(cause) + bal message + addiu $a0, $a0, %lo(cause) + + bal printhex + move $a0, $s0 + + lui $a0, %hi(epc) + bal message + addiu $a0, $a0, %lo(epc) + + bal printhex + move $a0, $s1 + + lui $a0, %hi(badvaddr) + bal message + addiu $a0, $a0, %lo(badvaddr) + + bal printhex + move $a0, $s2 + + lui $a0, %hi(newline) + bal message + addiu $a0, $a0, %lo(newline) + + lui $a0, %hi(unhandled_exception) + b fatal + addiu $a0, $a0, %lo(unhandled_exception) + + /* Same as similarly named C function but in asm since + we need it early. */ + /* In: none. Out: none. Clobbered: $t0, $t1, $a0. */ +serial_hw_init: + lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT) + + /* Turn off the interrupt. */ + sb $zero, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_IER)($t0) + + /* Set DLAB. */ + ori $t1, $zero, UART_DLAB + sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LCR)($t0) + + /* Set the baud rate 115200. */ + ori $t1, $zero, GRUB_MACHINE_SERIAL_DIVISOR_115200 + sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLL)($t0) + sb $zero, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLH)($t0) + + /* Set the line status. */ + ori $t1, $zero, (UART_NO_PARITY | UART_8BITS_WORD | UART_1_STOP_BIT) + sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LCR)($t0) + + /* Enable the FIFO. */ + ori $t1, $zero, UART_ENABLE_FIFO_TRIGGER1 + sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_FCR)($t0) + + /* Turn on DTR and RTS. */ + ori $t1, $zero, UART_ENABLE_DTRRTS + sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_MCR)($t0) + + /* Let message return to original caller. */ + lui $a0, %hi(notification_string) + addiu $a0, $a0, %lo(notification_string) + + /* Print message on serial console. */ + /* In: $a0 = asciiz message. Out: none. Clobbered: $t0, $t1, $a0. */ +message: + lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT) +1: + lb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LSR)($t0) + andi $t1, $t1, UART_EMPTY_TRANSMITTER + beq $t1, $zero, 1b + nop + lb $t1, 0($a0) + sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_TX)($t0) + bne $t1, $zero, 1b + 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, %hi (GRUB_MACHINE_SERIAL_PORT) + ori $t2, $zero, 8 +1: + lb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + 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, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_TX)($t0) + addiu $t2, $t2, -1 + bne $t2, $zero, 1b + nop + jr $ra + nop + +fatal: + bal message + nop +self: + b self + nop + + /* 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 byte, $a1 device. 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, $a1, 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 $t2, %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, $a1, 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" +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" +unimplemented_memory_type: .asciz "non-DDR2 memory isn't supported.\n\r" +no_cas_latency: .asciz "Couldn't determine CAS latency.\n\r" +cause: .asciz "Cause: " +epc: .asciz "\n\rEPC: " +badvaddr: .asciz "\n\rBadVaddr: " +newline: .asciz "\n\r" +return_msg: .asciz "\n\rReturn address: " +caches_enabled: .asciz "Caches enabled\n\r" + + .p2align 3 + +regdump: + .quad 0x0100010000000101 /* 0 */ + .quad 0x0100010100000000 /* 2 */ + .quad 0x0101000001000000 /* 3 */ + .quad 0x0100020200010101 /* 4 */ + .quad 0x0a04030603050203 /* 6 */ + .quad 0x0f0e040000010a0b /* 7 */ + .quad 0x0000010200000102 /* 8 */ + .quad 0x0000060c00000000 /* 9 */ + .quad 0x2323233f3f1f0200 /* a */ + .quad 0x5f7f232323232323 /* b */ + .quad 0x002a3c0615000000 /* c */ + .quad 0x002a002a002a002a /* d */ + .quad 0x002a002a002a002a /* e */ + .quad 0x00b40020006d0004 /* f */ + .quad 0x070007ff00000087 /* 10 */ + .quad 0x000000000016101f /* 11 */ + .quad 0x001c000000000000 /* 12 */ + .quad 0x28e1000200c8006b /* 13 */ + .quad 0x0000204200c8002f /* 14 */ + .quad 0x0000000000030d40 /* 15 */ + .quad 0 /* 16 */ + .quad 0 /* 17 */ + .quad 0 /* 18 */ + .quad 0 /* 19 */ + .quad 0 /* 1a */ + .quad 0 /* 1b */ + .quad 0 /* 1c */ + + .p2align + +write_dumpreg: + ld $t2, 0($t6) + sd $t2, 0($t4) + addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP + jr $ra + addiu $t6, $t6, GRUB_CPU_LOONGSON_DDR2_REG_SIZE + +continue: + lui $t4, %hi(GRUB_CPU_LOONGSON_DDR2_BASE) + addiu $t4, $t4, %lo(GRUB_CPU_LOONGSON_DDR2_BASE) + lui $t6, %hi(regdump) + + /* 0 */ + bal write_dumpreg + addiu $t6, $t6, %lo(regdump) + + /* 1 */ + ori $a1, $a1, GRUB_SMB_RAM_START_ADDR + move $t8, $zero + lui $t5, 0x0001 + bal read_spd + ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_BANKS_ADDR + ori $t7, $zero, 8 + bne $v0, $t7, 1f + ori $t5, $t5, 0x0001 + ori $t8, $t8, GRUB_CPU_LOONGSON_DDR2_REG1_HI_8BANKS +1: + dsll $t8, $t8, 32 + or $t5, $t5, $t8 + sd $t5, 0 ($t4) + addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP + + /* 2 */ + bal write_dumpreg + nop + + /* 3 */ + bal write_dumpreg + nop + + /* 4 */ + bal write_dumpreg + nop + + /* 5 */ + /* FIXME: figure termination resistance. */ + ori $t5, $zero, 0x2 + bal read_spd + ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_ROWS_ADDR + /* $v0 = 15 - $v0. */ + xori $v0, $v0, 0xf + andi $v0, $v0, 0x7 + sll $v0, $v0, 8 + or $t5, $t5, $v0 + + /* Find the fastest supported CAS latency. */ + bal read_spd + ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_ADDR + ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE + ori $t1, $zero, (1 << GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE) +2: + and $t2, $t1, $v0 + bne $t2, $zero, 1f + ori $t3, $zero, 8 + lui $a0, %hi(no_cas_latency) + beq $t0, $t3, fatal + addiu $a0, $a0, %lo(no_cas_latency) + addiu $t0, $t0, 1 + b 2b + sll $t1, $t1, 1 +1: + sll $t0, $t0, 16 + or $t5, $t5, $t0 + + bal read_spd + ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_COLUMNS_ADDR + /* $v0 = 15 - ($v0 + 1) = 14 - $v0. */ + addiu $v0, $v0, 1 + xori $v0, $v0, 0xf + andi $v0, $v0, 0x7 + sll $v0, 24 + or $t5, $t5, $v0 + sd $t5, 0 ($t4) + + addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP + + ori $t7, $zero, 0x16 + +1: + ld $t2, 0($t6) + sd $t2, 0($t4) + addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP + addiu $t7, $t7, -1 + bne $t7, $zero, 1b + addiu $t6, $t6, GRUB_CPU_LOONGSON_DDR2_REG_SIZE + + lui $t4, %hi(GRUB_CPU_LOONGSON_DDR2_BASE) + ld $t5, (%lo(GRUB_CPU_LOONGSON_DDR2_BASE) + 0x30) ($t4) + ori $t0, $zero, 1 + dsll $t0, $t0, 40 + or $t5, $t5, $t0 + sd $t5, (%lo(GRUB_CPU_LOONGSON_DDR2_BASE) + 0x30) ($t4) + + /* Desactivate DDR2 registers. */ + lui $t0, %hi (GRUB_CPU_LOONGSON_CORECFG) + ld $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0) + ori $t1, $t1, GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE + sd $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0) + + /* Enable cache. */ + mfc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG + addiu $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK + and $t0, $t1, $t1 + /* Set line size to 32 bytes and disabled cache. */ + ori $t0, $t0, (GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE \ + | GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE \ + | GRUB_CPU_LOONGSON_CACHE_ACCELERATED) + mtc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG + + /* Invalidate all I-cache entries. */ + srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_ISIZE_SHIFT + andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK + ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \ + - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \ + - GRUB_CPU_LOONGSON_I_CACHE_LOG_WAYS)) + sll $t1, $t2, $t1 + lui $t2, 0x8000 + +1: + cache GRUB_CPU_LOONGSON_COP0_I_INDEX_INVALIDATE, 0($t2) + addiu $t1, $t1, -1 + bne $t1, $zero, 1b + addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_I_INDEX_BIT_OFFSET) + + /* Invalidate all D-cache entries. */ + srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT + andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK + ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \ + - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \ + - GRUB_CPU_LOONGSON_D_CACHE_LOG_WAYS)) + sll $t1, $t2, $t1 + lui $t2, 0x8000 + mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO + mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI +1: + /* All four ways. */ + cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 0($t2) + cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 1($t2) + cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 2($t2) + cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 3($t2) + addiu $t1, $t1, -1 + bne $t1, $zero, 1b + addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET) + + /* Invalidate all S-cache entries. */ + ori $t1, $zero, (1 << (GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE \ + - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \ + - GRUB_CPU_LOONGSON_S_CACHE_LOG_WAYS)) + lui $t2, 0x8000 + mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO + mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI +1: + /* All four ways. */ + cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 0($t2) + cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 1($t2) + cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 2($t2) + cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 3($t2) + addiu $t1, $t1, -1 + bne $t1, $zero, 1b + addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET) + + /* Finally enable cache. */ + mfc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG + addiu $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK + and $t0, $t1, $t1 + ori $t0, $t0, GRUB_CPU_LOONGSON_CACHE_CACHED + mtc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG + + lui $a0, %hi(caches_enabled) + bal message + addiu $a0, $a0, %lo(caches_enabled) + + /* Set ROM delay cycles to 1. */ + lui $t0, %hi(GRUB_CPU_LOONGSON_LIOCFG) + lw $t1, %lo(GRUB_CPU_LOONGSON_LIOCFG) ($t0) + addiu $t2, $zero, ~(GRUB_CPU_LOONGSON_ROM_DELAY_MASK \ + << GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET) + and $t1, $t1, $t2 + ori $t1, $t1, (1 << GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET) + sw $t1, %lo(GRUB_CPU_LOONGSON_LIOCFG) ($t0) + + addiu $a0, $zero, -1 + addiu $a1, $zero, -1 + + /* Take advantage of cache. */ + lui $t0, %hi(cached_continue - 0x20000000) + addiu $t0, $t0, %lo(cached_continue - 0x20000000) + jr $t0 + addiu $a2, $zero, -1 + +cached_continue: \ No newline at end of file diff --git a/bus/cs5536.c b/bus/cs5536.c index 61b0646b4..088f4dfc1 100644 --- a/bus/cs5536.c +++ b/bus/cs5536.c @@ -213,3 +213,168 @@ grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev, return GRUB_ERR_NONE; } +/* Dump of GPIO connections. FIXME: Remove useless and macroify. */ +static grub_uint32_t gpiodump[] = { + 0xffff0000, 0x2ffdd002, 0xffff0000, 0xffff0000, + 0x2fffd000, 0xffff0000, 0x1000efff, 0xefff1000, + 0x3ffbc004, 0xffff0000, 0xffff0000, 0xffff0000, + 0x3ffbc004, 0x3ffbc004, 0xffff0000, 0x00000000, + 0xffff0000, 0xffff0000, 0x3ffbc004, 0x3f9bc064, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, + 0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000, + 0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000, + 0xefff1000, 0xefff1000, 0xffff0000, 0x00000000, + 0xffff0000, 0xffff0000, 0xefff1000, 0xffff0000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x50000000, 0x00000000, 0x00000000, +}; + +static inline void +set_io_space (grub_pci_device_t dev, int num, grub_uint16_t start, + grub_uint16_t len) +{ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_REGIONS_START + num, + ((((grub_uint64_t) start + len - 4) + << GRUB_CS5536_MSR_GL_REGION_IO_TOP_SHIFT) + & GRUB_CS5536_MSR_GL_REGION_TOP_MASK) + | (((grub_uint64_t) start + << GRUB_CS5536_MSR_GL_REGION_IO_BASE_SHIFT) + & GRUB_CS5536_MSR_GL_REGION_BASE_MASK) + | GRUB_CS5536_MSR_GL_REGION_IO + | GRUB_CS5536_MSR_GL_REGION_ENABLE); +} + +static inline void +set_iod (grub_pci_device_t dev, int num, int dest, int start, int mask) +{ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_IOD_START + num, + ((grub_uint64_t) dest << GRUB_CS5536_IOD_DEST_SHIFT) + | (((grub_uint64_t) start & GRUB_CS5536_IOD_ADDR_MASK) + << GRUB_CS5536_IOD_BASE_SHIFT) + | ((mask & GRUB_CS5536_IOD_ADDR_MASK) + << GRUB_CS5536_IOD_MASK_SHIFT)); +} + +static inline void +set_p2d (grub_pci_device_t dev, int num, int dest, grub_uint32_t start) +{ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_P2D_START + num, + (((grub_uint64_t) dest) << GRUB_CS5536_P2D_DEST_SHIFT) + | ((grub_uint64_t) (start >> GRUB_CS5536_P2D_LOG_ALIGN) + << GRUB_CS5536_P2D_BASE_SHIFT) + | (((1 << (32 - GRUB_CS5536_P2D_LOG_ALIGN)) - 1) + << GRUB_CS5536_P2D_MASK_SHIFT)); +} + +void +grub_cs5536_init_geode (grub_pci_device_t dev) +{ + int i; + + /* Make sure GPIO is where we expect it to be. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GPIO_BAR, + GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_GPIO); + + /* Setup GPIO. */ + for (i = 0; i < (int) ARRAY_SIZE (gpiodump); i++) + ((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_IO_BASE + + GRUB_CS5536_LBAR_GPIO)) [i] = gpiodump[i]; + + /* Enable more BARs. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IRQ_MAP_BAR, + GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_IRQ_MAP); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_MFGPT_BAR, + GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_MFGPT); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_ACPI_BAR, + GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_ACPI); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_PM_BAR, + GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_PM); + + /* Setup DIVIL. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO, + GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 + | GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP + | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 + | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK, + (~GRUB_CS5536_DIVIL_LPC_INTERRUPTS) & 0xffff); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK, + GRUB_CS5536_DIVIL_LPC_INTERRUPTS); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL, + GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE); + + /* Initialise USB controller. */ + /* FIXME: assign adresses dynamically. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, + GRUB_CS5536_MSR_USB_BASE_BUS_MASTER + | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE + | 0x05024000); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, + GRUB_CS5536_MSR_USB_BASE_BUS_MASTER + | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE + | (0x20ULL << GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT) + | 0x05023000); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_CONTROLLER_BASE, + GRUB_CS5536_MSR_USB_BASE_BUS_MASTER + | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE | 0x05020000); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE, + GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE | 0x05022000); + set_p2d (dev, 0, GRUB_CS5536_DESTINATION_USB, 0x05020000); + set_p2d (dev, 1, GRUB_CS5536_DESTINATION_USB, 0x05022000); + set_p2d (dev, 5, GRUB_CS5536_DESTINATION_USB, 0x05024000); + set_p2d (dev, 6, GRUB_CS5536_DESTINATION_USB, 0x05023000); + + { + volatile grub_uint32_t *oc; + oc = grub_pci_device_map_range (dev, 0x05022000, + GRUB_CS5536_USB_OPTION_REGS_SIZE); + + oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX] = + (oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX] + & ~GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK) + | GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC; + grub_pci_device_unmap_range (dev, oc, GRUB_CS5536_USB_OPTION_REGS_SIZE); + } + + /* Setup IDE controller. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_IO_BAR, + GRUB_CS5536_LBAR_IDE + | GRUB_CS5536_MSR_IDE_IO_BAR_UNITS); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CFG, + GRUB_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_TIMING, + (GRUB_CS5536_MSR_IDE_TIMING_PIO0 + << GRUB_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT) + | (GRUB_CS5536_MSR_IDE_TIMING_PIO0 + << GRUB_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT)); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CAS_TIMING, + (GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0 + << GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT) + | (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 + << GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT) + | (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 + << GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT)); + + /* Setup Geodelink PCI. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_PCI_CTRL, + (4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT) + | (4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT) + | (8ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT) + | GRUB_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE + | GRUB_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE); + + /* Setup windows. */ + set_io_space (dev, 0, GRUB_CS5536_LBAR_SMBUS, GRUB_CS5536_SMBUS_REGS_SIZE); + set_io_space (dev, 1, GRUB_CS5536_LBAR_GPIO, GRUB_CS5536_GPIO_REGS_SIZE); + set_io_space (dev, 2, GRUB_CS5536_LBAR_MFGPT, GRUB_CS5536_MFGPT_REGS_SIZE); + set_io_space (dev, 3, GRUB_CS5536_LBAR_IRQ_MAP, GRUB_CS5536_IRQ_MAP_REGS_SIZE); + set_io_space (dev, 4, GRUB_CS5536_LBAR_PM, GRUB_CS5536_PM_REGS_SIZE); + set_io_space (dev, 5, GRUB_CS5536_LBAR_ACPI, GRUB_CS5536_ACPI_REGS_SIZE); + set_iod (dev, 0, GRUB_CS5536_DESTINATION_IDE, GRUB_ATA_CH0_PORT1, 0xffff8); + set_iod (dev, 1, GRUB_CS5536_DESTINATION_ACC, GRUB_CS5536_LBAR_ACC, 0xfff80); + set_iod (dev, 2, GRUB_CS5536_DESTINATION_IDE, GRUB_CS5536_LBAR_IDE, 0xffff0); +} diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 956a27292..47cca7ce4 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -222,7 +222,6 @@ grub_ohci_pci_iter (grub_pci_device_t dev, if ((revision & 0xFF) != 0x10) goto fail; - { grub_uint32_t control; /* Check SMM/BIOS ownership of OHCI (SMM = USB Legacy Support driver for BIOS) */ diff --git a/commands/mips/yeeloong/lsspd.c b/commands/mips/yeeloong/lsspd.c new file mode 100644 index 000000000..539cda34c --- /dev/null +++ b/commands/mips/yeeloong/lsspd.c @@ -0,0 +1,92 @@ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_lsspd (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_pci_device_t dev; + grub_port_t smbbase; + int i; + grub_err_t err; + + if (!grub_cs5536_find (&dev)) + { + grub_printf ("No CS5536 found\n"); + return GRUB_ERR_NONE; + } + grub_printf ("CS5536 at %d:%d.%d\n", grub_pci_get_bus (dev), + grub_pci_get_device (dev), grub_pci_get_function (dev)); + + err = grub_cs5536_init_smbus (dev, 0x7fff, &smbbase); + if (err) + return err; + + grub_printf ("SMB base = 0x%x\n", smbbase); + + for (i = GRUB_SMB_RAM_START_ADDR; + i < GRUB_SMB_RAM_START_ADDR + GRUB_SMB_RAM_NUM_MAX; i++) + { + struct grub_smbus_spd spd; + grub_memset (&spd, 0, sizeof (spd)); + grub_printf ("Device %d\n", i); + err = grub_cs5536_read_spd (smbbase, i, &spd); + if (err) + { + grub_print_error (); + continue; + } + grub_printf ("Written SPD bytes: %d B.\n", spd.written_size); + grub_printf ("Total flash size: %d B.\n", 1 << spd.log_total_flash_size); + if (spd.memory_type == GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2) + { + char str[sizeof (spd.ddr2.part_number) + 1]; + grub_printf ("Memory type: DDR2.\n"); + grub_memcpy (str, spd.ddr2.part_number, + sizeof (spd.ddr2.part_number)); + str[sizeof (spd.ddr2.part_number)] = 0; + grub_printf ("Part no: %s.\n", str); + } + else + grub_printf ("Memory type: Unknown.\n"); + } + + return GRUB_ERR_NONE; +} + +static grub_command_t cmd; + +GRUB_MOD_INIT(lsspd) +{ + cmd = grub_register_command ("lsspd", grub_cmd_lsspd, 0, + "Print Memory information."); +} + +GRUB_MOD_FINI(lsspd) +{ + grub_unregister_command (cmd); +} diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk index b7eb513e7..be2b9f555 100644 --- a/conf/mips-qemu-mips.rmk +++ b/conf/mips-qemu-mips.rmk @@ -20,3 +20,9 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic kernel_img_FORMAT = binary + +# For serial.mod. +pkglib_MODULES += serial.mod +serial_mod_SOURCES = term/serial.c +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 337bc41aa..deb6dd33f 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -27,13 +27,21 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \ video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \ term/gfxterm.c commands/extcmd.c lib/arg.c \ - bus/cs5536.c \ + bus/cs5536.c term/serial.c term/terminfo.c term/tparm.c \ symlist.c kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic kernel_img_FORMAT = binary +pkglib_IMAGES += fwstart.img +fwstart_img_SOURCES = boot/$(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 @@ -65,12 +73,24 @@ datetime_mod_SOURCES = lib/cmos_datetime.c datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For lsspd.mod +pkglib_MODULES += lsspd.mod +lsspd_mod_SOURCES = commands/mips/yeeloong/lsspd.c +lsspd_mod_CFLAGS = $(COMMON_CFLAGS) +lsspd_mod_LDFLAGS = $(COMMON_LDFLAGS) + pkglib_MODULES += linux.mod linux_mod_SOURCES = loader/$(target_cpu)/linux.c linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_ASFLAGS = $(COMMON_ASFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For halt.mod. +pkglib_MODULES += halt.mod +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For usb.mod pkglib_MODULES += usb.mod usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c diff --git a/conf/mips.rmk b/conf/mips.rmk index 7d30f55f1..26c516fc4 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -10,12 +10,6 @@ kernel_img_HEADERS += cpu/cache.h sbin_SCRIPTS = bin_SCRIPTS = -# For serial.mod. -pkglib_MODULES += serial.mod -serial_mod_SOURCES = term/serial.c -serial_mod_CFLAGS = $(COMMON_CFLAGS) -serial_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For relocator.mod. pkglib_MODULES += relocator.mod relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/$(target_cpu)/relocator_asm.S diff --git a/disk/ata.c b/disk/ata.c index 687ed9378..1b55ee680 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -24,10 +24,13 @@ #include #include #include +#include /* At the moment, only two IDE ports are supported. */ -static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 }; -static const grub_port_t grub_ata_ioaddress2[] = { 0x3f6, 0x376 }; +static const grub_port_t grub_ata_ioaddress[] = { GRUB_ATA_CH0_PORT1, + GRUB_ATA_CH1_PORT1 }; +static const grub_port_t grub_ata_ioaddress2[] = { GRUB_ATA_CH0_PORT2, + GRUB_ATA_CH1_PORT2 }; static struct grub_ata_device *grub_ata_devices; @@ -331,11 +334,38 @@ grub_ata_identify (struct grub_ata_device *dev) return 0; } +static grub_err_t +check_device (struct grub_ata_device *dev) +{ + grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4); + grub_ata_wait (); + + /* Try to detect if the port is in use by writing to it, + waiting for a while and reading it again. If the value + was preserved, there is a device connected. */ + grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A); + grub_ata_wait (); + grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS); + grub_dprintf ("ata", "sectors=0x%x\n", sec); + if (sec != 0x5A) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no device connected"); + + /* The above test may detect a second (slave) device + connected to a SATA controller which supports only one + (master) device. It is not safe to use the status register + READY bit to check for controller channel existence. Some + ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */ + + /* Use the IDENTIFY DEVICE command to query the device. */ + return grub_ata_identify (dev); +} + static grub_err_t grub_ata_device_initialize (int port, int device, int addr, int addr2) { struct grub_ata_device *dev; struct grub_ata_device **devp; + grub_err_t err; grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n", port, device, addr, addr2); @@ -351,39 +381,14 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2) dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE; dev->next = NULL; - grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4); - grub_ata_wait (); - - /* Try to detect if the port is in use by writing to it, - waiting for a while and reading it again. If the value - was preserved, there is a device connected. */ - grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A); - grub_ata_wait (); - grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS); - grub_dprintf ("ata", "sectors=0x%x\n", sec); - if (sec != 0x5A) - { - grub_free(dev); - return 0; - } - - /* The above test may detect a second (slave) device - connected to a SATA controller which supports only one - (master) device. It is not safe to use the status register - READY bit to check for controller channel existence. Some - ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */ - - /* Use the IDENTIFY DEVICE command to query the device. */ - if (grub_ata_identify (dev)) - { - grub_free (dev); - return 0; - } - /* Register the device. */ for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next); *devp = dev; + err = check_device (dev); + if (err) + grub_print_error (); + return 0; } @@ -408,7 +413,7 @@ grub_ata_pciinit (grub_pci_device_t dev, class = grub_pci_read (addr); /* AMD CS5536 Southbridge. */ - if (pciid == 0x208f1022) + if (pciid == GRUB_CS5536_PCIID) { cs5536 = 1; nports = 1; @@ -666,6 +671,14 @@ grub_ata_iterate (int (*hook) (const char *name)) for (dev = grub_ata_devices; dev; dev = dev->next) { char devname[10]; + grub_err_t err; + + err = check_device (dev); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } if (dev->atapi) continue; @@ -684,6 +697,7 @@ static grub_err_t grub_ata_open (const char *name, grub_disk_t disk) { struct grub_ata_device *dev; + grub_err_t err; for (dev = grub_ata_devices; dev; dev = dev->next) { @@ -700,6 +714,11 @@ grub_ata_open (const char *name, grub_disk_t disk) if (dev->atapi) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk"); + err = check_device (dev); + + if (err) + return err; + disk->total_sectors = dev->size; disk->id = (unsigned long) dev; @@ -756,6 +775,16 @@ grub_atapi_iterate (int (*hook) (const char *name, int luns)) for (dev = grub_ata_devices; dev; dev = dev->next) { char devname[10]; + + grub_err_t err; + + err = check_device (dev); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + grub_snprintf (devname, sizeof (devname), "ata%d", dev->port * 2 + dev->device); @@ -826,6 +855,7 @@ grub_atapi_open (const char *name, struct grub_scsi *scsi) { struct grub_ata_device *dev; struct grub_ata_device *devfnd = 0; + grub_err_t err; for (dev = grub_ata_devices; dev; dev = dev->next) { @@ -845,6 +875,13 @@ grub_atapi_open (const char *name, struct grub_scsi *scsi) if (! devfnd) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device"); + err = check_device (devfnd); + if (err) + return err; + + if (! devfnd->atapi) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device"); + scsi->data = devfnd; return GRUB_ERR_NONE; diff --git a/include/grub/ata.h b/include/grub/ata.h index 940e67102..9e3aaf0e6 100644 --- a/include/grub/ata.h +++ b/include/grub/ata.h @@ -32,6 +32,12 @@ typedef enum GRUB_ATA_LBA48 } grub_ata_addressing_t; +#define GRUB_ATA_CH0_PORT1 0x1f0 +#define GRUB_ATA_CH1_PORT1 0x170 + +#define GRUB_ATA_CH0_PORT2 0x3f6 +#define GRUB_ATA_CH1_PORT2 0x376 + #define GRUB_ATA_REG_DATA 0 #define GRUB_ATA_REG_ERROR 1 #define GRUB_ATA_REG_FEATURES 1 diff --git a/include/grub/mips/loongson.h b/include/grub/mips/loongson.h new file mode 100644 index 000000000..6cb1178d5 --- /dev/null +++ b/include/grub/mips/loongson.h @@ -0,0 +1,90 @@ +/* + * 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 . + */ + +#ifndef GRUB_LOONGSON_CPU_HEADER +#define GRUB_LOONGSON_CPU_HEADER 1 + +#ifdef ASM_FILE +#define GRUB_CPU_REGISTER_WRAP(x) x +#else +#define GRUB_CPU_REGISTER_WRAP(x) #x +#endif + +#define GRUB_CPU_LOONGSON_FLASH_START 0xbfc00000 +#define GRUB_CPU_LOONGSON_FLASH_TLB_REFILL 0xbfc00200 +#define GRUB_CPU_LOONGSON_FLASH_CACHE_ERROR 0xbfc00300 +#define GRUB_CPU_LOONGSON_FLASH_OTHER_EXCEPTION 0xbfc00380 + +#define GRUB_CPU_LOONGSON_DDR2_BASE 0xaffffe00 +#define GRUB_CPU_LOONGSON_DDR2_REG1_HI_8BANKS 0x00000001 +#define GRUB_CPU_LOONGSON_DDR2_REG_SIZE 0x8 +#define GRUB_CPU_LOONGSON_DDR2_REG_STEP 0x10 + +#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG GRUB_CPU_REGISTER_WRAP($16) +#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE 0x10 +#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE 0x8 +#define GRUB_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT 6 +#define GRUB_CPU_LOONGSON_COP0_CACHE_ISIZE_SHIFT 9 +#define GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK 0x7 +#define GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET 12 + +#define GRUB_CPU_LOONGSON_COP0_I_INDEX_INVALIDATE 0 +#define GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE 9 +#define GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE 11 + +#define GRUB_CPU_LOONGSON_COP0_I_INDEX_BIT_OFFSET 5 +#define GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET 5 +#define GRUB_CPU_LOONGSON_COP0_S_INDEX_BIT_OFFSET 5 + +#define GRUB_CPU_LOONGSON_CACHE_ACCELERATED 7 +#define GRUB_CPU_LOONGSON_CACHE_UNCACHED 2 +#define GRUB_CPU_LOONGSON_CACHE_CACHED 3 +#define GRUB_CPU_LOONGSON_CACHE_TYPE_MASK 7 +#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_SMALL 4 +#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG 5 +#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_SMALL 16 +#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_BIG 32 + +#define GRUB_CPU_LOONGSON_I_CACHE_LOG_WAYS 2 +#define GRUB_CPU_LOONGSON_D_CACHE_LOG_WAYS 2 +#define GRUB_CPU_LOONGSON_S_CACHE_LOG_WAYS 2 + +/* FIXME: determine dynamically. */ +#define GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE 19 + +#define GRUB_CPU_LOONGSON_COP0_BADVADDR GRUB_CPU_REGISTER_WRAP($8) +#define GRUB_CPU_LOONGSON_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP($9) +#define GRUB_CPU_LOONGSON_COP0_CAUSE GRUB_CPU_REGISTER_WRAP($13) +#define GRUB_CPU_LOONGSON_COP0_EPC GRUB_CPU_REGISTER_WRAP($14) +#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO GRUB_CPU_REGISTER_WRAP($28) +#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI GRUB_CPU_REGISTER_WRAP($29) + +#define GRUB_CPU_LOONGSON_LIOCFG 0xbfe00108 +#define GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET 2 +#define GRUB_CPU_LOONGSON_ROM_DELAY_MASK 0x1f +#define GRUB_CPU_LOONGSON_CORECFG 0xbfe00180 +#define GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE 0x100 +#define GRUB_CPU_LOONGSON_CORECFG_BUFFER_CPU 0x200 + +#define GRUB_CPU_LOONGSON_PCI_HIT1_SEL_LO 0xbfe00150 +#define GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI 0xbfe00154 + +#define GRUB_CPU_LOONGSON_GPIOCFG 0xbfe00120 +#define GRUB_CPU_LOONGSON_SHUTDOWN_GPIO 1 + +#endif diff --git a/include/grub/mips/yeeloong/ec.h b/include/grub/mips/yeeloong/ec.h new file mode 100644 index 000000000..62d1d33d9 --- /dev/null +++ b/include/grub/mips/yeeloong/ec.h @@ -0,0 +1,41 @@ +/* + * 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 . + */ + +#ifndef GRUB_EC_MACHINE_HEADER +#define GRUB_EC_MACHINE_HEADER 1 + +#define GRUB_MACHINE_EC_MAGIC_PORT1 0x381 +#define GRUB_MACHINE_EC_MAGIC_PORT2 0x382 +#define GRUB_MACHINE_EC_DATA_PORT 0x383 + +#define GRUB_MACHINE_EC_MAGIC_VAL1 0xf4 +#define GRUB_MACHINE_EC_MAGIC_VAL2 0xec + +#define GRUB_MACHINE_EC_COMMAND_REBOOT 1 + +static inline void +grub_write_ec (grub_uint8_t value) +{ + grub_outb (GRUB_MACHINE_EC_MAGIC_VAL1, + GRUB_MACHINE_PCI_IO_BASE + GRUB_MACHINE_EC_MAGIC_PORT1); + grub_outb (GRUB_MACHINE_EC_MAGIC_VAL2, + GRUB_MACHINE_PCI_IO_BASE + GRUB_MACHINE_EC_MAGIC_PORT2); + grub_outb (value, GRUB_MACHINE_PCI_IO_BASE + GRUB_MACHINE_EC_DATA_PORT); +} + +#endif diff --git a/include/grub/mips/yeeloong/serial.h b/include/grub/mips/yeeloong/serial.h index 9390ea18a..ebe3638a1 100644 --- a/include/grub/mips/yeeloong/serial.h +++ b/include/grub/mips/yeeloong/serial.h @@ -19,6 +19,12 @@ #ifndef GRUB_MACHINE_SERIAL_HEADER #define GRUB_MACHINE_SERIAL_HEADER 1 -#define GRUB_MACHINE_SERIAL_PORTS { 0xbff003f8 } +#define GRUB_MACHINE_SERIAL_DIVISOR_115200 2 +#define GRUB_MACHINE_SERIAL_PORT 0xbff003f8 + +#ifndef ASM_FILE +#define GRUB_MACHINE_SERIAL_PORTS { GRUB_MACHINE_SERIAL_PORT } +#else +#endif #endif diff --git a/include/grub/misc.h b/include/grub/misc.h index 9bfc6974e..a1b753250 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -303,9 +303,9 @@ void EXPORT_FUNC (grub_reboot) (void); #ifdef GRUB_MACHINE_PCBIOS /* Halt the system, using APM if possible. If NO_APM is true, don't * use APM even if it is available. */ -void EXPORT_FUNC (grub_halt) (int no_apm); +void EXPORT_FUNC (grub_halt) (int no_apm) __attribute__ ((noreturn)); #else -void EXPORT_FUNC (grub_halt) (void); +void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn)); #endif #endif /* ! GRUB_MISC_HEADER */ diff --git a/include/grub/serial.h b/include/grub/serial.h index 1c35b4093..758b6fb3e 100644 --- a/include/grub/serial.h +++ b/include/grub/serial.h @@ -59,9 +59,15 @@ #define UART_DLAB 0x80 /* Enable the FIFO. */ -#define UART_ENABLE_FIFO 0xC7 +#define UART_ENABLE_FIFO_TRIGGER14 0xC7 + +/* Enable the FIFO. */ +#define UART_ENABLE_FIFO_TRIGGER1 0x07 /* Turn on DTR, RTS, and OUT2. */ -#define UART_ENABLE_MODEM 0x0B +#define UART_ENABLE_DTRRTS 0x03 + +/* Turn on DTR, RTS, and OUT2. */ +#define UART_ENABLE_OUT2 0x08 #endif /* ! GRUB_SERIAL_MACHINE_HEADER */ diff --git a/include/grub/term.h b/include/grub/term.h index 4a05909da..971a8db32 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -213,6 +213,14 @@ grub_term_register_input (const char *name __attribute__ ((unused)), } } +static inline void +grub_term_register_input_active (const char *name __attribute__ ((unused)), + grub_term_input_t term) +{ + if (! term->init || term->init () == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term)); +} + static inline void grub_term_register_output (const char *name __attribute__ ((unused)), grub_term_output_t term) @@ -229,6 +237,15 @@ grub_term_register_output (const char *name __attribute__ ((unused)), } } +static inline void +grub_term_register_output_active (const char *name __attribute__ ((unused)), + grub_term_output_t term) +{ + if (! term->init || term->init () == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), + GRUB_AS_LIST (term)); +} + static inline void grub_term_unregister_input (grub_term_input_t term) { diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 1d18131be..c67bb9742 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -49,8 +49,15 @@ codestart: /* Parse arguments. Has to be done before relocation. So need to do it in asm. */ #ifdef GRUB_MACHINE_MIPS_YEELOONG + move $s2, $zero + move $s3, $zero + move $s4, $zero + move $s5, $zero + /* $a2 has the environment. */ - move $t0, $a2 + addiu $t0, $a2, 1 + beq $t0, $zero, argdone + move $t0, $a2 argcont: lw $t1, 0($t0) beq $t1, $zero, argdone diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 47aa774a0..523f90282 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -26,6 +26,10 @@ #include #include #include +#include +#include +#include +#include extern void grub_video_sm712_init (void); extern void grub_video_init (void); @@ -33,6 +37,8 @@ extern void grub_bitmap_init (void); extern void grub_font_init (void); extern void grub_gfxterm_init (void); extern void grub_at_keyboard_init (void); +extern void grub_serial_init (void); +extern void grub_terminfo_init (void); /* FIXME: use interrupt to count high. */ grub_uint64_t @@ -42,7 +48,7 @@ grub_get_rtc (void) static grub_uint32_t last = 0; grub_uint32_t low; - asm volatile ("mfc0 %0, $9": "=r" (low)); + asm volatile ("mfc0 %0, " GRUB_CPU_LOONGSON_COP0_TIMER_COUNT : "=r" (low)); if (low < last) high++; last = low; @@ -62,25 +68,147 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, return GRUB_ERR_NONE; } +static void +init_pci (void) +{ + auto int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid); + int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid) + { + grub_pci_address_t addr; + /* FIXME: autoscan for BARs and devices. */ + switch (pciid) + { + case GRUB_YEELOONG_OHCI_PCIID: + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + grub_pci_write (addr, 0x5025000); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); + grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE + | GRUB_PCI_COMMAND_PARITY_ERROR + | GRUB_PCI_COMMAND_BUS_MASTER + | GRUB_PCI_COMMAND_MEM_ENABLED); + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); + grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES); + break; + case GRUB_YEELOONG_EHCI_PCIID: + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + grub_pci_write (addr, 0x5026000); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); + grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE + | GRUB_PCI_COMMAND_PARITY_ERROR + | GRUB_PCI_COMMAND_BUS_MASTER + | GRUB_PCI_COMMAND_MEM_ENABLED); + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); + grub_pci_write_word (addr, (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT) + | GRUB_PCI_STATUS_CAPABILITIES); + break; + } + return 0; + } + + *((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_LO) = 0x8000000c; + *((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI) = 0xffffffff; + + /* Setup PCI controller. */ + *((volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_COMMAND)) + = GRUB_PCI_COMMAND_PARITY_ERROR | GRUB_PCI_COMMAND_BUS_MASTER + | GRUB_PCI_COMMAND_MEM_ENABLED; + *((volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_STATUS)) + = (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT) + | GRUB_PCI_STATUS_FAST_B2B_CAPABLE | GRUB_PCI_STATUS_66MHZ_CAPABLE + | GRUB_PCI_STATUS_CAPABILITIES; + + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_CACHELINE)) = 0xff; + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_ADDRESS_REG0)) + = 0x80000000 | GRUB_PCI_ADDR_MEM_TYPE_64 | GRUB_PCI_ADDR_MEM_PREFETCH; + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_ADDRESS_REG1)) = 0; + + grub_pci_iterate (set_card); +} + void grub_machine_init (void) { grub_addr_t modend; + + /* FIXME: measure this. */ + if (grub_arch_busclock == 0) + { + grub_arch_busclock = 66000000; + grub_arch_cpuclock = 797000000; + } + + grub_install_get_time_ms (grub_rtc_get_time_ms); + + if (grub_arch_memsize == 0) + { + grub_port_t smbbase; + grub_err_t err; + grub_pci_device_t dev; + struct grub_smbus_spd spd; + unsigned totalmem; + int i; + + if (!grub_cs5536_find (&dev)) + grub_fatal ("No CS5536 found\n"); + + err = grub_cs5536_init_smbus (dev, 0x7ff, &smbbase); + if (err) + grub_fatal ("Couldn't init SMBus: %s\n", grub_errmsg); + + /* Yeeloong has only one memory slot. */ + err = grub_cs5536_read_spd (smbbase, GRUB_SMB_RAM_START_ADDR, &spd); + if (err) + grub_fatal ("Couldn't read SPD: %s\n", grub_errmsg); + for (i = 5; i < 13; i++) + if (spd.ddr2.rank_capacity & (1 << (i & 7))) + break; + /* Something is wrong. */ + if (i == 13) + totalmem = 256; + else + totalmem = ((spd.ddr2.num_of_ranks + & GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_MASK) + 1) << (i + 2); + + if (totalmem >= 256) + { + grub_arch_memsize = 256; + grub_arch_highmemsize = totalmem - 256; + } + else + { + grub_arch_memsize = (totalmem >> 20); + grub_arch_highmemsize = 0; + } + + grub_cs5536_init_geode (dev); + + init_pci (); + } + modend = grub_modules_get_end (); grub_mm_init_region ((void *) modend, (grub_arch_memsize << 20) - (modend - GRUB_ARCH_LOWMEMVSTART)); /* FIXME: use upper memory as well. */ - grub_install_get_time_ms (grub_rtc_get_time_ms); /* Initialize output terminal (can't be done earlier, as gfxterm relies on a working heap. */ - grub_video_sm712_init (); grub_video_init (); + grub_video_sm712_init (); grub_bitmap_init (); grub_font_init (); grub_gfxterm_init (); grub_at_keyboard_init (); + + grub_terminfo_init (); + grub_serial_init (); } void @@ -89,20 +217,29 @@ grub_machine_fini (void) } void -grub_exit (void) +grub_halt (void) { + grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG) + & ~GRUB_CPU_LOONGSON_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG); + + grub_printf ("Shutdown failed\n"); + grub_refresh (); while (1); } void -grub_halt (void) +grub_exit (void) { - while (1); + grub_halt (); } void grub_reboot (void) { + grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT); + + grub_printf ("Reboot failed\n"); + grub_refresh (); while (1); } diff --git a/term/serial.c b/term/serial.c index 2347bb3ee..ef9efac2e 100644 --- a/term/serial.c +++ b/term/serial.c @@ -300,10 +300,17 @@ serial_hw_init (void) /* In Yeeloong serial port has only 3 wires. */ #ifndef GRUB_MACHINE_MIPS_YEELOONG /* Enable the FIFO. */ - grub_outb (UART_ENABLE_FIFO, serial_settings.port + UART_FCR); + grub_outb (UART_ENABLE_FIFO_TRIGGER1, serial_settings.port + UART_FCR); + + /* Turn on DTR and RTS. */ + grub_outb (UART_ENABLE_DTRRTS, serial_settings.port + UART_MCR); +#else + /* Enable the FIFO. */ + grub_outb (UART_ENABLE_FIFO_TRIGGER14, serial_settings.port + UART_FCR); /* Turn on DTR, RTS, and OUT2. */ - grub_outb (UART_ENABLE_MODEM, serial_settings.port + UART_MCR); + grub_outb (UART_ENABLE_DTRRTS | UART_ENABLE_OUT2, + serial_settings.port + UART_MCR); #endif /* Drain the input buffer. */ @@ -629,6 +636,21 @@ GRUB_MOD_INIT(serial) serial_settings.word_len = UART_8BITS_WORD; serial_settings.parity = UART_NO_PARITY; serial_settings.stop_bits = UART_1_STOP_BIT; + +#ifdef GRUB_MACHINE_MIPS_YEELOONG + { + grub_err_t hwiniterr; + hwiniterr = serial_hw_init (); + + if (hwiniterr == GRUB_ERR_NONE) + { + grub_term_register_input_active ("serial", &grub_serial_term_input); + grub_term_register_output_active ("serial", &grub_serial_term_output); + + registered = 1; + } + } +#endif } GRUB_MOD_FINI(serial) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 7b03c2fd0..c89eddc32 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -53,7 +53,7 @@ struct image_target_desc enum { IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, - IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC + IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH } id; enum { @@ -223,6 +223,26 @@ struct image_target_desc image_targets[] = .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, }, + { + .name = "mipsel-yeeloong-flash", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_YEELOONG_FLASH, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, + .data_end = GRUB_KERNEL_MIPS_YEELOONG_DATA_END, + .raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE, + .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, + .compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE, + .kernel_image_size = GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN + }, { .name = "mipsel-yeeloong-elf", .voidp_sizeof = 4, @@ -984,6 +1004,34 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], free (boot_path); } break; + case IMAGE_YEELOONG_FLASH: + { + char *rom_img; + size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; + + boot_path = grub_util_get_path (dir, "fwstart.img"); + boot_size = grub_util_get_image_size (boot_path); + boot_img = grub_util_read_image (boot_path); + + rom_size = ALIGN_UP (core_size + boot_size, 512 * 1024); + + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); + + memcpy (rom_img, boot_img, boot_size); + + memcpy (rom_img + boot_size, core_img, core_size); + + memset (rom_img + boot_size + core_size, 0, + rom_size - (boot_size + core_size)); + + free (core_img); + core_img = rom_img; + core_size = rom_size; + } + break; case IMAGE_YEELOONG_ELF: case IMAGE_PPC: case IMAGE_COREBOOT: diff --git a/video/sm712.c b/video/sm712.c index 44bfd74c3..a58032c42 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -27,6 +27,10 @@ #include #include +#include "sm712_init.c" + +#define GRUB_SM712_TOTAL_MEMORY_SPACE 0x700400 + static struct { struct grub_video_mode_info mode_info; @@ -52,7 +56,7 @@ grub_video_sm712_video_fini (void) { if (framebuffer.mapped) grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr, - 1024 * 600 * 2); + GRUB_SM712_TOTAL_MEMORY_SPACE); return grub_video_fb_fini (); } @@ -64,6 +68,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, int depth; grub_err_t err; int found = 0; + unsigned i; auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))); int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))) @@ -99,11 +104,6 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, if (!found) return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); - if (found && framebuffer.base == 0) - { - /* FIXME: change framebuffer base */ - } - /* Fill mode info details. */ framebuffer.mode_info.width = 1024; framebuffer.mode_info.height = 600; @@ -121,12 +121,64 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, framebuffer.mode_info.reserved_mask_size = 0; framebuffer.mode_info.reserved_field_pos = 0; framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); + + if (found && framebuffer.base == 0) + { + grub_pci_address_t addr; + /* FIXME: choose address dynamically if needed. */ + framebuffer.base = 0x04000000; + + addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_ADDRESS_REG0); + grub_pci_write (addr, framebuffer.base); + + /* Set latency. */ + addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_CACHELINE); + grub_pci_write (addr, 0x8); + + /* Enable address spaces. */ + addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_COMMAND); + grub_pci_write (addr, 0x7); + } + /* We can safely discard volatile attribute. */ - framebuffer.ptr = (void *) grub_pci_device_map_range (framebuffer.dev, - framebuffer.base, - 1024 * 600 * 2); + framebuffer.ptr + = (void *) grub_pci_device_map_range (framebuffer.dev, + framebuffer.base, + GRUB_SM712_TOTAL_MEMORY_SPACE); framebuffer.mapped = 1; + /* Initialise SM712. */ + grub_outb (0x18, GRUB_MACHINE_PCI_IO_BASE + 0x3c4); + grub_outb (0x11, GRUB_MACHINE_PCI_IO_BASE + 0x3c5); + + /* Prevent garbage from appearing on the screen. */ + grub_memset (framebuffer.ptr, 0, + framebuffer.mode_info.height * framebuffer.mode_info.pitch); + + for (i = 0; i < ARRAY_SIZE (sm712_init); i++) + switch (sm712_init[i].directive) + { + case 1: + *(volatile grub_uint8_t *) ((char *) framebuffer.ptr + + sm712_init[i].addr) = sm712_init[i].val; + break; + case -1: + { + grub_uint8_t val = *(volatile grub_uint8_t *) + ((char *) framebuffer.ptr + sm712_init[i].addr); + (void) val; + } + break; + case 2: + *(volatile grub_uint16_t *) ((char *) framebuffer.ptr + + sm712_init[i].addr) = sm712_init[i].val; + break; + case 4: + *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + + sm712_init[i].addr) = sm712_init[i].val; + break; + } + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); if (err) @@ -143,19 +195,6 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, return err; } -static grub_err_t -grub_video_sm712_set_palette (unsigned int start, unsigned int count, - struct grub_video_palette_data *palette_data) -{ - if (framebuffer.index_color_mode) - { - /* TODO: Implement setting indexed color mode palette to hardware. */ - } - - /* Then set color to emulated palette. */ - return grub_video_fb_set_palette (start, count, palette_data); -} - static grub_err_t grub_video_sm712_swap_buffers (void) { @@ -197,7 +236,7 @@ static struct grub_video_adapter grub_video_sm712_adapter = .setup = grub_video_sm712_setup, .get_info = grub_video_fb_get_info, .get_info_and_fini = grub_video_sm712_get_info_and_fini, - .set_palette = grub_video_sm712_set_palette, + .set_palette = grub_video_fb_set_palette, .get_palette = grub_video_fb_get_palette, .set_viewport = grub_video_fb_set_viewport, .get_viewport = grub_video_fb_get_viewport, diff --git a/video/sm712_init.c b/video/sm712_init.c new file mode 100644 index 000000000..02c64c453 --- /dev/null +++ b/video/sm712_init.c @@ -0,0 +1,546 @@ +/* Following sequence is a capture of sm712 initialisation sequence. */ +static struct +{ + int directive; + grub_uint32_t addr; + grub_uint32_t val; +} sm712_init[] = +{ + {1, 0x7003c4, 0x21}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x62}, + {1, 0x7003c5, 0x7a}, + {1, 0x7003c4, 0x6a}, + {1, 0x7003c5, 0x16}, + {1, 0x7003c4, 0x6b}, + {1, 0x7003c5, 0x2}, + {1, 0x7003c6, 0x0}, + {1, 0x7003c4, 0x0}, + {1, 0x7003c5, 0x1}, + {1, 0x7003c2, 0xeb}, + {1, 0x7003c4, 0x0}, + {1, 0x7003c5, 0x3}, + {1, 0x7003c4, 0x1}, + {1, 0x7003c5, 0x1}, + {1, 0x7003c4, 0x2}, + {1, 0x7003c5, 0xf}, + {1, 0x7003c4, 0x3}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x4}, + {1, 0x7003c5, 0xe}, + {1, 0x7003c4, 0x10}, + {1, 0x7003c5, 0xc8}, + {1, 0x7003c4, 0x11}, + {1, 0x7003c5, 0x40}, + {1, 0x7003c4, 0x12}, + {1, 0x7003c5, 0x14}, + {1, 0x7003c4, 0x13}, + {1, 0x7003c5, 0x60}, + {1, 0x7003c4, 0x14}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x15}, + {1, 0x7003c5, 0xa}, + {1, 0x7003c4, 0x16}, + {1, 0x7003c5, 0x92}, + {1, 0x7003c4, 0x17}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x18}, + {1, 0x7003c5, 0x51}, + {1, 0x7003c4, 0x19}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x1a}, + {1, 0x7003c5, 0x1}, + {1, 0x7003c4, 0x1b}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x1c}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x1d}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x1e}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x1f}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x20}, + {1, 0x7003c5, 0xc4}, + {1, 0x7003c4, 0x21}, + {1, 0x7003c5, 0x30}, + {1, 0x7003c4, 0x22}, + {1, 0x7003c5, 0x2}, + {1, 0x7003c4, 0x23}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x24}, + {1, 0x7003c5, 0x1}, + {1, 0x7003c4, 0x30}, + {1, 0x7003c5, 0x28}, + {1, 0x7003c4, 0x31}, + {1, 0x7003c5, 0x3}, + {1, 0x7003c4, 0x32}, + {1, 0x7003c5, 0x24}, + {1, 0x7003c4, 0x33}, + {1, 0x7003c5, 0x9}, + {1, 0x7003c4, 0x34}, + {1, 0x7003c5, 0xc0}, + {1, 0x7003c4, 0x35}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x36}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x37}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x38}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x39}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x3a}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x3b}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x3c}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x3d}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x3e}, + {1, 0x7003c5, 0x3}, + {1, 0x7003c4, 0x3f}, + {1, 0x7003c5, 0xff}, + {1, 0x7003c4, 0x40}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x41}, + {1, 0x7003c5, 0xfc}, + {1, 0x7003c4, 0x42}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x43}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x44}, + {1, 0x7003c5, 0x20}, + {1, 0x7003c4, 0x45}, + {1, 0x7003c5, 0x18}, + {1, 0x7003c4, 0x46}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x47}, + {1, 0x7003c5, 0xfc}, + {1, 0x7003c4, 0x48}, + {1, 0x7003c5, 0x20}, + {1, 0x7003c4, 0x49}, + {1, 0x7003c5, 0xc}, + {1, 0x7003c4, 0x4a}, + {1, 0x7003c5, 0x44}, + {1, 0x7003c4, 0x4b}, + {1, 0x7003c5, 0x20}, + {1, 0x7003c4, 0x4c}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x4d}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x4e}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x4f}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x50}, + {1, 0x7003c5, 0x6}, + {1, 0x7003c4, 0x51}, + {1, 0x7003c5, 0x68}, + {1, 0x7003c4, 0x52}, + {1, 0x7003c5, 0xa7}, + {1, 0x7003c4, 0x53}, + {1, 0x7003c5, 0x7f}, + {1, 0x7003c4, 0x54}, + {1, 0x7003c5, 0x83}, + {1, 0x7003c4, 0x55}, + {1, 0x7003c5, 0x24}, + {1, 0x7003c4, 0x56}, + {1, 0x7003c5, 0xff}, + {1, 0x7003c4, 0x57}, + {1, 0x7003c5, 0x3}, + {1, 0x7003c4, 0x58}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x59}, + {1, 0x7003c5, 0x60}, + {1, 0x7003c4, 0x5a}, + {1, 0x7003c5, 0x59}, + {1, 0x7003c4, 0x5b}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x5c}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x5d}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x5e}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x5f}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x60}, + {1, 0x7003c5, 0x1}, + {1, 0x7003c4, 0x61}, + {1, 0x7003c5, 0x80}, + {1, 0x7003c4, 0x63}, + {1, 0x7003c5, 0x1a}, + {1, 0x7003c4, 0x64}, + {1, 0x7003c5, 0x1a}, + {1, 0x7003c4, 0x65}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x66}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x67}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x68}, + {1, 0x7003c5, 0x50}, + {1, 0x7003c4, 0x69}, + {1, 0x7003c5, 0x3}, + {1, 0x7003c4, 0x6c}, + {1, 0x7003c5, 0x52}, + {1, 0x7003c4, 0x6d}, + {1, 0x7003c5, 0x89}, + {1, 0x7003c4, 0x6e}, + {1, 0x7003c5, 0x9}, + {1, 0x7003c4, 0x6f}, + {1, 0x7003c5, 0x2}, + {1, 0x7003c4, 0x70}, + {1, 0x7003c5, 0x4}, + {1, 0x7003c4, 0x71}, + {1, 0x7003c5, 0x45}, + {1, 0x7003c4, 0x72}, + {1, 0x7003c5, 0x30}, + {1, 0x7003c4, 0x73}, + {1, 0x7003c5, 0x30}, + {1, 0x7003c4, 0x74}, + {1, 0x7003c5, 0x40}, + {1, 0x7003c4, 0x75}, + {1, 0x7003c5, 0x20}, + {1, 0x7003c4, 0x80}, + {1, 0x7003c5, 0xff}, + {1, 0x7003c4, 0x81}, + {1, 0x7003c5, 0x7}, + {1, 0x7003c4, 0x82}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x83}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x84}, + {1, 0x7003c5, 0x8}, + {1, 0x7003c4, 0x85}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x86}, + {1, 0x7003c5, 0x42}, + {1, 0x7003c4, 0x87}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x88}, + {1, 0x7003c5, 0x59}, + {1, 0x7003c4, 0x89}, + {1, 0x7003c5, 0x2}, + {1, 0x7003c4, 0x8a}, + {1, 0x7003c5, 0x44}, + {1, 0x7003c4, 0x8b}, + {1, 0x7003c5, 0x2}, + {1, 0x7003c4, 0x8c}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x8d}, + {1, 0x7003c5, 0xff}, + {1, 0x7003c4, 0x8e}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x8f}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x90}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x91}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x92}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x93}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0xa0}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0xa1}, + {1, 0x7003c5, 0x10}, + {1, 0x7003c4, 0xa2}, + {1, 0x7003c5, 0x8}, + {1, 0x7003c4, 0xa3}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0xa4}, + {1, 0x7003c5, 0x2}, + {1, 0x7003c4, 0xa5}, + {1, 0x7003c5, 0xed}, + {1, 0x7003c4, 0xa6}, + {1, 0x7003c5, 0xed}, + {1, 0x7003c4, 0xa7}, + {1, 0x7003c5, 0xed}, + {1, 0x7003c4, 0xa8}, + {1, 0x7003c5, 0x7b}, + {1, 0x7003c4, 0xa9}, + {1, 0x7003c5, 0xfb}, + {1, 0x7003c4, 0xaa}, + {1, 0x7003c5, 0xff}, + {1, 0x7003c4, 0xab}, + {1, 0x7003c5, 0xff}, + {1, 0x7003c4, 0xac}, + {1, 0x7003c5, 0x97}, + {1, 0x7003c4, 0xad}, + {1, 0x7003c5, 0xef}, + {1, 0x7003c4, 0xae}, + {1, 0x7003c5, 0xbf}, + {1, 0x7003c4, 0xaf}, + {1, 0x7003c5, 0xdf}, + {1, 0x7003ce, 0x0}, + {1, 0x7003cf, 0x0}, + {1, 0x7003ce, 0x1}, + {1, 0x7003cf, 0x0}, + {1, 0x7003ce, 0x2}, + {1, 0x7003cf, 0x0}, + {1, 0x7003ce, 0x3}, + {1, 0x7003cf, 0x0}, + {1, 0x7003ce, 0x4}, + {1, 0x7003cf, 0x0}, + {1, 0x7003ce, 0x5}, + {1, 0x7003cf, 0x40}, + {1, 0x7003ce, 0x6}, + {1, 0x7003cf, 0x5}, + {1, 0x7003ce, 0x7}, + {1, 0x7003cf, 0xf}, + {1, 0x7003ce, 0x8}, + {1, 0x7003cf, 0xff}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x0}, + {-1, 0x7003c1, 0x3e}, + {1, 0x7003c0, 0x0}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x1}, + {-1, 0x7003c1, 0x3b}, + {1, 0x7003c0, 0x1}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x2}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0x2}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x3}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0x3}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x4}, + {-1, 0x7003c1, 0x3b}, + {1, 0x7003c0, 0x4}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x5}, + {-1, 0x7003c1, 0x2f}, + {1, 0x7003c0, 0x5}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x6}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0x6}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x7}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0x7}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x8}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0x8}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x9}, + {-1, 0x7003c1, 0x3d}, + {1, 0x7003c0, 0x9}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0xa}, + {-1, 0x7003c1, 0x1f}, + {1, 0x7003c0, 0xa}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0xb}, + {-1, 0x7003c1, 0x1f}, + {1, 0x7003c0, 0xb}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0xc}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0xc}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0xd}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0xd}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0xe}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0xe}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0xf}, + {-1, 0x7003c1, 0x2e}, + {1, 0x7003c0, 0xf}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x10}, + {-1, 0x7003c1, 0x0}, + {1, 0x7003c0, 0x41}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x11}, + {-1, 0x7003c1, 0x0}, + {1, 0x7003c0, 0x0}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x12}, + {-1, 0x7003c1, 0x0}, + {1, 0x7003c0, 0xf}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x13}, + {-1, 0x7003c1, 0x0}, + {1, 0x7003c0, 0x0}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x14}, + {-1, 0x7003c1, 0x0}, + {1, 0x7003c0, 0x0}, + {1, 0x7003d4, 0x0}, + {1, 0x7003d5, 0xa3}, + {1, 0x7003d4, 0x1}, + {1, 0x7003d5, 0x7f}, + {1, 0x7003d4, 0x2}, + {1, 0x7003d5, 0x7f}, + {1, 0x7003d4, 0x3}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x4}, + {1, 0x7003d5, 0x85}, + {1, 0x7003d4, 0x5}, + {1, 0x7003d5, 0x16}, + {1, 0x7003d4, 0x6}, + {1, 0x7003d5, 0x24}, + {1, 0x7003d4, 0x7}, + {1, 0x7003d5, 0xf5}, + {1, 0x7003d4, 0x8}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x9}, + {1, 0x7003d5, 0x60}, + {1, 0x7003d4, 0xa}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xb}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xc}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xd}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xe}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xf}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x10}, + {1, 0x7003d5, 0x3}, + {1, 0x7003d4, 0x11}, + {1, 0x7003d5, 0x9}, + {1, 0x7003d4, 0x12}, + {1, 0x7003d5, 0xff}, + {1, 0x7003d4, 0x13}, + {1, 0x7003d5, 0x80}, + {1, 0x7003d4, 0x14}, + {1, 0x7003d5, 0x40}, + {1, 0x7003d4, 0x15}, + {1, 0x7003d5, 0xff}, + {1, 0x7003d4, 0x16}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x17}, + {1, 0x7003d5, 0xe3}, + {1, 0x7003d4, 0x18}, + {1, 0x7003d5, 0xff}, + {1, 0x7003d4, 0x30}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x31}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x32}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x33}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x34}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x35}, + {1, 0x7003d5, 0x80}, + {1, 0x7003d4, 0x36}, + {1, 0x7003d5, 0x2}, + {1, 0x7003d4, 0x37}, + {1, 0x7003d5, 0x20}, + {1, 0x7003d4, 0x38}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x39}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x3a}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x3b}, + {1, 0x7003d5, 0x40}, + {1, 0x7003d4, 0x3c}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x3d}, + {1, 0x7003d5, 0xff}, + {1, 0x7003d4, 0x3e}, + {1, 0x7003d5, 0x46}, + {1, 0x7003d4, 0x3f}, + {1, 0x7003d5, 0x91}, + {1, 0x7003d4, 0x40}, + {1, 0x7003d5, 0xa3}, + {1, 0x7003d4, 0x41}, + {1, 0x7003d5, 0x7f}, + {1, 0x7003d4, 0x42}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x43}, + {1, 0x7003d5, 0x86}, + {1, 0x7003d4, 0x44}, + {1, 0x7003d5, 0x15}, + {1, 0x7003d4, 0x45}, + {1, 0x7003d5, 0x24}, + {1, 0x7003d4, 0x46}, + {1, 0x7003d5, 0xff}, + {1, 0x7003d4, 0x47}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x48}, + {1, 0x7003d5, 0x1}, + {1, 0x7003d4, 0x49}, + {1, 0x7003d5, 0x7}, + {1, 0x7003d4, 0x4a}, + {1, 0x7003d5, 0xe5}, + {1, 0x7003d4, 0x4b}, + {1, 0x7003d5, 0x20}, + {1, 0x7003d4, 0x4c}, + {1, 0x7003d5, 0x7f}, + {1, 0x7003d4, 0x4d}, + {1, 0x7003d5, 0x57}, + {1, 0x7003d4, 0x90}, + {1, 0x7003d5, 0x55}, + {1, 0x7003d4, 0x91}, + {1, 0x7003d5, 0xd5}, + {1, 0x7003d4, 0x92}, + {1, 0x7003d5, 0x5d}, + {1, 0x7003d4, 0x93}, + {1, 0x7003d5, 0xdd}, + {1, 0x7003d4, 0x94}, + {1, 0x7003d5, 0x86}, + {1, 0x7003d4, 0x95}, + {1, 0x7003d5, 0x17}, + {1, 0x7003d4, 0x96}, + {1, 0x7003d5, 0x8e}, + {1, 0x7003d4, 0x97}, + {1, 0x7003d5, 0xaa}, + {1, 0x7003d4, 0x98}, + {1, 0x7003d5, 0x8a}, + {1, 0x7003d4, 0x99}, + {1, 0x7003d5, 0xa3}, + {1, 0x7003d4, 0x9a}, + {1, 0x7003d5, 0xde}, + {1, 0x7003d4, 0x9b}, + {1, 0x7003d5, 0xab}, + {1, 0x7003d4, 0x9c}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x9d}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x9e}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x9f}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xa0}, + {1, 0x7003d5, 0x2}, + {1, 0x7003d4, 0xa1}, + {1, 0x7003d5, 0x2}, + {1, 0x7003d4, 0xa2}, + {1, 0x7003d5, 0x2}, + {1, 0x7003d4, 0xa3}, + {1, 0x7003d5, 0x15}, + {1, 0x7003d4, 0xa4}, + {1, 0x7003d5, 0x2}, + {1, 0x7003d4, 0xa5}, + {1, 0x7003d5, 0x6}, + {1, 0x7003d4, 0xa6}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xa7}, + {1, 0x7003d5, 0x0}, + {1, 0x7003c2, 0x67}, + {4, 0x40c00c, 0x0}, + {4, 0x40c040, 0x0}, + {4, 0x40c000, 0x20000}, + {4, 0x40c010, 0x1020100}, + {1, 0x7003c4, 0x16}, + {-1, 0x7003c5, 0x17} +};