From fdf050d5fbf6feb146dfefc1651f8dafe0fd7f7e Mon Sep 17 00:00:00 2001 From: Heiher Date: Fri, 1 May 2015 21:46:39 +0800 Subject: [PATCH 1/2] MIPS: Loongson: Add support for Loongson3. --- grub-core/boot/mips/startup_raw.S | 12 ++ grub-core/bus/bonito.c | 20 ++- grub-core/bus/pci.c | 2 +- grub-core/kern/mips/loongson/init.c | 66 +++++++--- grub-core/kern/mips/startup.S | 3 + grub-core/lib/mips/loongson/reboot.c | 15 ++- grub-core/loader/mips/linux.c | 120 ++++++++++-------- grub-core/term/serial.c | 3 +- include/grub/mips/loongson.h | 6 + include/grub/mips/loongson/boot.h | 236 +++++++++++++++++++++++++++++++++++ include/grub/mips/loongson/kernel.h | 3 +- include/grub/mips/loongson/pci.h | 24 +++- include/grub/mips/loongson/serial.h | 4 +- 13 files changed, 430 insertions(+), 84 deletions(-) create mode 100644 include/grub/mips/loongson/boot.h diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index fd95c31..3316232 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -23,6 +23,9 @@ #include #include #include +#ifdef GRUB_MACHINE_MIPS_LOONGSON +#include +#endif #define BASE_ADDR 8 @@ -82,6 +85,15 @@ codestart: move $s5, $zero move $s7, $zero + /* The Loongson 3A/3B has a new boot interface and + not compatiable with 2E or 2F. */ + mfc0 $t0, GRUB_CPU_LOONGSON_COP0_PRID + li $t1, GRUB_CPU_LOONGSON_PRID_LOONGSON3A + li $s7, GRUB_ARCH_MACHINE_YEELOONG_3X + slt $t0, $t0, $t1 + beqz $t0, cmdlinedone + move $s5, $a2 + /* $a2 has the environment. */ addiu $t0, $zero, -0x10 and $t1, $a2, $t0 diff --git a/grub-core/bus/bonito.c b/grub-core/bus/bonito.c index 9a63f07..0023036 100644 --- a/grub-core/bus/bonito.c +++ b/grub-core/bus/bonito.c @@ -45,9 +45,9 @@ config_addr (grub_pci_address_t addr) { if (addr >> 16) - return (volatile void *) (GRUB_MACHINE_PCI_CONFSPACE_3A_EXT | addr); + return (volatile void *) (GRUB_MACHINE_PCI_CONFSPACE_3X_EXT | addr); else - return (volatile void *) (GRUB_MACHINE_PCI_CONFSPACE_3A | addr); + return (volatile void *) (GRUB_MACHINE_PCI_CONFSPACE_3X | addr); } } @@ -132,6 +132,19 @@ grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), } grub_fatal ("Out of PCI windows."); } + else if (grub_bonito_type == GRUB_BONITO_3X) + { + if (GRUB_MACHINE_PCI_MEM_BASE0_3X <= base && + GRUB_MACHINE_PCI_MEM_BASE0_3X + GRUB_MACHINE_PCI_MEM_SIZE0_3X > base + size) + return (void *) (GRUB_MACHINE_PCI_MEM_ADDR0_3X | base); + else if (GRUB_MACHINE_PCI_MEM_BASE1_3X <= base && + GRUB_MACHINE_PCI_MEM_BASE1_3X + GRUB_MACHINE_PCI_MEM_SIZE1_3X > base + size) + return (void *) (GRUB_MACHINE_PCI_MEM_ADDR1_3X | base); + else if (GRUB_MACHINE_PCI_MEM_BASE2_3X <= base && + GRUB_MACHINE_PCI_MEM_BASE2_3X + GRUB_MACHINE_PCI_MEM_SIZE2_3X > base + size) + return (void *) (GRUB_MACHINE_PCI_MEM_ADDR2_3X | base); + grub_fatal ("Out of PCI windows."); + } else { int region = 0; @@ -173,4 +186,7 @@ grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), } grub_fatal ("Tried to unmap not mapped region"); } + else if (grub_bonito_type == GRUB_BONITO_3X) + { + } } diff --git a/grub-core/bus/pci.c b/grub-core/bus/pci.c index b388ce5..82d7870 100644 --- a/grub-core/bus/pci.c +++ b/grub-core/bus/pci.c @@ -72,7 +72,7 @@ grub_dma_get_virt (struct grub_pci_dma_chunk *ch) grub_uint32_t grub_dma_get_phys (struct grub_pci_dma_chunk *ch) { - return (((grub_uint32_t) ch) & 0x1fffffff) | 0x80000000; + return (((grub_uint32_t) ch) & 0x1fffffff); } #else diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index 7b96531..2df8dfb 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -44,8 +45,9 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) { hook (GRUB_ARCH_LOWMEMPSTART, grub_arch_memsize << 20, GRUB_MEMORY_AVAILABLE, hook_data); - hook (GRUB_ARCH_HIGHMEMPSTART, grub_arch_highmemsize << 20, - GRUB_MEMORY_AVAILABLE, hook_data); + if (grub_bonito_type != GRUB_BONITO_3X) + hook (GRUB_ARCH_HIGHMEMPSTART, grub_arch_highmemsize << 20, + GRUB_MEMORY_AVAILABLE, hook_data); return GRUB_ERR_NONE; } @@ -127,21 +129,23 @@ grub_machine_init (void) switch (prid) { /* Loongson 2E. */ - case 0x6302: + case GRUB_CPU_LOONGSON_PRID_LOONGSON2E: grub_arch_machine = GRUB_ARCH_MACHINE_FULOONG2E; grub_bonito_type = GRUB_BONITO_2F; break; /* Loongson 2F. */ - case 0x6303: + case GRUB_CPU_LOONGSON_PRID_LOONGSON2F: 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; + /* Loongson 3A/3B. */ + case GRUB_CPU_LOONGSON_PRID_LOONGSON3A: + case GRUB_CPU_LOONGSON_PRID_LOONGSON3BR1: + case GRUB_CPU_LOONGSON_PRID_LOONGSON3BR2: + grub_arch_machine = GRUB_ARCH_MACHINE_YEELOONG_3X; + grub_bonito_type = GRUB_BONITO_3X; break; } @@ -150,10 +154,40 @@ grub_machine_init (void) { grub_arch_busclock = 66000000; grub_arch_cpuclock = 797000000; + + if (grub_bonito_type == GRUB_BONITO_3X) + { + struct efi_cpuinfo_loongson *cpuinfo; + + cpuinfo = grub_mips_loongson_params_get_cpu (grub_arch_lefi); + grub_arch_cpuclock = cpuinfo->cpu_clock_freq; + } } grub_install_get_time_ms (grub_rtc_get_time_ms); + if (grub_bonito_type == GRUB_BONITO_3X) + { + grub_uint32_t i; + struct efi_memory_map_loongson *mmap; + + mmap = grub_mips_loongson_params_get_memory (grub_arch_lefi); + for (i=0; inr_map; i++) + { + if (SYSTEM_RAM_LOW == mmap->map[i].mem_type) + { + grub_arch_memsize = mmap->map[i].mem_size; + break; + } + } + if (grub_arch_memsize == 0) + grub_fatal ("No memory map found\n"); + + /* Workarounds for old BIOS, the boot params start at + * system ram low end address - 512k */ + if (grub_vtop ((void *) grub_arch_lefi) < (grub_arch_memsize << 20)) + grub_arch_memsize -= 1; + } if (grub_arch_memsize == 0) { grub_port_t smbbase; @@ -216,7 +250,7 @@ grub_machine_init (void) grub_keylayouts_init (); if (grub_arch_machine == GRUB_ARCH_MACHINE_YEELOONG - || grub_arch_machine == GRUB_ARCH_MACHINE_YEELOONG_3A) + || grub_arch_machine == GRUB_ARCH_MACHINE_YEELOONG_3X) grub_at_keyboard_init (); grub_terminfo_init (); @@ -289,12 +323,14 @@ grub_halt (void) & ~GRUB_CPU_YEELOONG_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG); grub_millisleep (1500); break; - case GRUB_ARCH_MACHINE_YEELOONG_3A: - grub_millisleep (1); - grub_outb (0x4e, GRUB_MACHINE_PCI_IO_BASE_3A | 0x66); - grub_millisleep (1); - grub_outb (2, GRUB_MACHINE_PCI_IO_BASE_3A | 0x62); - grub_millisleep (5000); + case GRUB_ARCH_MACHINE_YEELOONG_3X: + { + struct boot_params *bp = (struct boot_params *) grub_arch_lefi; + void (*shutdown) (void) = (void *) (long) bp->reset_system.Shutdown; + if (shutdown) + shutdown (); + grub_millisleep (5000); + } break; } diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 337aca9..3b1c7a9 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -48,6 +48,9 @@ VARIABLE (grub_arch_cpuclock) .long 0 VARIABLE (grub_arch_memsize) .long 0 +#ifdef GRUB_MACHINE_MIPS_LOONGSON +VARIABLE (grub_arch_lefi) +#endif VARIABLE (grub_arch_highmemsize) .long 0 #ifdef GRUB_MACHINE_MIPS_LOONGSON diff --git a/grub-core/lib/mips/loongson/reboot.c b/grub-core/lib/mips/loongson/reboot.c index a20e574..afb30b6 100644 --- a/grub-core/lib/mips/loongson/reboot.c +++ b/grub-core/lib/mips/loongson/reboot.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -49,12 +50,14 @@ grub_reboot (void) case GRUB_ARCH_MACHINE_YEELOONG: grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT); break; - case GRUB_ARCH_MACHINE_YEELOONG_3A: - grub_millisleep (1); - grub_outb (0x4e, GRUB_MACHINE_PCI_IO_BASE_3A | 0x66); - grub_millisleep (1); - grub_outb (1, GRUB_MACHINE_PCI_IO_BASE_3A | 0x62); - grub_millisleep (5000); + case GRUB_ARCH_MACHINE_YEELOONG_3X: + { + struct boot_params *bp = (struct boot_params *) grub_arch_lefi; + void (*reboot) (void) = (void *) (long) bp->reset_system.ResetWarm; + if (reboot) + reboot (); + grub_millisleep (5000); + } } grub_millisleep (1500); diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 5f383be..b9e4203 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -53,7 +53,7 @@ static grub_dl_t my_mod; static int loaded; -static grub_size_t linux_size; +static grub_size_t linux_size, cmdline_size; static struct grub_relocator *relocator; static grub_uint8_t *playground; @@ -106,7 +106,10 @@ grub_linux_boot (void) state.gpr[4] = linux_argc; state.gpr[5] = target_addr + argv_off; #ifdef GRUB_MACHINE_MIPS_LOONGSON - state.gpr[6] = target_addr + envp_off; + if (GRUB_ARCH_MACHINE_YEELOONG_3X == grub_arch_machine) + state.gpr[6] = grub_arch_lefi; + else + state.gpr[6] = target_addr + envp_off; #else state.gpr[6] = 0; #endif @@ -139,7 +142,6 @@ grub_linux_load32 (grub_elf_t elf, const char *filename, void **extra_mem, grub_size_t extra_size) { Elf32_Addr base; - int extraoff; grub_err_t err; /* Linux's entry point incorrectly contains a virtual address. */ @@ -152,8 +154,6 @@ grub_linux_load32 (grub_elf_t elf, const char *filename, /* Pad it; the kernel scribbles over memory beyond its load address. */ linux_size += 0x100000; linux_size = ALIGN_UP (base + linux_size, 4) - base; - extraoff = linux_size; - linux_size += extra_size; relocator = grub_relocator_new (); if (!relocator) @@ -167,9 +167,14 @@ grub_linux_load32 (grub_elf_t elf, const char *filename, if (err) return err; playground = get_virtual_current_address (ch); - } - *extra_mem = playground + extraoff; + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + grub_mmap_get_lower () - extra_size, + extra_size); + if (err) + return err; + *extra_mem = get_virtual_current_address (ch); + } /* Now load the segments into the area we claimed. */ return grub_elf32_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); @@ -180,7 +185,6 @@ grub_linux_load64 (grub_elf_t elf, const char *filename, void **extra_mem, grub_size_t extra_size) { Elf64_Addr base; - int extraoff; grub_err_t err; /* Linux's entry point incorrectly contains a virtual address. */ @@ -193,8 +197,6 @@ grub_linux_load64 (grub_elf_t elf, const char *filename, /* Pad it; the kernel scribbles over memory beyond its load address. */ linux_size += 0x100000; linux_size = ALIGN_UP (base + linux_size, 4) - base; - extraoff = linux_size; - linux_size += extra_size; relocator = grub_relocator_new (); if (!relocator) @@ -208,9 +210,14 @@ grub_linux_load64 (grub_elf_t elf, const char *filename, if (err) return err; playground = get_virtual_current_address (ch); - } - *extra_mem = playground + extraoff; + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + grub_mmap_get_lower () - extra_size, + extra_size); + if (err) + return err; + *extra_mem = get_virtual_current_address (ch); + } /* Now load the segments into the area we claimed. */ return grub_elf64_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); @@ -258,7 +265,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* For arguments. */ linux_argc = argc; #ifdef GRUB_MACHINE_MIPS_LOONGSON - linux_argc++; + if (GRUB_ARCH_MACHINE_YEELOONG_3X != grub_arch_machine) + linux_argc++; #endif /* Main arguments. */ size = (linux_argc) * sizeof (grub_uint32_t); @@ -273,7 +281,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), for (i = 1; i < argc; i++) size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); #ifdef GRUB_MACHINE_MIPS_LOONGSON - size += ALIGN_UP (sizeof (loongson_machtypes[0]), 4); + if (GRUB_ARCH_MACHINE_YEELOONG_3X != grub_arch_machine) + size += ALIGN_UP (sizeof (loongson_machtypes[0]), 4); #endif /* rd arguments. */ @@ -281,12 +290,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); /* For the environment. */ - size += sizeof (grub_uint32_t); - size += 4 * sizeof (grub_uint32_t); - size += ALIGN_UP (sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"), 4) - + ALIGN_UP (sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), 4) - + ALIGN_UP (sizeof ("busclock=XXXXXXXXXX"), 4) - + ALIGN_UP (sizeof ("cpuclock=XXXXXXXXXX"), 4); + if (GRUB_ARCH_MACHINE_YEELOONG_3X != grub_arch_machine) + { + size += sizeof (grub_uint32_t); + size += 4 * sizeof (grub_uint32_t); + size += ALIGN_UP (sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"), 4) + + ALIGN_UP (sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), 4) + + ALIGN_UP (sizeof ("busclock=XXXXXXXXXX"), 4) + + ALIGN_UP (sizeof ("cpuclock=XXXXXXXXXX"), 4); + } #endif if (grub_elf_is_elf32 (elf)) @@ -328,6 +340,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_args += ALIGN_UP (sizeof ("a0"), 4); #ifdef GRUB_MACHINE_MIPS_LOONGSON + if (GRUB_ARCH_MACHINE_YEELOONG_3X != grub_arch_machine) { unsigned mtype = grub_arch_machine; if (mtype >= ARRAY_SIZE (loongson_machtypes)) @@ -368,36 +381,40 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), extra = linux_args; #ifdef GRUB_MACHINE_MIPS_LOONGSON - linux_envp = extra; - envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground; - linux_envs = (char *) (linux_envp + 5); - grub_snprintf (linux_envs, sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"), - "memsize=%lld", - (unsigned long long) grub_mmap_get_lower () >> 20); - linux_envp[0] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground - + target_addr; - linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); - grub_snprintf (linux_envs, sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), - "highmemsize=%lld", - (unsigned long long) grub_mmap_get_upper () >> 20); - linux_envp[1] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground - + target_addr; - linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); - - grub_snprintf (linux_envs, sizeof ("busclock=XXXXXXXXXX"), - "busclock=%d", grub_arch_busclock); - linux_envp[2] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground - + target_addr; - linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); - grub_snprintf (linux_envs, sizeof ("cpuclock=XXXXXXXXXX"), - "cpuclock=%d", grub_arch_cpuclock); - linux_envp[3] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground - + target_addr; - linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); - - linux_envp[4] = 0; + if (GRUB_ARCH_MACHINE_YEELOONG_3X != grub_arch_machine) + { + linux_envp = extra; + envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground; + linux_envs = (char *) (linux_envp + 5); + grub_snprintf (linux_envs, sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"), + "memsize=%lld", + (unsigned long long) grub_mmap_get_lower () >> 20); + linux_envp[0] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground + + target_addr; + linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); + grub_snprintf (linux_envs, sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), + "highmemsize=%lld", + (unsigned long long) grub_mmap_get_upper () >> 20); + linux_envp[1] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground + + target_addr; + linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); + + grub_snprintf (linux_envs, sizeof ("busclock=XXXXXXXXXX"), + "busclock=%d", grub_arch_busclock); + linux_envp[2] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground + + target_addr; + linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); + grub_snprintf (linux_envs, sizeof ("cpuclock=XXXXXXXXXX"), + "cpuclock=%d", grub_arch_cpuclock); + linux_envp[3] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground + + target_addr; + linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); + + linux_envp[4] = 0; + } #endif #endif + cmdline_size = size; grub_loader_set (grub_linux_boot, grub_linux_unload, 1); initrd_loaded = 0; @@ -432,12 +449,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), size = grub_get_initrd_size (&initrd_ctx); { + grub_uint64_t start_addr; grub_relocator_chunk_t ch; + start_addr = grub_mmap_get_lower () - cmdline_size - size; err = grub_relocator_alloc_chunk_align (relocator, &ch, - (target_addr & 0x1fffffff) - + linux_size + 0x10000, - (0x10000000 - size), + start_addr - 0xf00000, + start_addr - 0x800000, size, 0x10000, GRUB_RELOCATOR_PREFERENCE_NONE, 0); diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index db80b3b..fcaedbb 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -311,7 +311,8 @@ const char loongson_defserial[][6] = { [GRUB_ARCH_MACHINE_YEELOONG] = "com0", [GRUB_ARCH_MACHINE_FULOONG2F] = "com2", - [GRUB_ARCH_MACHINE_FULOONG2E] = "com1" + [GRUB_ARCH_MACHINE_FULOONG2E] = "com1", + [GRUB_ARCH_MACHINE_YEELOONG_3X] = "com3" }; #endif diff --git a/include/grub/mips/loongson.h b/include/grub/mips/loongson.h index e6f0241..784b516 100644 --- a/include/grub/mips/loongson.h +++ b/include/grub/mips/loongson.h @@ -70,6 +70,12 @@ #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_PRID_LOONGSON2E 0x6302 +#define GRUB_CPU_LOONGSON_PRID_LOONGSON2F 0x6303 +#define GRUB_CPU_LOONGSON_PRID_LOONGSON3A 0x6305 +#define GRUB_CPU_LOONGSON_PRID_LOONGSON3BR1 0x6306 +#define GRUB_CPU_LOONGSON_PRID_LOONGSON3BR2 0x6307 + #define GRUB_CPU_LOONGSON_LIOCFG 0xbfe00108 #define GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET 2 #define GRUB_CPU_LOONGSON_ROM_DELAY_MASK 0x1f diff --git a/include/grub/mips/loongson/boot.h b/include/grub/mips/loongson/boot.h new file mode 100644 index 0000000..382a3db --- /dev/null +++ b/include/grub/mips/loongson/boot.h @@ -0,0 +1,236 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2015 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_MACHINE_BOOT_H +#define GRUB_MACHINE_BOOT_H + +#include + +#define SYSTEM_RAM_LOW 1 +#define SYSTEM_RAM_HIGH 2 +#define MEM_RESERVEI 3 +#define PCI_IO 4 +#define PCI_MEM 5 +#define LOONGSON_CFG_REG 6 +#define VIDEO_ROM 7 +#define ADAPTER_ROM 8 +#define ACPI_TABLE 9 +#define SMBIOS_TABLE 10 +#define MAX_MEMORY_TYPE 11 + +#define MAX_UARTS 64 + +#define MAX_SENSORS 64 +#define SENSOR_TEMPER 0x00000001 +#define SENSOR_VOLTAGE 0x00000002 +#define SENSOR_FAN 0x00000004 + +#define CONSTANT_SPEED_POLICY 0 /* at constent speed */ +#define STEP_SPEED_POLICY 1 /* use up/down arrays to describe policy */ +#define KERNEL_HELPER_POLICY 2 /* kernel as a helper to fan control */ + +#define LOONGSON3_BOOT_MEM_MAP_MAX 128 +#define MAX_RESOURCE_NUMBER 128 + +#define WORKAROUND_CPUFREQ 0x00000001 +#define WORKAROUND_CPUHOTPLUG 0x00000002 +#define WORKAROUND_LVDS_EC 0x00000004 +#define WORKAROUND_LVDS_GPIO 0x00000008 +#define WORKAROUND_USB_TMCS 0x00000010 +#define WORKAROUND_PCIE_DMA 0x00000020 + +extern grub_uint64_t loongson_workarounds; + +struct efi_memory_map_loongson{ + grub_uint16_t vers; /* version of efi_memory_map */ + grub_uint32_t nr_map; /* number of memory_maps */ + grub_uint32_t mem_freq; /* memory frequence */ + struct mem_map{ + grub_uint32_t node_id; /* node_id which memory attached to */ + grub_uint32_t mem_type; /* system memory, pci memory, pci io, etc. */ + grub_uint64_t mem_start; /* memory map start address */ + grub_uint32_t mem_size; /* each memory_map size, not the total size */ + }map[LOONGSON3_BOOT_MEM_MAP_MAX]; + }__attribute__((packed)); + +enum loongson_cpu_type +{ + Loongson_2F, + Loongson_2E, + Loongson_3A, + Loongson_3B, + Loongson_1A, + Loongson_1B +}; + +/* +* Capability and feature descriptor structure for MIPS CPU +*/ +struct efi_cpuinfo_loongson { + grub_uint16_t vers; /* version of efi_cpuinfo_loongson */ + grub_uint32_t processor_id; /* PRID, e.g. 6305, 6306 */ + enum loongson_cpu_type cputype; /* 3A, 3B ,etc. */ + grub_uint32_t total_node; /* num of total numa nodes */ + grub_uint16_t cpu_startup_core_id; /* Core id */ + grub_uint16_t reserved_cores_mask; /* reserved cores mask */ + grub_uint32_t cpu_clock_freq; /* cpu_clock */ + grub_uint32_t nr_cpus; +}__attribute__((packed)); + +struct uart_device { + grub_uint32_t iotype; /* see include/linux/serial_core.h */ + grub_uint32_t uartclk; + grub_uint32_t int_offset; + grub_uint64_t uart_base; +}__attribute__((packed)); + +struct sensor_device { + char name[32]; /* a formal name */ + char label[64]; /* a flexible description */ + grub_uint32_t type; /* SENSOR_* */ + grub_uint32_t id; /* instance id of a sensor-class */ + grub_uint32_t fan_policy; /* see arch/mips/include/asm/mach-loongson/loongson_hwmon.h */ + grub_uint32_t fan_percent;/* only for constant speed policy */ + grub_uint64_t base_addr; /* base address of device registers */ +}__attribute__((packed)); + + +struct system_loongson{ + grub_uint16_t vers; /* version of system_loongson */ + grub_uint32_t ccnuma_smp; /* 0: no numa; 1: has numa */ + grub_uint32_t sing_double_channel; /* 1:single; 2:double */ + grub_uint32_t nr_uarts; + struct uart_device uarts[MAX_UARTS]; + grub_uint32_t nr_sensors; + struct sensor_device sensors[MAX_SENSORS]; + char has_ec; + char ec_name[32]; + grub_uint64_t ec_base_addr; + char has_tcm; + char tcm_name[32]; + grub_uint64_t tcm_base_addr; + grub_uint64_t workarounds; /* see workarounds.h */ +}__attribute__((packed)); + +struct irq_source_routing_table { + grub_uint16_t vers; + grub_uint16_t size; + grub_uint16_t rtr_bus; + grub_uint16_t rtr_devfn; + grub_uint32_t vendor; + grub_uint32_t device; + grub_uint32_t PIC_type; /* conform use HT or PCI to route to CPU-PIC */ + grub_uint64_t ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */ + grub_uint64_t ht_enable; /* irqs used in this PIC */ + grub_uint32_t node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */ + grub_uint64_t pci_mem_start_addr; + grub_uint64_t pci_mem_end_addr; + grub_uint64_t pci_io_start_addr; + grub_uint64_t pci_io_end_addr; + grub_uint64_t pci_config_addr; + grub_uint32_t dma_mask_bits; +}__attribute__((packed)); + +struct interface_info{ + grub_uint16_t vers; /* version of the specificition */ + grub_uint16_t size; + grub_uint8_t flag; + char description[64]; +}__attribute__((packed)); + +struct resource_loongson { + grub_uint64_t start; /* resource start address */ + grub_uint64_t end; /* resource end address */ + char name[64]; + grub_uint32_t flags; +}; + +struct archdev_data {}; /* arch specific additions */ + +struct board_devices{ + char name[64]; /* hold the device name */ + grub_uint32_t num_resources; /* number of device_resource */ + struct resource_loongson resource[MAX_RESOURCE_NUMBER]; /* for each device's resource */ + /* arch specific additions */ + struct archdev_data archdata; +}; + +struct loongson_special_attribute{ + grub_uint16_t vers; /* version of this special */ + char special_name[64]; /* special_atribute_name */ + grub_uint32_t loongson_special_type; /* type of special device */ + struct resource_loongson resource[MAX_RESOURCE_NUMBER]; /* for each device's resource */ +}; + +struct loongson_params{ + grub_uint64_t memory_offset; /* efi_memory_map_loongson struct offset */ + grub_uint64_t cpu_offset; /* efi_cpuinfo_loongson struct offset */ + grub_uint64_t system_offset; /* system_loongson struct offset */ + grub_uint64_t irq_offset; /* irq_source_routing_table struct offset */ + grub_uint64_t interface_offset; /* interface_info struct offset */ + grub_uint64_t special_offset; /* loongson_special_attribute struct offset */ + grub_uint64_t boarddev_table_offset; /* board_devices offset */ +}; + +struct smbios_tables { + grub_uint16_t vers; /* version of smbios */ + grub_uint64_t vga_bios; /* vga_bios address */ + struct loongson_params lp; +}; + +struct efi_reset_system_t{ + grub_uint64_t ResetCold; + grub_uint64_t ResetWarm; + grub_uint64_t ResetType; + grub_uint64_t Shutdown; + grub_uint64_t DoSuspend; /* NULL if not support */ +}; + +struct efi_loongson { + grub_uint64_t mps; /* MPS table */ + grub_uint64_t acpi; /* ACPI table (IA64 ext 0.71) */ + grub_uint64_t acpi20; /* ACPI table (ACPI 2.0) */ + struct smbios_tables smbios; /* SM BIOS table */ + grub_uint64_t sal_systab; /* SAL system table */ + grub_uint64_t boot_info; /* boot info table */ +}; + +struct boot_params{ + struct efi_loongson efi; + struct efi_reset_system_t reset_system; +}; + +static inline struct efi_memory_map_loongson * +grub_mips_loongson_params_get_memory (grub_addr_t lefi) +{ + struct boot_params *bp = (struct boot_params *) lefi; + struct loongson_params *lp = &bp->efi.smbios.lp; + + return (void *) ((long) lp + (long) lp->memory_offset); +} + +static inline struct efi_cpuinfo_loongson * +grub_mips_loongson_params_get_cpu (grub_addr_t lefi) +{ + struct boot_params *bp = (struct boot_params *) lefi; + struct loongson_params *lp = &bp->efi.smbios.lp; + + return (void *) ((long) lp + (long) lp->cpu_offset); +} + +#endif /* GRUB_MACHINE_BOOT_H */ diff --git a/include/grub/mips/loongson/kernel.h b/include/grub/mips/loongson/kernel.h index 0587191..29ad007 100644 --- a/include/grub/mips/loongson/kernel.h +++ b/include/grub/mips/loongson/kernel.h @@ -25,11 +25,12 @@ #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 +#define GRUB_ARCH_MACHINE_YEELOONG_3X 3 #ifndef ASM_FILE extern grub_uint32_t EXPORT_VAR (grub_arch_machine) __attribute__ ((section(".text"))); +extern grub_addr_t EXPORT_VAR (grub_arch_lefi) __attribute__ ((section(".text"))); #endif diff --git a/include/grub/mips/loongson/pci.h b/include/grub/mips/loongson/pci.h index b3272e9..7177733 100644 --- a/include/grub/mips/loongson/pci.h +++ b/include/grub/mips/loongson/pci.h @@ -28,10 +28,10 @@ #define GRUB_LOONGSON_EHCI_PCIID 0x00e01033 #define GRUB_MACHINE_PCI_IO_BASE_2F 0xbfd00000 -#define GRUB_MACHINE_PCI_IO_BASE_3A 0xb8000000 +#define GRUB_MACHINE_PCI_IO_BASE_3X 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_CONFSPACE_3X 0xba000000 +#define GRUB_MACHINE_PCI_CONFSPACE_3X_EXT 0xbb000000 #define GRUB_MACHINE_PCI_CONTROLLER_HEADER 0xbfe00000 #define GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR_2F 0xbfe00118 @@ -40,7 +40,7 @@ #ifndef ASM_FILE -typedef enum { GRUB_BONITO_2F, GRUB_BONITO_3A } grub_bonito_type_t; +typedef enum { GRUB_BONITO_2F, GRUB_BONITO_3X } grub_bonito_type_t; extern grub_bonito_type_t EXPORT_VAR (grub_bonito_type); #define GRUB_PCI_NUM_DEVICES (grub_bonito_type ? 32 \ @@ -48,13 +48,13 @@ extern grub_bonito_type_t EXPORT_VAR (grub_bonito_type); #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_3X \ : 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 *) \ +#define GRUB_MACHINE_PCI_CONF_CTRL_REG_3X (*(volatile grub_uint32_t *) \ 0xbfe00118) #endif @@ -75,6 +75,18 @@ extern grub_bonito_type_t EXPORT_VAR (grub_bonito_type); #define GRUB_MACHINE_PCI_WIN2_ADDR 0xb4000000 #define GRUB_MACHINE_PCI_WIN3_ADDR 0xb8000000 +#define GRUB_MACHINE_PCI_MEM_BASE0_3X 0x10000000u +#define GRUB_MACHINE_PCI_MEM_ADDR0_3X 0xb0000000u +#define GRUB_MACHINE_PCI_MEM_SIZE0_3X 0x8000000u + +#define GRUB_MACHINE_PCI_MEM_BASE1_3X 0x1c000000u +#define GRUB_MACHINE_PCI_MEM_ADDR1_3X 0xbc000000u +#define GRUB_MACHINE_PCI_MEM_SIZE1_3X 0x2000000u + +#define GRUB_MACHINE_PCI_MEM_BASE2_3X 0x40000000u +#define GRUB_MACHINE_PCI_MEM_ADDR2_3X 0xc0000000u +#define GRUB_MACHINE_PCI_MEM_SIZE2_3X 0x40000000u + #ifndef ASM_FILE grub_uint32_t EXPORT_FUNC (grub_pci_read) (grub_pci_address_t addr); diff --git a/include/grub/mips/loongson/serial.h b/include/grub/mips/loongson/serial.h index 45e6d84..4ee5e9d 100644 --- a/include/grub/mips/loongson/serial.h +++ b/include/grub/mips/loongson/serial.h @@ -21,12 +21,14 @@ #define GRUB_MACHINE_SERIAL_PORT0_DIVISOR_115200 2 #define GRUB_MACHINE_SERIAL_PORT2_DIVISOR_115200 1 +#define GRUB_MACHINE_SERIAL_PORT3_DIVISOR_115200 1 #define GRUB_MACHINE_SERIAL_PORT0 0xbff003f8 #define GRUB_MACHINE_SERIAL_PORT1 0xbfd003f8 #define GRUB_MACHINE_SERIAL_PORT2 0xbfd002f8 +#define GRUB_MACHINE_SERIAL_PORT3 0xbfe001e0 #ifndef ASM_FILE -#define GRUB_MACHINE_SERIAL_PORTS { GRUB_MACHINE_SERIAL_PORT0, GRUB_MACHINE_SERIAL_PORT1, GRUB_MACHINE_SERIAL_PORT2 } +#define GRUB_MACHINE_SERIAL_PORTS { GRUB_MACHINE_SERIAL_PORT0, GRUB_MACHINE_SERIAL_PORT1, GRUB_MACHINE_SERIAL_PORT2, GRUB_MACHINE_SERIAL_PORT3 } #else #endif -- 2.4.2