From f9e7780cfff7fad076c23c73a930f3bb5b33fcee Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 6 Apr 2010 02:40:44 +0200 Subject: [PATCH] Fix an early timer-related hang --- include/grub/cs5536.h | 9 +++++++++ kern/mips/yeeloong/init.c | 41 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h index ec554f002..21d6d55fc 100644 --- a/include/grub/cs5536.h +++ b/include/grub/cs5536.h @@ -29,8 +29,12 @@ #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_IRQ_MAP_BAR 0x80000008 #define GRUB_CS5536_MSR_SMB_BAR 0x8000000b #define GRUB_CS5536_MSR_GPIO_BAR 0x8000000c +#define GRUB_CS5536_MSR_MFGPT_BAR 0x8000000d +#define GRUB_CS5536_MSR_ACPI_BAR 0x8000000e +#define GRUB_CS5536_MSR_PM_BAR 0x8000000f #define GRUB_CS5536_SMB_REG_DATA 0x0 #define GRUB_CS5536_SMB_REG_STATUS 0x1 #define GRUB_CS5536_SMB_REG_STATUS_SDAST (1 << 6) @@ -55,10 +59,15 @@ #define GRUB_CS5536_LBAR_ADDR_MASK GRUB_ULL (0x000000000000fff8) #define GRUB_CS5536_LBAR_ENABLE GRUB_ULL (0x0000000100000000) #define GRUB_CS5536_LBAR_MASK_MASK GRUB_ULL (0x0000f00000000000) +#define GRUB_CS5536_LBAR_TURN_ON (GRUB_CS5536_LBAR_ENABLE | GRUB_CS5536_LBAR_MASK_MASK) /* PMON-compatible LBARs. */ +#define GRUB_CS5536_LBAR_IRQ_MAP 0x0b360 #define GRUB_CS5536_LBAR_GPIO 0x0b000 +#define GRUB_CS5536_LBAR_MFGPT 0x0b300 #define GRUB_CS5536_LBAR_SMBUS 0x0b390 +#define GRUB_CS5536_LBAR_ACPI 0x0b340 +#define GRUB_CS5536_LBAR_PM 0x0b280 #define GRUB_GPIO_SMBUS_PINS ((1 << 14) | (1 << 15)) #define GRUB_GPIO_REG_OUT_EN 0x4 diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 127cf870e..9cadd64b2 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -67,6 +67,26 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, 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, +}; + void grub_machine_init (void) { @@ -121,6 +141,27 @@ grub_machine_init (void) grub_arch_memsize = (totalmem >> 20); grub_arch_highmemsize = 0; } + + /* 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); + + 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); } modend = grub_modules_get_end ();