Hi,

Update v2: Split fix get dma physical address for loongson.

The mips-qemu_mips looks like a mips big endian platform. I have not a mips
big endian toolchains to build and test it. Is there anyone can help?
thanks!

On Fri, Jun 12, 2015 at 7:58 PM, Heiher <r...@hev.cc> wrote:

> Hi,
>
> Ok, you are right.
> On Jun 12, 2015 7:57 PM, "Andrei Borzenkov" <arvidj...@gmail.com> wrote:
>
>> В Fri, 12 Jun 2015 19:52:31 +0800
>> Heiher <r...@hev.cc> пишет:
>>
>> > Hi,
>> >
>> > Thanks for reivew.
>> >
>> > On Fri, Jun 12, 2015 at 6:02 PM, Andrei Borzenkov <arvidj...@gmail.com>
>> > wrote:
>> >
>> > > В Mon, 8 Jun 2015 17:25:16 +0800
>> > > Heiher <r...@hev.cc> пишет:
>> > >
>> > > > --- 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);
>> > >
>> > > I do not have experience with hardware but that does not look right.
>> > > Either this chunk breaks existing hardware or this part was not needed
>> > > in the first place. I suspect the former because later you re-add the
>> > > same code in subsequent patch.
>> > >
>> >
>> > I think this is a old mistake that caused grub on loongson3 broken. The
>> dma
>> > chunk address (ch & 0x1fffffff) is physical address. and it or
>> 0x80000000
>> > is cached virtual address.
>> >
>>
>> So if this is not needed for existing platforms please make it separate
>> patch to make it obvious and facilitate regression search. Do not hide
>> it inside additional platform support.
>>
>> > My next subsequent patch fixed grub_dma_get_virt (not grub_dma_get_phys)
>> > function,  because the Loongson 3B has a dma cached coherent issue, just
>> > only access memory by uncached for dma. so i add a grub_dma_coherent
>> flag
>> > to control grub_dma_get_virt return cached virtual address or uncached.
>> >
>> >
>> > >
>> > > This makes it hard to bisect later as it leaves some commits in
>> > > non-functional state.
>> > >
>> > > Could you please rearrange your patches so that they do not impact
>> > > existing platforms?
>> > >
>> >
>> > I have tested on Loongson 2F and Loongson 3A, 3B platforms. I have not
>> > tested on qemu mips, and i will do that next. thanks!
>> >
>>
>>


-- 
Best regards!
Heiher
http://hev.cc
From 96e1b5c52d06f515f39809d1ba58d507ecf9e79b Mon Sep 17 00:00:00 2001
From: Heiher <r...@hev.cc>
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/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 +-
 12 files changed, 429 insertions(+), 83 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 <grub/machine/kernel.h>
 #include <grub/cpu/kernel.h>
 #include <grub/offsets.h>
+#ifdef GRUB_MACHINE_MIPS_LOONGSON
+#include <grub/cpu/loongson.h>
+#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/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 <grub/machine/time.h>
 #include <grub/machine/kernel.h>
 #include <grub/machine/memory.h>
+#include <grub/machine/boot.h>
 #include <grub/memory.h>
 #include <grub/mips/loongson.h>
 #include <grub/cs5536.h>
@@ -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; i<mmap->nr_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 <grub/machine/ec.h>
 #include <grub/machine/kernel.h>
 #include <grub/machine/memory.h>
+#include <grub/machine/boot.h>
 #include <grub/misc.h>
 #include <grub/pci.h>
 #include <grub/cs5536.h>
@@ -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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_BOOT_H
+#define GRUB_MACHINE_BOOT_H
+
+#include <grub/types.h>
+
+#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.3

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to