Open figozhang opened 6 years ago
Hi,
I also meet same problem. As far as I investigated the issue, there are two problems at least. 1) Accessing EL3 register Certainly, some hardware like RASPI3 starts from EL3 or EL2. But in this case, bootloader or OS kernel should entering el1. So exception handler use el1 system registers however 6a17d accesses elr_el3 and spsr_el3. This cause sync trap repeatedly. This is a main cause of hung. 2) The change of trap frame layout should be applied to struct trapframe 6a17d changes trapframe, but struct trapframe has not been changed yet.
You can see the current snapshot of my work at https://github.com/takeharukato/xv6-OS-for-arm-v8/tree/devel-tkato-rework-aarch64-work .
I fixed these thing to confirm my investigation, but I got a message 'und at: 0xffffffff47fdbee01` In this case user instruction does not point regular address.
xv6 on ARMv8-A (64-bit) Architecture
message banner is printed by init
so this indicates the kernel could invoke init.
starting xv6 for ARMv8...
Implementer: ARM Limited
Current EL: EL1
Flushing TLB and Instr Cache
Setting Memory Attribute Indirection Register (MAIR_EL1)
Setting Vector Base Address Register (VBAR_EL1)
Setting Translation Control Register (TCR_EL1)
Setting Translation Table Base Register 1 (TTBR1_EL1)
Setting Translation Table Base Register 0 (TTBR0_EL1)
Setting System Control Register (SCTLR_EL1)
System Configure Completed...
clearing BSS section for the main kernel
Starting Kernel
**************************************************************************
** **
** **
** xv6 on ARMv8-A (64-bit) Architecture **
** **
** **
***********************Gund at: 0xffffffff47fdbee0
sp: 0x3ed8
pc: 0xffffffff47fdbee0
spsr: 0x20000000
r0: 0x1
r1: 0x1
r2: 0x3ed3
r3: 0x1
r4: 0xffffffff47fdbed0
r5: 0x0
r6: 0x0
r7: 0x0
r8: 0x0
r9: 0x0
r10: 0x0
r11: 0x0
r12: 0x0
r13: 0x0
r14: 0x0
r15: 0x0
r16: 0x0
r17: 0x0
r18: 0x0
r19: 0x0
r20: 0x0
r21: 0x0
r22: 0x0
r23: 0x0
r24: 0x0
r25: 0x0
r26: 0x0
r27: 0x0
r28: 0x0
r29: 0x3c040035874
r30: 0xffffffff47fdbee0
I hope that this might be useful information for you.
Thanks, Regards,
Hi,
After all, I found the cause of this hang and I fixed this problem, may be.
I've done the following things and the kernel work fine again.
(1) Fix the definition of struct trapframe to adapt to the current trap frame in trap_asm.S (2) Use elr_el1, spsr_el1 instead of elr_el3, spsr_el3 because EL3 is used by security monitors not OS kernels. (3) Set a kernel stack pointer ( sp ) to the bottom of process's kernel stack when the kernel returns to EL0.
I've pushed my fix to https://github.com/takeharukato/xv6-OS-for-arm-v8/tree/devel-tkato-rework-aarch64-work . Would you please give it a try?
FYI, I show the result of my fix:
$ ./run.sh
starting xv6 for ARMv8...
Implementer: ARM Limited
Current EL: EL1
Flushing TLB and Instr Cache
Setting Memory Attribute Indirection Register (MAIR_EL1)
Setting Vector Base Address Register (VBAR_EL1)
Setting Translation Control Register (TCR_EL1)
Setting Translation Table Base Register 1 (TTBR1_EL1)
Setting Translation Table Base Register 0 (TTBR0_EL1)
Setting System Control Register (SCTLR_EL1)
System Configure Completed...
clearing BSS section for the main kernel
Starting Kernel
**************************************************************************
** **
** **
** xv6 on ARMv8-A (64-bit) Architecture **
** **
** **
**************************************************************************
init: Starting Shell
$
I show what I modified as follows:
diff --git a/xv6-armv8/arm.h b/xv6-armv8/arm.h
index 94fcf02..fb0dd06 100644
--- a/xv6-armv8/arm.h
+++ b/xv6-armv8/arm.h
@@ -21,9 +21,6 @@
// and switches to a new process (including user-space banked registers)
#ifndef __ASSEMBLER__
struct trapframe {
- uint64 sp; // user mode sp
- uint64 pc; // user mode pc (elr)
- uint64 spsr;
uint64 r0;
uint64 r1;
uint64 r2;
@@ -55,6 +52,9 @@ struct trapframe {
uint64 r28;
uint64 r29;
uint64 r30; // user mode lr
+ uint64 sp; // user mode sp
+ uint64 pc; // user mode pc (elr)
+ uint64 spsr;
};
#endif
diff --git a/xv6-armv8/trap_asm.S b/xv6-armv8/trap_asm.S
index 04227f4..d364676 100644
--- a/xv6-armv8/trap_asm.S
+++ b/xv6-armv8/trap_asm.S
@@ -20,8 +20,8 @@
stp x0, x1, [sp, #-16]!
add x21, sp, #0x110
- mrs x22, elr_el3 /* ELR */
- mrs x23, spsr_el3 /* SPSR */
+ mrs x22, elr_el1 /* ELR */
+ mrs x23, spsr_el1 /* SPSR */
stp x30, x21, [sp, #0xf0] /* LR, SP */
stp x22, x23, [sp, #0x100] /* ELR, SPSR */
@@ -31,8 +31,8 @@
ldp x22, x23, [sp, #0x100] /* ELR, SPSR */
ldp x30, x28, [sp, #0xf0] /* LR, SP */
- msr elr_el3, x22 /* ELR */
- msr spsr_el3, x23
+ msr elr_el1, x22 /* ELR */
+ msr spsr_el1, x23
mov x29, sp
mov sp, x28
@@ -75,8 +75,8 @@
stp x0, x1, [sp, #-16]!
mrs x21, sp_el0
- mrs x22, elr_el3 /* ELR */
- mrs x23, spsr_el3 /* SPSR */
+ mrs x22, elr_el1 /* ELR */
+ mrs x23, spsr_el1 /* SPSR */
stp x30, x21, [sp, #0xf0] /* LR, SP */
stp x22, x23, [sp, #0x100] /* ELR, SPSR */
@@ -86,11 +86,12 @@
ldp x22, x23, [sp, #0x100] /* ELR, SPSR */
ldp x30, x28, [sp, #0xf0] /* LR, SP */
- msr elr_el3, x22 /* ELR */
- msr spsr_el3, x23
+ msr elr_el1, x22 /* ELR */
+ msr spsr_el1, x23
msr sp_el0, x28
mov x29, sp
+ add sp, sp, #0x110
ldp x0, x1, [x29], #16
ldp x2, x3, [x29], #16
I might have written the codes to move into EL1 from EL2/EL3 before I sent a PR. But I can not write and test such codes because I do not have a machine which boots the kernel from EL3.
Thanks, Regards,
Hi,
After all, I found the cause of this hang and I fixed this problem, may be.
I've done the following things and the kernel work fine again.
(1) Fix the definition of struct trapframe to adapt to the current trap frame in trap_asm.S (2) Use elr_el1, spsr_el1 instead of elr_el3, spsr_el3 because EL3 is used by security monitors not OS kernels. (3) Set a kernel stack pointer ( sp ) to the bottom of process's kernel stack when the kernel returns to EL0.
I've pushed my fix to https://github.com/takeharukato/xv6-OS-for-arm-v8/tree/devel-tkato-rework-aarch64-work . Would you please give it a try?
FYI, I show the result of my fix:
$ ./run.sh starting xv6 for ARMv8... Implementer: ARM Limited Current EL: EL1 Flushing TLB and Instr Cache Setting Memory Attribute Indirection Register (MAIR_EL1) Setting Vector Base Address Register (VBAR_EL1) Setting Translation Control Register (TCR_EL1) Setting Translation Table Base Register 1 (TTBR1_EL1) Setting Translation Table Base Register 0 (TTBR0_EL1) Setting System Control Register (SCTLR_EL1) System Configure Completed... clearing BSS section for the main kernel Starting Kernel ************************************************************************** ** ** ** ** ** xv6 on ARMv8-A (64-bit) Architecture ** ** ** ** ** ************************************************************************** init: Starting Shell $
I show what I modified as follows:
diff --git a/xv6-armv8/arm.h b/xv6-armv8/arm.h index 94fcf02..fb0dd06 100644 --- a/xv6-armv8/arm.h +++ b/xv6-armv8/arm.h @@ -21,9 +21,6 @@ // and switches to a new process (including user-space banked registers) #ifndef __ASSEMBLER__ struct trapframe { - uint64 sp; // user mode sp - uint64 pc; // user mode pc (elr) - uint64 spsr; uint64 r0; uint64 r1; uint64 r2; @@ -55,6 +52,9 @@ struct trapframe { uint64 r28; uint64 r29; uint64 r30; // user mode lr + uint64 sp; // user mode sp + uint64 pc; // user mode pc (elr) + uint64 spsr; }; #endif diff --git a/xv6-armv8/trap_asm.S b/xv6-armv8/trap_asm.S index 04227f4..d364676 100644 --- a/xv6-armv8/trap_asm.S +++ b/xv6-armv8/trap_asm.S @@ -20,8 +20,8 @@ stp x0, x1, [sp, #-16]! add x21, sp, #0x110 - mrs x22, elr_el3 /* ELR */ - mrs x23, spsr_el3 /* SPSR */ + mrs x22, elr_el1 /* ELR */ + mrs x23, spsr_el1 /* SPSR */ stp x30, x21, [sp, #0xf0] /* LR, SP */ stp x22, x23, [sp, #0x100] /* ELR, SPSR */ @@ -31,8 +31,8 @@ ldp x22, x23, [sp, #0x100] /* ELR, SPSR */ ldp x30, x28, [sp, #0xf0] /* LR, SP */ - msr elr_el3, x22 /* ELR */ - msr spsr_el3, x23 + msr elr_el1, x22 /* ELR */ + msr spsr_el1, x23 mov x29, sp mov sp, x28 @@ -75,8 +75,8 @@ stp x0, x1, [sp, #-16]! mrs x21, sp_el0 - mrs x22, elr_el3 /* ELR */ - mrs x23, spsr_el3 /* SPSR */ + mrs x22, elr_el1 /* ELR */ + mrs x23, spsr_el1 /* SPSR */ stp x30, x21, [sp, #0xf0] /* LR, SP */ stp x22, x23, [sp, #0x100] /* ELR, SPSR */ @@ -86,11 +86,12 @@ ldp x22, x23, [sp, #0x100] /* ELR, SPSR */ ldp x30, x28, [sp, #0xf0] /* LR, SP */ - msr elr_el3, x22 /* ELR */ - msr spsr_el3, x23 + msr elr_el1, x22 /* ELR */ + msr spsr_el1, x23 msr sp_el0, x28 mov x29, sp + add sp, sp, #0x110 ldp x0, x1, [x29], #16 ldp x2, x3, [x29], #16
I might have written the codes to move into EL1 from EL2/EL3 before I sent a PR. But I can not write and test such codes because I do not have a machine which boots the kernel from EL3.
Thanks, Regards,
that seems like a useful fix. But doesnt work for me on m2 macos, still stuck in the same issue, any ideas?
i try your git tree on qemu, but it cannot go into shell, here is log:
starting xv6 for ARMv8... Implementer: ARM Limited Current EL: EL1 Flushing TLB and Instr Cache Setting Memory Attribute Indirection Register (MAIR_EL1) Setting Vector Base Address Register (VBAR_EL1) Setting Translation Control Register (TCR_EL1) Setting Translation Table Base Register 1 (TTBR1_EL1) Setting Translation Table Base Register 0 (TTBR0_EL1) Setting System Control Register (SCTLR_EL1) System Configure Completed...
clearing BSS section for the main kernel Starting Kernel