From patchwork Mon Nov 1 15:01:20 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 69816 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 7A002B6EF1 for ; Tue, 2 Nov 2010 03:47:40 +1100 (EST) Received: from localhost ([127.0.0.1]:53380 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PCwsM-0006o5-UN for incoming@patchwork.ozlabs.org; Mon, 01 Nov 2010 12:04:51 -0400 Received: from [140.186.70.92] (port=52825 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PCvtk-0003ek-LJ for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:02:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PCvtV-0000eI-HE for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:02:00 -0400 Received: from cantor2.suse.de ([195.135.220.15]:39320 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PCvtU-0000cq-VJ for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:01:57 -0400 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id 0F0FD8655F; Mon, 1 Nov 2010 16:01:54 +0100 (CET) From: Alexander Graf To: qemu-devel Developers Date: Mon, 1 Nov 2010 16:01:20 +0100 Message-Id: <1288623713-28062-8-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 07/40] xenner: kernel: 32 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 files required to implement 32bit support in the xenner kernel. Signed-off-by: Alexander Graf --- pc-bios/xenner/xenner32-pae.lds | 37 ++++ pc-bios/xenner/xenner32.S | 441 +++++++++++++++++++++++++++++++++++++++ pc-bios/xenner/xenner32.h | 191 +++++++++++++++++ pc-bios/xenner/xenner32.lds | 37 ++++ 4 files changed, 706 insertions(+), 0 deletions(-) create mode 100644 pc-bios/xenner/xenner32-pae.lds create mode 100644 pc-bios/xenner/xenner32.S create mode 100644 pc-bios/xenner/xenner32.h create mode 100644 pc-bios/xenner/xenner32.lds diff --git a/pc-bios/xenner/xenner32-pae.lds b/pc-bios/xenner/xenner32-pae.lds new file mode 100644 index 0000000..6d56ae4 --- /dev/null +++ b/pc-bios/xenner/xenner32-pae.lds @@ -0,0 +1,37 @@ +OUTPUT_FORMAT("elf32-i386") + +SECTIONS +{ + . = 0xff000000; + _vstart = .; + + /* code */ + .text : AT(ADDR(.text) - 0xff000000) { *(.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 = .; +} diff --git a/pc-bios/xenner/xenner32.S b/pc-bios/xenner/xenner32.S new file mode 100644 index 0000000..052a91b --- /dev/null +++ b/pc-bios/xenner/xenner32.S @@ -0,0 +1,441 @@ + +#define ENTRY(name) \ + .globl name; \ + .align 16; \ + name: + + .macro PUSH_ERROR + sub $4, %esp /* space for error code */ + .endm + + .macro PUSH_TRAP_EBP trapno + sub $4, %esp /* space for trap number */ + push %ebp + mov $\trapno, %ebp + mov %ebp, %ss:4(%esp) /* save trap number on stack */ + .endm + + .macro PUSH_REGS + mov %es,%ebp + push %ebp + mov %ds,%ebp + push %ebp + mov $0xe010,%ebp /* ring0 data flat */ + mov %ebp,%ds + mov %ebp,%es + + push %edi + push %esi + push %edx + push %ecx + push %ebx + push %eax + push %esp /* struct regs pointer */ + .endm + + .macro POP_REGS + pop %eax /* dummy (struct regs pointer) */ + pop %eax + pop %ebx + pop %ecx + pop %edx + pop %esi + pop %edi + pop %ebp + mov %ebp,%ds + pop %ebp + mov %ebp,%es + pop %ebp + .endm + + .macro RETURN + add $8, %esp /* remove error code & trap number */ + iret /* jump back */ + .endm + + .macro DO_TRAP trapno func + PUSH_TRAP_EBP \trapno + PUSH_REGS + call \func + POP_REGS + RETURN + .endm + +/* ------------------------------------------------------------------ */ + + .code32 + .text + +/* --- 16-bit boot entry point --- */ + +ENTRY(boot) + .code16 + + cli + + /* load the GDT */ + lgdt (gdt_desc - boot) + + /* turn on paging */ + mov $0x1, %eax + mov %eax, %cr0 + + /* enable boot page table */ + mov $(emu_boot_pgd - boot), %eax + mov %eax, %cr3 + + /* set PSE, maybe PAE */ +#ifdef CONFIG_PAE + mov $0x30, %eax +#else + mov $0x10, %eax +#endif + mov %eax, %cr4 + + /* turn on paging */ + mov $0x80000001, %eax + mov %eax, %cr0 + + ljmp $0x8, $(boot32 - boot) + + +.align 4, 0 +gdt: +.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* dummy */ +.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9b, 0xcf, 0x00 /* code32 */ +.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00 /* data32 */ + +gdt_desc: +.short (3 * 8) - 1 +.long (gdt - boot) + + +/* --- boot entry point --- */ + +boot32: + .code32 + + mov $0x10, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + + jmp *(boot32_ind - boot) + +boot32_ind: + .long boot32_real + +boot32_real: + + /* switch to the real page table */ + + mov $(emu_pgd - boot), %eax + mov %eax, %cr3 + + lea boot_stack_high, %esp /* setup stack */ + sub $64, %esp /* sizeof(struct regs_32) */ + push %esp /* struct regs pointer */ + cmp $0, %ebx + jne secondary + call do_boot + POP_REGS + RETURN + +secondary: + push %ebx + call do_boot_secondary + pop %ebx + 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_EBP 0 + jmp guest_forward + +ENTRY(nmi) + PUSH_ERROR + PUSH_TRAP_EBP 2 + jmp guest_forward + +ENTRY(overflow) + PUSH_ERROR + PUSH_TRAP_EBP 4 + jmp guest_forward + +ENTRY(bound_check) + PUSH_ERROR + PUSH_TRAP_EBP 5 + jmp guest_forward + +ENTRY(coprocessor) + PUSH_ERROR + PUSH_TRAP_EBP 9 + jmp guest_forward + +ENTRY(invalid_tss) + PUSH_TRAP_EBP 10 + jmp guest_forward + +ENTRY(segment_not_present) + PUSH_TRAP_EBP 11 + jmp guest_forward + +ENTRY(stack_fault) + PUSH_TRAP_EBP 12 + jmp guest_forward + +ENTRY(floating_point) + PUSH_ERROR + PUSH_TRAP_EBP 16 + jmp guest_forward + +ENTRY(alignment) + PUSH_TRAP_EBP 17 + jmp guest_forward + +ENTRY(machine_check) + PUSH_ERROR + PUSH_TRAP_EBP 18 + jmp guest_forward + +ENTRY(simd_floating_point) + PUSH_ERROR + PUSH_TRAP_EBP 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(xen_hypercall) + PUSH_ERROR + PUSH_TRAP_EBP -1 + PUSH_REGS + call do_hypercall + POP_REGS + add $8, %esp /* remove error code & trap number */ + cmp $-1, -4(%esp) + jne 1f + out %al, $0xe0 /* let userspace handle it */ +1: + iret + +ENTRY(irq_entries) +vector=0 +.rept 256 + .align 16 + PUSH_ERROR + PUSH_TRAP_EBP vector + jmp irq_common +vector=vector+1 +.endr + +ENTRY(irq_common) + PUSH_REGS + call do_irq + POP_REGS + RETURN + +/* --- helpers --- */ + +ENTRY(broken_memcpy_pf) + mov 4(%esp),%edi + mov 8(%esp),%esi + mov 12(%esp),%ecx + cld +1: rep movsb + xor %eax,%eax +8: ret + + .section .exfix, "ax" +9: mov $-1, %eax + jmp 8b + .previous + + .section .extab, "a" + .align 4 + .long 1b,9b + .previous + +ENTRY(broken_copy32_pf) + mov 4(%esp),%edi + mov 8(%esp),%esi +1: mov (%esi),%eax +2: mov %eax,(%edi) + xor %eax,%eax +8: ret + + .section .exfix, "ax" +9: mov $-1, %eax + jmp 8b + .previous + + .section .extab, "a" + .align 4 + .long 1b,9b + .long 2b,9b + .previous + +ENTRY(broken_copy64_pf) + mov 4(%esp),%edi + mov 8(%esp),%esi +1: mov (%esi), %ebx +2: mov 4(%esi), %ecx +3: mov (%edi), %eax +4: mov 4(%edi), %edx +5: cmpxchg8b (%edi) + xor %eax,%eax +8: ret + + .section .exfix, "ax" +9: mov $-1, %eax + jmp 8b + .previous + + .section .extab, "a" + .align 4 + .long 1b,9b + .long 2b,9b + .long 3b,9b + .long 4b,9b + .previous + +ENTRY(instructions) + .byte 0x0f, 0x11, 0x00, 0x0f, 0x11, 0x48, 0x10, 0x0f + nop + nop + nop + nop + nop + nop + nop + nop + +/* 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 + .code32 + +/* data section */ + + .data + .globl boot_stack_low, boot_stack_high + .globl cpu_ptr + .align 4096 +boot_stack_low: +cpu_ptr: + .long 0 + .align 4096 +boot_stack_high: + +/* boot page tables */ + +#define pageflags 0x063 /* preset, rw, accessed, dirty */ +#define largepage 0x080 /* pse */ + +#ifdef CONFIG_PAE + + .section .pt, "aw" + .globl emu_pgd_pae,emu_pmd_pae,emu_boot_pmd,emu_pgd,emu_pmd + + .align 4096 +emu_pgd_pae: +emu_pgd: + .fill 3,8,0 + .long emu_pmd_pae - 0xff000000 + 0x001 + .long 0 + .fill 508,8,0 + + .align 4096 +emu_pmd_pae: +emu_pmd: + .fill 504,8,0 + .quad pageflags + largepage + .fill 7,8,0 + + /* boot page tables */ + + .align 4096 +emu_boot_pgd: + .long emu_boot_pmd - 0xff000000 + 0x001 + .long 0 + .fill 2,8,0 + .long emu_boot_pmd - 0xff000000 + 0x001 + .long 0 + .fill 508,8,0 + + .align 4096 +emu_boot_pmd: + .quad pageflags + largepage + .fill 503,8,0 + .quad pageflags + largepage + .fill 7,8,0 + +#else + + .section .pt, "aw" + .globl emu_pgd_32,emu_boot_pgd,emu_pgd,emu_pmd + + .align 4096 +emu_pgd_32: +emu_pgd: +emu_pmd: + .fill 1020,4,0 + .long pageflags + largepage + .fill 3,4,0 + + /* boot page tables */ + + .align 4096 +emu_boot_pgd: + .long pageflags + largepage + .fill 1019,4,0 + .long pageflags + largepage + .fill 3,4,0 + +#endif diff --git a/pc-bios/xenner/xenner32.h b/pc-bios/xenner/xenner32.h new file mode 100644 index 0000000..5b4a6d4 --- /dev/null +++ b/pc-bios/xenner/xenner32.h @@ -0,0 +1,191 @@ +#include + +struct regs_32 { + /* pushed onto stack before calling into C code */ + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + uint32_t esi; + uint32_t edi; + uint32_t ds; + uint32_t es; + uint32_t ebp; + uint32_t trapno; + /* trap / fault / int created */ + uint32_t error; + uint32_t eip; + uint32_t cs; + uint32_t eflags; + uint32_t esp; + uint32_t ss; +}; + +/* 32bit defines */ +#define EMUNAME "xenner32" +#define regs regs_32 +#define fix_sel fix_sel32 +#define fix_desc fix_desc32 +#define ureg_t uint32_t +#define sreg_t int32_t +#define PRIxREG PRIx32 +#define rax eax +#define rbx ebx +#define rcx ecx +#define rdx edx +#define rsi esi +#define rdi edi +#define rbp ebp +#define rsp esp +#define rip eip +#define rflags eflags +#define tss(_v) ((0xe000 >> 3) + 8 + (((_v)->id) << 1)) +#define ldt(_v) ((0xe000 >> 3) + 9 + (((_v)->id) << 1)) + +/* xenner32.S */ +extern uint32_t emu_pgd_32[]; +extern uint64_t emu_pgd_pae[]; +extern uint64_t emu_pmd_pae[]; +extern pte_t emu_pmd[]; + +/* xenner-data.c */ +#define MAPS_MAX 256 +extern page_aligned uint32_t maps_32[]; +extern page_aligned uint64_t maps_pae[]; +extern uint32_t maps_refcnt[MAPS_MAX]; + +extern struct descriptor_32 page_aligned xen_idt[256]; + +/* xenner-mm.c */ +void *map_page(unsigned long maddr); +void *fixmap_page(struct xen_cpu *cpu, unsigned long maddr); +void free_page(void *ptr); +pte_t *find_pte_lpt(uint32_t va); +pte_t *find_pte_map(struct xen_cpu *cpu, uint32_t va); +void pgtable_walk(struct xen_cpu *cpu, uint32_t va); + +/* xenner-hcall.c */ +asmlinkage void do_hypercall(struct regs_32 *regs); + +/* macros */ +#define context_is_emu(_r) (((_r)->cs & 0x03) == 0x00) +#define context_is_kernel(_v,_r) (((_r)->cs & 0x03) == 0x01) +#define context_is_user(_v,_r) (((_r)->cs & 0x03) == 0x03) + +/* inline asm bits */ +static inline int wrmsr_safe(uint32_t msr, uint32_t ax, uint32_t dx) +{ + int ret; + asm volatile("91: wrmsr \n" + " xorl %0,%0 \n" + "92: nop \n" + ".section .exfix, \"ax\" \n" + "93: mov $-1,%0 \n" + " jmp 92b \n" + ".previous \n" + ".section .extab, \"a\" \n" + " .align 4 \n" + " .long 91b,93b \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 4 \n" + " .long 91b,99b \n" + ".previous \n" + : [ ret ] "=r" (ret), + [ esi ] "+S" (src), + [ edi ] "+D" (dest), + [ ecx ] "+c" (bytes) + : + : "memory" ); + return ret; +} + +static inline int copy32_pf(uint32_t *dest, const uint32_t *src) +{ + int ret; + + asm volatile("91: mov (%[src]),%%ecx \n" + "92: mov %%ecx,(%[dst]) \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 4 \n" + " .long 91b,99b \n" + " .long 92b,99b \n" + ".previous \n" + + : [ ret ] "=r" (ret) + : [ src ] "r" (src), + [ dst ] "r" (dest) + : "ecx", "memory" ); + return ret; +} + +static inline int copy64_pf(uint64_t *dest, const uint64_t *src) +{ + int ret; + + asm volatile("91: mov (%[src]), %%ebx \n" + "92: mov 4(%[src]), %%ecx \n" + "93: mov (%[dst]), %%eax \n" + "94: mov 4(%[dst]), %%edx \n" + "95: cmpxchg8b (%[dst]) \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 4 \n" + " .long 91b,99b \n" + " .long 92b,99b \n" + " .long 93b,99b \n" + " .long 94b,99b \n" + " .long 95b,99b \n" + ".previous \n" + : [ ret ] "=r" (ret) + : [ src ] "r" (src), + [ dst ] "r" (dest) + : "eax", "ebx", "ecx", "edx", "memory"); + return ret; +} + +/* PAE agnosticity */ + +static inline int copypt_pf(pte_t *dest, const pte_t *src) +{ +#ifdef CONFIG_PAE + return copy64_pf(dest, src); +#else + return copy32_pf(dest, src); +#endif +} + diff --git a/pc-bios/xenner/xenner32.lds b/pc-bios/xenner/xenner32.lds new file mode 100644 index 0000000..6d56ae4 --- /dev/null +++ b/pc-bios/xenner/xenner32.lds @@ -0,0 +1,37 @@ +OUTPUT_FORMAT("elf32-i386") + +SECTIONS +{ + . = 0xff000000; + _vstart = .; + + /* code */ + .text : AT(ADDR(.text) - 0xff000000) { *(.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 = .; +}