[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 07/40] xenner: kernel: 32 bit files
From: |
Alexander Graf |
Subject: |
[Qemu-devel] [PATCH 07/40] xenner: kernel: 32 bit files |
Date: |
Mon, 1 Nov 2010 16:01:20 +0100 |
This patch adds various files required to implement 32bit support in the
xenner kernel.
Signed-off-by: Alexander Graf <address@hidden>
---
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 <xen/foreign/x86_32.h>
+
+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 = .;
+}
--
1.6.0.2
- [Qemu-devel] Re: [PATCH 02/40] elf: Add notes implementation, (continued)
[Qemu-devel] [PATCH 05/40] xen-disk: disable aio, Alexander Graf, 2010/11/01
[Qemu-devel] [PATCH 31/40] xenner: libxc emu: xenstore, Alexander Graf, 2010/11/01
[Qemu-devel] [PATCH 04/40] elf: add section analyzer, Alexander Graf, 2010/11/01
[Qemu-devel] [PATCH 10/40] xenner: kernel: Hypercall handler (i386), Alexander Graf, 2010/11/01
[Qemu-devel] [PATCH 11/40] xenner: kernel: Hypercall handler (x86_64), Alexander Graf, 2010/11/01
[Qemu-devel] [PATCH 07/40] xenner: kernel: 32 bit files,
Alexander Graf <=
[Qemu-devel] [PATCH 26/40] xenner: kernel: xen-names, Alexander Graf, 2010/11/01
[Qemu-devel] [PATCH 16/40] xenner: kernel: Main (i386), Alexander Graf, 2010/11/01
[Qemu-devel] [PATCH 28/40] xenner: libxc emu: evtchn, Alexander Graf, 2010/11/01
- Re: [Qemu-devel] [PATCH 28/40] xenner: libxc emu: evtchn, Anthony Liguori, 2010/11/01
- Re: [Qemu-devel] [PATCH 28/40] xenner: libxc emu: evtchn, Alexander Graf, 2010/11/01
- Re: [Qemu-devel] [PATCH 28/40] xenner: libxc emu: evtchn, Anthony Liguori, 2010/11/01
- Re: [Qemu-devel] [PATCH 28/40] xenner: libxc emu: evtchn, Alexander Graf, 2010/11/01
- Re: [Qemu-devel] [PATCH 28/40] xenner: libxc emu: evtchn, Anthony Liguori, 2010/11/01
- Re: [Qemu-devel] [PATCH 28/40] xenner: libxc emu: evtchn, Alexander Graf, 2010/11/01
[Qemu-devel] Re: [PATCH 28/40] xenner: libxc emu: evtchn, Paolo Bonzini, 2010/11/01