From fd4650a5567944cc14e10aaba828c95f5f7ae2a6 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Tue, 17 Dec 2013 22:49:27 +0100 Subject: [PATCH] Add bonito 3A support. --- ChangeLog | 4 + grub-core/boot/mips/loongson/fwstart.S | 82 ++++++------- grub-core/bus/bonito.c | 149 +++++++++++++++++------ grub-core/kern/mips/loongson/init.c | 7 ++ include/grub/mips/loongson/at_keyboard.h | 6 +- include/grub/mips/loongson/kernel.h | 1 + include/grub/mips/loongson/pci.h | 89 ++++++-------- 7 files changed, 208 insertions(+), 130 deletions(-) diff --git a/ChangeLog b/ChangeLog index 440e9ca44..6314dfb36 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-17 Vladimir Serbinenko + + Add bonito 3A support. + 2013-12-17 Vladimir Serbinenko * grub-core/loader/machoXX.c: Fix compilation on non-i386. diff --git a/grub-core/boot/mips/loongson/fwstart.S b/grub-core/boot/mips/loongson/fwstart.S index c62b28fe9..6ae326990 100644 --- a/grub-core/boot/mips/loongson/fwstart.S +++ b/grub-core/boot/mips/loongson/fwstart.S @@ -63,18 +63,18 @@ __start: This way we don't need to sacrifice a register for it. */ retry_cs5536: /* 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 $t0, %hi(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR_2F) + lui $t1, %hi(GRUB_MACHINE_PCI_CONFSPACE_2F) lui $t3, %hi(GRUB_CS5536_PCIID) addiu $t3, $t3, %lo(GRUB_CS5536_PCIID) ori $t4, $zero, 1 1: - andi $t4, $t4, ((1 << GRUB_PCI_NUM_DEVICES) - 1) + andi $t4, $t4, ((1 << GRUB_PCI_NUM_DEVICES_2F) - 1) /* In case of failure try again. CS5536 may be slow to come up. */ beql $t4, $zero, retry_cs5536 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) + sw $t4, %lo(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR_2F) ($t0) + lw $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE_2F) + GRUB_PCI_REG_PCI_ID) ($t1) bnel $t2, $t3, 1b sll $t4, $t4, 1 @@ -86,9 +86,9 @@ retry_cs5536: move $a0, $t4 #endif - lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE) + lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE_2F) li $t1, GRUB_CS5536_MSR_MAILBOX_CONFIG_ENABLED - sw $t1, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_CONFIG) ($t0) + sw $t1, (%lo(GRUB_MACHINE_PCI_CONFSPACE_2F) + GRUB_CS5536_MSR_MAILBOX_CONFIG) ($t0) /* Set GPIO LBAR. */ lui $a0, %hi(GRUB_CS5536_MSR_GPIO_BAR) @@ -121,21 +121,21 @@ retry_cs5536: bal message addiu $a0, $a0, %lo(smbus_enabled) - lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS) + lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE_2F + GRUB_CS5536_LBAR_SMBUS) /* Disable SMB. */ - sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0) + sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE_2F + 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) + sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE_2F + 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) + sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE_2F + 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) + sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE_2F + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL3) ($t0) + sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE_2F + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0) /* Yeeloong and Fuloong2f have only one memory slot. */ /* Output first byte on serial for debugging. */ @@ -237,8 +237,8 @@ other_exception: addiu $a0, $a0, %lo(unhandled_exception) gpio_init: - lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO) - addiu $t0, $t0, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO) + lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE_2F + GRUB_CS5536_LBAR_GPIO) + addiu $t0, $t0, %lo(GRUB_MACHINE_PCI_IO_BASE_2F + GRUB_CS5536_LBAR_GPIO) lui $t1, %hi (gpio_dump) addiu $t1, $t1, %lo (gpio_dump) @@ -368,18 +368,18 @@ self: 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) + lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE_2F) + sw $a0, (%lo(GRUB_MACHINE_PCI_CONFSPACE_2F) + GRUB_CS5536_MSR_MAILBOX_ADDR) ($t0) + sw $a1, (%lo(GRUB_MACHINE_PCI_CONFSPACE_2F) + GRUB_CS5536_MSR_MAILBOX_DATA0) ($t0) jr $ra - sw $a2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_DATA1) ($t0) + sw $a2, (%lo(GRUB_MACHINE_PCI_CONFSPACE_2F) + 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) + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE_2F) + lb $t0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) andi $t1, $t0, GRUB_CS5536_SMB_REG_STATUS_SDAST bne $t1, $zero, return nop @@ -401,52 +401,52 @@ read_spd: 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) + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) + lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($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) + sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) /* Send device address. */ - lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) 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) + sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) ($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) + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) + lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($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) + sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) /* Send byte address. */ - lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) bal smbus_wait - sb $t2, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0) + sb $t2, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) ($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) + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) + lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($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) + sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) /* Send device address. */ - lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) 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) + sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) ($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) + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) + lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($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) + sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($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) + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) + lb $v0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) jr $t3 andi $v0, $v0, 0xff read_spd_fail: diff --git a/grub-core/bus/bonito.c b/grub-core/bus/bonito.c index 985608181..9a63f073c 100644 --- a/grub-core/bus/bonito.c +++ b/grub-core/bus/bonito.c @@ -30,8 +30,66 @@ static grub_addr_t addr_win[GRUB_MACHINE_PCI_NUM_WIN] = {GRUB_MACHINE_PCI_WIN1_ADDR, GRUB_MACHINE_PCI_WIN2_ADDR, GRUB_MACHINE_PCI_WIN3_ADDR}; +grub_bonito_type_t grub_bonito_type; + +static volatile void * +config_addr (grub_pci_address_t addr) +{ + if (grub_bonito_type == GRUB_BONITO_2F) + { + GRUB_MACHINE_PCI_CONF_CTRL_REG_2F = 1 << ((addr >> 11) & 0xf); + return (volatile void *) (GRUB_MACHINE_PCI_CONFSPACE_2F + | (addr & 0x07ff)); + } + else + { + + if (addr >> 16) + return (volatile void *) (GRUB_MACHINE_PCI_CONFSPACE_3A_EXT | addr); + else + return (volatile void *) (GRUB_MACHINE_PCI_CONFSPACE_3A | addr); + } +} + +grub_uint32_t +grub_pci_read (grub_pci_address_t addr) +{ + return *(volatile grub_uint32_t *) config_addr (addr); +} + +grub_uint16_t +grub_pci_read_word (grub_pci_address_t addr) +{ + return *(volatile grub_uint16_t *) config_addr (addr); +} + +grub_uint8_t +grub_pci_read_byte (grub_pci_address_t addr) +{ + return *(volatile grub_uint8_t *) config_addr (addr); +} + +void +grub_pci_write (grub_pci_address_t addr, grub_uint32_t data) +{ + *(volatile grub_uint32_t *) config_addr (addr) = data; +} + +void +grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data) +{ + *(volatile grub_uint16_t *) config_addr (addr) = data; +} + +void +grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) +{ + *(volatile grub_uint8_t *) config_addr (addr) = data; +} + + static inline void -write_bases (void) +write_bases_2f (void) { int i; grub_uint32_t reg = 0; @@ -39,38 +97,54 @@ write_bases (void) reg |= (((base_win[i] >> GRUB_MACHINE_PCI_WIN_SHIFT) & GRUB_MACHINE_PCI_WIN_MASK) << (i * GRUB_MACHINE_PCI_WIN_MASK_SIZE)); - GRUB_MACHINE_PCI_IO_CTRL_REG = reg; + GRUB_MACHINE_PCI_IO_CTRL_REG_2F = reg; } volatile void * grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), grub_addr_t base, grub_size_t size) { - int i; - grub_addr_t newbase; + if (grub_bonito_type == GRUB_BONITO_2F) + { + int i; + grub_addr_t newbase; - /* First try already used registers. */ - for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) - if (usage_win[i] && base_win[i] <= base - && base_win[i] + sizes_win[i] > base + size) - { - usage_win[i]++; - return (void *) - (addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK)); - } - /* Map new register. */ - newbase = base & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK; - for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) - if (!usage_win[i] && newbase <= base - && newbase + sizes_win[i] > base + size) - { - usage_win[i]++; - base_win[i] = newbase; - write_bases (); - return (void *) - (addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK)); - } - grub_fatal ("Out of PCI windows."); + /* First try already used registers. */ + for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) + if (usage_win[i] && base_win[i] <= base + && base_win[i] + sizes_win[i] > base + size) + { + usage_win[i]++; + return (void *) + (addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK)); + } + /* Map new register. */ + newbase = base & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK; + for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) + if (!usage_win[i] && newbase <= base + && newbase + sizes_win[i] > base + size) + { + usage_win[i]++; + base_win[i] = newbase; + write_bases_2f (); + return (void *) + (addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK)); + } + grub_fatal ("Out of PCI windows."); + } + else + { + int region = 0; + if (base >= 0x10000000 + && base + size <= 0x18000000) + region = 1; + if (base >= 0x1c000000 + && base + size <= 0x1f000000) + region = 2; + if (region == 0) + grub_fatal ("Attempt to map out of regions"); + return (void *) (0xa0000000 | base); + } } void * @@ -86,14 +160,17 @@ grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), volatile void *mem, grub_size_t size __attribute__ ((unused))) { - int i; - for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) - if (usage_win[i] && addr_win[i] - == (((grub_addr_t) mem | 0x20000000) - & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK)) - { - usage_win[i]--; - return; - } - grub_fatal ("Tried to unmap not mapped region"); + if (grub_bonito_type == GRUB_BONITO_2F) + { + int i; + for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) + if (usage_win[i] && addr_win[i] + == (((grub_addr_t) mem | 0x20000000) + & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK)) + { + usage_win[i]--; + return; + } + grub_fatal ("Tried to unmap not mapped region"); + } } diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index d2f579588..b9cbcec27 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -129,12 +129,19 @@ grub_machine_init (void) /* Loongson 2E. */ case 0x6302: grub_arch_machine = GRUB_ARCH_MACHINE_FULOONG2E; + grub_bonito_type = GRUB_BONITO_2F; break; /* Loongson 2F. */ case 0x6303: if (grub_arch_machine != GRUB_ARCH_MACHINE_FULOONG2F && grub_arch_machine != GRUB_ARCH_MACHINE_YEELOONG) grub_arch_machine = GRUB_ARCH_MACHINE_YEELOONG; + grub_bonito_type = GRUB_BONITO_2F; + break; + /* Loongson 3A. */ + case 0x6305: + grub_arch_machine = GRUB_ARCH_MACHINE_YEELOONG_3A; + grub_bonito_type = GRUB_BONITO_3A; break; } diff --git a/include/grub/mips/loongson/at_keyboard.h b/include/grub/mips/loongson/at_keyboard.h index f279ac86d..8e58cfb17 100644 --- a/include/grub/mips/loongson/at_keyboard.h +++ b/include/grub/mips/loongson/at_keyboard.h @@ -19,7 +19,9 @@ #ifndef GRUB_MACHINE_AT_KEYBOARD_HEADER #define GRUB_MACHINE_AT_KEYBOARD_HEADER 1 -#define KEYBOARD_REG_DATA 0xbfd00060 -#define KEYBOARD_REG_STATUS 0xbfd00064 +#include + +#define KEYBOARD_REG_DATA (GRUB_MACHINE_PCI_IO_BASE | 0x60) +#define KEYBOARD_REG_STATUS (GRUB_MACHINE_PCI_IO_BASE | 0x64) #endif diff --git a/include/grub/mips/loongson/kernel.h b/include/grub/mips/loongson/kernel.h index 5e6e6fdfb..05871910b 100644 --- a/include/grub/mips/loongson/kernel.h +++ b/include/grub/mips/loongson/kernel.h @@ -25,6 +25,7 @@ #define GRUB_ARCH_MACHINE_YEELOONG 0 #define GRUB_ARCH_MACHINE_FULOONG2F 1 #define GRUB_ARCH_MACHINE_FULOONG2E 2 +#define GRUB_ARCH_MACHINE_YEELOONG_3A 3 #ifndef ASM_FILE diff --git a/include/grub/mips/loongson/pci.h b/include/grub/mips/loongson/pci.h index a81f7d75d..b3272e922 100644 --- a/include/grub/mips/loongson/pci.h +++ b/include/grub/mips/loongson/pci.h @@ -27,19 +27,36 @@ #define GRUB_LOONGSON_OHCI_PCIID 0x00351033 #define GRUB_LOONGSON_EHCI_PCIID 0x00e01033 -#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 +#define GRUB_MACHINE_PCI_IO_BASE_2F 0xbfd00000 +#define GRUB_MACHINE_PCI_IO_BASE_3A 0xb8000000 +#define GRUB_MACHINE_PCI_CONFSPACE_2F 0xbfe80000 +#define GRUB_MACHINE_PCI_CONFSPACE_3A 0xba000000 +#define GRUB_MACHINE_PCI_CONFSPACE_3A_EXT 0xbb000000 #define GRUB_MACHINE_PCI_CONTROLLER_HEADER 0xbfe00000 -#define GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR 0xbfe00118 +#define GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR_2F 0xbfe00118 + +#define GRUB_PCI_NUM_DEVICES_2F 16 #ifndef ASM_FILE -#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) \ - GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) -#define GRUB_MACHINE_PCI_IO_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00110) + +typedef enum { GRUB_BONITO_2F, GRUB_BONITO_3A } grub_bonito_type_t; +extern grub_bonito_type_t EXPORT_VAR (grub_bonito_type); + +#define GRUB_PCI_NUM_DEVICES (grub_bonito_type ? 32 \ + : GRUB_PCI_NUM_DEVICES_2F) +#define GRUB_PCI_NUM_BUS (grub_bonito_type ? 256 : 1) + +#define GRUB_MACHINE_PCI_IO_BASE (grub_bonito_type \ + ? GRUB_MACHINE_PCI_IO_BASE_3A \ + : GRUB_MACHINE_PCI_IO_BASE_2F) + +#define GRUB_MACHINE_PCI_CONF_CTRL_REG_2F (*(volatile grub_uint32_t *) \ + GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR_2F) +#define GRUB_MACHINE_PCI_IO_CTRL_REG_2F (*(volatile grub_uint32_t *) 0xbfe00110) +#define GRUB_MACHINE_PCI_CONF_CTRL_REG_3A (*(volatile grub_uint32_t *) \ + 0xbfe00118) + #endif #define GRUB_MACHINE_PCI_WIN_MASK_SIZE 6 #define GRUB_MACHINE_PCI_WIN_MASK ((1 << GRUB_MACHINE_PCI_WIN_MASK_SIZE) - 1) @@ -59,53 +76,23 @@ #define GRUB_MACHINE_PCI_WIN3_ADDR 0xb8000000 #ifndef ASM_FILE -static inline grub_uint32_t -grub_pci_read (grub_pci_address_t addr) -{ - GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); - return *(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0x07ff)); -} +grub_uint32_t +EXPORT_FUNC (grub_pci_read) (grub_pci_address_t addr); -static inline grub_uint16_t -grub_pci_read_word (grub_pci_address_t addr) -{ - GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); - return *(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0x07ff)); -} +grub_uint16_t +EXPORT_FUNC (grub_pci_read_word) (grub_pci_address_t addr); -static inline grub_uint8_t -grub_pci_read_byte (grub_pci_address_t addr) -{ - GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); - return *(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0x07ff)); -} +grub_uint8_t +EXPORT_FUNC (grub_pci_read_byte) (grub_pci_address_t addr); -static inline void -grub_pci_write (grub_pci_address_t addr, grub_uint32_t data) -{ - GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); - *(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0x07ff)) = data; -} +void +EXPORT_FUNC (grub_pci_write) (grub_pci_address_t addr, grub_uint32_t data); -static inline void -grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data) -{ - GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); - *(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0x07ff)) = data; -} +void +EXPORT_FUNC (grub_pci_write_word) (grub_pci_address_t addr, grub_uint16_t data); -static inline void -grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) -{ - GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); - *(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0x07ff)) = data; -} +void +EXPORT_FUNC (grub_pci_write_byte) (grub_pci_address_t addr, grub_uint8_t data); volatile void * EXPORT_FUNC (grub_pci_device_map_range) (grub_pci_device_t dev,