From patchwork Mon Nov 1 15:01:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 69791 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 65E6B1007D3 for ; Tue, 2 Nov 2010 02:46:35 +1100 (EST) Received: from localhost ([127.0.0.1]:58390 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PCwWb-0007uA-0c for incoming@patchwork.ozlabs.org; Mon, 01 Nov 2010 11:42:21 -0400 Received: from [140.186.70.92] (port=52810 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PCvtj-0003eJ-BH for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:02:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PCvtV-0000dp-4e for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:01:59 -0400 Received: from cantor.suse.de ([195.135.220.2]:60251 helo=mx1.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PCvtU-0000cy-KW for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:01:57 -0400 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id 37A61945D8; Mon, 1 Nov 2010 16:01:54 +0100 (CET) From: Alexander Graf To: qemu-devel Developers Date: Mon, 1 Nov 2010 16:01:21 +0100 Message-Id: <1288623713-28062-9-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1288623713-28062-1-git-send-email-agraf@suse.de> References: <1288623713-28062-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH 08/40] xenner: kernel: 64-bit files X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This patch adds various header files required for the xenner kernel on 64 bit systems. Signed-off-by: Alexander Graf --- 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 = .; +}