From ad79c2e137e801c490fc35d4cecefbca6619fbea Mon Sep 17 00:00:00 2001
From: Huang Yang <huangyang@loongson.cn>
Date: Thu, 25 Apr 2024 12:14:01 +0000
Subject: [PATCH] add loongarch support for anaconda

---
 pyanaconda/modules/storage/bootloader/base.py |  9 +++--
 pyanaconda/modules/storage/bootloader/efi.py  | 33 ++++++++++++++++++-
 .../modules/storage/bootloader/factory.py     |  4 +++
 .../modules/storage/devicetree/fsset.py       |  6 +++-
 pyanaconda/modules/storage/platform.py        | 10 ++++++
 5 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/pyanaconda/modules/storage/bootloader/base.py b/pyanaconda/modules/storage/bootloader/base.py
index d40086d..191b8af 100644
--- a/pyanaconda/modules/storage/bootloader/base.py
+++ b/pyanaconda/modules/storage/bootloader/base.py
@@ -796,11 +796,14 @@ class BootLoader(object):
         swap_devices = storage.fsset.swap_devices
         dracut_devices.extend(swap_devices)
 
-        # Add resume= option to enable hibernation on x86.
+        # Add resume= option to enable hibernation on x86 and loongarch.
         # Choose the largest swap device for that.
-        if blivet.arch.is_x86() and swap_devices:
+        if (blivet.arch.is_x86() or blivet.arch.is_loongarch())and swap_devices:
             resume_device = max(swap_devices, key=lambda x: x.size)
-            self.boot_args.add("resume=%s" % resume_device.fstab_spec)
+            if not blivet.arch.is_efi() and blivet.arch.is_loongarch():
+                self.boot_args.add("resume=%s" % resume_device.path)
+            else:
+                self.boot_args.add("resume=%s" % resume_device.fstab_spec)
 
         # Does /usr have its own device? If so, we need to tell dracut
         usr_device = storage.mountpoints.get("/usr")
diff --git a/pyanaconda/modules/storage/bootloader/efi.py b/pyanaconda/modules/storage/bootloader/efi.py
index 6135699..96450dc 100644
--- a/pyanaconda/modules/storage/bootloader/efi.py
+++ b/pyanaconda/modules/storage/bootloader/efi.py
@@ -28,7 +28,7 @@ from pyanaconda.product import productName
 from pyanaconda.anaconda_loggers import get_module_logger
 log = get_module_logger(__name__)
 
-__all__ = ["EFIBase", "EFIGRUB", "Aarch64EFIGRUB", "ArmEFIGRUB", "MacEFIGRUB"]
+__all__ = ["EFIBase", "EFIGRUB", "Aarch64EFIGRUB", "ArmEFIGRUB", "MacEFIGRUB", "LOONGARCHEFIGRUB"]
 
 
 class EFIBase(object):
@@ -169,6 +169,37 @@ class Aarch64EFIGRUB(EFIGRUB):
         super().__init__()
         self._packages64 = ["grub2-efi-aa64", "shim-aa64"]
 
+class LOONGARCHEFIGRUB(EFIGRUB):
+    _efi_binary = "grubloongarch64.efi"
+    stage2_is_valid_stage1 = False
+    stage2_bootable = False
+
+    def __init__(self):
+        super().__init__()
+        self._packages64 = ["grub2-efi-loongarch64"]
+
+    def remove_efi_boot_target(self):
+        return
+
+    def _add_single_efi_boot_target(self, partition):
+        boot_disk = partition.disk
+        boot_part_num = str(partition.parted_partition.number)
+
+        rc = util.execInSysroot("cp", ["-a", "/boot/efi/EFI/openEuler/" + self._efi_binary, "/boot/efi/EFI/BOOT/" + "BOOTLOONGARCH64.EFI"])
+        if rc:
+            raise BootLoaderError("Failed to set new efi boot target. This is most "
+                                  "likely a kernel or firmware bug.")
+        rc = util.execInSysroot("cp", ["-a", "/boot/efi/EFI/openEuler/" + self._efi_binary, "/boot/efi/EFI/BOOT/" + "BOOTLOONGARCH.EFI"])
+        if rc:
+            raise BootLoaderError("Failed to set new efi boot target for new BIOS. This is most "
+                                  "likely a kernel or firmware bug.")
+
+    def add_efi_boot_target(self):
+        if self.stage1_device.type == "partition":  # pylint: disable=no-member
+           self._add_single_efi_boot_target(self.stage1_device)  # pylint: disable=no-member
+        elif self.stage1_device.type == "mdarray":  # pylint: disable=no-member
+           for parent in self.stage1_device.parents:  # pylint: disable=no-member
+                self._add_single_efi_boot_target(parent)
 
 class ArmEFIGRUB(EFIGRUB):
     _serial_consoles = ["ttyAMA", "ttyS"]
diff --git a/pyanaconda/modules/storage/bootloader/factory.py b/pyanaconda/modules/storage/bootloader/factory.py
index 8aa3afb..2fb9993 100644
--- a/pyanaconda/modules/storage/bootloader/factory.py
+++ b/pyanaconda/modules/storage/bootloader/factory.py
@@ -114,6 +114,10 @@ class BootLoaderFactory(object):
             from pyanaconda.modules.storage.bootloader.efi import EFIGRUB
             return EFIGRUB
 
+        if platform_class is platform.LOONGARCHEFI:
+            from pyanaconda.modules.storage.bootloader.efi import LOONGARCHEFIGRUB
+            return LOONGARCHEFIGRUB
+
         if platform_class is platform.MacEFI:
             from pyanaconda.modules.storage.bootloader.efi import MacEFIGRUB
             return MacEFIGRUB
diff --git a/pyanaconda/modules/storage/devicetree/fsset.py b/pyanaconda/modules/storage/devicetree/fsset.py
index 4db3759..6f85a37 100644
--- a/pyanaconda/modules/storage/devicetree/fsset.py
+++ b/pyanaconda/modules/storage/devicetree/fsset.py
@@ -23,6 +23,7 @@ import gi
 gi.require_version("BlockDev", "3.0")
 from gi.repository import BlockDev as blockdev
 
+from blivet import arch
 from blivet.devices import NoDevice, DirectoryDevice, NFSDevice, FileDevice, MDRaidArrayDevice, \
     NetworkStorageDevice, OpticalDevice
 from blivet.errors import UnrecognizedFSTabEntryError, FSTabTypeMismatchError
@@ -776,7 +777,10 @@ class FSSet(object):
                     break
             if device.encrypted:
                 options += ",x-systemd.device-timeout=0"
-            devspec = device.fstab_spec
+            if not arch.is_efi() and arch.is_loongarch():
+                devspec = device.path
+            else:
+                devspec = device.fstab_spec
             dump = device.format.dump
             if device.format.check and mountpoint == "/":
                 passno = 1
diff --git a/pyanaconda/modules/storage/platform.py b/pyanaconda/modules/storage/platform.py
index d0aa7ca..3a238f9 100644
--- a/pyanaconda/modules/storage/platform.py
+++ b/pyanaconda/modules/storage/platform.py
@@ -287,6 +287,14 @@ class Aarch64EFI(EFI):
         return ["vfat", "ntfs"]
 
 
+class LOONGARCHEFI(EFI):
+
+    @property
+    def non_linux_format_types(self):
+        """Format types of devices with non-linux operating systems."""
+        return ["vfat", "ntfs"]
+
+
 class ArmEFI(EFI):
 
     @property
@@ -486,6 +494,8 @@ def get_platform():
             return Aarch64EFI()
         elif arch.is_arm():
             return ArmEFI()
+        elif arch.is_loongarch():
+            return LOONGARCHEFI()
         else:
             return EFI()
     elif arch.is_x86():
-- 
2.43.0

