Init video early on yeeloong to avoid being rebooted by watchdog.

* grub-core/Makefile.am (gensm712): New target.
	(sm712_start.S): Likewise.
	(boot/mips/loongson/fwstart.S): Depend on sm712_start.S
	* grub-core/boot/mips/loongson/fwstart.S [!FULOONG2F]: Init SM712.
	* grub-core/video/sm712.c [GENINIT]: Generate compact init procedure
	description.
	* include/grub/vga.h: Move registry definitions to...
	* include/grub/vgaregs.h: ... here.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-06-26 03:36:14 +02:00
parent 5f92c8a110
commit c50c867da3
6 changed files with 507 additions and 288 deletions

View file

@ -40,6 +40,15 @@ trigtables.c: gentrigtables gentrigtables.c $(top_srcdir)/configure.ac
$(builddir)/gentrigtables > $@
CLEANFILES += trigtables.c
gensm712: video/sm712.c
$(BUILD_CC) -DGENINIT -o $@ -I$(top_builddir) -I$(top_builddir)/include -I$(top_srcdir)/include $(CPPFLAGS) $<
CLEANFILES += gensm712
# trigtables.c
sm712_start.S: gensm712 video/sm712.c $(top_srcdir)/configure.ac
$(builddir)/gensm712 > $@
CLEANFILES += sm712_start.S
# XXX Use Automake's LEX & YACC support
grub_script.tab.h: script/parser.y
$(YACC) -d -p grub_script_yy -b grub_script $<
@ -55,6 +64,7 @@ rs_decoder.S: $(srcdir)/lib/reed_solomon.c
$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Os -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3 -ffreestanding
kern/i386/pc/startup.S: $(builddir)/rs_decoder.S
boot/mips/loongson/fwstart.S: $(builddir)/sm712_start.S
CLEANFILES += grub_script.yy.c grub_script.yy.h

View file

@ -26,6 +26,12 @@
#include <grub/cs5536.h>
#include <grub/smbus.h>
#ifndef FULOONG2F
#include <grub/vgaregs.h>
#define GRUB_SM712_REG_BASE 0x700000
#define GRUB_SM712_PCIID 0x0712126f
#endif
#ifdef FULOONG2F
#define GRUB_MACHINE_SERIAL_PORT GRUB_MACHINE_SERIAL_PORT2
#define GRUB_MACHINE_SERIAL_DIVISOR_115200 GRUB_MACHINE_SERIAL_PORT2_DIVISOR_115200
@ -748,3 +754,140 @@ continue:
#endif
cached_continue:
#ifndef FULOONG2F
/* We have to init video early enough or watchdog will reboot us. */
/* Setup PCI controller. */
lui $t0, %hi (GRUB_CPU_LOONGSON_PCI_HIT1_SEL_LO)
lui $t1, %hi(0x8000000c)
addiu $t1, $t1, %lo(0x8000000c)
sw $t1, %lo (GRUB_CPU_LOONGSON_PCI_HIT1_SEL_LO) ($t0)
li $t1, 0xffffffff
sw $t1, %lo (GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI) ($t0)
li $t0, GRUB_MACHINE_PCI_CONTROLLER_HEADER
li $t1, (GRUB_PCI_COMMAND_PARITY_ERROR | GRUB_PCI_COMMAND_BUS_MASTER \
| GRUB_PCI_COMMAND_MEM_ENABLED)
sh $t0, GRUB_PCI_REG_COMMAND ($t1)
li $t1, ((1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT) \
| GRUB_PCI_STATUS_FAST_B2B_CAPABLE \
| GRUB_PCI_STATUS_66MHZ_CAPABLE \
| GRUB_PCI_STATUS_CAPABILITIES)
sh $t0, GRUB_PCI_REG_STATUS ($t1)
li $t0, 0xff
sw $t0, GRUB_PCI_REG_CACHELINE ($t1)
lui $t1, %hi(0x80000000 | GRUB_PCI_ADDR_MEM_TYPE_64 \
| GRUB_PCI_ADDR_MEM_PREFETCH)
addiu $t1, $t1, %lo(0x80000000 | GRUB_PCI_ADDR_MEM_TYPE_64 \
| GRUB_PCI_ADDR_MEM_PREFETCH)
sw $t0, GRUB_PCI_REG_ADDRESS_REG0 ($t1)
sw $zero, GRUB_PCI_REG_ADDRESS_REG1 ($t1)
/* Find video. */
/* $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. */
retry_sm712:
/* 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_SM712_PCIID)
addiu $t3, $t3, %lo(GRUB_SM712_PCIID)
ori $t4, $zero, 1
1:
andi $t4, $t4, ((1 << GRUB_PCI_NUM_DEVICES) - 1)
/* In case of failure try again. SM712 may be slow to come up. */
beql $t4, $zero, retry_sm712
nop
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
/* FIXME: choose address dynamically if needed. */
#define SM712_MAP 0x04000000
lui $t2, %hi(SM712_MAP)
sw $t4, %lo(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) ($t0)
sw $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_PCI_REG_ADDRESS_REG0) ($t1)
/* Set latency. */
li $t2, 0x8
sw $t4, %lo(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) ($t0)
sw $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_PCI_REG_CACHELINE) ($t1)
/* Enable address spaces. */
li $t2, 0x7
sw $t4, %lo(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) ($t0)
sw $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_PCI_REG_COMMAND) ($t1)
lui $t3, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_INDEX)
li $t2, 0x18
sb $t2, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_INDEX)($t3)
lui $t3, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_DATA)
li $t2, 0x11
sb $t2, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_DATA)($t3)
li $t2, ((((SM712_MAP & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK) \
>> GRUB_MACHINE_PCI_WIN_SHIFT) \
& GRUB_MACHINE_PCI_WIN_MASK))
lui $t3, %hi(0xbfe00110)
addiu $t3, $t3, %lo(0xbfe00110)
sw $t2, 0 ($t3)
li $t2, (GRUB_MACHINE_PCI_WIN1_ADDR \
| (SM712_MAP & GRUB_MACHINE_PCI_WIN_OFFSET_MASK))
lui $t3, %hi(GRUB_SM712_REG_BASE)
addiu $t3, $t3, %lo(GRUB_SM712_REG_BASE)
addu $t2, $t2, $t3
lui $t0, %hi(init_table - 0x20000000)
addiu $t0, $t0, %lo(init_table - 0x20000000)
lui $t1, %hi(init_table_end - 0x20000000)
addiu $t1, $t1, %lo(init_table_end - 0x20000000)
li $t5, 0x80
addiu $t6, $t2, 0x3c0
table_cont:
lb $t3, 0($t0)
andi $t5, $t3, 0x80
andi $t3, $t3, 0x7f
addu $t3, $t3, $t6
lb $t4, 1($t0)
bne $zero, $t5, 1f
addiu $t0, $t0, 2
b 2f
sb $t4, 0($t3)
1:
lb $t4, 0($t3)
2:
bne $t0, $t1, table_cont
nop
lui $t3, %hi(0x40c000 - GRUB_SM712_REG_BASE)
addiu $t3, $t3, %lo(0x40c000 - GRUB_SM712_REG_BASE)
addu $t1, $t2, $t3
sw $zero, 0xc ($t1)
sw $zero, 0x40 ($t1)
li $t3, 0x20000
sw $t3, 0x0 ($t1)
lui $t3, %hi(0x1020100)
addiu $t3, $t3, %lo(0x1020100)
sw $t3, 0x10 ($t1)
li $t4, 0x16
sb $t4, GRUB_VGA_IO_SR_INDEX($t2)
lb $t4, GRUB_VGA_IO_SR_DATA($t2)
b init_end
nop
init_table:
#include "sm712_start.S"
init_table_end:
.align 4
init_end:
#endif

View file

@ -18,6 +18,7 @@
#define grub_video_render_target grub_video_fbrender_target
#if !defined (TEST) && !defined(GENINIT)
#include <grub/err.h>
#include <grub/types.h>
#include <grub/dl.h>
@ -28,6 +29,15 @@
#include <grub/pci.h>
#include <grub/vga.h>
#include <grub/cache.h>
#else
typedef unsigned char grub_uint8_t;
typedef unsigned short grub_uint16_t;
typedef unsigned int grub_uint32_t;
typedef int grub_err_t;
#include <grub/vgaregs.h>
#include <stdio.h>
#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))
#endif
#include "sm712_init.c"
@ -194,16 +204,20 @@ static struct
static struct
{
#if !defined (TEST) && !defined(GENINIT)
struct grub_video_mode_info mode_info;
#endif
volatile grub_uint8_t *ptr;
grub_uint8_t *cached_ptr;
int mapped;
grub_uint32_t base;
#if !defined (TEST) && !defined(GENINIT)
grub_pci_device_t dev;
#endif
} framebuffer;
#ifndef TEST
#if !defined (TEST) && !defined(GENINIT)
static grub_err_t
grub_video_sm712_video_init (void)
{
@ -232,6 +246,10 @@ grub_sm712_write_reg (grub_uint8_t val, grub_uint16_t addr)
{
#ifdef TEST
printf (" {1, 0x%x, 0x%x},\n", addr, val);
#elif defined (GENINIT)
printf (" .byte 0x%02x, 0x%02x\n", (addr - 0x3c0), val);
if ((addr - 0x3c0) & ~0x7f)
printf ("FAIL\n");
#else
*(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE
+ addr) = val;
@ -243,6 +261,10 @@ grub_sm712_read_reg (grub_uint16_t addr)
{
#ifdef TEST
printf (" {-1, 0x%x, 0x5},\n", addr);
#elif defined (GENINIT)
if ((addr - 0x3c0) & ~0x7f)
printf ("FAIL\n");
printf (" .byte 0x%04x, 0x00\n", (addr - 0x3c0) | 0x80);
#else
return *(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE
+ addr);
@ -342,12 +364,12 @@ static grub_err_t
grub_video_sm712_setup (unsigned int width, unsigned int height,
unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
{
unsigned i;
#if !defined (TEST) && !defined(GENINIT)
int depth;
grub_err_t err;
int found = 0;
unsigned i;
#ifndef TEST
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)))
{
@ -382,7 +404,6 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
grub_pci_iterate (find_card);
if (!found)
return grub_error (GRUB_ERR_IO, "Couldn't find graphics card");
#endif
/* Fill mode info details. */
framebuffer.mode_info.width = 1024;
framebuffer.mode_info.height = 600;
@ -401,12 +422,11 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
framebuffer.mode_info.blue_field_pos = 0;
framebuffer.mode_info.reserved_mask_size = 0;
framebuffer.mode_info.reserved_field_pos = 0;
#ifndef TEST
framebuffer.mode_info.blit_format
= grub_video_get_blit_format (&framebuffer.mode_info);
#endif
#ifndef TEST
#if !defined (TEST) && !defined(GENINIT)
if (found && framebuffer.base == 0)
{
grub_pci_address_t addr;
@ -427,7 +447,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
#endif
/* We can safely discard volatile attribute. */
#ifndef TEST
#if !defined (TEST) && !defined(GENINIT)
framebuffer.ptr
= grub_pci_device_map_range (framebuffer.dev,
framebuffer.base,
@ -440,12 +460,12 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
framebuffer.mapped = 1;
/* Initialise SM712. */
#ifndef TEST
#if !defined (TEST) && !defined(GENINIT)
/* FIXME */
grub_vga_sr_write (0x11, 0x18);
#endif
#ifndef TEST
#if !defined (TEST) && !defined(GENINIT)
/* Prevent garbage from appearing on the screen. */
grub_memset ((void *) framebuffer.cached_ptr, 0,
framebuffer.mode_info.height * framebuffer.mode_info.pitch);
@ -687,7 +707,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
| GRUB_VGA_IO_MISC_COLOR,
GRUB_VGA_IO_MISC_WRITE);
#ifndef TEST
#if !defined (TEST) && !defined(GENINIT)
/* Undocumented? */
*(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c00c) = 0;
*(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c040) = 0;
@ -697,7 +717,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
(void) grub_sm712_sr_read (0x16);
#ifndef TEST
#if !defined (TEST) && !defined(GENINIT)
err = grub_video_fb_setup (mode_type, mode_mask,
&framebuffer.mode_info,
framebuffer.cached_ptr, NULL, NULL);
@ -707,11 +727,13 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
/* Copy default palette to initialize emulated palette. */
err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
grub_video_fbstd_colors);
#endif
return err;
#else
return 0;
#endif
}
#ifndef TEST
#if !defined (TEST) && !defined(GENINIT)
static grub_err_t
grub_video_sm712_swap_buffers (void)