From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=55768 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PCwt8-0007RR-FC for qemu-devel@nongnu.org; Mon, 01 Nov 2010 12:05:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PCwYZ-00011w-BU for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:44:27 -0400 Received: from mail-gy0-f173.google.com ([209.85.160.173]:49894) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PCwYZ-00011k-1X for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:44:23 -0400 Received: by gya6 with SMTP id 6so3585173gya.4 for ; Mon, 01 Nov 2010 08:44:22 -0700 (PDT) Message-ID: <4CCEE053.9020906@codemonkey.ws> Date: Mon, 01 Nov 2010 10:44:19 -0500 From: Anthony Liguori MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH 08/40] xenner: kernel: 64-bit files References: <1288623713-28062-1-git-send-email-agraf@suse.de> <1288623713-28062-9-git-send-email-agraf@suse.de> In-Reply-To: <1288623713-28062-9-git-send-email-agraf@suse.de> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alexander Graf Cc: qemu-devel Developers , Gerd Hoffmann On 11/01/2010 10:01 AM, Alexander Graf wrote: > This patch adds various header files required for the xenner kernel on 64 bit > systems. > > Signed-off-by: Alexander Graf > I think it might make more sense to put this on a separate git.qemu.org repository and then use a submodule in roms/. I'm happy to setup access for you/Gerd and it can use qemu-devel as a mailing list. Regards, Anthony Liguori > --- > pc-bios/xenner/xenner64.S | 400 +++++++++++++++++++++++++++++++++++++++++++ > pc-bios/xenner/xenner64.h | 117 +++++++++++++ > pc-bios/xenner/xenner64.lds | 38 ++++ > 3 files changed, 555 insertions(+), 0 deletions(-) > create mode 100644 pc-bios/xenner/xenner64.S > create mode 100644 pc-bios/xenner/xenner64.h > create mode 100644 pc-bios/xenner/xenner64.lds > > diff --git a/pc-bios/xenner/xenner64.S b/pc-bios/xenner/xenner64.S > new file mode 100644 > index 0000000..b140214 > --- /dev/null > +++ b/pc-bios/xenner/xenner64.S > @@ -0,0 +1,400 @@ > +#define ENTRY(name) \ > + .globl name; \ > + .align 16; \ > + name: > + > + .macro PUSH_ERROR > + sub $8, %rsp /* space for error code */ > + .endm > + > + .macro PUSH_TRAP_RBP trapno > + sub $8, %rsp /* space for trap number */ > + push %rbp > + mov $\trapno, %rbp > + mov %rbp, 8(%rsp) /* save trap number on stack */ > + .endm > + > + .macro PUSH_REGS > + push %rdi > + push %rsi > + push %r15 > + push %r14 > + push %r13 > + push %r12 > + push %r11 > + push %r10 > + push %r9 > + push %r8 > + push %rdx > + push %rcx > + push %rbx > + push %rax > + mov %rsp,%rdi /* struct regs pointer */ > + .endm > + > + .macro POP_REGS > + pop %rax > + pop %rbx > + pop %rcx > + pop %rdx > + pop %r8 > + pop %r9 > + pop %r10 > + pop %r11 > + pop %r12 > + pop %r13 > + pop %r14 > + pop %r15 > + pop %rsi > + pop %rdi > + pop %rbp > + .endm > + > + .macro RETURN > + add $16, %rsp /* remove error code& trap number */ > + iretq /* jump back */ > + .endm > + > + .macro DO_TRAP trapno func > + PUSH_TRAP_RBP \trapno > + PUSH_REGS > + call \func > + POP_REGS > + RETURN > + .endm > + > +/* ------------------------------------------------------------------ */ > + > + .code64 > + .text > + > +/* --- 16-bit boot entry point --- */ > + > +ENTRY(boot) > + .code16 > + > + cli > + > + /* load the GDT */ > + lgdt (gdt_desc - boot) > + > + /* turn on long mode and paging */ > + mov $0x1, %eax > + mov %eax, %cr0 > + > + /* enable pagetables */ > + mov $(boot_pgd - boot), %eax > + mov %eax, %cr3 > + > + /* set PSE, PAE */ > + mov $0x30, %eax > + mov %eax, %cr4 > + > + /* long mode */ > + mov $0xc0000080, %ecx > + rdmsr > + or $0x101, %eax > + wrmsr > + > + /* turn on long mode and paging */ > + mov $0x80010001, %eax > + mov %eax, %cr0 > + > + ljmp $0x8, $(boot64 - boot) > + > + > +.align 4, 0 > +gdt: > +.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* dummy */ > +.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9b, 0xaf, 0x00 /* code64 */ > +.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xaf, 0x00 /* data64 */ > + > +gdt_desc: > +.short (3 * 8) - 1 > +.long (gdt - boot) > + > + > +/* --- 64-bit entry point --- */ > + > +boot64: > + .code64 > + > + mov $0x10, %ax > + mov %ax, %ds > + mov %ax, %es > + mov %ax, %fs > + mov %ax, %gs > + mov %ax, %ss > + > + jmpq *(boot64_ind - boot) > + > +boot64_ind: > + .quad boot64_real > + > +boot64_real: > + > + /* switch to real pagetables */ > + mov $(emu_pgd - boot), %rax > + mov %rax, %cr3 > + > + lea boot_stack_high(%rip), %rsp /* setup stack */ > + sub $176, %rsp /* sizeof(struct regs_64) */ > + mov %rsp,%rdi /* struct regs pointer */ > + cmp $0, %rbx > + jne secondary > + call do_boot > + POP_REGS > + RETURN > + > +secondary: > + mov %rdi,%rsi > + mov %rbx,%rdi > + call do_boot_secondary > + POP_REGS > + RETURN > + > +/* --- traps/faults handled by emu --- */ > + > +ENTRY(debug_int1) > + PUSH_ERROR > + DO_TRAP 1 do_int1 > + > +ENTRY(debug_int3) > + PUSH_ERROR > + DO_TRAP 3 do_int3 > + > +ENTRY(illegal_instruction) > + PUSH_ERROR > + DO_TRAP 6 do_illegal_instruction > + > +ENTRY(no_device) > + PUSH_ERROR > + DO_TRAP 7 do_lazy_fpu > + > +ENTRY(double_fault) > + DO_TRAP 8 do_double_fault > + > +ENTRY(general_protection) > + DO_TRAP 13 do_general_protection > + > +ENTRY(page_fault) > + DO_TRAP 14 do_page_fault > + > +/* --- traps/faults forwarded to guest --- */ > + > +ENTRY(division_by_zero) > + PUSH_ERROR > + PUSH_TRAP_RBP 0 > + jmp guest_forward > + > +ENTRY(nmi) > + PUSH_ERROR > + PUSH_TRAP_RBP 2 > + jmp guest_forward > + > +ENTRY(overflow) > + PUSH_ERROR > + PUSH_TRAP_RBP 4 > + jmp guest_forward > + > +ENTRY(bound_check) > + PUSH_ERROR > + PUSH_TRAP_RBP 5 > + jmp guest_forward > + > +ENTRY(coprocessor) > + PUSH_ERROR > + PUSH_TRAP_RBP 9 > + jmp guest_forward > + > +ENTRY(invalid_tss) > + PUSH_TRAP_RBP 10 > + jmp guest_forward > + > +ENTRY(segment_not_present) > + PUSH_TRAP_RBP 11 > + jmp guest_forward > + > +ENTRY(stack_fault) > + PUSH_TRAP_RBP 12 > + jmp guest_forward > + > +ENTRY(floating_point) > + PUSH_ERROR > + PUSH_TRAP_RBP 16 > + jmp guest_forward > + > +ENTRY(alignment) > + PUSH_TRAP_RBP 17 > + jmp guest_forward > + > +ENTRY(machine_check) > + PUSH_ERROR > + PUSH_TRAP_RBP 18 > + jmp guest_forward > + > +ENTRY(simd_floating_point) > + PUSH_ERROR > + PUSH_TRAP_RBP 19 > + jmp guest_forward > + > +guest_forward: > + PUSH_REGS > + call do_guest_forward > + POP_REGS > + RETURN > + > +/* --- interrupts 32 ... 255 --- */ > + > +ENTRY(smp_flush_tlb) > + PUSH_ERROR > + DO_TRAP -1 do_smp_flush_tlb > + > +ENTRY(int_80) > + PUSH_ERROR > + DO_TRAP -1 do_int_80 > + > +ENTRY(irq_entries) > +vector=0 > +.rept 256 > + .align 16 > + PUSH_ERROR > + PUSH_TRAP_RBP vector > + jmp irq_common > +vector=vector+1 > +.endr > + > +ENTRY(irq_common) > + PUSH_REGS > + call do_irq > + POP_REGS > + RETURN > + > +/* --- syscall --- */ > + > +ENTRY(trampoline_syscall) > + /* we arrive here via per-cpu trampoline > + * which sets up the stack for us */ > + PUSH_ERROR > + PUSH_TRAP_RBP -1 > + PUSH_REGS > + call do_syscall > + POP_REGS > + > + add $16, %rsp /* remove error code + trapno */ > + cmp $-1, -8(%rsp) > + je syscall_vmexit > + cmp $-2, -8(%rsp) > + je syscall_iretq > + > +syscall_default: > + /* default sysret path */ > + popq %rcx /* rip */ > + popq %r11 /* cs */ > + popq %r11 /* rflags */ > + popq %rsp /* rsp */ > + sysretq > + > +syscall_vmexit: > + /* bounce hypercall to userspace */ > + popq %rcx /* rip */ > + popq %r11 /* cs */ > + popq %r11 /* rflags */ > + popq %rsp /* rsp */ > + out %al, $0xe0 /* let userspace handle it */ > + sysretq > + > +syscall_iretq: > + /* return from syscall via iretq */ > + iretq > + > +/* helpers */ > + > +ENTRY(broken_memcpy_pf) > + mov %rdx,%rcx > + cld > +1: rep movsb > + xor %rax,%rax > +8: ret > + > + .section .exfix, "ax" > +9: mov $-1, %rax > + jmp 8b > + .previous > + > + .section .extab, "a" > + .align 8 > + .quad 1b,9b > + .previous > + > +/* some 16 bit code for smp boot */ > + > + .code16 > + .align 4096 > +ENTRY(sipi) > + mov $0x00060000, %eax /* EMUDEV_CMD_INIT_SECONDARY_VCPU */ > + outl %eax, $0xe8 /* EMUDEV_REG_COMMAND */ > + hlt > + .code64 > + > +/* emu boot stack, including syscall trampoline template */ > + > + .data > + .globl boot_stack_low, boot_stack_high > + .globl cpu_ptr > + .globl trampoline_start, trampoline_patch, trampoline_stop > + .align 4096 > +boot_stack_low: > +cpu_ptr: > + .quad 0 > +trampoline_start: > + movq %rsp, boot_stack_high-16(%rip) > + leaq boot_stack_high-16(%rip), %rsp > + push %r11 /* rflags */ > + mov $0xdeadbeef, %r11 /* C code must fix cs& ss */ > + movq %r11, boot_stack_high-8(%rip) /* ss */ > + push %r11 /* cs */ > + push %rcx /* rip */ > + > + .byte 0x49, 0xbb /* mov data, %r11 ... */ > +trampoline_patch: > + .quad 0 /* ... data, for jump to ... */ > + jmpq *%r11 /* ... trampoline_syscall */ > +trampoline_stop: > + .align 4096 > +boot_stack_high: > + > +/* boot page tables */ > + > +#define pageflags 0x063 /* preset, rw, accessed, dirty */ > +#define largepage 0x080 /* pse */ > + > + .section .pt, "aw" > + .globl emu_pgd > + > + .align 4096 > +boot_pgd: > + .quad emu_pud - 0xffff830000000000 + pageflags > + .fill 261,8,0 > + .quad emu_pud - 0xffff830000000000 + pageflags > + .fill 249,8,0 > + > + .align 4096 > +emu_pgd: > + .fill 262,8,0 > + .quad emu_pud - 0xffff830000000000 + pageflags > + .fill 249,8,0 > + > + .align 4096 > +emu_pud: > + .quad emu_pmd - 0xffff830000000000 + pageflags > + .fill 511,8,0 > + > + .align 4096 > +emu_pmd: > +i = 0 > + .rept 512 > + .quad pageflags + largepage | (i<< 21) > + i = i + 1 > + .endr > + .align 4096 > diff --git a/pc-bios/xenner/xenner64.h b/pc-bios/xenner/xenner64.h > new file mode 100644 > index 0000000..92d956e > --- /dev/null > +++ b/pc-bios/xenner/xenner64.h > @@ -0,0 +1,117 @@ > +#include > + > +struct regs_64 { > + /* pushed onto stack before calling into C code */ > + uint64_t rax; > + uint64_t rbx; > + uint64_t rcx; > + uint64_t rdx; > + uint64_t r8; > + uint64_t r9; > + uint64_t r10; > + uint64_t r11; > + uint64_t r12; > + uint64_t r13; > + uint64_t r14; > + uint64_t r15; > + uint64_t rsi; > + uint64_t rdi; > + uint64_t rbp; > + uint64_t trapno; > + /* trap / fault / int created */ > + uint64_t error; > + uint64_t rip; > + uint64_t cs; > + uint64_t rflags; > + uint64_t rsp; > + uint64_t ss; > +}; > + > +/* 64bit defines */ > +#define EMUNAME "xenner64" > +#define regs regs_64 > +#define fix_sel fix_sel64 > +#define fix_desc fix_desc64 > +#define ureg_t uint64_t > +#define sreg_t int64_t > +#define PRIxREG PRIx64 > +#define tss(_v) ((0xe000>> 3) + 8 + (((_v)->id)<< 2)) > +#define ldt(_v) ((0xe000>> 3) + 10 + (((_v)->id)<< 2)) > + > +/* xenner-data.c */ > +extern struct idt_64 page_aligned xen_idt[256]; > + > +/* xenner-main.c */ > +asmlinkage void do_int_80(struct regs_64 *regs); > + > +/* xenner-hcall.c */ > +void switch_mode(struct xen_cpu *cpu); > +int is_kernel(struct xen_cpu *cpu); > +asmlinkage void do_syscall(struct regs_64 *regs); > + > +/* xenner-mm.c */ > +void pgtable_walk(int level, uint64_t va, uint64_t root_mfn); > +int pgtable_fixup_flag(struct xen_cpu *cpu, uint64_t va, uint32_t flag); > +int pgtable_is_present(uint64_t va, uint64_t root_mfn); > +void *map_page(uint64_t maddr); > +void *fixmap_page(struct xen_cpu *cpu, uint64_t maddr); > +static inline void free_page(void *ptr) {} > +uint64_t *find_pte_64(uint64_t va); > + > +/* macros */ > +#define context_is_emu(_r) (((_r)->cs& 0x03) == 0x00) > +#define context_is_kernel(_v,_r) (((_r)->cs& 0x03) == 0x03&& is_kernel(_v)) > +#define context_is_user(_v,_r) (((_r)->cs& 0x03) == 0x03&& !is_kernel(_v)) > + > +#define addr_is_emu(va) (((va)>= XEN_M2P_64)&& ((va)< XEN_DOM_64)) > +#define addr_is_kernel(va) ((va)>= XEN_DOM_64) > +#define addr_is_user(va) ((va)< XEN_M2P_64) > + > +/* inline asm bits */ > +static inline int wrmsr_safe(uint32_t msr, uint32_t ax, uint32_t dx) > +{ > + int ret; > + asm volatile("1: wrmsr \n" > + " xorl %0,%0 \n" > + "2: nop \n" > + > + ".section .exfix, \"ax\" \n" > + "3: mov $-1,%0 \n" > + " jmp 2b \n" > + ".previous \n" > + > + ".section .extab, \"a\" \n" > + " .align 8 \n" > + " .quad 1b,3b \n" > + ".previous \n" > + : "=r" (ret) > + : "c" (msr), "a" (ax), "d" (dx)); > + return ret; > +} > + > +static inline int memcpy_pf(void *dest, const void *src, size_t bytes) > +{ > + int ret; > + > + asm volatile(" cld \n" > + "91: rep movsb \n" > + " xor %[ret],%[ret] \n" > + "98: \n" > + > + ".section .exfix, \"ax\" \n" > + "99: mov $-1, %[ret] \n" > + " jmp 98b \n" > + ".previous \n" > + > + ".section .extab, \"a\" \n" > + " .align 8 \n" > + " .quad 91b,99b \n" > + ".previous \n" > + : [ ret ] "=a" (ret), > + [ rsi ] "+S" (src), > + [ rdi ] "+D" (dest), > + [ rcx ] "+c" (bytes) > + : > + : "memory" ); > + return ret; > +} > diff --git a/pc-bios/xenner/xenner64.lds b/pc-bios/xenner/xenner64.lds > new file mode 100644 > index 0000000..0b580a9 > --- /dev/null > +++ b/pc-bios/xenner/xenner64.lds > @@ -0,0 +1,38 @@ > +OUTPUT_FORMAT("elf64-x86-64") > + > +SECTIONS > +{ > + . = 0xffff830000000000; > + _vstart = .; > + phys_startup_64 = 0x0; > + > + /* code */ > + .text : AT(ADDR(.text) - 0xffff830000000000) { *(.text) } > + . = ALIGN(4k); > + .exfix : { *(.exfix) } > + > + /* data, ro */ > + . = ALIGN(4k); > + .note.gnu.build-id : { *(.note.gnu.build-id) } > + . = ALIGN(4k); > + _estart = .; > + .extab : { *(.extab) } > + _estop = .; > + . = ALIGN(4k); > + .rodata : { *(.rodata) } > + > + /* data, rw */ > + . = ALIGN(4k); > + .pt : { *(.pt) } > + . = ALIGN(4k); > + .pgdata : { *(.pgdata) } > + . = ALIGN(4k); > + .data : { *(.data) } > + > + /* bss */ > + . = ALIGN(4k); > + .bss : { *(.bss) } > + > + . = ALIGN(4k); > + _vstop = .; > +} >