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