2000 lines
65 KiB
Diff
2000 lines
65 KiB
Diff
From 5930ad6d2fa6071dbec9a790724ac2ec364fb28f Mon Sep 17 00:00:00 2001
|
|
From: lixianglai <lixianglai@loongson.cn>
|
|
Date: Tue, 7 Feb 2023 07:16:26 -0500
|
|
Subject: [PATCH] Add linux-headers and linux-user.
|
|
|
|
Add linux-headers and linux-user files.
|
|
|
|
Signed-off-by: lixianglai <lixianglai@loongson.cn>
|
|
---
|
|
linux-headers/asm-loongarch64/bitsperlong.h | 25 ++
|
|
linux-headers/asm-loongarch64/kvm.h | 351 ++++++++++++++++++++
|
|
linux-headers/asm-loongarch64/sgidefs.h | 31 ++
|
|
linux-headers/asm-loongarch64/unistd.h | 22 ++
|
|
linux-headers/linux/kvm.h | 25 ++
|
|
linux-user/elfload.c | 64 ++++
|
|
linux-user/loongarch64/cpu_loop.c | 179 ++++++++++
|
|
linux-user/loongarch64/meson.build | 6 +
|
|
linux-user/loongarch64/signal.c | 218 ++++++++++++
|
|
linux-user/loongarch64/sockbits.h | 18 +
|
|
linux-user/loongarch64/syscall_nr.h | 304 +++++++++++++++++
|
|
linux-user/loongarch64/target_cpu.h | 47 +++
|
|
linux-user/loongarch64/target_elf.h | 24 ++
|
|
linux-user/loongarch64/target_fcntl.h | 23 ++
|
|
linux-user/loongarch64/target_signal.h | 40 +++
|
|
linux-user/loongarch64/target_structs.h | 63 ++++
|
|
linux-user/loongarch64/target_syscall.h | 63 ++++
|
|
linux-user/loongarch64/termbits.h | 241 ++++++++++++++
|
|
linux-user/meson.build | 1 +
|
|
linux-user/qemu.h | 2 +-
|
|
linux-user/syscall.c | 3 +
|
|
linux-user/syscall_defs.h | 10 +-
|
|
22 files changed, 1755 insertions(+), 5 deletions(-)
|
|
create mode 100644 linux-headers/asm-loongarch64/bitsperlong.h
|
|
create mode 100644 linux-headers/asm-loongarch64/kvm.h
|
|
create mode 100644 linux-headers/asm-loongarch64/sgidefs.h
|
|
create mode 100644 linux-headers/asm-loongarch64/unistd.h
|
|
create mode 100644 linux-user/loongarch64/cpu_loop.c
|
|
create mode 100644 linux-user/loongarch64/meson.build
|
|
create mode 100644 linux-user/loongarch64/signal.c
|
|
create mode 100644 linux-user/loongarch64/sockbits.h
|
|
create mode 100644 linux-user/loongarch64/syscall_nr.h
|
|
create mode 100644 linux-user/loongarch64/target_cpu.h
|
|
create mode 100644 linux-user/loongarch64/target_elf.h
|
|
create mode 100644 linux-user/loongarch64/target_fcntl.h
|
|
create mode 100644 linux-user/loongarch64/target_signal.h
|
|
create mode 100644 linux-user/loongarch64/target_structs.h
|
|
create mode 100644 linux-user/loongarch64/target_syscall.h
|
|
create mode 100644 linux-user/loongarch64/termbits.h
|
|
|
|
diff --git a/linux-headers/asm-loongarch64/bitsperlong.h b/linux-headers/asm-loongarch64/bitsperlong.h
|
|
new file mode 100644
|
|
index 0000000000..a7981540d2
|
|
--- /dev/null
|
|
+++ b/linux-headers/asm-loongarch64/bitsperlong.h
|
|
@@ -0,0 +1,25 @@
|
|
+/*
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef __ASM_LOONGARCH_BITSPERLONG_H
|
|
+#define __ASM_LOONGARCH_BITSPERLONG_H
|
|
+
|
|
+#define __BITS_PER_LONG _LOONGARCH_SZLONG
|
|
+
|
|
+#include <asm-generic/bitsperlong.h>
|
|
+
|
|
+#endif /* __ASM_LOONGARCH_BITSPERLONG_H */
|
|
diff --git a/linux-headers/asm-loongarch64/kvm.h b/linux-headers/asm-loongarch64/kvm.h
|
|
new file mode 100644
|
|
index 0000000000..a473916d50
|
|
--- /dev/null
|
|
+++ b/linux-headers/asm-loongarch64/kvm.h
|
|
@@ -0,0 +1,351 @@
|
|
+/*
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef __LINUX_KVM_LOONGARCH_H
|
|
+#define __LINUX_KVM_LOONGARCH_H
|
|
+
|
|
+#include <linux/types.h>
|
|
+
|
|
+#define __KVM_HAVE_GUEST_DEBUG
|
|
+#define KVM_GUESTDBG_USE_SW_BP 0x00010000
|
|
+#define KVM_GUESTDBG_USE_HW_BP 0x00020000
|
|
+#define KVM_DATA_HW_BREAKPOINT_NUM 8
|
|
+#define KVM_INST_HW_BREAKPOINT_NUM 8
|
|
+
|
|
+/*
|
|
+ * KVM Loongarch specific structures and definitions.
|
|
+ *
|
|
+ * Some parts derived from the x86 version of this file.
|
|
+ */
|
|
+
|
|
+#define __KVM_HAVE_READONLY_MEM
|
|
+
|
|
+#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
|
|
+#define KVM_LARCH_VCPU_PVTIME_CTRL 2
|
|
+#define KVM_LARCH_VCPU_PVTIME_IPA 0
|
|
+
|
|
+/*
|
|
+ * for KVM_GET_REGS and KVM_SET_REGS
|
|
+ */
|
|
+struct kvm_regs {
|
|
+ /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
|
|
+ __u64 gpr[32];
|
|
+ __u64 pc;
|
|
+};
|
|
+
|
|
+/*
|
|
+ * for KVM_GET_CPUCFG
|
|
+ */
|
|
+struct kvm_cpucfg {
|
|
+ /* out (KVM_GET_CPUCFG) */
|
|
+ __u32 cpucfg[64];
|
|
+};
|
|
+
|
|
+/*
|
|
+ * for KVM_GET_FPU and KVM_SET_FPU
|
|
+ */
|
|
+struct kvm_fpu {
|
|
+ __u32 fcsr;
|
|
+ __u32 vcsr;
|
|
+ __u64 fcc; /* 8x8 */
|
|
+ struct kvm_fpureg {
|
|
+ __u64 val64[4]; // support max 256 bits
|
|
+ } fpr[32];
|
|
+};
|
|
+
|
|
+/*
|
|
+ * For LOONGARCH, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access various
|
|
+ * registers. The id field is broken down as follows:
|
|
+ *
|
|
+ * bits[63..52] - As per linux/kvm.h
|
|
+ * bits[51..32] - Must be zero.
|
|
+ * bits[31..16] - Register set.
|
|
+ *
|
|
+ * Register set = 0: GP registers from kvm_regs (see definitions below).
|
|
+ *
|
|
+ * Register set = 1: CSR registers.
|
|
+ *
|
|
+ * Register set = 2: KVM specific registers (see definitions below).
|
|
+ *
|
|
+ * Register set = 3: FPU / MSA registers (see definitions below).
|
|
+ *
|
|
+ * Other sets registers may be added in the future. Each set would
|
|
+ * have its own identifier in bits[31..16].
|
|
+ */
|
|
+
|
|
+#define KVM_REG_LOONGARCH_GP (KVM_REG_LOONGARCH | 0x0000000000000000ULL)
|
|
+#define KVM_REG_LOONGARCH_CSR (KVM_REG_LOONGARCH | 0x0000000000010000ULL)
|
|
+#define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x0000000000020000ULL)
|
|
+#define KVM_REG_LOONGARCH_FPU (KVM_REG_LOONGARCH | 0x0000000000030000ULL)
|
|
+
|
|
+/*
|
|
+ * KVM_REG_LOONGARCH_GP - General purpose registers from kvm_regs.
|
|
+ */
|
|
+
|
|
+#define KVM_REG_LOONGARCH_R0 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 0)
|
|
+#define KVM_REG_LOONGARCH_R1 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 1)
|
|
+#define KVM_REG_LOONGARCH_R2 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 2)
|
|
+#define KVM_REG_LOONGARCH_R3 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 3)
|
|
+#define KVM_REG_LOONGARCH_R4 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 4)
|
|
+#define KVM_REG_LOONGARCH_R5 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 5)
|
|
+#define KVM_REG_LOONGARCH_R6 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 6)
|
|
+#define KVM_REG_LOONGARCH_R7 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 7)
|
|
+#define KVM_REG_LOONGARCH_R8 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 8)
|
|
+#define KVM_REG_LOONGARCH_R9 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 9)
|
|
+#define KVM_REG_LOONGARCH_R10 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 10)
|
|
+#define KVM_REG_LOONGARCH_R11 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 11)
|
|
+#define KVM_REG_LOONGARCH_R12 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 12)
|
|
+#define KVM_REG_LOONGARCH_R13 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 13)
|
|
+#define KVM_REG_LOONGARCH_R14 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 14)
|
|
+#define KVM_REG_LOONGARCH_R15 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 15)
|
|
+#define KVM_REG_LOONGARCH_R16 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 16)
|
|
+#define KVM_REG_LOONGARCH_R17 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 17)
|
|
+#define KVM_REG_LOONGARCH_R18 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 18)
|
|
+#define KVM_REG_LOONGARCH_R19 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 19)
|
|
+#define KVM_REG_LOONGARCH_R20 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 20)
|
|
+#define KVM_REG_LOONGARCH_R21 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 21)
|
|
+#define KVM_REG_LOONGARCH_R22 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 22)
|
|
+#define KVM_REG_LOONGARCH_R23 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 23)
|
|
+#define KVM_REG_LOONGARCH_R24 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 24)
|
|
+#define KVM_REG_LOONGARCH_R25 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 25)
|
|
+#define KVM_REG_LOONGARCH_R26 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 26)
|
|
+#define KVM_REG_LOONGARCH_R27 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 27)
|
|
+#define KVM_REG_LOONGARCH_R28 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 28)
|
|
+#define KVM_REG_LOONGARCH_R29 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 29)
|
|
+#define KVM_REG_LOONGARCH_R30 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 30)
|
|
+#define KVM_REG_LOONGARCH_R31 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 31)
|
|
+
|
|
+#define KVM_REG_LOONGARCH_HI (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 32)
|
|
+#define KVM_REG_LOONGARCH_LO (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 33)
|
|
+#define KVM_REG_LOONGARCH_PC (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 34)
|
|
+
|
|
+/*
|
|
+ * KVM_REG_LOONGARCH_KVM - KVM specific control registers.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * CP0_Count control
|
|
+ * DC: Set 0: Master disable CP0_Count and set COUNT_RESUME to now
|
|
+ * Set 1: Master re-enable CP0_Count with unchanged bias, handling timer
|
|
+ * interrupts since COUNT_RESUME
|
|
+ * This can be used to freeze the timer to get a consistent snapshot of
|
|
+ * the CP0_Count and timer interrupt pending state, while also resuming
|
|
+ * safely without losing time or guest timer interrupts.
|
|
+ * Other: Reserved, do not change.
|
|
+ */
|
|
+#define KVM_REG_LOONGARCH_COUNT_CTL \
|
|
+ (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 0)
|
|
+#define KVM_REG_LOONGARCH_COUNT_CTL_DC 0x00000001
|
|
+
|
|
+/*
|
|
+ * CP0_Count resume monotonic nanoseconds
|
|
+ * The monotonic nanosecond time of the last set of COUNT_CTL.DC (master
|
|
+ * disable). Any reads and writes of Count related registers while
|
|
+ * COUNT_CTL.DC=1 will appear to occur at this time. When COUNT_CTL.DC is
|
|
+ * cleared again (master enable) any timer interrupts since this time will be
|
|
+ * emulated.
|
|
+ * Modifications to times in the future are rejected.
|
|
+ */
|
|
+#define KVM_REG_LOONGARCH_COUNT_RESUME \
|
|
+ (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 1)
|
|
+/*
|
|
+ * CP0_Count rate in Hz
|
|
+ * Specifies the rate of the CP0_Count timer in Hz. Modifications occur without
|
|
+ * discontinuities in CP0_Count.
|
|
+ */
|
|
+#define KVM_REG_LOONGARCH_COUNT_HZ \
|
|
+ (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 2)
|
|
+#define KVM_REG_LOONGARCH_COUNTER \
|
|
+ (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3)
|
|
+#define KVM_REG_LOONGARCH_VCPU_RESET \
|
|
+ (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 4)
|
|
+
|
|
+struct kvm_iocsr_entry {
|
|
+ __u32 addr;
|
|
+ __u32 pad;
|
|
+ __u64 data;
|
|
+};
|
|
+
|
|
+struct kvm_csr_entry {
|
|
+ __u32 index;
|
|
+ __u32 reserved;
|
|
+ __u64 data;
|
|
+};
|
|
+
|
|
+/* for KVM_GET_MSRS and KVM_SET_MSRS */
|
|
+struct kvm_msrs {
|
|
+ __u32 ncsrs; /* number of msrs in entries */
|
|
+ __u32 pad;
|
|
+ struct kvm_csr_entry entries[0];
|
|
+};
|
|
+
|
|
+#define __KVM_HAVE_IRQ_LINE
|
|
+
|
|
+struct kvm_debug_exit_arch {
|
|
+ __u64 epc;
|
|
+ __u32 fwps;
|
|
+ __u32 mwps;
|
|
+ __u32 exception;
|
|
+};
|
|
+
|
|
+/* for KVM_SET_GUEST_DEBUG */
|
|
+struct hw_breakpoint {
|
|
+ __u64 addr;
|
|
+ __u64 mask;
|
|
+ __u32 asid;
|
|
+ __u32 ctrl;
|
|
+};
|
|
+
|
|
+struct kvm_guest_debug_arch {
|
|
+ struct hw_breakpoint data_breakpoint[KVM_DATA_HW_BREAKPOINT_NUM];
|
|
+ struct hw_breakpoint inst_breakpoint[KVM_INST_HW_BREAKPOINT_NUM];
|
|
+ int inst_bp_nums, data_bp_nums;
|
|
+};
|
|
+
|
|
+/* definition of registers in kvm_run */
|
|
+struct kvm_sync_regs {
|
|
+};
|
|
+
|
|
+/* dummy definition */
|
|
+struct kvm_sregs {
|
|
+};
|
|
+
|
|
+struct kvm_loongarch_interrupt {
|
|
+ /* in */
|
|
+ __u32 cpu;
|
|
+ __u32 irq;
|
|
+};
|
|
+
|
|
+#define KVM_IRQCHIP_LS7A_IOAPIC 0x0
|
|
+#define KVM_IRQCHIP_LS3A_GIPI 0x1
|
|
+#define KVM_IRQCHIP_LS3A_HT_IRQ 0x2
|
|
+#define KVM_IRQCHIP_LS3A_ROUTE 0x3
|
|
+#define KVM_IRQCHIP_LS3A_EXTIRQ 0x4
|
|
+#define KVM_IRQCHIP_LS3A_IPMASK 0x5
|
|
+#define KVM_NR_IRQCHIPS 1
|
|
+#define KVM_IRQCHIP_NUM_PINS 64
|
|
+
|
|
+#define KVM_MAX_CORES 256
|
|
+#define KVM_EXTIOI_IRQS (256)
|
|
+#define KVM_EXTIOI_IRQS_BITMAP_SIZE (KVM_EXTIOI_IRQS / 8)
|
|
+/* map to ipnum per 32 irqs */
|
|
+#define KVM_EXTIOI_IRQS_IPMAP_SIZE (KVM_EXTIOI_IRQS / 32)
|
|
+#define KVM_EXTIOI_IRQS_PER_GROUP 32
|
|
+#define KVM_EXTIOI_IRQS_COREMAP_SIZE (KVM_EXTIOI_IRQS)
|
|
+#define KVM_EXTIOI_IRQS_NODETYPE_SIZE 16
|
|
+
|
|
+struct ls7a_ioapic_state {
|
|
+ __u64 int_id;
|
|
+ /* 0x020 interrupt mask register */
|
|
+ __u64 int_mask;
|
|
+ /* 0x040 1=msi */
|
|
+ __u64 htmsi_en;
|
|
+ /* 0x060 edge=1 level =0 */
|
|
+ __u64 intedge;
|
|
+ /* 0x080 for clean edge int,set 1 clean,set 0 is noused */
|
|
+ __u64 intclr;
|
|
+ /* 0x0c0 */
|
|
+ __u64 auto_crtl0;
|
|
+ /* 0x0e0 */
|
|
+ __u64 auto_crtl1;
|
|
+ /* 0x100 - 0x140 */
|
|
+ __u8 route_entry[64];
|
|
+ /* 0x200 - 0x240 */
|
|
+ __u8 htmsi_vector[64];
|
|
+ /* 0x300 */
|
|
+ __u64 intisr_chip0;
|
|
+ /* 0x320 */
|
|
+ __u64 intisr_chip1;
|
|
+ /* edge detection */
|
|
+ __u64 last_intirr;
|
|
+ /* 0x380 interrupt request register */
|
|
+ __u64 intirr;
|
|
+ /* 0x3a0 interrupt service register */
|
|
+ __u64 intisr;
|
|
+ /* 0x3e0 interrupt level polarity selection register,
|
|
+ * 0 for high level tirgger
|
|
+ */
|
|
+ __u64 int_polarity;
|
|
+};
|
|
+
|
|
+struct loongarch_gipi_single {
|
|
+ __u32 status;
|
|
+ __u32 en;
|
|
+ __u32 set;
|
|
+ __u32 clear;
|
|
+ __u64 buf[4];
|
|
+};
|
|
+
|
|
+struct loongarch_gipiState {
|
|
+ struct loongarch_gipi_single core[KVM_MAX_CORES];
|
|
+};
|
|
+
|
|
+struct kvm_loongarch_ls3a_extirq_state {
|
|
+ union ext_en_r
|
|
+ {
|
|
+ uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8];
|
|
+ uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4];
|
|
+ uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE];
|
|
+ } ext_en_r;
|
|
+ union bounce_r
|
|
+ {
|
|
+ uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8];
|
|
+ uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4];
|
|
+ uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE];
|
|
+ } bounce_r;
|
|
+ union ext_isr_r
|
|
+ {
|
|
+ uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8];
|
|
+ uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4];
|
|
+ uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE];
|
|
+ } ext_isr_r;
|
|
+ union ext_core_isr_r
|
|
+ {
|
|
+ uint64_t reg_u64[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE / 8];
|
|
+ uint32_t reg_u32[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE / 4];
|
|
+ uint8_t reg_u8[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE];
|
|
+ } ext_core_isr_r;
|
|
+ union ip_map_r
|
|
+ {
|
|
+ uint64_t reg_u64;
|
|
+ uint32_t reg_u32[KVM_EXTIOI_IRQS_IPMAP_SIZE / 4];
|
|
+ uint8_t reg_u8[KVM_EXTIOI_IRQS_IPMAP_SIZE];
|
|
+ } ip_map_r;
|
|
+ union core_map_r
|
|
+ {
|
|
+ uint64_t reg_u64[KVM_EXTIOI_IRQS_COREMAP_SIZE / 8];
|
|
+ uint32_t reg_u32[KVM_EXTIOI_IRQS_COREMAP_SIZE / 4];
|
|
+ uint8_t reg_u8[KVM_EXTIOI_IRQS_COREMAP_SIZE];
|
|
+ } core_map_r;
|
|
+ union node_type_r
|
|
+ {
|
|
+ uint64_t reg_u64[KVM_EXTIOI_IRQS_NODETYPE_SIZE / 4];
|
|
+ uint32_t reg_u32[KVM_EXTIOI_IRQS_NODETYPE_SIZE / 2];
|
|
+ uint16_t reg_u16[KVM_EXTIOI_IRQS_NODETYPE_SIZE];
|
|
+ uint8_t reg_u8[KVM_EXTIOI_IRQS_NODETYPE_SIZE * 2];
|
|
+ } node_type_r;
|
|
+};
|
|
+
|
|
+struct loongarch_kvm_irqchip {
|
|
+ __u16 chip_id;
|
|
+ __u16 len;
|
|
+ __u16 vcpu_id;
|
|
+ __u16 reserved;
|
|
+ char data[0];
|
|
+};
|
|
+
|
|
+#endif /* __LINUX_KVM_LOONGARCH_H */
|
|
diff --git a/linux-headers/asm-loongarch64/sgidefs.h b/linux-headers/asm-loongarch64/sgidefs.h
|
|
new file mode 100644
|
|
index 0000000000..89e8be582e
|
|
--- /dev/null
|
|
+++ b/linux-headers/asm-loongarch64/sgidefs.h
|
|
@@ -0,0 +1,31 @@
|
|
+/*
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef __ASM_SGIDEFS_H
|
|
+#define __ASM_SGIDEFS_H
|
|
+
|
|
+#define _LOONGARCH_ISA_LOONGARCH32 6
|
|
+#define _LOONGARCH_ISA_LOONGARCH64 7
|
|
+
|
|
+/*
|
|
+ * Subprogram calling convention
|
|
+ */
|
|
+#define _LOONGARCH_SIM_ABILP32 1
|
|
+#define _LOONGARCH_SIM_ABILPX32 2
|
|
+#define _LOONGARCH_SIM_ABILP64 3
|
|
+
|
|
+#endif /* __ASM_SGIDEFS_H */
|
|
diff --git a/linux-headers/asm-loongarch64/unistd.h b/linux-headers/asm-loongarch64/unistd.h
|
|
new file mode 100644
|
|
index 0000000000..ef710673a3
|
|
--- /dev/null
|
|
+++ b/linux-headers/asm-loongarch64/unistd.h
|
|
@@ -0,0 +1,22 @@
|
|
+/*
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifdef __LP64__
|
|
+#define __ARCH_WANT_NEW_STAT
|
|
+#endif /* __LP64__ */
|
|
+
|
|
+#include <asm-generic/unistd.h>
|
|
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
|
|
index 7870cd0280..c9986c1966 100644
|
|
--- a/linux-headers/linux/kvm.h
|
|
+++ b/linux-headers/linux/kvm.h
|
|
@@ -2008,6 +2008,31 @@ struct kvm_stats_desc {
|
|
char name[];
|
|
};
|
|
|
|
+#ifdef __loongarch__
|
|
+struct kvm_loongarch_vcpu_state {
|
|
+ __u8 online_vcpus;
|
|
+ __u8 is_migrate;
|
|
+ __u32 cpu_freq;
|
|
+ __u32 count_ctl;
|
|
+ __u64 pending_exceptions;
|
|
+ __u64 pending_exceptions_clr;
|
|
+ __u64 core_ext_ioisr[4];
|
|
+};
|
|
+
|
|
+#define KVM_CAP_LOONGARCH_FPU 800
|
|
+#define KVM_CAP_LOONGARCH_LSX 801
|
|
+#define KVM_CAP_LOONGARCH_VZ 802
|
|
+#define KVM_REG_LOONGARCH 0x9000000000000000ULL
|
|
+#define KVM_LARCH_GET_VCPU_STATE \
|
|
+ _IOR(KVMIO, 0xc0, struct kvm_loongarch_vcpu_state)
|
|
+#define KVM_LARCH_SET_VCPU_STATE \
|
|
+ _IOW(KVMIO, 0xc1, struct kvm_loongarch_vcpu_state)
|
|
+#define KVM_LARCH_GET_CPUCFG _IOR(KVMIO, 0xc2, struct kvm_cpucfg)
|
|
+#define KVM_LOONGARCH_GET_IOCSR _IOR(KVMIO, 0xc3, struct kvm_iocsr_entry)
|
|
+#define KVM_LOONGARCH_SET_IOCSR _IOW(KVMIO, 0xc4, struct kvm_iocsr_entry)
|
|
+#define KVM_LARCH_SET_CPUCFG _IOR(KVMIO, 0xc5, struct kvm_cpucfg)
|
|
+#endif
|
|
+
|
|
#define KVM_GET_STATS_FD _IO(KVMIO, 0xce)
|
|
|
|
/* Available with KVM_CAP_XSAVE2 */
|
|
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
|
|
index 767f54c76d..2625af99dd 100644
|
|
--- a/linux-user/elfload.c
|
|
+++ b/linux-user/elfload.c
|
|
@@ -1041,6 +1041,70 @@ static uint32_t get_elf_hwcap(void)
|
|
|
|
#endif /* TARGET_MIPS */
|
|
|
|
+#ifdef TARGET_LOONGARCH64
|
|
+
|
|
+#define ELF_START_MMAP 0x80000000
|
|
+
|
|
+#define ELF_CLASS ELFCLASS64
|
|
+#define ELF_ARCH EM_LOONGARCH
|
|
+
|
|
+#define elf_check_arch(x) ((x) == EM_LOONGARCH)
|
|
+
|
|
+static inline void init_thread(struct target_pt_regs *regs,
|
|
+ struct image_info *infop)
|
|
+{
|
|
+ regs->csr_crmd = 2 << 3;
|
|
+ regs->csr_era = infop->entry;
|
|
+ regs->regs[3] = infop->start_stack;
|
|
+}
|
|
+
|
|
+/* See linux kernel: arch/mips/include/asm/elf.h. */
|
|
+#define ELF_NREG 45
|
|
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
|
|
+
|
|
+/* See linux kernel: arch/loongarch/include/uapi/asm/reg.h */
|
|
+enum {
|
|
+ TARGET_EF_R0 = 0,
|
|
+ TARGET_EF_R26 = TARGET_EF_R0 + 26,
|
|
+ TARGET_EF_R27 = TARGET_EF_R0 + 27,
|
|
+ TARGET_EF_CSR_ERA = TARGET_EF_R0 + 32,
|
|
+ TARGET_EF_CSR_BADV = TARGET_EF_R0 + 33,
|
|
+ TARGET_EF_CSR_CRMD = TARGET_EF_R0 + 34,
|
|
+ TARGET_EF_CSR_ESTAT = TARGET_EF_R0 + 38
|
|
+};
|
|
+
|
|
+/* See linux kernel: arch/loongarch/kernel/process.c:elf_dump_regs. */
|
|
+static void elf_core_copy_regs(target_elf_gregset_t *regs,
|
|
+ const CPULOONGARCHState *env)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ (*regs)[TARGET_EF_R0] = 0;
|
|
+
|
|
+ for (i = 1; i < ARRAY_SIZE(env->active_tc.gpr); i++) {
|
|
+ (*regs)[TARGET_EF_R0 + i] = tswapreg(env->active_tc.gpr[i]);
|
|
+ }
|
|
+
|
|
+ (*regs)[TARGET_EF_R26] = 0;
|
|
+ (*regs)[TARGET_EF_R27] = 0;
|
|
+ (*regs)[TARGET_EF_CSR_ERA] = tswapreg(env->active_tc.PC);
|
|
+ (*regs)[TARGET_EF_CSR_BADV] = tswapreg(env->CSR_BADV);
|
|
+ (*regs)[TARGET_EF_CSR_CRMD] = tswapreg(env->CSR_CRMD);
|
|
+ (*regs)[TARGET_EF_CSR_ESTAT] = tswapreg(env->CSR_ESTAT);
|
|
+}
|
|
+
|
|
+#define USE_ELF_CORE_DUMP
|
|
+#define ELF_EXEC_PAGESIZE 4096
|
|
+
|
|
+#define ELF_HWCAP get_elf_hwcap()
|
|
+
|
|
+static uint32_t get_elf_hwcap(void)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#endif /* TARGET_LOONGARCH64 */
|
|
+
|
|
#ifdef TARGET_MICROBLAZE
|
|
|
|
#define ELF_START_MMAP 0x80000000
|
|
diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c
|
|
new file mode 100644
|
|
index 0000000000..eb455465ab
|
|
--- /dev/null
|
|
+++ b/linux-user/loongarch64/cpu_loop.c
|
|
@@ -0,0 +1,179 @@
|
|
+/*
|
|
+ * qemu user cpu loop
|
|
+ *
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include "qemu/osdep.h"
|
|
+#include "qemu.h"
|
|
+#include "cpu_loop-common.h"
|
|
+#include "elf.h"
|
|
+
|
|
+/* Break codes */
|
|
+enum { BRK_OVERFLOW = 6, BRK_DIVZERO = 7 };
|
|
+
|
|
+void force_sig_fault(CPULOONGARCHState *env, target_siginfo_t *info,
|
|
+ unsigned int code)
|
|
+{
|
|
+
|
|
+ switch (code) {
|
|
+ case BRK_OVERFLOW:
|
|
+ case BRK_DIVZERO:
|
|
+ info->si_signo = TARGET_SIGFPE;
|
|
+ info->si_errno = 0;
|
|
+ info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV;
|
|
+ queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
|
|
+ ret = 0;
|
|
+ break;
|
|
+ default:
|
|
+ info->si_signo = TARGET_SIGTRAP;
|
|
+ info->si_errno = 0;
|
|
+ queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
|
|
+ ret = 0;
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+void cpu_loop(CPULOONGARCHState *env)
|
|
+{
|
|
+ CPUState *cs = CPU(loongarch_env_get_cpu(env));
|
|
+ target_siginfo_t info;
|
|
+ int trapnr;
|
|
+ abi_long ret;
|
|
+
|
|
+ for (;;) {
|
|
+ cpu_exec_start(cs);
|
|
+ trapnr = cpu_exec(cs);
|
|
+ cpu_exec_end(cs);
|
|
+ process_queued_cpu_work(cs);
|
|
+
|
|
+ switch (trapnr) {
|
|
+ case EXCP_SYSCALL:
|
|
+ env->active_tc.PC += 4;
|
|
+ ret =
|
|
+ do_syscall(env, env->active_tc.gpr[11], env->active_tc.gpr[4],
|
|
+ env->active_tc.gpr[5], env->active_tc.gpr[6],
|
|
+ env->active_tc.gpr[7], env->active_tc.gpr[8],
|
|
+ env->active_tc.gpr[9], -1, -1);
|
|
+ if (ret == -TARGET_ERESTARTSYS) {
|
|
+ env->active_tc.PC -= 4;
|
|
+ break;
|
|
+ }
|
|
+ if (ret == -TARGET_QEMU_ESIGRETURN) {
|
|
+ /*
|
|
+ * Returning from a successful sigreturn syscall.
|
|
+ * Avoid clobbering register state.
|
|
+ */
|
|
+ break;
|
|
+ }
|
|
+ env->active_tc.gpr[4] = ret;
|
|
+ break;
|
|
+ case EXCP_TLBL:
|
|
+ case EXCP_TLBS:
|
|
+ case EXCP_AdEL:
|
|
+ case EXCP_AdES:
|
|
+ info.si_signo = TARGET_SIGSEGV;
|
|
+ info.si_errno = 0;
|
|
+ /* XXX: check env->error_code */
|
|
+ info.si_code = TARGET_SEGV_MAPERR;
|
|
+ info._sifields._sigfault._addr = env->CSR_BADV;
|
|
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
|
+ break;
|
|
+ case EXCP_FPDIS:
|
|
+ case EXCP_LSXDIS:
|
|
+ case EXCP_LASXDIS:
|
|
+ case EXCP_RI:
|
|
+ info.si_signo = TARGET_SIGILL;
|
|
+ info.si_errno = 0;
|
|
+ info.si_code = 0;
|
|
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
|
+ break;
|
|
+ case EXCP_INTERRUPT:
|
|
+ /* just indicate that signals should be handled asap */
|
|
+ break;
|
|
+ case EXCP_DEBUG:
|
|
+ info.si_signo = TARGET_SIGTRAP;
|
|
+ info.si_errno = 0;
|
|
+ info.si_code = TARGET_TRAP_BRKPT;
|
|
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
|
+ break;
|
|
+ case EXCP_FPE:
|
|
+ info.si_signo = TARGET_SIGFPE;
|
|
+ info.si_errno = 0;
|
|
+ info.si_code = TARGET_FPE_FLTUNK;
|
|
+ if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_INVALID) {
|
|
+ info.si_code = TARGET_FPE_FLTINV;
|
|
+ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_DIV0) {
|
|
+ info.si_code = TARGET_FPE_FLTDIV;
|
|
+ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_OVERFLOW) {
|
|
+ info.si_code = TARGET_FPE_FLTOVF;
|
|
+ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_UNDERFLOW) {
|
|
+ info.si_code = TARGET_FPE_FLTUND;
|
|
+ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_INEXACT) {
|
|
+ info.si_code = TARGET_FPE_FLTRES;
|
|
+ }
|
|
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
|
+ break;
|
|
+ case EXCP_BREAK: {
|
|
+ abi_ulong trap_instr;
|
|
+ unsigned int code;
|
|
+
|
|
+ ret = get_user_u32(trap_instr, env->active_tc.PC);
|
|
+ if (ret != 0) {
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ code = trap_instr & 0x7fff;
|
|
+ force_sig_fault(env, &info, code);
|
|
+ } break;
|
|
+ case EXCP_TRAP: {
|
|
+ abi_ulong trap_instr;
|
|
+ unsigned int code = 0;
|
|
+
|
|
+ ret = get_user_u32(trap_instr, env->active_tc.PC);
|
|
+
|
|
+ if (ret != 0) {
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ /* The immediate versions don't provide a code. */
|
|
+ if (!(trap_instr & 0xFC000000)) {
|
|
+ code = ((trap_instr >> 6) & ((1 << 10) - 1));
|
|
+ }
|
|
+ force_sig_fault(env, &info, code);
|
|
+ } break;
|
|
+ case EXCP_ATOMIC:
|
|
+ cpu_exec_step_atomic(cs);
|
|
+ break;
|
|
+ default:
|
|
+ error:
|
|
+ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n",
|
|
+ trapnr);
|
|
+ abort();
|
|
+ }
|
|
+ process_pending_signals(env);
|
|
+ }
|
|
+}
|
|
+
|
|
+void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < 32; i++) {
|
|
+ env->active_tc.gpr[i] = regs->regs[i];
|
|
+ }
|
|
+ env->active_tc.PC = regs->csr_era & ~(target_ulong)1;
|
|
+}
|
|
diff --git a/linux-user/loongarch64/meson.build b/linux-user/loongarch64/meson.build
|
|
new file mode 100644
|
|
index 0000000000..c4c0b4d701
|
|
--- /dev/null
|
|
+++ b/linux-user/loongarch64/meson.build
|
|
@@ -0,0 +1,6 @@
|
|
+syscall_nr_generators += {
|
|
+ 'loongarch64': generator(sh,
|
|
+ arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@',
|
|
+ '', 'TARGET_SYSCALL_OFFSET' ],
|
|
+ output: '@BASENAME@_nr.h')
|
|
+}
|
|
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
|
|
new file mode 100644
|
|
index 0000000000..2f336035c9
|
|
--- /dev/null
|
|
+++ b/linux-user/loongarch64/signal.c
|
|
@@ -0,0 +1,218 @@
|
|
+/*
|
|
+ * Emulation of Linux signals
|
|
+ *
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include "qemu/osdep.h"
|
|
+#include "qemu.h"
|
|
+#include "signal-common.h"
|
|
+#include "linux-user/trace.h"
|
|
+
|
|
+#define FPU_REG_WIDTH 256
|
|
+union fpureg
|
|
+{
|
|
+ uint32_t val32[FPU_REG_WIDTH / 32];
|
|
+ uint64_t val64[FPU_REG_WIDTH / 64];
|
|
+};
|
|
+
|
|
+struct target_sigcontext {
|
|
+ uint64_t sc_pc;
|
|
+ uint64_t sc_regs[32];
|
|
+ uint32_t sc_flags;
|
|
+
|
|
+ uint32_t sc_fcsr;
|
|
+ uint32_t sc_vcsr;
|
|
+ uint64_t sc_fcc;
|
|
+ union fpureg sc_fpregs[32] __attribute__((aligned(32)));
|
|
+
|
|
+ uint32_t sc_reserved;
|
|
+};
|
|
+
|
|
+struct sigframe {
|
|
+ uint32_t sf_ass[4]; /* argument save space for o32 */
|
|
+ uint32_t sf_code[2]; /* signal trampoline */
|
|
+ struct target_sigcontext sf_sc;
|
|
+ target_sigset_t sf_mask;
|
|
+};
|
|
+
|
|
+struct target_ucontext {
|
|
+ target_ulong tuc_flags;
|
|
+ target_ulong tuc_link;
|
|
+ target_stack_t tuc_stack;
|
|
+ target_ulong pad0;
|
|
+ struct target_sigcontext tuc_mcontext;
|
|
+ target_sigset_t tuc_sigmask;
|
|
+};
|
|
+
|
|
+struct target_rt_sigframe {
|
|
+ uint32_t rs_ass[4]; /* argument save space for o32 */
|
|
+ uint32_t rs_code[2]; /* signal trampoline */
|
|
+ struct target_siginfo rs_info;
|
|
+ struct target_ucontext rs_uc;
|
|
+};
|
|
+
|
|
+static inline void setup_sigcontext(CPULOONGARCHState *regs,
|
|
+ struct target_sigcontext *sc)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ __put_user(exception_resume_pc(regs), &sc->sc_pc);
|
|
+ regs->hflags &= ~LARCH_HFLAG_BMASK;
|
|
+
|
|
+ __put_user(0, &sc->sc_regs[0]);
|
|
+ for (i = 1; i < 32; ++i) {
|
|
+ __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < 32; ++i) {
|
|
+ __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i].val64[0]);
|
|
+ }
|
|
+}
|
|
+
|
|
+static inline void restore_sigcontext(CPULOONGARCHState *regs,
|
|
+ struct target_sigcontext *sc)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ __get_user(regs->CSR_ERA, &sc->sc_pc);
|
|
+
|
|
+ for (i = 1; i < 32; ++i) {
|
|
+ __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < 32; ++i) {
|
|
+ __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i].val64[0]);
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Determine which stack to use..
|
|
+ */
|
|
+static inline abi_ulong get_sigframe(struct target_sigaction *ka,
|
|
+ CPULOONGARCHState *regs,
|
|
+ size_t frame_size)
|
|
+{
|
|
+ unsigned long sp;
|
|
+
|
|
+ /*
|
|
+ * FPU emulator may have its own trampoline active just
|
|
+ * above the user stack, 16-bytes before the next lowest
|
|
+ * 16 byte boundary. Try to avoid trashing it.
|
|
+ */
|
|
+ sp = target_sigsp(get_sp_from_cpustate(regs) - 32, ka);
|
|
+
|
|
+ return (sp - frame_size) & ~7;
|
|
+}
|
|
+
|
|
+void setup_rt_frame(int sig, struct target_sigaction *ka,
|
|
+ target_siginfo_t *info, target_sigset_t *set,
|
|
+ CPULOONGARCHState *env)
|
|
+{
|
|
+ struct target_rt_sigframe *frame;
|
|
+ abi_ulong frame_addr;
|
|
+ int i;
|
|
+
|
|
+ frame_addr = get_sigframe(ka, env, sizeof(*frame));
|
|
+ trace_user_setup_rt_frame(env, frame_addr);
|
|
+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
|
|
+ goto give_sigsegv;
|
|
+ }
|
|
+
|
|
+ /* ori a7, $r0, TARGET_NR_rt_sigreturn */
|
|
+ /* syscall 0 */
|
|
+ __put_user(0x0380000b + (TARGET_NR_rt_sigreturn << 10),
|
|
+ &frame->rs_code[0]);
|
|
+ __put_user(0x002b0000, &frame->rs_code[1]);
|
|
+
|
|
+ tswap_siginfo(&frame->rs_info, info);
|
|
+
|
|
+ __put_user(0, &frame->rs_uc.tuc_flags);
|
|
+ __put_user(0, &frame->rs_uc.tuc_link);
|
|
+ target_save_altstack(&frame->rs_uc.tuc_stack, env);
|
|
+
|
|
+ setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
|
|
+
|
|
+ for (i = 0; i < TARGET_NSIG_WORDS; i++) {
|
|
+ __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Arguments to signal handler:
|
|
+ *
|
|
+ * a0 = signal number
|
|
+ * a1 = pointer to siginfo_t
|
|
+ * a2 = pointer to ucontext_t
|
|
+ *
|
|
+ * $25 and PC point to the signal handler, $29 points to the
|
|
+ * struct sigframe.
|
|
+ */
|
|
+ env->active_tc.gpr[4] = sig;
|
|
+ env->active_tc.gpr[5] =
|
|
+ frame_addr + offsetof(struct target_rt_sigframe, rs_info);
|
|
+ env->active_tc.gpr[6] =
|
|
+ frame_addr + offsetof(struct target_rt_sigframe, rs_uc);
|
|
+ env->active_tc.gpr[3] = frame_addr;
|
|
+ env->active_tc.gpr[1] =
|
|
+ frame_addr + offsetof(struct target_rt_sigframe, rs_code);
|
|
+ /*
|
|
+ * The original kernel code sets CP0_ERA to the handler
|
|
+ * since it returns to userland using ertn
|
|
+ * we cannot do this here, and we must set PC directly
|
|
+ */
|
|
+ env->active_tc.PC = env->active_tc.gpr[20] = ka->_sa_handler;
|
|
+ unlock_user_struct(frame, frame_addr, 1);
|
|
+ return;
|
|
+
|
|
+give_sigsegv:
|
|
+ unlock_user_struct(frame, frame_addr, 1);
|
|
+ force_sigsegv(sig);
|
|
+}
|
|
+
|
|
+long do_rt_sigreturn(CPULOONGARCHState *env)
|
|
+{
|
|
+ struct target_rt_sigframe *frame;
|
|
+ abi_ulong frame_addr;
|
|
+ sigset_t blocked;
|
|
+
|
|
+ frame_addr = env->active_tc.gpr[3];
|
|
+ trace_user_do_rt_sigreturn(env, frame_addr);
|
|
+ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
|
|
+ goto badframe;
|
|
+ }
|
|
+
|
|
+ target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
|
|
+ set_sigmask(&blocked);
|
|
+
|
|
+ restore_sigcontext(env, &frame->rs_uc.tuc_mcontext);
|
|
+
|
|
+ if (do_sigaltstack(
|
|
+ frame_addr + offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
|
|
+ 0, get_sp_from_cpustate(env)) == -EFAULT)
|
|
+ goto badframe;
|
|
+
|
|
+ env->active_tc.PC = env->CSR_ERA;
|
|
+ /*
|
|
+ * I am not sure this is right, but it seems to work
|
|
+ * maybe a problem with nested signals ?
|
|
+ */
|
|
+ env->CSR_ERA = 0;
|
|
+ return -TARGET_QEMU_ESIGRETURN;
|
|
+
|
|
+badframe:
|
|
+ force_sig(TARGET_SIGSEGV);
|
|
+ return -TARGET_QEMU_ESIGRETURN;
|
|
+}
|
|
diff --git a/linux-user/loongarch64/sockbits.h b/linux-user/loongarch64/sockbits.h
|
|
new file mode 100644
|
|
index 0000000000..8bcbfcb060
|
|
--- /dev/null
|
|
+++ b/linux-user/loongarch64/sockbits.h
|
|
@@ -0,0 +1,18 @@
|
|
+/*
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include "../generic/sockbits.h"
|
|
diff --git a/linux-user/loongarch64/syscall_nr.h b/linux-user/loongarch64/syscall_nr.h
|
|
new file mode 100644
|
|
index 0000000000..0217ad77f9
|
|
--- /dev/null
|
|
+++ b/linux-user/loongarch64/syscall_nr.h
|
|
@@ -0,0 +1,304 @@
|
|
+/*
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef LINUX_USER_LOONGARCH_SYSCALL_NR_H
|
|
+#define LINUX_USER_LOONGARCH_SYSCALL_NR_H
|
|
+
|
|
+#define TARGET_NR_io_setup 0
|
|
+#define TARGET_NR_io_destroy 1
|
|
+#define TARGET_NR_io_submit 2
|
|
+#define TARGET_NR_io_cancel 3
|
|
+#define TARGET_NR_io_getevents 4
|
|
+#define TARGET_NR_setxattr 5
|
|
+#define TARGET_NR_lsetxattr 6
|
|
+#define TARGET_NR_fsetxattr 7
|
|
+#define TARGET_NR_getxattr 8
|
|
+#define TARGET_NR_lgetxattr 9
|
|
+#define TARGET_NR_fgetxattr 10
|
|
+#define TARGET_NR_listxattr 11
|
|
+#define TARGET_NR_llistxattr 12
|
|
+#define TARGET_NR_flistxattr 13
|
|
+#define TARGET_NR_removexattr 14
|
|
+#define TARGET_NR_lremovexattr 15
|
|
+#define TARGET_NR_fremovexattr 16
|
|
+#define TARGET_NR_getcwd 17
|
|
+#define TARGET_NR_lookup_dcookie 18
|
|
+#define TARGET_NR_eventfd2 19
|
|
+#define TARGET_NR_epoll_create1 20
|
|
+#define TARGET_NR_epoll_ctl 21
|
|
+#define TARGET_NR_epoll_pwait 22
|
|
+#define TARGET_NR_dup 23
|
|
+#define TARGET_NR_dup3 24
|
|
+#define TARGET_NR_fcntl 25
|
|
+#define TARGET_NR_inotify_init1 26
|
|
+#define TARGET_NR_inotify_add_watch 27
|
|
+#define TARGET_NR_inotify_rm_watch 28
|
|
+#define TARGET_NR_ioctl 29
|
|
+#define TARGET_NR_ioprio_set 30
|
|
+#define TARGET_NR_ioprio_get 31
|
|
+#define TARGET_NR_flock 32
|
|
+#define TARGET_NR_mknodat 33
|
|
+#define TARGET_NR_mkdirat 34
|
|
+#define TARGET_NR_unlinkat 35
|
|
+#define TARGET_NR_symlinkat 36
|
|
+#define TARGET_NR_linkat 37
|
|
+#define TARGET_NR_renameat 38
|
|
+#define TARGET_NR_umount2 39
|
|
+#define TARGET_NR_mount 40
|
|
+#define TARGET_NR_pivot_root 41
|
|
+#define TARGET_NR_nfsservctl 42
|
|
+#define TARGET_NR_statfs 43
|
|
+#define TARGET_NR_fstatfs 44
|
|
+#define TARGET_NR_truncate 45
|
|
+#define TARGET_NR_ftruncate 46
|
|
+#define TARGET_NR_fallocate 47
|
|
+#define TARGET_NR_faccessat 48
|
|
+#define TARGET_NR_chdir 49
|
|
+#define TARGET_NR_fchdir 50
|
|
+#define TARGET_NR_chroot 51
|
|
+#define TARGET_NR_fchmod 52
|
|
+#define TARGET_NR_fchmodat 53
|
|
+#define TARGET_NR_fchownat 54
|
|
+#define TARGET_NR_fchown 55
|
|
+#define TARGET_NR_openat 56
|
|
+#define TARGET_NR_close 57
|
|
+#define TARGET_NR_vhangup 58
|
|
+#define TARGET_NR_pipe2 59
|
|
+#define TARGET_NR_quotactl 60
|
|
+#define TARGET_NR_getdents64 61
|
|
+#define TARGET_NR_lseek 62
|
|
+#define TARGET_NR_read 63
|
|
+#define TARGET_NR_write 64
|
|
+#define TARGET_NR_readv 65
|
|
+#define TARGET_NR_writev 66
|
|
+#define TARGET_NR_pread64 67
|
|
+#define TARGET_NR_pwrite64 68
|
|
+#define TARGET_NR_preadv 69
|
|
+#define TARGET_NR_pwritev 70
|
|
+#define TARGET_NR_sendfile 71
|
|
+#define TARGET_NR_pselect6 72
|
|
+#define TARGET_NR_ppoll 73
|
|
+#define TARGET_NR_signalfd4 74
|
|
+#define TARGET_NR_vmsplice 75
|
|
+#define TARGET_NR_splice 76
|
|
+#define TARGET_NR_tee 77
|
|
+#define TARGET_NR_readlinkat 78
|
|
+#define TARGET_NR_newfstatat 79
|
|
+#define TARGET_NR_fstat 80
|
|
+#define TARGET_NR_sync 81
|
|
+#define TARGET_NR_fsync 82
|
|
+#define TARGET_NR_fdatasync 83
|
|
+#define TARGET_NR_sync_file_range 84
|
|
+#define TARGET_NR_timerfd_create 85
|
|
+#define TARGET_NR_timerfd_settime 86
|
|
+#define TARGET_NR_timerfd_gettime 87
|
|
+#define TARGET_NR_utimensat 88
|
|
+#define TARGET_NR_acct 89
|
|
+#define TARGET_NR_capget 90
|
|
+#define TARGET_NR_capset 91
|
|
+#define TARGET_NR_personality 92
|
|
+#define TARGET_NR_exit 93
|
|
+#define TARGET_NR_exit_group 94
|
|
+#define TARGET_NR_waitid 95
|
|
+#define TARGET_NR_set_tid_address 96
|
|
+#define TARGET_NR_unshare 97
|
|
+#define TARGET_NR_futex 98
|
|
+#define TARGET_NR_set_robust_list 99
|
|
+#define TARGET_NR_get_robust_list 100
|
|
+#define TARGET_NR_nanosleep 101
|
|
+#define TARGET_NR_getitimer 102
|
|
+#define TARGET_NR_setitimer 103
|
|
+#define TARGET_NR_kexec_load 104
|
|
+#define TARGET_NR_init_module 105
|
|
+#define TARGET_NR_delete_module 106
|
|
+#define TARGET_NR_timer_create 107
|
|
+#define TARGET_NR_timer_gettime 108
|
|
+#define TARGET_NR_timer_getoverrun 109
|
|
+#define TARGET_NR_timer_settime 110
|
|
+#define TARGET_NR_timer_delete 111
|
|
+#define TARGET_NR_clock_settime 112
|
|
+#define TARGET_NR_clock_gettime 113
|
|
+#define TARGET_NR_clock_getres 114
|
|
+#define TARGET_NR_clock_nanosleep 115
|
|
+#define TARGET_NR_syslog 116
|
|
+#define TARGET_NR_ptrace 117
|
|
+#define TARGET_NR_sched_setparam 118
|
|
+#define TARGET_NR_sched_setscheduler 119
|
|
+#define TARGET_NR_sched_getscheduler 120
|
|
+#define TARGET_NR_sched_getparam 121
|
|
+#define TARGET_NR_sched_setaffinity 122
|
|
+#define TARGET_NR_sched_getaffinity 123
|
|
+#define TARGET_NR_sched_yield 124
|
|
+#define TARGET_NR_sched_get_priority_max 125
|
|
+#define TARGET_NR_sched_get_priority_min 126
|
|
+#define TARGET_NR_sched_rr_get_interval 127
|
|
+#define TARGET_NR_restart_syscall 128
|
|
+#define TARGET_NR_kill 129
|
|
+#define TARGET_NR_tkill 130
|
|
+#define TARGET_NR_tgkill 131
|
|
+#define TARGET_NR_sigaltstack 132
|
|
+#define TARGET_NR_rt_sigsuspend 133
|
|
+#define TARGET_NR_rt_sigaction 134
|
|
+#define TARGET_NR_rt_sigprocmask 135
|
|
+#define TARGET_NR_rt_sigpending 136
|
|
+#define TARGET_NR_rt_sigtimedwait 137
|
|
+#define TARGET_NR_rt_sigqueueinfo 138
|
|
+#define TARGET_NR_rt_sigreturn 139
|
|
+#define TARGET_NR_setpriority 140
|
|
+#define TARGET_NR_getpriority 141
|
|
+#define TARGET_NR_reboot 142
|
|
+#define TARGET_NR_setregid 143
|
|
+#define TARGET_NR_setgid 144
|
|
+#define TARGET_NR_setreuid 145
|
|
+#define TARGET_NR_setuid 146
|
|
+#define TARGET_NR_setresuid 147
|
|
+#define TARGET_NR_getresuid 148
|
|
+#define TARGET_NR_setresgid 149
|
|
+#define TARGET_NR_getresgid 150
|
|
+#define TARGET_NR_setfsuid 151
|
|
+#define TARGET_NR_setfsgid 152
|
|
+#define TARGET_NR_times 153
|
|
+#define TARGET_NR_setpgid 154
|
|
+#define TARGET_NR_getpgid 155
|
|
+#define TARGET_NR_getsid 156
|
|
+#define TARGET_NR_setsid 157
|
|
+#define TARGET_NR_getgroups 158
|
|
+#define TARGET_NR_setgroups 159
|
|
+#define TARGET_NR_uname 160
|
|
+#define TARGET_NR_sethostname 161
|
|
+#define TARGET_NR_setdomainname 162
|
|
+#define TARGET_NR_getrlimit 163
|
|
+#define TARGET_NR_setrlimit 164
|
|
+#define TARGET_NR_getrusage 165
|
|
+#define TARGET_NR_umask 166
|
|
+#define TARGET_NR_prctl 167
|
|
+#define TARGET_NR_getcpu 168
|
|
+#define TARGET_NR_gettimeofday 169
|
|
+#define TARGET_NR_settimeofday 170
|
|
+#define TARGET_NR_adjtimex 171
|
|
+#define TARGET_NR_getpid 172
|
|
+#define TARGET_NR_getppid 173
|
|
+#define TARGET_NR_getuid 174
|
|
+#define TARGET_NR_geteuid 175
|
|
+#define TARGET_NR_getgid 176
|
|
+#define TARGET_NR_getegid 177
|
|
+#define TARGET_NR_gettid 178
|
|
+#define TARGET_NR_sysinfo 179
|
|
+#define TARGET_NR_mq_open 180
|
|
+#define TARGET_NR_mq_unlink 181
|
|
+#define TARGET_NR_mq_timedsend 182
|
|
+#define TARGET_NR_mq_timedreceive 183
|
|
+#define TARGET_NR_mq_notify 184
|
|
+#define TARGET_NR_mq_getsetattr 185
|
|
+#define TARGET_NR_msgget 186
|
|
+#define TARGET_NR_msgctl 187
|
|
+#define TARGET_NR_msgrcv 188
|
|
+#define TARGET_NR_msgsnd 189
|
|
+#define TARGET_NR_semget 190
|
|
+#define TARGET_NR_semctl 191
|
|
+#define TARGET_NR_semtimedop 192
|
|
+#define TARGET_NR_semop 193
|
|
+#define TARGET_NR_shmget 194
|
|
+#define TARGET_NR_shmctl 195
|
|
+#define TARGET_NR_shmat 196
|
|
+#define TARGET_NR_shmdt 197
|
|
+#define TARGET_NR_socket 198
|
|
+#define TARGET_NR_socketpair 199
|
|
+#define TARGET_NR_bind 200
|
|
+#define TARGET_NR_listen 201
|
|
+#define TARGET_NR_accept 202
|
|
+#define TARGET_NR_connect 203
|
|
+#define TARGET_NR_getsockname 204
|
|
+#define TARGET_NR_getpeername 205
|
|
+#define TARGET_NR_sendto 206
|
|
+#define TARGET_NR_recvfrom 207
|
|
+#define TARGET_NR_setsockopt 208
|
|
+#define TARGET_NR_getsockopt 209
|
|
+#define TARGET_NR_shutdown 210
|
|
+#define TARGET_NR_sendmsg 211
|
|
+#define TARGET_NR_recvmsg 212
|
|
+#define TARGET_NR_readahead 213
|
|
+#define TARGET_NR_brk 214
|
|
+#define TARGET_NR_munmap 215
|
|
+#define TARGET_NR_mremap 216
|
|
+#define TARGET_NR_add_key 217
|
|
+#define TARGET_NR_request_key 218
|
|
+#define TARGET_NR_keyctl 219
|
|
+#define TARGET_NR_clone 220
|
|
+#define TARGET_NR_execve 221
|
|
+#define TARGET_NR_mmap 222
|
|
+#define TARGET_NR_fadvise64 223
|
|
+#define TARGET_NR_swapon 224
|
|
+#define TARGET_NR_swapoff 225
|
|
+#define TARGET_NR_mprotect 226
|
|
+#define TARGET_NR_msync 227
|
|
+#define TARGET_NR_mlock 228
|
|
+#define TARGET_NR_munlock 229
|
|
+#define TARGET_NR_mlockall 230
|
|
+#define TARGET_NR_munlockall 231
|
|
+#define TARGET_NR_mincore 232
|
|
+#define TARGET_NR_madvise 233
|
|
+#define TARGET_NR_remap_file_pages 234
|
|
+#define TARGET_NR_mbind 235
|
|
+#define TARGET_NR_get_mempolicy 236
|
|
+#define TARGET_NR_set_mempolicy 237
|
|
+#define TARGET_NR_migrate_pages 238
|
|
+#define TARGET_NR_move_pages 239
|
|
+#define TARGET_NR_rt_tgsigqueueinfo 240
|
|
+#define TARGET_NR_perf_event_open 241
|
|
+#define TARGET_NR_accept4 242
|
|
+#define TARGET_NR_recvmmsg 243
|
|
+#define TARGET_NR_arch_specific_syscall 244
|
|
+#define TARGET_NR_wait4 260
|
|
+#define TARGET_NR_prlimit64 261
|
|
+#define TARGET_NR_fanotify_init 262
|
|
+#define TARGET_NR_fanotify_mark 263
|
|
+#define TARGET_NR_name_to_handle_at 264
|
|
+#define TARGET_NR_open_by_handle_at 265
|
|
+#define TARGET_NR_clock_adjtime 266
|
|
+#define TARGET_NR_syncfs 267
|
|
+#define TARGET_NR_setns 268
|
|
+#define TARGET_NR_sendmmsg 269
|
|
+#define TARGET_NR_process_vm_readv 270
|
|
+#define TARGET_NR_process_vm_writev 271
|
|
+#define TARGET_NR_kcmp 272
|
|
+#define TARGET_NR_finit_module 273
|
|
+#define TARGET_NR_sched_setattr 274
|
|
+#define TARGET_NR_sched_getattr 275
|
|
+#define TARGET_NR_renameat2 276
|
|
+#define TARGET_NR_seccomp 277
|
|
+#define TARGET_NR_getrandom 278
|
|
+#define TARGET_NR_memfd_create 279
|
|
+#define TARGET_NR_bpf 280
|
|
+#define TARGET_NR_execveat 281
|
|
+#define TARGET_NR_userfaultfd 282
|
|
+#define TARGET_NR_membarrier 283
|
|
+#define TARGET_NR_mlock2 284
|
|
+#define TARGET_NR_copy_file_range 285
|
|
+#define TARGET_NR_preadv2 286
|
|
+#define TARGET_NR_pwritev2 287
|
|
+#define TARGET_NR_pkey_mprotect 288
|
|
+#define TARGET_NR_pkey_alloc 289
|
|
+#define TARGET_NR_pkey_free 290
|
|
+#define TARGET_NR_statx 291
|
|
+#define TARGET_NR_io_pgetevents 292
|
|
+#define TARGET_NR_rseq 293
|
|
+#define TARGET_NR_kexec_file_load 294
|
|
+
|
|
+#define TARGET_NR_syscalls (TARGET_NR_kexec_file_load + 1)
|
|
+
|
|
+#endif
|
|
diff --git a/linux-user/loongarch64/target_cpu.h b/linux-user/loongarch64/target_cpu.h
|
|
new file mode 100644
|
|
index 0000000000..c4bdb4648b
|
|
--- /dev/null
|
|
+++ b/linux-user/loongarch64/target_cpu.h
|
|
@@ -0,0 +1,47 @@
|
|
+/*
|
|
+ * loongarch specific CPU ABI and functions for linux-user
|
|
+ *
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef LOONGARCH_TARGET_CPU_H
|
|
+#define LOONGARCH_TARGET_CPU_H
|
|
+
|
|
+static inline void cpu_clone_regs_child(CPULOONGARCHState *env,
|
|
+ target_ulong newsp, unsigned flags)
|
|
+{
|
|
+ if (newsp) {
|
|
+ env->active_tc.gpr[3] = newsp;
|
|
+ }
|
|
+ env->active_tc.gpr[7] = 0;
|
|
+ env->active_tc.gpr[4] = 0;
|
|
+}
|
|
+
|
|
+static inline void cpu_clone_regs_parent(CPULOONGARCHState *env,
|
|
+ unsigned flags)
|
|
+{
|
|
+}
|
|
+
|
|
+static inline void cpu_set_tls(CPULOONGARCHState *env, target_ulong newtls)
|
|
+{
|
|
+ env->active_tc.gpr[2] = newtls;
|
|
+}
|
|
+
|
|
+static inline abi_ulong get_sp_from_cpustate(CPULOONGARCHState *state)
|
|
+{
|
|
+ return state->active_tc.gpr[3];
|
|
+}
|
|
+#endif
|
|
diff --git a/linux-user/loongarch64/target_elf.h b/linux-user/loongarch64/target_elf.h
|
|
new file mode 100644
|
|
index 0000000000..2290a9a6d1
|
|
--- /dev/null
|
|
+++ b/linux-user/loongarch64/target_elf.h
|
|
@@ -0,0 +1,24 @@
|
|
+/*
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef LOONGARCH_TARGET_ELF_H
|
|
+#define LOONGARCH_TARGET_ELF_H
|
|
+static inline const char *cpu_get_model(uint32_t eflags)
|
|
+{
|
|
+ return "Loongson-3A5000";
|
|
+}
|
|
+#endif
|
|
diff --git a/linux-user/loongarch64/target_fcntl.h b/linux-user/loongarch64/target_fcntl.h
|
|
new file mode 100644
|
|
index 0000000000..9a2bc1cef5
|
|
--- /dev/null
|
|
+++ b/linux-user/loongarch64/target_fcntl.h
|
|
@@ -0,0 +1,23 @@
|
|
+/*
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef LOONGARCH_TARGET_FCNTL_H
|
|
+#define LOONGARCH_TARGET_FCNTL_H
|
|
+
|
|
+#include "../generic/fcntl.h"
|
|
+
|
|
+#endif /* LOONGARCH_TARGET_FCNTL_H */
|
|
diff --git a/linux-user/loongarch64/target_signal.h b/linux-user/loongarch64/target_signal.h
|
|
new file mode 100644
|
|
index 0000000000..be98151723
|
|
--- /dev/null
|
|
+++ b/linux-user/loongarch64/target_signal.h
|
|
@@ -0,0 +1,40 @@
|
|
+/*
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef LOONGARCH_TARGET_SIGNAL_H
|
|
+#define LOONGARCH_TARGET_SIGNAL_H
|
|
+
|
|
+/* this struct defines a stack used during syscall handling */
|
|
+
|
|
+typedef struct target_sigaltstack {
|
|
+ abi_long ss_sp;
|
|
+ abi_int ss_flags;
|
|
+ abi_ulong ss_size;
|
|
+} target_stack_t;
|
|
+
|
|
+/*
|
|
+ * sigaltstack controls
|
|
+ */
|
|
+#define TARGET_SS_ONSTACK 1
|
|
+#define TARGET_SS_DISABLE 2
|
|
+
|
|
+#define TARGET_MINSIGSTKSZ 2048
|
|
+#define TARGET_SIGSTKSZ 8192
|
|
+
|
|
+#include "../generic/signal.h"
|
|
+
|
|
+#endif /* LOONGARCH_TARGET_SIGNAL_H */
|
|
diff --git a/linux-user/loongarch64/target_structs.h b/linux-user/loongarch64/target_structs.h
|
|
new file mode 100644
|
|
index 0000000000..53e7b3e0e2
|
|
--- /dev/null
|
|
+++ b/linux-user/loongarch64/target_structs.h
|
|
@@ -0,0 +1,63 @@
|
|
+/*
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef LOONGARCH_TARGET_STRUCTS_H
|
|
+#define LOONGARCH_TARGET_STRUCTS_H
|
|
+
|
|
+struct target_ipc_perm {
|
|
+ abi_int __key; /* Key. */
|
|
+ abi_uint uid; /* Owner's user ID. */
|
|
+ abi_uint gid; /* Owner's group ID. */
|
|
+ abi_uint cuid; /* Creator's user ID. */
|
|
+ abi_uint cgid; /* Creator's group ID. */
|
|
+ abi_uint mode; /* Read/write permission. */
|
|
+ abi_ushort __seq; /* Sequence number. */
|
|
+ abi_ushort __pad1;
|
|
+ abi_ulong __unused1;
|
|
+ abi_ulong __unused2;
|
|
+};
|
|
+
|
|
+struct target_shmid_ds {
|
|
+ struct target_ipc_perm shm_perm; /* operation permission struct */
|
|
+ abi_long shm_segsz; /* size of segment in bytes */
|
|
+ abi_ulong shm_atime; /* time of last shmat() */
|
|
+ abi_ulong shm_dtime; /* time of last shmdt() */
|
|
+ abi_ulong shm_ctime; /* time of last change by shmctl() */
|
|
+ abi_int shm_cpid; /* pid of creator */
|
|
+ abi_int shm_lpid; /* pid of last shmop */
|
|
+ abi_ulong shm_nattch; /* number of current attaches */
|
|
+ abi_ulong __unused1;
|
|
+ abi_ulong __unused2;
|
|
+};
|
|
+
|
|
+#define TARGET_SEMID64_DS
|
|
+
|
|
+/*
|
|
+ * The semid64_ds structure for the MIPS architecture.
|
|
+ * Note extra padding because this structure is passed back and forth
|
|
+ * between kernel and user space.
|
|
+ */
|
|
+struct target_semid64_ds {
|
|
+ struct target_ipc_perm sem_perm;
|
|
+ abi_ulong sem_otime;
|
|
+ abi_ulong sem_ctime;
|
|
+ abi_ulong sem_nsems;
|
|
+ abi_ulong __unused1;
|
|
+ abi_ulong __unused2;
|
|
+};
|
|
+
|
|
+#endif
|
|
diff --git a/linux-user/loongarch64/target_syscall.h b/linux-user/loongarch64/target_syscall.h
|
|
new file mode 100644
|
|
index 0000000000..6acc015b85
|
|
--- /dev/null
|
|
+++ b/linux-user/loongarch64/target_syscall.h
|
|
@@ -0,0 +1,63 @@
|
|
+/*
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef LOONGARCH_TARGET_SYSCALL_H
|
|
+#define LOONGARCH_TARGET_SYSCALL_H
|
|
+
|
|
+/*
|
|
+ * this struct defines the way the registers are stored on the
|
|
+ * stack during a system call.
|
|
+ */
|
|
+
|
|
+struct target_pt_regs {
|
|
+ /* Saved main processor registers. */
|
|
+ target_ulong regs[32];
|
|
+
|
|
+ /* Saved special registers. */
|
|
+ /* Saved special registers. */
|
|
+ target_ulong csr_crmd;
|
|
+ target_ulong csr_prmd;
|
|
+ target_ulong csr_euen;
|
|
+ target_ulong csr_ecfg;
|
|
+ target_ulong csr_estat;
|
|
+ target_ulong csr_era;
|
|
+ target_ulong csr_badvaddr;
|
|
+ target_ulong orig_a0;
|
|
+ target_ulong __last[0];
|
|
+};
|
|
+
|
|
+#define UNAME_MACHINE "loongarch"
|
|
+#define UNAME_MINIMUM_RELEASE "2.6.32"
|
|
+
|
|
+#define TARGET_CLONE_BACKWARDS
|
|
+#define TARGET_MINSIGSTKSZ 2048
|
|
+#define TARGET_MLOCKALL_MCL_CURRENT 1
|
|
+#define TARGET_MLOCKALL_MCL_FUTURE 2
|
|
+
|
|
+#define TARGET_FORCE_SHMLBA
|
|
+
|
|
+static inline abi_ulong target_shmlba(CPULOONGARCHState *env)
|
|
+{
|
|
+ return 0x40000;
|
|
+}
|
|
+
|
|
+#define TARGET_PR_SET_FP_MODE 45
|
|
+#define TARGET_PR_GET_FP_MODE 46
|
|
+#define TARGET_PR_FP_MODE_FR (1 << 0)
|
|
+#define TARGET_PR_FP_MODE_FRE (1 << 1)
|
|
+
|
|
+#endif /* LOONGARCH_TARGET_SYSCALL_H */
|
|
diff --git a/linux-user/loongarch64/termbits.h b/linux-user/loongarch64/termbits.h
|
|
new file mode 100644
|
|
index 0000000000..dd251e14b3
|
|
--- /dev/null
|
|
+++ b/linux-user/loongarch64/termbits.h
|
|
@@ -0,0 +1,241 @@
|
|
+/*
|
|
+ * Copyright (c) 2023 Loongarch Technology
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2 or later, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope 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
|
|
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef LINUX_USER_LOONGARCH_TERMBITS_H
|
|
+#define LINUX_USER_LOONGARCH_TERMBITS_H
|
|
+
|
|
+#define TARGET_NCCS 19
|
|
+
|
|
+struct target_termios {
|
|
+ unsigned int c_iflag; /* input mode flags */
|
|
+ unsigned int c_oflag; /* output mode flags */
|
|
+ unsigned int c_cflag; /* control mode flags */
|
|
+ unsigned int c_lflag; /* local mode flags */
|
|
+ unsigned char c_line; /* line discipline */
|
|
+ unsigned char c_cc[TARGET_NCCS]; /* control characters */
|
|
+};
|
|
+
|
|
+/* c_iflag bits */
|
|
+#define TARGET_IGNBRK 0000001
|
|
+#define TARGET_BRKINT 0000002
|
|
+#define TARGET_IGNPAR 0000004
|
|
+#define TARGET_PARMRK 0000010
|
|
+#define TARGET_INPCK 0000020
|
|
+#define TARGET_ISTRIP 0000040
|
|
+#define TARGET_INLCR 0000100
|
|
+#define TARGET_IGNCR 0000200
|
|
+#define TARGET_ICRNL 0000400
|
|
+#define TARGET_IUCLC 0001000
|
|
+#define TARGET_IXON 0002000
|
|
+#define TARGET_IXANY 0004000
|
|
+#define TARGET_IXOFF 0010000
|
|
+#define TARGET_IMAXBEL 0020000
|
|
+#define TARGET_IUTF8 0040000
|
|
+
|
|
+/* c_oflag bits */
|
|
+#define TARGET_OPOST 0000001
|
|
+#define TARGET_OLCUC 0000002
|
|
+#define TARGET_ONLCR 0000004
|
|
+#define TARGET_OCRNL 0000010
|
|
+#define TARGET_ONOCR 0000020
|
|
+#define TARGET_ONLRET 0000040
|
|
+#define TARGET_OFILL 0000100
|
|
+#define TARGET_OFDEL 0000200
|
|
+#define TARGET_NLDLY 0000400
|
|
+#define TARGET_NL0 0000000
|
|
+#define TARGET_NL1 0000400
|
|
+#define TARGET_CRDLY 0003000
|
|
+#define TARGET_CR0 0000000
|
|
+#define TARGET_CR1 0001000
|
|
+#define TARGET_CR2 0002000
|
|
+#define TARGET_CR3 0003000
|
|
+#define TARGET_TABDLY 0014000
|
|
+#define TARGET_TAB0 0000000
|
|
+#define TARGET_TAB1 0004000
|
|
+#define TARGET_TAB2 0010000
|
|
+#define TARGET_TAB3 0014000
|
|
+#define TARGET_XTABS 0014000
|
|
+#define TARGET_BSDLY 0020000
|
|
+#define TARGET_BS0 0000000
|
|
+#define TARGET_BS1 0020000
|
|
+#define TARGET_VTDLY 0040000
|
|
+#define TARGET_VT0 0000000
|
|
+#define TARGET_VT1 0040000
|
|
+#define TARGET_FFDLY 0100000
|
|
+#define TARGET_FF0 0000000
|
|
+#define TARGET_FF1 0100000
|
|
+
|
|
+/* c_cflag bit meaning */
|
|
+#define TARGET_CBAUD 0010017
|
|
+#define TARGET_B0 0000000 /* hang up */
|
|
+#define TARGET_B50 0000001
|
|
+#define TARGET_B75 0000002
|
|
+#define TARGET_B110 0000003
|
|
+#define TARGET_B134 0000004
|
|
+#define TARGET_B150 0000005
|
|
+#define TARGET_B200 0000006
|
|
+#define TARGET_B300 0000007
|
|
+#define TARGET_B600 0000010
|
|
+#define TARGET_B1200 0000011
|
|
+#define TARGET_B1800 0000012
|
|
+#define TARGET_B2400 0000013
|
|
+#define TARGET_B4800 0000014
|
|
+#define TARGET_B9600 0000015
|
|
+#define TARGET_B19200 0000016
|
|
+#define TARGET_B38400 0000017
|
|
+#define TARGET_EXTA B19200
|
|
+#define TARGET_EXTB B38400
|
|
+#define TARGET_CSIZE 0000060
|
|
+#define TARGET_CS5 0000000
|
|
+#define TARGET_CS6 0000020
|
|
+#define TARGET_CS7 0000040
|
|
+#define TARGET_CS8 0000060
|
|
+#define TARGET_CSTOPB 0000100
|
|
+#define TARGET_CREAD 0000200
|
|
+#define TARGET_PARENB 0000400
|
|
+#define TARGET_PARODD 0001000
|
|
+#define TARGET_HUPCL 0002000
|
|
+#define TARGET_CLOCAL 0004000
|
|
+#define TARGET_CBAUDEX 0010000
|
|
+#define TARGET_B57600 0010001
|
|
+#define TARGET_B115200 0010002
|
|
+#define TARGET_B230400 0010003
|
|
+#define TARGET_B460800 0010004
|
|
+#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */
|
|
+#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */
|
|
+#define TARGET_CRTSCTS 020000000000 /* flow control */
|
|
+
|
|
+/* c_lflag bits */
|
|
+#define TARGET_ISIG 0000001
|
|
+#define TARGET_ICANON 0000002
|
|
+#define TARGET_XCASE 0000004
|
|
+#define TARGET_ECHO 0000010
|
|
+#define TARGET_ECHOE 0000020
|
|
+#define TARGET_ECHOK 0000040
|
|
+#define TARGET_ECHONL 0000100
|
|
+#define TARGET_NOFLSH 0000200
|
|
+#define TARGET_TOSTOP 0000400
|
|
+#define TARGET_ECHOCTL 0001000
|
|
+#define TARGET_ECHOPRT 0002000
|
|
+#define TARGET_ECHOKE 0004000
|
|
+#define TARGET_FLUSHO 0010000
|
|
+#define TARGET_PENDIN 0040000
|
|
+#define TARGET_IEXTEN 0100000
|
|
+
|
|
+/* c_cc character offsets */
|
|
+#define TARGET_VINTR 0
|
|
+#define TARGET_VQUIT 1
|
|
+#define TARGET_VERASE 2
|
|
+#define TARGET_VKILL 3
|
|
+#define TARGET_VEOF 4
|
|
+#define TARGET_VTIME 5
|
|
+#define TARGET_VMIN 6
|
|
+#define TARGET_VSWTC 7
|
|
+#define TARGET_VSTART 8
|
|
+#define TARGET_VSTOP 9
|
|
+#define TARGET_VSUSP 10
|
|
+#define TARGET_VEOL 11
|
|
+#define TARGET_VREPRINT 12
|
|
+#define TARGET_VDISCARD 13
|
|
+#define TARGET_VWERASE 14
|
|
+#define TARGET_VLNEXT 15
|
|
+#define TARGET_VEOL2 16
|
|
+
|
|
+/* ioctls */
|
|
+
|
|
+#define TARGET_TCGETS 0x5401
|
|
+#define TARGET_TCSETS 0x5402
|
|
+#define TARGET_TCSETSW 0x5403
|
|
+#define TARGET_TCSETSF 0x5404
|
|
+#define TARGET_TCGETA 0x5405
|
|
+#define TARGET_TCSETA 0x5406
|
|
+#define TARGET_TCSETAW 0x5407
|
|
+#define TARGET_TCSETAF 0x5408
|
|
+#define TARGET_TCSBRK 0x5409
|
|
+#define TARGET_TCXONC 0x540A
|
|
+#define TARGET_TCFLSH 0x540B
|
|
+
|
|
+#define TARGET_TIOCEXCL 0x540C
|
|
+#define TARGET_TIOCNXCL 0x540D
|
|
+#define TARGET_TIOCSCTTY 0x540E
|
|
+#define TARGET_TIOCGPGRP 0x540F
|
|
+#define TARGET_TIOCSPGRP 0x5410
|
|
+#define TARGET_TIOCOUTQ 0x5411
|
|
+#define TARGET_TIOCSTI 0x5412
|
|
+#define TARGET_TIOCGWINSZ 0x5413
|
|
+#define TARGET_TIOCSWINSZ 0x5414
|
|
+#define TARGET_TIOCMGET 0x5415
|
|
+#define TARGET_TIOCMBIS 0x5416
|
|
+#define TARGET_TIOCMBIC 0x5417
|
|
+#define TARGET_TIOCMSET 0x5418
|
|
+#define TARGET_TIOCGSOFTCAR 0x5419
|
|
+#define TARGET_TIOCSSOFTCAR 0x541A
|
|
+#define TARGET_FIONREAD 0x541B
|
|
+#define TARGET_TIOCINQ TARGET_FIONREAD
|
|
+#define TARGET_TIOCLINUX 0x541C
|
|
+#define TARGET_TIOCCONS 0x541D
|
|
+#define TARGET_TIOCGSERIAL 0x541E
|
|
+#define TARGET_TIOCSSERIAL 0x541F
|
|
+#define TARGET_TIOCPKT 0x5420
|
|
+#define TARGET_FIONBIO 0x5421
|
|
+#define TARGET_TIOCNOTTY 0x5422
|
|
+#define TARGET_TIOCSETD 0x5423
|
|
+#define TARGET_TIOCGETD 0x5424
|
|
+#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
|
|
+#define TARGET_TIOCTTYGSTRUCT 0x5426 /* For debugging only */
|
|
+#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */
|
|
+#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */
|
|
+#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */
|
|
+/* Get Pty Number (of pty-mux device) */
|
|
+#define TARGET_TIOCGPTN TARGET_IOR('T', 0x30, unsigned int)
|
|
+/* Lock/unlock Pty */
|
|
+#define TARGET_TIOCSPTLCK TARGET_IOW('T', 0x31, int)
|
|
+/* Safely open the slave */
|
|
+#define TARGET_TIOCGPTPEER TARGET_IO('T', 0x41)
|
|
+
|
|
+#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */
|
|
+#define TARGET_FIOCLEX 0x5451
|
|
+#define TARGET_FIOASYNC 0x5452
|
|
+#define TARGET_TIOCSERCONFIG 0x5453
|
|
+#define TARGET_TIOCSERGWILD 0x5454
|
|
+#define TARGET_TIOCSERSWILD 0x5455
|
|
+#define TARGET_TIOCGLCKTRMIOS 0x5456
|
|
+#define TARGET_TIOCSLCKTRMIOS 0x5457
|
|
+#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */
|
|
+#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */
|
|
+#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */
|
|
+#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */
|
|
+
|
|
+/* wait for a change on serial input line(s) */
|
|
+#define TARGET_TIOCMIWAIT 0x545C
|
|
+/* read serial port inline interrupt counts */
|
|
+#define TARGET_TIOCGICOUNT 0x545D
|
|
+#define TARGET_TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */
|
|
+#define TARGET_TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */
|
|
+
|
|
+/* Used for packet mode */
|
|
+#define TARGET_TIOCPKT_DATA 0
|
|
+#define TARGET_TIOCPKT_FLUSHREAD 1
|
|
+#define TARGET_TIOCPKT_FLUSHWRITE 2
|
|
+#define TARGET_TIOCPKT_STOP 4
|
|
+#define TARGET_TIOCPKT_START 8
|
|
+#define TARGET_TIOCPKT_NOSTOP 16
|
|
+#define TARGET_TIOCPKT_DOSTOP 32
|
|
+
|
|
+#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */
|
|
+
|
|
+#endif
|
|
diff --git a/linux-user/meson.build b/linux-user/meson.build
|
|
index 4f4196ed13..8b8edefa6e 100644
|
|
--- a/linux-user/meson.build
|
|
+++ b/linux-user/meson.build
|
|
@@ -40,3 +40,4 @@ subdir('sparc')
|
|
subdir('sw64')
|
|
subdir('x86_64')
|
|
subdir('xtensa')
|
|
+subdir('loongarch64')
|
|
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
|
|
index 5c713fa8ab..66ddb25d1c 100644
|
|
--- a/linux-user/qemu.h
|
|
+++ b/linux-user/qemu.h
|
|
@@ -61,7 +61,7 @@ struct image_info {
|
|
/* For target-specific processing of NT_GNU_PROPERTY_TYPE_0. */
|
|
uint32_t note_flags;
|
|
|
|
-#ifdef TARGET_MIPS
|
|
+#if defined(TARGET_MIPS) || defined(TARGET_LOONGARCH64)
|
|
int fp_abi;
|
|
int interp_fp_abi;
|
|
#endif
|
|
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
|
|
index fce2c03259..a544d04524 100644
|
|
--- a/linux-user/syscall.c
|
|
+++ b/linux-user/syscall.c
|
|
@@ -1614,6 +1614,9 @@ static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
|
|
#elif defined(TARGET_MIPS)
|
|
((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
|
|
return host_pipe[0];
|
|
+#elif defined(TARGET_LOONGARCH64)
|
|
+ ((CPULOONGARCHState *)cpu_env)->active_tc.gpr[5] = host_pipe[1];
|
|
+ return host_pipe[0];
|
|
#elif defined(TARGET_SH4)
|
|
((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
|
|
return host_pipe[0];
|
|
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
|
|
index 0b13975937..04ca5fe7a0 100644
|
|
--- a/linux-user/syscall_defs.h
|
|
+++ b/linux-user/syscall_defs.h
|
|
@@ -74,7 +74,7 @@
|
|
|| defined(TARGET_M68K) || defined(TARGET_CRIS) \
|
|
|| defined(TARGET_S390X) || defined(TARGET_OPENRISC) \
|
|
|| defined(TARGET_NIOS2) || defined(TARGET_RISCV) \
|
|
- || defined(TARGET_XTENSA)
|
|
+ || defined(TARGET_XTENSA) || defined(TARGET_LOONGARCH64)
|
|
|
|
#define TARGET_IOC_SIZEBITS 14
|
|
#define TARGET_IOC_DIRBITS 2
|
|
@@ -450,7 +450,7 @@ struct target_dirent64 {
|
|
#define TARGET_SIG_IGN ((abi_long)1) /* ignore signal */
|
|
#define TARGET_SIG_ERR ((abi_long)-1) /* error return from signal */
|
|
|
|
-#ifdef TARGET_MIPS
|
|
+#if defined(TARGET_MIPS) || defined(TARGET_LOONGARCH64)
|
|
#define TARGET_NSIG 128
|
|
#else
|
|
#define TARGET_NSIG 64
|
|
@@ -2133,7 +2133,8 @@ struct target_stat64 {
|
|
abi_ulong __unused5;
|
|
};
|
|
|
|
-#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) || defined(TARGET_RISCV)
|
|
+#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) || \
|
|
+ defined(TARGET_RISCV) || defined(TARGET_LOONGARCH64)
|
|
|
|
/* These are the asm-generic versions of the stat and stat64 structures */
|
|
|
|
@@ -2161,7 +2162,7 @@ struct target_stat {
|
|
unsigned int __unused5;
|
|
};
|
|
|
|
-#if !defined(TARGET_RISCV64)
|
|
+#if !(defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64))
|
|
#define TARGET_HAS_STRUCT_STAT64
|
|
struct target_stat64 {
|
|
uint64_t st_dev;
|
|
@@ -2331,6 +2332,7 @@ struct target_statfs64 {
|
|
};
|
|
#elif (defined(TARGET_PPC64) || defined(TARGET_X86_64) || \
|
|
defined(TARGET_SPARC64) || defined(TARGET_AARCH64) || \
|
|
+ defined(TARGET_LOONGARCH64) || \
|
|
defined(TARGET_RISCV)) && !defined(TARGET_ABI32)
|
|
struct target_statfs {
|
|
abi_long f_type;
|
|
--
|
|
2.27.0
|
|
|