/trunk/kernel/kernel.config |
---|
3,12 → 3,12 |
# Architecture |
@ "amd64" AMD64/Intel EM64T |
@ "ia32" Intel IA-32 |
@ "ia32xen" Intel IA-32 on Xen hypervisor |
@ "ia64" Intel IA-64 |
@ "mips32" MIPS 32-bit |
@ "ppc32" PowerPC 32-bit |
@ "ppc64" PowerPC 64-bit |
@ "sparc64" Sun UltraSPARC 64-bit |
@ "xen32" Xen 32-bit |
! ARCH (choice) |
# Compiler |
22,7 → 22,7 |
@ "athlon-xp" Athlon XP |
@ "athlon-mp" Athlon MP |
@ "prescott" Prescott |
! [ARCH=ia32|ARCH=xen32] MACHINE (choice) |
! [ARCH=ia32|ARCH=ia32xen] MACHINE (choice) |
# CPU type |
@ "opteron" Opteron |
71,16 → 71,16 |
! [(ARCH=ia32|ARCH=amd64)&CONFIG_FB=y] CONFIG_VESA_BPP (choice) |
# Support for SMP |
! [ARCH=ia32|ARCH=amd64|ARCH=xen32|ARCH=sparc64] CONFIG_SMP (y/n) |
! [ARCH=ia32|ARCH=amd64|ARCH=ia32xen|ARCH=sparc64] CONFIG_SMP (y/n) |
# Improved support for hyperthreading |
! [(ARCH=ia32|ARCH=amd64|ARCH=xen32)&CONFIG_SMP=y] CONFIG_HT (y/n) |
! [(ARCH=ia32|ARCH=amd64|ARCH=ia32xen)&CONFIG_SMP=y] CONFIG_HT (y/n) |
# Simics BIOS AP boot fix |
! [(ARCH=ia32|ARCH=amd64)&CONFIG_SMP=y] CONFIG_SIMICS_FIX (y/n) |
# Lazy FPU context switching |
! [(ARCH=mips32&MACHINE!=msim&MACHINE!=simics)|ARCH=amd64|ARCH=ia32|ARCH=ia64|ARCH=sparc64|ARCH=xen32] CONFIG_FPU_LAZY (y/n) |
! [(ARCH=mips32&MACHINE!=msim&MACHINE!=simics)|ARCH=amd64|ARCH=ia32|ARCH=ia64|ARCH=sparc64|ARCH=ia32xen] CONFIG_FPU_LAZY (y/n) |
# Power off on halt |
! [ARCH=ppc32] CONFIG_POWEROFF (n/y) |
94,10 → 94,10 |
! [CONFIG_DEBUG=y&CONFIG_SMP=y] CONFIG_DEBUG_SPINLOCK (y/n) |
# Watchpoint on rewriting AS with zero |
! [CONFIG_DEBUG=y&(ARCH=amd64|ARCH=ia32|ARCH=xen32)] CONFIG_DEBUG_AS_WATCHPOINT (y/n) |
! [CONFIG_DEBUG=y&(ARCH=amd64|ARCH=ia32|ARCH=ia32xen)] CONFIG_DEBUG_AS_WATCHPOINT (y/n) |
# Save all interrupt registers |
! [CONFIG_DEBUG=y&(ARCH=amd64|ARCH=mips32|ARCH=ia32|ARCH=xen32)] CONFIG_DEBUG_ALLREGS (y/n) |
! [CONFIG_DEBUG=y&(ARCH=amd64|ARCH=mips32|ARCH=ia32|ARCH=ia32xen)] CONFIG_DEBUG_ALLREGS (y/n) |
# Use VHPT |
! [ARCH=ia64] CONFIG_VHPT (n/y) |
124,8 → 124,8 |
@ "synch/rwlock5" Read write test 5 |
@ "synch/semaphore1" Semaphore test 1 |
@ "synch/semaphore2" Sempahore test 2 |
@ [ARCH=ia32|ARCH=amd64|ARCH=ia64|ARCH=xen32] "fpu/fpu1" Intel FPU test 1 |
@ [ARCH=ia32|ARCH=amd64|ARCH=xen32] "fpu/sse1" Intel SSE test 1 |
@ [ARCH=ia32|ARCH=amd64|ARCH=ia64|ARCH=ia32xen] "fpu/fpu1" Intel FPU test 1 |
@ [ARCH=ia32|ARCH=amd64|ARCH=ia32xen] "fpu/sse1" Intel SSE test 1 |
@ [ARCH=mips32&MACHINE!=msim&MACHINE!=simics] "fpu/mips1" MIPS FPU test 1 |
@ "print/print1" Printf test 1 |
@ "thread/thread1" Thread test 1 |
/trunk/kernel/arch/xen32/_link.ld.in |
---|
File deleted |
/trunk/kernel/arch/xen32/include/fpu_context.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/byteorder.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/types.h |
---|
File deleted |
/trunk/kernel/arch/xen32/include/cpuid.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/elf.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/bios |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/memstr.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/smp |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/arg.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/ddi |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/pm.h |
---|
File deleted |
/trunk/kernel/arch/xen32/include/atomic.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/arch.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/proc |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/boot/boot.h |
---|
File deleted |
/trunk/kernel/arch/xen32/include/faddr.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/asm.h |
---|
File deleted |
/trunk/kernel/arch/xen32/include/hypercall.h |
---|
File deleted |
/trunk/kernel/arch/xen32/include/mm/memory_init.h |
---|
File deleted |
/trunk/kernel/arch/xen32/include/mm/page.h |
---|
File deleted |
/trunk/kernel/arch/xen32/include/mm/asid.h |
---|
File deleted |
/trunk/kernel/arch/xen32/include/mm/tlb.h |
---|
File deleted |
/trunk/kernel/arch/xen32/include/mm/as.h |
---|
File deleted |
/trunk/kernel/arch/xen32/include/mm/frame.h |
---|
File deleted |
/trunk/kernel/arch/xen32/include/debugger.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/context.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/barrier.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/debug.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/cpu.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/include/drivers/xconsole.h |
---|
File deleted |
/trunk/kernel/arch/xen32/include/interrupt.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/Makefile.inc |
---|
File deleted |
/trunk/kernel/arch/xen32/src/delay.s |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/src/smp/apic.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/smp/mps.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/smp/smp.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/smp/ipi.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/ddi |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/src/boot/boot.S |
---|
File deleted |
/trunk/kernel/arch/xen32/src/proc/thread.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/proc/scheduler.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/proc/task.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/debugger.c |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/src/mm/frame.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/mm/memory_init.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/mm/page.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/mm/tlb.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/mm/as.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/userspace.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/atomic.S |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/src/interrupt.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/drivers/xconsole.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/fpu_context.c |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/src/xen32.c |
---|
File deleted |
/trunk/kernel/arch/xen32/src/asm.S |
---|
File deleted |
/trunk/kernel/arch/xen32/src/context.s |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/src/debug |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/src/cpu |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/src/bios |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/trunk/kernel/arch/xen32/src/pm.c |
---|
File deleted |
/trunk/kernel/arch/ia32xen/include/types.h |
---|
0,0 → 1,63 |
/* |
* Copyright (C) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_TYPES_H_ |
#define KERN_ia32xen_TYPES_H_ |
#define NULL 0 |
typedef signed char int8_t; |
typedef signed short int16_t; |
typedef signed long int32_t; |
typedef signed long long int64_t; |
typedef unsigned char uint8_t; |
typedef unsigned short uint16_t; |
typedef unsigned long uint32_t; |
typedef unsigned long long uint64_t; |
typedef uint32_t uintptr_t; |
typedef uint32_t pfn_t; |
typedef uint8_t ipl_t; |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef struct page_specifier pte_t; |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/include/pm.h |
---|
0,0 → 1,160 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_PM_H_ |
#define KERN_ia32xen_PM_H_ |
#define IDT_ITEMS 64 |
#define GDT_ITEMS 7 |
#define NULL_DES 0 |
#define KTEXT_DES 1 |
#define KDATA_DES 2 |
#define UTEXT_DES 3 |
#define UDATA_DES 4 |
#define TSS_DES 5 |
#define TLS_DES 6 /* Pointer to Thread-Local-Storage data */ |
#define selector(des) ((des) << 3) |
#define PL_KERNEL 1 |
#define PL_USER 3 |
#define AR_PRESENT (1<<7) |
#define AR_DATA (2<<3) |
#define AR_CODE (3<<3) |
#define AR_WRITABLE (1<<1) |
#define AR_INTERRUPT (0xe) |
#define AR_TSS (0x9) |
#define DPL_KERNEL (PL_KERNEL<<5) |
#define DPL_USER (PL_USER<<5) |
#define TSS_BASIC_SIZE 104 |
#define TSS_IOMAP_SIZE (16*1024+1) /* 16K for bitmap + 1 terminating byte for convenience */ |
#define IO_PORTS (64*1024) |
#ifndef __ASM__ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <arch/context.h> |
struct ptr_16_32 { |
uint16_t limit; |
uint32_t base; |
} __attribute__ ((packed)); |
typedef struct ptr_16_32 ptr_16_32_t; |
struct descriptor { |
unsigned limit_0_15: 16; |
unsigned base_0_15: 16; |
unsigned base_16_23: 8; |
unsigned access: 8; |
unsigned limit_16_19: 4; |
unsigned available: 1; |
unsigned unused: 1; |
unsigned special: 1; |
unsigned granularity : 1; |
unsigned base_24_31: 8; |
} __attribute__ ((packed)); |
typedef struct descriptor descriptor_t; |
struct tss { |
uint16_t link; |
unsigned : 16; |
uint32_t esp0; |
uint16_t ss0; |
unsigned : 16; |
uint32_t esp1; |
uint16_t ss1; |
unsigned : 16; |
uint32_t esp2; |
uint16_t ss2; |
unsigned : 16; |
uint32_t cr3; |
uint32_t eip; |
uint32_t eflags; |
uint32_t eax; |
uint32_t ecx; |
uint32_t edx; |
uint32_t ebx; |
uint32_t esp; |
uint32_t ebp; |
uint32_t esi; |
uint32_t edi; |
uint16_t es; |
unsigned : 16; |
uint16_t cs; |
unsigned : 16; |
uint16_t ss; |
unsigned : 16; |
uint16_t ds; |
unsigned : 16; |
uint16_t fs; |
unsigned : 16; |
uint16_t gs; |
unsigned : 16; |
uint16_t ldtr; |
unsigned : 16; |
unsigned : 16; |
uint16_t iomap_base; |
uint8_t iomap[TSS_IOMAP_SIZE]; |
} __attribute__ ((packed)); |
typedef struct tss tss_t; |
extern ptr_16_32_t gdtr; |
extern ptr_16_32_t bootstrap_gdtr; |
extern ptr_16_32_t protected_ap_gdtr; |
extern struct tss *tss_p; |
extern descriptor_t gdt[]; |
extern void pm_init(void); |
extern void gdt_setbase(descriptor_t *d, uintptr_t base); |
extern void gdt_setlimit(descriptor_t *d, uint32_t limit); |
extern void traps_init(void); |
extern void tss_initialize(tss_t *t); |
extern void set_tls_desc(uintptr_t tls); |
#endif /* __ASM__ */ |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/include/boot/boot.h |
---|
0,0 → 1,132 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_BOOT_H_ |
#define KERN_ia32xen_BOOT_H_ |
#define GUEST_CMDLINE 1024 |
#define VIRT_CPUS 32 |
#define START_INFO_SIZE 1104 |
#define BOOT_OFFSET 0x0000 |
#define TEMP_STACK_SIZE 0x1000 |
#define XEN_VIRT_START 0xFC000000 |
#define XEN_CS 0xe019 |
#ifndef __ASM__ |
#define mp_map ((pfn_t *) XEN_VIRT_START) |
#define SIF_PRIVILEGED (1 << 0) /**< Privileged domain */ |
#define SIF_INITDOMAIN (1 << 1) /**< Iinitial control domain */ |
#include <arch/types.h> |
typedef uint32_t evtchn_t; |
typedef struct { |
uint32_t version; |
uint32_t pad0; |
uint64_t tsc_timestamp; /**< TSC at last update of time vals */ |
uint64_t system_time; /**< Time, in nanosecs, since boot */ |
uint32_t tsc_to_system_mul; |
int8_t tsc_shift; |
int8_t pad1[3]; |
} vcpu_time_info_t; |
typedef struct { |
uint32_t cr2; |
uint32_t pad[5]; |
} arch_vcpu_info_t; |
typedef struct arch_shared_info { |
pfn_t max_pfn; /**< max pfn that appears in table */ |
uint32_t pfn_to_mfn_frame_list_list; |
uint32_t nmi_reason; |
} arch_shared_info_t; |
typedef struct { |
uint8_t evtchn_upcall_pending; |
ipl_t evtchn_upcall_mask; |
evtchn_t evtchn_pending_sel; |
arch_vcpu_info_t arch; |
vcpu_time_info_t time; |
} vcpu_info_t; |
typedef struct { |
vcpu_info_t vcpu_info[VIRT_CPUS]; |
evtchn_t evtchn_pending[32]; |
evtchn_t evtchn_mask[32]; |
uint32_t wc_version; /**< Version counter */ |
uint32_t wc_sec; /**< Secs 00:00:00 UTC, Jan 1, 1970 */ |
uint32_t wc_nsec; /**< Nsecs 00:00:00 UTC, Jan 1, 1970 */ |
arch_shared_info_t arch; |
} shared_info_t; |
typedef struct { |
int8_t magic[32]; /**< "xen-<version>-<platform>" */ |
uint32_t frames; /**< Available frames */ |
shared_info_t *shared_info; /**< Shared info structure (machine address) */ |
uint32_t flags; /**< SIF_xxx flags */ |
pfn_t store_mfn; /**< Shared page (machine page) */ |
evtchn_t store_evtchn; /**< Event channel for store communication */ |
pfn_t console_mfn; /**< Console page (machine page) */ |
evtchn_t console_evtchn; /**< Event channel for console messages */ |
pte_t *ptl0; /**< Boot PTL0 (kernel address) */ |
uint32_t pt_frames; /**< Number of bootstrap page table frames */ |
pfn_t *pm_map; /**< Physical->machine frame map (kernel address) */ |
void *mod_start; /**< Modules start (kernel address) */ |
uint32_t mod_len; /**< Modules size (bytes) */ |
int8_t cmd_line[GUEST_CMDLINE]; |
} start_info_t; |
typedef struct { |
pfn_t start; |
pfn_t size; |
pfn_t reserved; |
} memzone_t; |
extern start_info_t start_info; |
extern shared_info_t shared_info; |
extern memzone_t meminfo; |
#endif |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/include/asm.h |
---|
0,0 → 1,281 |
/* |
* Copyright (C) 2001-2004 Jakub Jermar |
* Copyright (C) 2005 Sergey Bondari |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_ASM_H_ |
#define KERN_ia32xen_ASM_H_ |
#include <arch/pm.h> |
#include <arch/types.h> |
#include <arch/barrier.h> |
#include <config.h> |
extern void enable_l_apic_in_msr(void); |
extern void asm_delay_loop(uint32_t t); |
extern void asm_fake_loop(uint32_t t); |
/** Halt CPU |
* |
* Halt the current CPU until interrupt event. |
*/ |
#define cpu_halt() ((void) 0) |
#define cpu_sleep() ((void) 0) |
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \ |
{ \ |
unative_t res; \ |
__asm__ volatile ("movl %%" #reg ", %0" : "=r" (res) ); \ |
return res; \ |
} |
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \ |
{ \ |
__asm__ volatile ("movl %0, %%" #reg : : "r" (regn)); \ |
} |
GEN_READ_REG(cr0); |
GEN_READ_REG(cr2); |
GEN_READ_REG(dr0); |
GEN_READ_REG(dr1); |
GEN_READ_REG(dr2); |
GEN_READ_REG(dr3); |
GEN_READ_REG(dr6); |
GEN_READ_REG(dr7); |
GEN_WRITE_REG(dr0); |
GEN_WRITE_REG(dr1); |
GEN_WRITE_REG(dr2); |
GEN_WRITE_REG(dr3); |
GEN_WRITE_REG(dr6); |
GEN_WRITE_REG(dr7); |
/** Byte to port |
* |
* Output byte to port |
* |
* @param port Port to write to |
* @param val Value to write |
*/ |
static inline void outb(uint16_t port, uint8_t val) { __asm__ volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) ); } |
/** Word to port |
* |
* Output word to port |
* |
* @param port Port to write to |
* @param val Value to write |
*/ |
static inline void outw(uint16_t port, uint16_t val) { __asm__ volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port) ); } |
/** Double word to port |
* |
* Output double word to port |
* |
* @param port Port to write to |
* @param val Value to write |
*/ |
static inline void outl(uint16_t port, uint32_t val) { __asm__ volatile ("outl %l0, %w1\n" : : "a" (val), "d" (port) ); } |
/** Byte from port |
* |
* Get byte from port |
* |
* @param port Port to read from |
* @return Value read |
*/ |
static inline uint8_t inb(uint16_t port) { uint8_t val; __asm__ volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) ); return val; } |
/** Word from port |
* |
* Get word from port |
* |
* @param port Port to read from |
* @return Value read |
*/ |
static inline uint16_t inw(uint16_t port) { uint16_t val; __asm__ volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port) ); return val; } |
/** Double word from port |
* |
* Get double word from port |
* |
* @param port Port to read from |
* @return Value read |
*/ |
static inline uint32_t inl(uint16_t port) { uint32_t val; __asm__ volatile ("inl %w1, %l0 \n" : "=a" (val) : "d" (port) ); return val; } |
/** Enable interrupts. |
* |
* Enable interrupts and return previous |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
*/ |
static inline ipl_t interrupts_enable(void) |
{ |
// FIXME SMP |
ipl_t v = shared_info.vcpu_info[0].evtchn_upcall_mask; |
write_barrier(); |
shared_info.vcpu_info[0].evtchn_upcall_mask = 0; |
write_barrier(); |
if (shared_info.vcpu_info[0].evtchn_upcall_pending) |
force_evtchn_callback(); |
return v; |
} |
/** Disable interrupts. |
* |
* Disable interrupts and return previous |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
*/ |
static inline ipl_t interrupts_disable(void) |
{ |
// FIXME SMP |
ipl_t v = shared_info.vcpu_info[0].evtchn_upcall_mask; |
shared_info.vcpu_info[0].evtchn_upcall_mask = 1; |
write_barrier(); |
return v; |
} |
/** Restore interrupt priority level. |
* |
* Restore EFLAGS. |
* |
* @param ipl Saved interrupt priority level. |
*/ |
static inline void interrupts_restore(ipl_t ipl) |
{ |
if (ipl == 0) |
interrupts_enable(); |
else |
interrupts_disable(); |
} |
/** Return interrupt priority level. |
* |
* @return EFLAFS. |
*/ |
static inline ipl_t interrupts_read(void) |
{ |
// FIXME SMP |
return shared_info.vcpu_info[0].evtchn_upcall_mask; |
} |
/** Return base address of current stack |
* |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
uintptr_t v; |
__asm__ volatile ("andl %%esp, %0\n" : "=r" (v) : "0" (~(STACK_SIZE-1))); |
return v; |
} |
static inline uint64_t rdtsc(void) |
{ |
uint64_t v; |
__asm__ volatile("rdtsc\n" : "=A" (v)); |
return v; |
} |
/** Return current IP address */ |
static inline uintptr_t * get_ip() |
{ |
uintptr_t *ip; |
__asm__ volatile ( |
"mov %%eip, %0" |
: "=r" (ip) |
); |
return ip; |
} |
/** Invalidate TLB Entry. |
* |
* @param addr Address on a page whose TLB entry is to be invalidated. |
*/ |
static inline void invlpg(uintptr_t addr) |
{ |
__asm__ volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr)); |
} |
/** Load GDTR register from memory. |
* |
* @param gdtr_reg Address of memory from where to load GDTR. |
*/ |
static inline void gdtr_load(ptr_16_32_t *gdtr_reg) |
{ |
__asm__ volatile ("lgdtl %0\n" : : "m" (*gdtr_reg)); |
} |
/** Store GDTR register to memory. |
* |
* @param gdtr_reg Address of memory to where to load GDTR. |
*/ |
static inline void gdtr_store(ptr_16_32_t *gdtr_reg) |
{ |
__asm__ volatile ("sgdtl %0\n" : : "m" (*gdtr_reg)); |
} |
/** Load TR from descriptor table. |
* |
* @param sel Selector specifying descriptor of TSS segment. |
*/ |
static inline void tr_load(uint16_t sel) |
{ |
__asm__ volatile ("ltr %0" : : "r" (sel)); |
} |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/include/hypercall.h |
---|
0,0 → 1,252 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef KERN_ia32xen_HYPERCALL_H_ |
#define KERN_ia32xen_HYPERCALL_H_ |
#include <arch/types.h> |
#include <macros.h> |
typedef uint16_t domid_t; |
typedef struct { |
uint8_t vector; /**< Exception vector */ |
uint8_t flags; /**< 0-3: privilege level; 4: clear event enable */ |
uint16_t cs; /**< Code selector */ |
void *address; /**< Code offset */ |
} trap_info_t; |
typedef struct { |
evtchn_t port; |
} evtchn_send_t; |
typedef struct { |
uint32_t cmd; |
union { |
evtchn_send_t send; |
}; |
} evtchn_op_t; |
#define XEN_SET_TRAP_TABLE 0 |
#define XEN_MMU_UPDATE 1 |
#define XEN_SET_CALLBACKS 4 |
#define XEN_UPDATE_VA_MAPPING 14 |
#define XEN_EVENT_CHANNEL_OP 16 |
#define XEN_VERSION 17 |
#define XEN_CONSOLE_IO 18 |
#define XEN_VM_ASSIST 21 |
#define XEN_MMUEXT_OP 26 |
/* |
* Commands for XEN_CONSOLE_IO |
*/ |
#define CONSOLE_IO_WRITE 0 |
#define CONSOLE_IO_READ 1 |
#define MMUEXT_PIN_L1_TABLE 0 |
#define MMUEXT_PIN_L2_TABLE 1 |
#define MMUEXT_PIN_L3_TABLE 2 |
#define MMUEXT_PIN_L4_TABLE 3 |
#define MMUEXT_UNPIN_TABLE 4 |
#define MMUEXT_NEW_BASEPTR 5 |
#define MMUEXT_TLB_FLUSH_LOCAL 6 |
#define MMUEXT_INVLPG_LOCAL 7 |
#define MMUEXT_TLB_FLUSH_MULTI 8 |
#define MMUEXT_INVLPG_MULTI 9 |
#define MMUEXT_TLB_FLUSH_ALL 10 |
#define MMUEXT_INVLPG_ALL 11 |
#define MMUEXT_FLUSH_CACHE 12 |
#define MMUEXT_SET_LDT 13 |
#define MMUEXT_NEW_USER_BASEPTR 15 |
#define EVTCHNOP_SEND 4 |
#define UVMF_NONE 0 /**< No flushing at all */ |
#define UVMF_TLB_FLUSH 1 /**< Flush entire TLB(s) */ |
#define UVMF_INVLPG 2 /**< Flush only one entry */ |
#define UVMF_FLUSHTYPE_MASK 3 |
#define UVMF_MULTI 0 /**< Flush subset of TLBs */ |
#define UVMF_LOCAL 0 /**< Flush local TLB */ |
#define UVMF_ALL (1 << 2) /**< Flush all TLBs */ |
/* |
* Commands to XEN_VM_ASSIST |
*/ |
#define VMASST_CMD_ENABLE 0 |
#define VMASST_CMD_DISABLE 1 |
#define VMASST_TYPE_4GB_SEGMENTS 0 |
#define VMASST_TYPE_4GB_SEGMENTS_NOTIFY 1 |
#define VMASST_TYPE_WRITABLE_PAGETABLES 2 |
#define DOMID_SELF (0x7FF0U) |
#define DOMID_IO (0x7FF1U) |
#define force_evtchn_callback() ((void) xen_version(0, 0)) |
#define hypercall0(id) \ |
({ \ |
unative_t ret; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret) \ |
: \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall1(id, p1) \ |
({ \ |
unative_t ret, __ign1; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1) \ |
: "1" (p1) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall2(id, p1, p2) \ |
({ \ |
unative_t ret, __ign1, __ign2; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1), \ |
"=c" (__ign2) \ |
: "1" (p1), \ |
"2" (p2) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall3(id, p1, p2, p3) \ |
({ \ |
unative_t ret, __ign1, __ign2, __ign3; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1), \ |
"=c" (__ign2), \ |
"=d" (__ign3) \ |
: "1" (p1), \ |
"2" (p2), \ |
"3" (p3) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall4(id, p1, p2, p3, p4) \ |
({ \ |
unative_t ret, __ign1, __ign2, __ign3, __ign4; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1), \ |
"=c" (__ign2), \ |
"=d" (__ign3), \ |
"=S" (__ign4) \ |
: "1" (p1), \ |
"2" (p2), \ |
"3" (p3), \ |
"4" (p4) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall5(id, p1, p2, p3, p4, p5) \ |
({ \ |
unative_t ret, __ign1, __ign2, __ign3, __ign4, __ign5; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1), \ |
"=c" (__ign2), \ |
"=d" (__ign3), \ |
"=S" (__ign4), \ |
"=D" (__ign5) \ |
: "1" (p1), \ |
"2" (p2), \ |
"3" (p3), \ |
"4" (p4), \ |
"5" (p5) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
static inline int xen_console_io(const unsigned int cmd, const unsigned int count, const char *str) |
{ |
return hypercall3(XEN_CONSOLE_IO, cmd, count, str); |
} |
static inline int xen_vm_assist(const unsigned int cmd, const unsigned int type) |
{ |
return hypercall2(XEN_VM_ASSIST, cmd, type); |
} |
static inline int xen_set_callbacks(const unsigned int event_selector, const void *event_address, const unsigned int failsafe_selector, void *failsafe_address) |
{ |
return hypercall4(XEN_SET_CALLBACKS, event_selector, event_address, failsafe_selector, failsafe_address); |
} |
static inline int xen_set_trap_table(const trap_info_t *table) |
{ |
return hypercall1(XEN_SET_TRAP_TABLE, table); |
} |
static inline int xen_version(const unsigned int cmd, const void *arg) |
{ |
return hypercall2(XEN_VERSION, cmd, arg); |
} |
static inline int xen_notify_remote(evtchn_t channel) |
{ |
evtchn_op_t op; |
op.cmd = EVTCHNOP_SEND; |
op.send.port = channel; |
return hypercall1(XEN_EVENT_CHANNEL_OP, &op); |
} |
#endif |
/trunk/kernel/arch/ia32xen/include/mm/frame.h |
---|
0,0 → 1,59 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_FRAME_H_ |
#define KERN_ia32xen_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
#include <arch/types.h> |
#include <arch/boot/boot.h> |
#define PA2MA(x) ((start_info.pm_map[((uintptr_t) (x)) >> 12] << 12) + (((uintptr_t) (x)) & 0xfff)) |
#define MA2PA(x) ((mp_map[((uintptr_t) (x)) >> 12] << 12) + (((uintptr_t) (x)) & 0xfff)) |
extern void frame_arch_init(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/include/mm/memory_init.h |
---|
0,0 → 1,48 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
* @ingroup ia32xen_mm |
*/ |
#ifndef KERN_ia32xen_MEMORY_INIT_H_ |
#define KERN_ia32xen_MEMORY_INIT_H_ |
#include <typedefs.h> |
size_t get_memory_size(void); |
void memory_print_map(void); |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/include/mm/page.h |
---|
0,0 → 1,221 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_PAGE_H_ |
#define KERN_ia32xen_PAGE_H_ |
#include <arch/mm/frame.h> |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#ifdef KERNEL |
#ifndef __ASM__ |
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
#else |
# define KA2PA(x) ((x) - 0x80000000) |
# define PA2KA(x) ((x) + 0x80000000) |
#endif |
/* |
* Implementation of generic 4-level page table interface. |
* IA-32 has 2-level page tables, so PTL1 and PTL2 are left out. |
*/ |
#define PTL0_ENTRIES_ARCH 1024 |
#define PTL1_ENTRIES_ARCH 0 |
#define PTL2_ENTRIES_ARCH 0 |
#define PTL3_ENTRIES_ARCH 1024 |
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff) |
#define PTL1_INDEX_ARCH(vaddr) 0 |
#define PTL2_INDEX_ARCH(vaddr) 0 |
#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff) |
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) ((pte_t *) MA2PA((((pte_t *) (ptl0))[(i)].frame_address) << 12)) |
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) (ptl1) |
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) (ptl2) |
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) ((uintptr_t) MA2PA((((pte_t *) (ptl3))[(i)].frame_address) << 12)) |
#define SET_PTL0_ADDRESS_ARCH(ptl0) { \ |
mmuext_op_t mmu_ext; \ |
\ |
mmu_ext.cmd = MMUEXT_NEW_BASEPTR; \ |
mmu_ext.mfn = ADDR2PFN(PA2MA(ptl0)); \ |
xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF); \ |
} |
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) { \ |
mmu_update_t update; \ |
\ |
update.ptr = PA2MA(KA2PA(&((pte_t *) (ptl0))[(i)])); \ |
update.val = PA2MA(a) | 0x0003; \ |
xen_mmu_update(&update, 1, NULL, DOMID_SELF); \ |
} |
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) |
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) |
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) (((pte_t *) (ptl3))[(i)].frame_address = PA2MA(a) >> 12) |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_flags((pte_t *) (ptl0), (index_t)(i)) |
#define GET_PTL2_FLAGS_ARCH(ptl1, i) PAGE_PRESENT |
#define GET_PTL3_FLAGS_ARCH(ptl2, i) PAGE_PRESENT |
#define GET_FRAME_FLAGS_ARCH(ptl3, i) get_pt_flags((pte_t *) (ptl3), (index_t)(i)) |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) set_pt_flags((pte_t *) (ptl0), (index_t)(i), (x)) |
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) |
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *) (ptl3), (index_t)(i), (x)) |
#define PTE_VALID_ARCH(p) (*((uint32_t *) (p)) != 0) |
#define PTE_PRESENT_ARCH(p) ((p)->present != 0) |
#define PTE_GET_FRAME_ARCH(p) ((p)->frame_address << FRAME_WIDTH) |
#define PTE_WRITABLE_ARCH(p) ((p)->writeable != 0) |
#define PTE_EXECUTABLE_ARCH(p) 1 |
#ifndef __ASM__ |
#include <mm/page.h> |
#include <arch/types.h> |
#include <arch/mm/frame.h> |
#include <typedefs.h> |
#include <arch/hypercall.h> |
/* Page fault error codes. */ |
/** When bit on this position is 0, the page fault was caused by a not-present page. */ |
#define PFERR_CODE_P (1 << 0) |
/** When bit on this position is 1, the page fault was caused by a write. */ |
#define PFERR_CODE_RW (1 << 1) |
/** When bit on this position is 1, the page fault was caused in user mode. */ |
#define PFERR_CODE_US (1 << 2) |
/** When bit on this position is 1, a reserved bit was set in page directory. */ |
#define PFERR_CODE_RSVD (1 << 3) |
/** Page Table Entry. */ |
struct page_specifier { |
unsigned present : 1; |
unsigned writeable : 1; |
unsigned uaccessible : 1; |
unsigned page_write_through : 1; |
unsigned page_cache_disable : 1; |
unsigned accessed : 1; |
unsigned dirty : 1; |
unsigned pat : 1; |
unsigned global : 1; |
unsigned soft_valid : 1; /**< Valid content even if the present bit is not set. */ |
unsigned avl : 2; |
unsigned frame_address : 20; |
} __attribute__ ((packed)); |
typedef struct { |
uint64_t ptr; /**< Machine address of PTE */ |
union { /**< New contents of PTE */ |
uint64_t val; |
pte_t pte; |
}; |
} mmu_update_t; |
typedef struct { |
unsigned int cmd; |
union { |
unsigned long mfn; |
unsigned long linear_addr; |
}; |
union { |
unsigned int nr_ents; |
void *vcpumask; |
}; |
} mmuext_op_t; |
static inline int xen_update_va_mapping(const void *va, const pte_t pte, const unsigned int flags) |
{ |
return hypercall4(XEN_UPDATE_VA_MAPPING, va, pte, 0, flags); |
} |
static inline int xen_mmu_update(const mmu_update_t *req, const unsigned int count, unsigned int *success_count, domid_t domid) |
{ |
return hypercall4(XEN_MMU_UPDATE, req, count, success_count, domid); |
} |
static inline int xen_mmuext_op(const mmuext_op_t *op, const unsigned int count, unsigned int *success_count, domid_t domid) |
{ |
return hypercall4(XEN_MMUEXT_OP, op, count, success_count, domid); |
} |
static inline int get_pt_flags(pte_t *pt, index_t i) |
{ |
pte_t *p = &pt[i]; |
return ( |
(!p->page_cache_disable)<<PAGE_CACHEABLE_SHIFT | |
(!p->present)<<PAGE_PRESENT_SHIFT | |
p->uaccessible<<PAGE_USER_SHIFT | |
1<<PAGE_READ_SHIFT | |
p->writeable<<PAGE_WRITE_SHIFT | |
1<<PAGE_EXEC_SHIFT | |
p->global<<PAGE_GLOBAL_SHIFT |
); |
} |
static inline void set_pt_flags(pte_t *pt, index_t i, int flags) |
{ |
pte_t *p = &pt[i]; |
p->page_cache_disable = !(flags & PAGE_CACHEABLE); |
p->present = !(flags & PAGE_NOT_PRESENT); |
p->uaccessible = (flags & PAGE_USER) != 0; |
p->writeable = (flags & PAGE_WRITE) != 0; |
p->global = (flags & PAGE_GLOBAL) != 0; |
/* |
* Ensure that there is at least one bit set even if the present bit is cleared. |
*/ |
p->soft_valid = true; |
} |
extern void page_arch_init(void); |
extern void page_fault(int n, istate_t *istate); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/include/mm/asid.h |
---|
0,0 → 1,55 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
* @ingroup ia32xen_mm |
*/ |
/* |
* ia32xen has no hardware support for address space identifiers. |
* This file is provided to do nop-implementation of mm/asid.h |
* interface. |
*/ |
#ifndef KERN_ia32xen_ASID_H_ |
#define KERN_ia32xen_ASID_H_ |
typedef int asid_t; |
#define ASID_MAX_ARCH 3 |
#define asid_get() (ASID_START+1) |
#define asid_put(asid) |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/include/mm/tlb.h |
---|
0,0 → 1,44 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_TLB_H_ |
#define KERN_ia32xen_TLB_H_ |
#define tlb_arch_init() |
#define tlb_print() |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/include/mm/as.h |
---|
0,0 → 1,62 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_AS_H_ |
#define KERN_ia32xen_AS_H_ |
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0 |
#define KERNEL_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x80000000) |
#define KERNEL_ADDRESS_SPACE_END_ARCH ((unsigned long) 0xffffffff) |
#define USER_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x00000000) |
#define USER_ADDRESS_SPACE_END_ARCH ((unsigned long) 0x7fffffff) |
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1)) |
typedef struct { |
} as_arch_t; |
#define as_constructor_arch(as, flags) (as != as) |
#define as_destructor_arch(as) (as != as) |
#define as_create_arch(as, flags) (as != as) |
#define as_install_arch(as) |
#define as_deinstall_arch(as) |
#define as_invalidate_translation_cache(as, page, cnt) |
extern void as_arch_init(void); |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/include/drivers/xconsole.h |
---|
0,0 → 1,56 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_XCONSOLE_H_ |
#define KERN_ia32xen_XCONSOLE_H_ |
#include <arch/types.h> |
typedef struct { |
char in[1024]; |
char out[2048]; |
uint32_t in_cons; |
uint32_t in_prod; |
uint32_t out_cons; |
uint32_t out_prod; |
} xencons_t; |
extern xencons_t console_page; |
extern void xen_console_init(void); |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/include/interrupt.h |
---|
0,0 → 1,0 |
link ../../ia32/include/interrupt.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/fpu_context.h |
---|
0,0 → 1,0 |
link ../../ia32/include/fpu_context.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/byteorder.h |
---|
0,0 → 1,0 |
link ../../ia32/include/byteorder.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/cpuid.h |
---|
0,0 → 1,0 |
link ../../ia32/include/cpuid.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/elf.h |
---|
0,0 → 1,0 |
link ../../ia32/include/elf.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/bios |
---|
0,0 → 1,0 |
link ../../ia32/include/bios |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/memstr.h |
---|
0,0 → 1,0 |
link ../../ia32/include/memstr.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/arg.h |
---|
0,0 → 1,0 |
link ../../ia32/include/arg.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/smp |
---|
0,0 → 1,0 |
link ../../ia32/include/smp |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/ddi |
---|
0,0 → 1,0 |
link ../../ia32/include/ddi |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/atomic.h |
---|
0,0 → 1,0 |
link ../../ia32/include/atomic.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/arch.h |
---|
0,0 → 1,0 |
link ../../ia32/include/arch.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/proc |
---|
0,0 → 1,0 |
link ../../ia32/include/proc |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/faddr.h |
---|
0,0 → 1,0 |
link ../../ia32/include/faddr.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/debugger.h |
---|
0,0 → 1,0 |
link ../../ia32/include/debugger.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/context.h |
---|
0,0 → 1,0 |
link ../../ia32/include/context.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/debug.h |
---|
0,0 → 1,0 |
link ../../ia32/include/debug.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/barrier.h |
---|
0,0 → 1,0 |
link ../../ia32/include/barrier.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/include/cpu.h |
---|
0,0 → 1,0 |
link ../../ia32/include/cpu.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/src/xen32.c |
---|
0,0 → 1,213 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <arch.h> |
#include <main/main.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <align.h> |
#include <arch/pm.h> |
#include <arch/drivers/xconsole.h> |
#include <arch/mm/page.h> |
#include <arch/context.h> |
#include <config.h> |
#include <arch/interrupt.h> |
#include <arch/asm.h> |
#include <genarch/acpi/acpi.h> |
#include <arch/bios/bios.h> |
#include <arch/boot/boot.h> |
#include <arch/mm/memory_init.h> |
#include <interrupt.h> |
#include <arch/debugger.h> |
#include <proc/thread.h> |
#include <syscall/syscall.h> |
#include <console/console.h> |
start_info_t start_info; |
memzone_t meminfo; |
extern void xen_callback(void); |
extern void xen_failsafe_callback(void); |
void arch_pre_main(void) |
{ |
xen_vm_assist(VMASST_CMD_ENABLE, VMASST_TYPE_WRITABLE_PAGETABLES); |
pte_t pte; |
memsetb((uintptr_t) &pte, sizeof(pte), 0); |
pte.present = 1; |
pte.writeable = 1; |
pte.frame_address = ADDR2PFN((uintptr_t) start_info.shared_info); |
xen_update_va_mapping(&shared_info, pte, UVMF_INVLPG); |
pte.present = 1; |
pte.writeable = 1; |
pte.frame_address = start_info.console_mfn; |
xen_update_va_mapping(&console_page, pte, UVMF_INVLPG); |
xen_set_callbacks(XEN_CS, xen_callback, XEN_CS, xen_failsafe_callback); |
/* Create identity mapping */ |
meminfo.start = ADDR2PFN(ALIGN_UP(KA2PA(start_info.ptl0), PAGE_SIZE)) + start_info.pt_frames; |
meminfo.size = start_info.frames - meminfo.start; |
meminfo.reserved = 0; |
uintptr_t pa; |
index_t last_ptl0 = 0; |
for (pa = PFN2ADDR(meminfo.start); pa < PFN2ADDR(meminfo.start + meminfo.size); pa += FRAME_SIZE) { |
uintptr_t va = PA2KA(pa); |
if ((PTL0_INDEX(va) != last_ptl0) && (GET_PTL1_FLAGS(start_info.ptl0, PTL0_INDEX(va)) & PAGE_NOT_PRESENT)) { |
/* New page directory entry needed */ |
uintptr_t tpa = PFN2ADDR(meminfo.start + meminfo.reserved); |
uintptr_t tva = PA2KA(tpa); |
memsetb(tva, PAGE_SIZE, 0); |
pte_t *tptl3 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(tva))); |
SET_FRAME_FLAGS(tptl3, PTL3_INDEX(tva), PAGE_PRESENT); |
SET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(va), tpa); |
last_ptl0 = PTL0_INDEX(va); |
meminfo.reserved++; |
} |
pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(va))); |
SET_FRAME_ADDRESS(ptl3, PTL3_INDEX(va), pa); |
SET_FRAME_FLAGS(ptl3, PTL3_INDEX(va), PAGE_PRESENT | PAGE_WRITE); |
} |
/* Put initial stack safely in the mapped area */ |
stack_safe = PA2KA(PFN2ADDR(meminfo.start + meminfo.reserved)); |
} |
void arch_pre_mm_init(void) |
{ |
pm_init(); |
if (config.cpu_active == 1) { |
// bios_init(); |
exc_register(VECTOR_SYSCALL, "syscall", (iroutine) syscall); |
#ifdef CONFIG_SMP |
exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", |
(iroutine) tlb_shootdown_ipi); |
#endif /* CONFIG_SMP */ |
} |
} |
void arch_post_mm_init(void) |
{ |
if (config.cpu_active == 1) { |
/* video */ |
xen_console_init(); |
/* Enable debugger */ |
debugger_init(); |
/* Merge all memory zones to 1 big zone */ |
zone_merge_all(); |
} |
} |
void arch_post_cpu_init(void) |
{ |
} |
void arch_pre_smp_init(void) |
{ |
if (config.cpu_active == 1) { |
memory_print_map(); |
#ifdef CONFIG_SMP |
acpi_init(); |
#endif /* CONFIG_SMP */ |
} |
} |
void arch_post_smp_init(void) |
{ |
} |
void calibrate_delay_loop(void) |
{ |
// i8254_calibrate_delay_loop(); |
if (config.cpu_active == 1) { |
/* |
* This has to be done only on UP. |
* On SMP, i8254 is not used for time keeping and its interrupt pin remains masked. |
*/ |
// i8254_normal_operation(); |
} |
} |
/** Set thread-local-storage pointer |
* |
* TLS pointer is set in GS register. That means, the GS contains |
* selector, and the descriptor->base is the correct address. |
*/ |
unative_t sys_tls_set(unative_t addr) |
{ |
THREAD->arch.tls = addr; |
set_tls_desc(addr); |
return 0; |
} |
/** Acquire console back for kernel |
* |
*/ |
void arch_grab_console(void) |
{ |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/pm.c |
---|
0,0 → 1,214 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/pm.h> |
#include <config.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <arch/interrupt.h> |
#include <arch/asm.h> |
#include <arch/context.h> |
#include <panic.h> |
#include <arch/mm/page.h> |
#include <mm/slab.h> |
#include <memstr.h> |
#include <arch/boot/boot.h> |
#include <interrupt.h> |
/* |
* Early ia32xen configuration functions and data structures. |
*/ |
/* |
* We have no use for segmentation so we set up flat mode. In this |
* mode, we use, for each privilege level, two segments spanning the |
* whole memory. One is for code and one is for data. |
* |
* One is for GS register which holds pointer to the TLS thread |
* structure in it's base. |
*/ |
descriptor_t gdt[GDT_ITEMS] = { |
/* NULL descriptor */ |
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
/* KTEXT descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 }, |
/* KDATA descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 }, |
/* UTEXT descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }, |
/* UDATA descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }, |
/* TSS descriptor - set up will be completed later */ |
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
/* TLS descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }, |
}; |
static trap_info_t traps[IDT_ITEMS + 1]; |
static tss_t tss; |
tss_t *tss_p = NULL; |
/* gdtr is changed by kmp before next CPU is initialized */ |
ptr_16_32_t bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((uintptr_t) gdt) }; |
ptr_16_32_t gdtr = { .limit = sizeof(gdt), .base = (uintptr_t) gdt }; |
void gdt_setbase(descriptor_t *d, uintptr_t base) |
{ |
d->base_0_15 = base & 0xffff; |
d->base_16_23 = ((base) >> 16) & 0xff; |
d->base_24_31 = ((base) >> 24) & 0xff; |
} |
void gdt_setlimit(descriptor_t *d, uint32_t limit) |
{ |
d->limit_0_15 = limit & 0xffff; |
d->limit_16_19 = (limit >> 16) & 0xf; |
} |
void tss_initialize(tss_t *t) |
{ |
memsetb((uintptr_t) t, sizeof(struct tss), 0); |
} |
static void trap(void) |
{ |
} |
void traps_init(void) |
{ |
index_t i; |
for (i = 0; i < IDT_ITEMS; i++) { |
traps[i].vector = i; |
if (i == VECTOR_SYSCALL) |
traps[i].flags = 3; |
else |
traps[i].flags = 0; |
traps[i].cs = XEN_CS; |
traps[i].address = trap; |
exc_register(i, "undef", (iroutine) null_interrupt); |
} |
traps[IDT_ITEMS].vector = 0; |
traps[IDT_ITEMS].flags = 0; |
traps[IDT_ITEMS].cs = 0; |
traps[IDT_ITEMS].address = NULL; |
exc_register(13, "gp_fault", (iroutine) gp_fault); |
exc_register( 7, "nm_fault", (iroutine) nm_fault); |
exc_register(12, "ss_fault", (iroutine) ss_fault); |
exc_register(19, "simd_fp", (iroutine) simd_fp_exception); |
} |
/* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */ |
static void clean_IOPL_NT_flags(void) |
{ |
// __asm__ volatile ( |
// "pushfl\n" |
// "pop %%eax\n" |
// "and $0xffff8fff, %%eax\n" |
// "push %%eax\n" |
// "popfl\n" |
// : : : "eax" |
// ); |
} |
/* Clean AM(18) flag in CR0 register */ |
static void clean_AM_flag(void) |
{ |
// __asm__ volatile ( |
// "mov %%cr0, %%eax\n" |
// "and $0xfffbffff, %%eax\n" |
// "mov %%eax, %%cr0\n" |
// : : : "eax" |
// ); |
} |
void pm_init(void) |
{ |
descriptor_t *gdt_p = (descriptor_t *) gdtr.base; |
// gdtr_load(&gdtr); |
if (config.cpu_active == 1) { |
traps_init(); |
xen_set_trap_table(traps); |
/* |
* NOTE: bootstrap CPU has statically allocated TSS, because |
* the heap hasn't been initialized so far. |
*/ |
tss_p = &tss; |
} else { |
tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC); |
if (!tss_p) |
panic("could not allocate TSS\n"); |
} |
// tss_initialize(tss_p); |
gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL; |
gdt_p[TSS_DES].special = 1; |
gdt_p[TSS_DES].granularity = 0; |
gdt_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p); |
gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1); |
/* |
* As of this moment, the current CPU has its own GDT pointing |
* to its own TSS. We just need to load the TR register. |
*/ |
// tr_load(selector(TSS_DES)); |
clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels and clear NT flag. */ |
clean_AM_flag(); /* Disable alignment check */ |
} |
void set_tls_desc(uintptr_t tls) |
{ |
ptr_16_32_t cpugdtr; |
descriptor_t *gdt_p; |
gdtr_store(&cpugdtr); |
gdt_p = (descriptor_t *) cpugdtr.base; |
gdt_setbase(&gdt_p[TLS_DES], tls); |
/* Reload gdt register to update GS in CPU */ |
gdtr_load(&cpugdtr); |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/smp/mps.c |
---|
0,0 → 1,434 |
/* |
* Copyright (C) 2001-2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifdef CONFIG_SMP |
#include <config.h> |
#include <print.h> |
#include <debug.h> |
#include <arch/smp/mps.h> |
#include <arch/smp/apic.h> |
#include <arch/smp/smp.h> |
#include <func.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <cpu.h> |
#include <arch/asm.h> |
#include <arch/bios/bios.h> |
#include <mm/frame.h> |
/* |
* MultiProcessor Specification detection code. |
*/ |
#define FS_SIGNATURE 0x5f504d5f |
#define CT_SIGNATURE 0x504d4350 |
int mps_fs_check(uint8_t *base); |
int mps_ct_check(void); |
int configure_via_ct(void); |
int configure_via_default(uint8_t n); |
int ct_processor_entry(struct __processor_entry *pr); |
void ct_bus_entry(struct __bus_entry *bus); |
void ct_io_apic_entry(struct __io_apic_entry *ioa); |
void ct_io_intr_entry(struct __io_intr_entry *iointr); |
void ct_l_intr_entry(struct __l_intr_entry *lintr); |
void ct_extended_entries(void); |
static struct mps_fs *fs; |
static struct mps_ct *ct; |
struct __processor_entry *processor_entries = NULL; |
struct __bus_entry *bus_entries = NULL; |
struct __io_apic_entry *io_apic_entries = NULL; |
struct __io_intr_entry *io_intr_entries = NULL; |
struct __l_intr_entry *l_intr_entries = NULL; |
int processor_entry_cnt = 0; |
int bus_entry_cnt = 0; |
int io_apic_entry_cnt = 0; |
int io_intr_entry_cnt = 0; |
int l_intr_entry_cnt = 0; |
waitq_t ap_completion_wq; |
/* |
* Implementation of IA-32 SMP configuration interface. |
*/ |
static count_t get_cpu_count(void); |
static bool is_cpu_enabled(index_t i); |
static bool is_bsp(index_t i); |
static uint8_t get_cpu_apic_id(index_t i); |
static int mps_irq_to_pin(int irq); |
struct smp_config_operations mps_config_operations = { |
.cpu_count = get_cpu_count, |
.cpu_enabled = is_cpu_enabled, |
.cpu_bootstrap = is_bsp, |
.cpu_apic_id = get_cpu_apic_id, |
.irq_to_pin = mps_irq_to_pin |
}; |
count_t get_cpu_count(void) |
{ |
return processor_entry_cnt; |
} |
bool is_cpu_enabled(index_t i) |
{ |
ASSERT(i < processor_entry_cnt); |
return processor_entries[i].cpu_flags & 0x1; |
} |
bool is_bsp(index_t i) |
{ |
ASSERT(i < processor_entry_cnt); |
return processor_entries[i].cpu_flags & 0x2; |
} |
uint8_t get_cpu_apic_id(index_t i) |
{ |
ASSERT(i < processor_entry_cnt); |
return processor_entries[i].l_apic_id; |
} |
/* |
* Used to check the integrity of the MP Floating Structure. |
*/ |
int mps_fs_check(uint8_t *base) |
{ |
int i; |
uint8_t sum; |
for (i = 0, sum = 0; i < 16; i++) |
sum += base[i]; |
return !sum; |
} |
/* |
* Used to check the integrity of the MP Configuration Table. |
*/ |
int mps_ct_check(void) |
{ |
uint8_t *base = (uint8_t *) ct; |
uint8_t *ext = base + ct->base_table_length; |
uint8_t sum; |
int i; |
/* count the checksum for the base table */ |
for (i=0,sum=0; i < ct->base_table_length; i++) |
sum += base[i]; |
if (sum) |
return 0; |
/* count the checksum for the extended table */ |
for (i=0,sum=0; i < ct->ext_table_length; i++) |
sum += ext[i]; |
return sum == ct->ext_table_checksum; |
} |
void mps_init(void) |
{ |
uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xf0000) }; |
int i, j, length[2] = { 1024, 64*1024 }; |
/* |
* Find MP Floating Pointer Structure |
* 1a. search first 1K of EBDA |
* 1b. if EBDA is undefined, search last 1K of base memory |
* 2. search 64K starting at 0xf0000 |
*/ |
addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024); |
for (i = 0; i < 2; i++) { |
for (j = 0; j < length[i]; j += 16) { |
if (*((uint32_t *) &addr[i][j]) == FS_SIGNATURE && mps_fs_check(&addr[i][j])) { |
fs = (struct mps_fs *) &addr[i][j]; |
goto fs_found; |
} |
} |
} |
return; |
fs_found: |
printf("%p: MPS Floating Pointer Structure\n", fs); |
if (fs->config_type == 0 && fs->configuration_table) { |
if (fs->mpfib2 >> 7) { |
printf("%s: PIC mode not supported\n", __FUNCTION__); |
return; |
} |
ct = (struct mps_ct *)PA2KA((uintptr_t)fs->configuration_table); |
config.cpu_count = configure_via_ct(); |
} |
else |
config.cpu_count = configure_via_default(fs->config_type); |
return; |
} |
int configure_via_ct(void) |
{ |
uint8_t *cur; |
int i, cnt; |
if (ct->signature != CT_SIGNATURE) { |
printf("%s: bad ct->signature\n", __FUNCTION__); |
return 1; |
} |
if (!mps_ct_check()) { |
printf("%s: bad ct checksum\n", __FUNCTION__); |
return 1; |
} |
if (ct->oem_table) { |
printf("%s: ct->oem_table not supported\n", __FUNCTION__); |
return 1; |
} |
l_apic = (uint32_t *)(uintptr_t)ct->l_apic; |
cnt = 0; |
cur = &ct->base_table[0]; |
for (i=0; i < ct->entry_count; i++) { |
switch (*cur) { |
/* Processor entry */ |
case 0: |
processor_entries = processor_entries ? processor_entries : (struct __processor_entry *) cur; |
processor_entry_cnt++; |
cnt += ct_processor_entry((struct __processor_entry *) cur); |
cur += 20; |
break; |
/* Bus entry */ |
case 1: |
bus_entries = bus_entries ? bus_entries : (struct __bus_entry *) cur; |
bus_entry_cnt++; |
ct_bus_entry((struct __bus_entry *) cur); |
cur += 8; |
break; |
/* I/O Apic */ |
case 2: |
io_apic_entries = io_apic_entries ? io_apic_entries : (struct __io_apic_entry *) cur; |
io_apic_entry_cnt++; |
ct_io_apic_entry((struct __io_apic_entry *) cur); |
cur += 8; |
break; |
/* I/O Interrupt Assignment */ |
case 3: |
io_intr_entries = io_intr_entries ? io_intr_entries : (struct __io_intr_entry *) cur; |
io_intr_entry_cnt++; |
ct_io_intr_entry((struct __io_intr_entry *) cur); |
cur += 8; |
break; |
/* Local Interrupt Assignment */ |
case 4: |
l_intr_entries = l_intr_entries ? l_intr_entries : (struct __l_intr_entry *) cur; |
l_intr_entry_cnt++; |
ct_l_intr_entry((struct __l_intr_entry *) cur); |
cur += 8; |
break; |
default: |
/* |
* Something is wrong. Fallback to UP mode. |
*/ |
printf("%s: ct badness\n", __FUNCTION__); |
return 1; |
} |
} |
/* |
* Process extended entries. |
*/ |
ct_extended_entries(); |
return cnt; |
} |
int configure_via_default(uint8_t n) |
{ |
/* |
* Not yet implemented. |
*/ |
printf("%s: not supported\n", __FUNCTION__); |
return 1; |
} |
int ct_processor_entry(struct __processor_entry *pr) |
{ |
/* |
* Ignore processors which are not marked enabled. |
*/ |
if ((pr->cpu_flags & (1<<0)) == 0) |
return 0; |
apic_id_mask |= (1<<pr->l_apic_id); |
return 1; |
} |
void ct_bus_entry(struct __bus_entry *bus) |
{ |
#ifdef MPSCT_VERBOSE |
char buf[7]; |
memcpy((void *) buf, (void *) bus->bus_type, 6); |
buf[6] = 0; |
printf("bus%d: %s\n", bus->bus_id, buf); |
#endif |
} |
void ct_io_apic_entry(struct __io_apic_entry *ioa) |
{ |
static int io_apic_count = 0; |
/* this ioapic is marked unusable */ |
if ((ioa->io_apic_flags & 1) == 0) |
return; |
if (io_apic_count++ > 0) { |
/* |
* Multiple IO APIC's are currently not supported. |
*/ |
return; |
} |
io_apic = (uint32_t *)(uintptr_t)ioa->io_apic; |
} |
//#define MPSCT_VERBOSE |
void ct_io_intr_entry(struct __io_intr_entry *iointr) |
{ |
#ifdef MPSCT_VERBOSE |
switch (iointr->intr_type) { |
case 0: printf("INT"); break; |
case 1: printf("NMI"); break; |
case 2: printf("SMI"); break; |
case 3: printf("ExtINT"); break; |
} |
putchar(','); |
switch (iointr->poel&3) { |
case 0: printf("bus-like"); break; |
case 1: printf("active high"); break; |
case 2: printf("reserved"); break; |
case 3: printf("active low"); break; |
} |
putchar(','); |
switch ((iointr->poel>>2)&3) { |
case 0: printf("bus-like"); break; |
case 1: printf("edge-triggered"); break; |
case 2: printf("reserved"); break; |
case 3: printf("level-triggered"); break; |
} |
putchar(','); |
printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq); |
putchar(','); |
printf("io_apic%d,pin%d", iointr->dst_io_apic_id, iointr->dst_io_apic_pin); |
putchar('\n'); |
#endif |
} |
void ct_l_intr_entry(struct __l_intr_entry *lintr) |
{ |
#ifdef MPSCT_VERBOSE |
switch (lintr->intr_type) { |
case 0: printf("INT"); break; |
case 1: printf("NMI"); break; |
case 2: printf("SMI"); break; |
case 3: printf("ExtINT"); break; |
} |
putchar(','); |
switch (lintr->poel&3) { |
case 0: printf("bus-like"); break; |
case 1: printf("active high"); break; |
case 2: printf("reserved"); break; |
case 3: printf("active low"); break; |
} |
putchar(','); |
switch ((lintr->poel>>2)&3) { |
case 0: printf("bus-like"); break; |
case 1: printf("edge-triggered"); break; |
case 2: printf("reserved"); break; |
case 3: printf("level-triggered"); break; |
} |
putchar(','); |
printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq); |
putchar(','); |
printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin); |
putchar('\n'); |
#endif |
} |
void ct_extended_entries(void) |
{ |
uint8_t *ext = (uint8_t *) ct + ct->base_table_length; |
uint8_t *cur; |
for (cur = ext; cur < ext + ct->ext_table_length; cur += cur[CT_EXT_ENTRY_LEN]) { |
switch (cur[CT_EXT_ENTRY_TYPE]) { |
default: |
printf("%p: skipping MP Configuration Table extended entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]); |
break; |
} |
} |
} |
int mps_irq_to_pin(int irq) |
{ |
int i; |
for(i=0;i<io_intr_entry_cnt;i++) { |
if (io_intr_entries[i].src_bus_irq == irq && io_intr_entries[i].intr_type == 0) |
return io_intr_entries[i].dst_io_apic_pin; |
} |
return -1; |
} |
#endif /* CONFIG_SMP */ |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/smp/smp.c |
---|
0,0 → 1,175 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <smp/smp.h> |
#include <arch/smp/smp.h> |
#include <arch/smp/mps.h> |
#include <arch/smp/ap.h> |
#include <arch/boot/boot.h> |
#include <genarch/acpi/acpi.h> |
#include <genarch/acpi/madt.h> |
#include <config.h> |
#include <synch/waitq.h> |
#include <synch/synch.h> |
#include <arch/pm.h> |
#include <func.h> |
#include <panic.h> |
#include <debug.h> |
#include <arch/asm.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <mm/slab.h> |
#include <mm/as.h> |
#include <print.h> |
#include <memstr.h> |
#ifdef CONFIG_SMP |
static struct smp_config_operations *ops = NULL; |
void smp_init(void) |
{ |
uintptr_t l_apic_address, io_apic_address; |
if (acpi_madt) { |
acpi_madt_parse(); |
ops = &madt_config_operations; |
} |
if (config.cpu_count == 1) { |
mps_init(); |
ops = &mps_config_operations; |
} |
l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA); |
if (!l_apic_address) |
panic("cannot allocate address for l_apic\n"); |
io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA); |
if (!io_apic_address) |
panic("cannot allocate address for io_apic\n"); |
if (config.cpu_count > 1) { |
page_mapping_insert(AS_KERNEL, l_apic_address, (uintptr_t) l_apic, |
PAGE_NOT_CACHEABLE); |
page_mapping_insert(AS_KERNEL, io_apic_address, (uintptr_t) io_apic, |
PAGE_NOT_CACHEABLE); |
l_apic = (uint32_t *) l_apic_address; |
io_apic = (uint32_t *) io_apic_address; |
} |
} |
/* |
* Kernel thread for bringing up application processors. It becomes clear |
* that we need an arrangement like this (AP's being initialized by a kernel |
* thread), for a thread has its dedicated stack. (The stack used during the |
* BSP initialization (prior the very first call to scheduler()) will be used |
* as an initialization stack for each AP.) |
*/ |
void kmp(void *arg) |
{ |
int i; |
ASSERT(ops != NULL); |
waitq_initialize(&ap_completion_wq); |
/* |
* We need to access data in frame 0. |
* We boldly make use of kernel address space mapping. |
*/ |
/* |
* Save 0xa to address 0xf of the CMOS RAM. |
* BIOS will not do the POST after the INIT signal. |
*/ |
outb(0x70,0xf); |
outb(0x71,0xa); |
// pic_disable_irqs(0xffff); |
apic_init(); |
for (i = 0; i < ops->cpu_count(); i++) { |
struct descriptor *gdt_new; |
/* |
* Skip processors marked unusable. |
*/ |
if (!ops->cpu_enabled(i)) |
continue; |
/* |
* The bootstrap processor is already up. |
*/ |
if (ops->cpu_bootstrap(i)) |
continue; |
if (ops->cpu_apic_id(i) == l_apic_id()) { |
printf("%s: bad processor entry #%d, will not send IPI to myself\n", __FUNCTION__, i); |
continue; |
} |
/* |
* Prepare new GDT for CPU in question. |
*/ |
if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS*sizeof(struct descriptor), FRAME_ATOMIC))) |
panic("couldn't allocate memory for GDT\n"); |
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor)); |
memsetb((uintptr_t)(&gdt_new[TSS_DES]), sizeof(struct descriptor), 0); |
gdtr.base = (uintptr_t) gdt_new; |
if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) { |
/* |
* There may be just one AP being initialized at |
* the time. After it comes completely up, it is |
* supposed to wake us up. |
*/ |
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) |
printf("%s: waiting for cpu%d (APIC ID = %d) timed out\n", __FUNCTION__, config.cpu_active > i ? config.cpu_active : i, ops->cpu_apic_id(i)); |
} else |
printf("INIT IPI for l_apic%d failed\n", ops->cpu_apic_id(i)); |
} |
} |
int smp_irq_to_pin(int irq) |
{ |
ASSERT(ops != NULL); |
return ops->irq_to_pin(irq); |
} |
#endif /* CONFIG_SMP */ |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/smp/ipi.c |
---|
0,0 → 1,48 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifdef CONFIG_SMP |
#include <smp/ipi.h> |
#include <arch/smp/apic.h> |
void ipi_broadcast_arch(int ipi) |
{ |
(void) l_apic_broadcast_custom_ipi((uint8_t) ipi); |
} |
#endif /* CONFIG_SMP */ |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/smp/apic.c |
---|
0,0 → 1,580 |
/* |
* Copyright (C) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/types.h> |
#include <arch/smp/apic.h> |
#include <arch/smp/ap.h> |
#include <arch/smp/mps.h> |
#include <arch/boot/boot.h> |
#include <mm/page.h> |
#include <time/delay.h> |
#include <interrupt.h> |
#include <arch/interrupt.h> |
#include <print.h> |
#include <arch/asm.h> |
#include <arch.h> |
#ifdef CONFIG_SMP |
/* |
* Advanced Programmable Interrupt Controller for SMP systems. |
* Tested on: |
* Bochs 2.0.2 - Bochs 2.2.6 with 2-8 CPUs |
* Simics 2.0.28 - Simics 2.2.19 2-15 CPUs |
* VMware Workstation 5.5 with 2 CPUs |
* QEMU 0.8.0 with 2-15 CPUs |
* ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs |
* ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs |
* MSI K7D Master-L with 2x 2100MHz Athlon MP CPUs |
*/ |
/* |
* These variables either stay configured as initilalized, or are changed by |
* the MP configuration code. |
* |
* Pay special attention to the volatile keyword. Without it, gcc -O2 would |
* optimize the code too much and accesses to l_apic and io_apic, that must |
* always be 32-bit, would use byte oriented instructions. |
*/ |
volatile uint32_t *l_apic = (uint32_t *) 0xfee00000; |
volatile uint32_t *io_apic = (uint32_t *) 0xfec00000; |
uint32_t apic_id_mask = 0; |
static int apic_poll_errors(void); |
#ifdef LAPIC_VERBOSE |
static char *delmod_str[] = { |
"Fixed", |
"Lowest Priority", |
"SMI", |
"Reserved", |
"NMI", |
"INIT", |
"STARTUP", |
"ExtInt" |
}; |
static char *destmod_str[] = { |
"Physical", |
"Logical" |
}; |
static char *trigmod_str[] = { |
"Edge", |
"Level" |
}; |
static char *mask_str[] = { |
"Unmasked", |
"Masked" |
}; |
static char *delivs_str[] = { |
"Idle", |
"Send Pending" |
}; |
static char *tm_mode_str[] = { |
"One-shot", |
"Periodic" |
}; |
static char *intpol_str[] = { |
"Polarity High", |
"Polarity Low" |
}; |
#endif /* LAPIC_VERBOSE */ |
static void apic_spurious(int n, istate_t *istate); |
static void l_apic_timer_interrupt(int n, istate_t *istate); |
/** Initialize APIC on BSP. */ |
void apic_init(void) |
{ |
io_apic_id_t idreg; |
int i; |
exc_register(VECTOR_APIC_SPUR, "apic_spurious", (iroutine) apic_spurious); |
enable_irqs_function = io_apic_enable_irqs; |
disable_irqs_function = io_apic_disable_irqs; |
eoi_function = l_apic_eoi; |
/* |
* Configure interrupt routing. |
* IRQ 0 remains masked as the time signal is generated by l_apic's themselves. |
* Other interrupts will be forwarded to the lowest priority CPU. |
*/ |
io_apic_disable_irqs(0xffff); |
exc_register(VECTOR_CLK, "l_apic_timer", (iroutine) l_apic_timer_interrupt); |
for (i = 0; i < IRQ_COUNT; i++) { |
int pin; |
if ((pin = smp_irq_to_pin(i)) != -1) { |
io_apic_change_ioredtbl(pin, DEST_ALL, IVT_IRQBASE+i, LOPRI); |
} |
} |
/* |
* Ensure that io_apic has unique ID. |
*/ |
idreg.value = io_apic_read(IOAPICID); |
if ((1<<idreg.apic_id) & apic_id_mask) { /* see if IO APIC ID is used already */ |
for (i = 0; i < APIC_ID_COUNT; i++) { |
if (!((1<<i) & apic_id_mask)) { |
idreg.apic_id = i; |
io_apic_write(IOAPICID, idreg.value); |
break; |
} |
} |
} |
/* |
* Configure the BSP's lapic. |
*/ |
l_apic_init(); |
l_apic_debug(); |
} |
/** APIC spurious interrupt handler. |
* |
* @param n Interrupt vector. |
* @param istate Interrupted state. |
*/ |
void apic_spurious(int n, istate_t *istate) |
{ |
#ifdef CONFIG_DEBUG |
printf("cpu%d: APIC spurious interrupt\n", CPU->id); |
#endif |
} |
/** Poll for APIC errors. |
* |
* Examine Error Status Register and report all errors found. |
* |
* @return 0 on error, 1 on success. |
*/ |
int apic_poll_errors(void) |
{ |
esr_t esr; |
esr.value = l_apic[ESR]; |
if (esr.send_checksum_error) |
printf("Send Checksum Error\n"); |
if (esr.receive_checksum_error) |
printf("Receive Checksum Error\n"); |
if (esr.send_accept_error) |
printf("Send Accept Error\n"); |
if (esr.receive_accept_error) |
printf("Receive Accept Error\n"); |
if (esr.send_illegal_vector) |
printf("Send Illegal Vector\n"); |
if (esr.received_illegal_vector) |
printf("Received Illegal Vector\n"); |
if (esr.illegal_register_address) |
printf("Illegal Register Address\n"); |
return !esr.err_bitmap; |
} |
/** Send all CPUs excluding CPU IPI vector. |
* |
* @param vector Interrupt vector to be sent. |
* |
* @return 0 on failure, 1 on success. |
*/ |
int l_apic_broadcast_custom_ipi(uint8_t vector) |
{ |
icr_t icr; |
icr.lo = l_apic[ICRlo]; |
icr.delmod = DELMOD_FIXED; |
icr.destmod = DESTMOD_LOGIC; |
icr.level = LEVEL_ASSERT; |
icr.shorthand = SHORTHAND_ALL_EXCL; |
icr.trigger_mode = TRIGMOD_LEVEL; |
icr.vector = vector; |
l_apic[ICRlo] = icr.lo; |
icr.lo = l_apic[ICRlo]; |
if (icr.delivs == DELIVS_PENDING) { |
#ifdef CONFIG_DEBUG |
printf("IPI is pending.\n"); |
#endif |
} |
return apic_poll_errors(); |
} |
/** Universal Start-up Algorithm for bringing up the AP processors. |
* |
* @param apicid APIC ID of the processor to be brought up. |
* |
* @return 0 on failure, 1 on success. |
*/ |
int l_apic_send_init_ipi(uint8_t apicid) |
{ |
icr_t icr; |
int i; |
/* |
* Read the ICR register in and zero all non-reserved fields. |
*/ |
icr.lo = l_apic[ICRlo]; |
icr.hi = l_apic[ICRhi]; |
icr.delmod = DELMOD_INIT; |
icr.destmod = DESTMOD_PHYS; |
icr.level = LEVEL_ASSERT; |
icr.trigger_mode = TRIGMOD_LEVEL; |
icr.shorthand = SHORTHAND_NONE; |
icr.vector = 0; |
icr.dest = apicid; |
l_apic[ICRhi] = icr.hi; |
l_apic[ICRlo] = icr.lo; |
/* |
* According to MP Specification, 20us should be enough to |
* deliver the IPI. |
*/ |
delay(20); |
if (!apic_poll_errors()) |
return 0; |
icr.lo = l_apic[ICRlo]; |
if (icr.delivs == DELIVS_PENDING) { |
#ifdef CONFIG_DEBUG |
printf("IPI is pending.\n"); |
#endif |
} |
icr.delmod = DELMOD_INIT; |
icr.destmod = DESTMOD_PHYS; |
icr.level = LEVEL_DEASSERT; |
icr.shorthand = SHORTHAND_NONE; |
icr.trigger_mode = TRIGMOD_LEVEL; |
icr.vector = 0; |
l_apic[ICRlo] = icr.lo; |
/* |
* Wait 10ms as MP Specification specifies. |
*/ |
delay(10000); |
if (!is_82489DX_apic(l_apic[LAVR])) { |
/* |
* If this is not 82489DX-based l_apic we must send two STARTUP IPI's. |
*/ |
for (i = 0; i<2; i++) { |
icr.lo = l_apic[ICRlo]; |
icr.delmod = DELMOD_STARTUP; |
icr.destmod = DESTMOD_PHYS; |
icr.level = LEVEL_ASSERT; |
icr.shorthand = SHORTHAND_NONE; |
icr.trigger_mode = TRIGMOD_LEVEL; |
l_apic[ICRlo] = icr.lo; |
delay(200); |
} |
} |
return apic_poll_errors(); |
} |
/** Initialize Local APIC. */ |
void l_apic_init(void) |
{ |
lvt_error_t error; |
lvt_lint_t lint; |
tpr_t tpr; |
svr_t svr; |
icr_t icr; |
tdcr_t tdcr; |
lvt_tm_t tm; |
ldr_t ldr; |
dfr_t dfr; |
uint32_t t1, t2; |
/* Initialize LVT Error register. */ |
error.value = l_apic[LVT_Err]; |
error.masked = true; |
l_apic[LVT_Err] = error.value; |
/* Initialize LVT LINT0 register. */ |
lint.value = l_apic[LVT_LINT0]; |
lint.masked = true; |
l_apic[LVT_LINT0] = lint.value; |
/* Initialize LVT LINT1 register. */ |
lint.value = l_apic[LVT_LINT1]; |
lint.masked = true; |
l_apic[LVT_LINT1] = lint.value; |
/* Task Priority Register initialization. */ |
tpr.value = l_apic[TPR]; |
tpr.pri_sc = 0; |
tpr.pri = 0; |
l_apic[TPR] = tpr.value; |
/* Spurious-Interrupt Vector Register initialization. */ |
svr.value = l_apic[SVR]; |
svr.vector = VECTOR_APIC_SPUR; |
svr.lapic_enabled = true; |
svr.focus_checking = true; |
l_apic[SVR] = svr.value; |
if (CPU->arch.family >= 6) |
enable_l_apic_in_msr(); |
/* Interrupt Command Register initialization. */ |
icr.lo = l_apic[ICRlo]; |
icr.delmod = DELMOD_INIT; |
icr.destmod = DESTMOD_PHYS; |
icr.level = LEVEL_DEASSERT; |
icr.shorthand = SHORTHAND_ALL_INCL; |
icr.trigger_mode = TRIGMOD_LEVEL; |
l_apic[ICRlo] = icr.lo; |
/* Timer Divide Configuration Register initialization. */ |
tdcr.value = l_apic[TDCR]; |
tdcr.div_value = DIVIDE_1; |
l_apic[TDCR] = tdcr.value; |
/* Program local timer. */ |
tm.value = l_apic[LVT_Tm]; |
tm.vector = VECTOR_CLK; |
tm.mode = TIMER_PERIODIC; |
tm.masked = false; |
l_apic[LVT_Tm] = tm.value; |
/* |
* Measure and configure the timer to generate timer |
* interrupt with period 1s/HZ seconds. |
*/ |
t1 = l_apic[CCRT]; |
l_apic[ICRT] = 0xffffffff; |
while (l_apic[CCRT] == t1) |
; |
t1 = l_apic[CCRT]; |
delay(1000000/HZ); |
t2 = l_apic[CCRT]; |
l_apic[ICRT] = t1-t2; |
/* Program Logical Destination Register. */ |
ldr.value = l_apic[LDR]; |
if (CPU->id < sizeof(CPU->id)*8) /* size in bits */ |
ldr.id = (1<<CPU->id); |
l_apic[LDR] = ldr.value; |
/* Program Destination Format Register for Flat mode. */ |
dfr.value = l_apic[DFR]; |
dfr.model = MODEL_FLAT; |
l_apic[DFR] = dfr.value; |
} |
/** Local APIC End of Interrupt. */ |
void l_apic_eoi(void) |
{ |
l_apic[EOI] = 0; |
} |
/** Dump content of Local APIC registers. */ |
void l_apic_debug(void) |
{ |
#ifdef LAPIC_VERBOSE |
lvt_tm_t tm; |
lvt_lint_t lint; |
lvt_error_t error; |
printf("LVT on cpu%d, LAPIC ID: %d\n", CPU->id, l_apic_id()); |
tm.value = l_apic[LVT_Tm]; |
printf("LVT Tm: vector=%hhd, %s, %s, %s\n", tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], tm_mode_str[tm.mode]); |
lint.value = l_apic[LVT_LINT0]; |
printf("LVT LINT0: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]); |
lint.value = l_apic[LVT_LINT1]; |
printf("LVT LINT1: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]); |
error.value = l_apic[LVT_Err]; |
printf("LVT Err: vector=%hhd, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]); |
#endif |
} |
/** Local APIC Timer Interrupt. |
* |
* @param n Interrupt vector number. |
* @param istate Interrupted state. |
*/ |
void l_apic_timer_interrupt(int n, istate_t *istate) |
{ |
l_apic_eoi(); |
clock(); |
} |
/** Get Local APIC ID. |
* |
* @return Local APIC ID. |
*/ |
uint8_t l_apic_id(void) |
{ |
l_apic_id_t idreg; |
idreg.value = l_apic[L_APIC_ID]; |
return idreg.apic_id; |
} |
/** Read from IO APIC register. |
* |
* @param address IO APIC register address. |
* |
* @return Content of the addressed IO APIC register. |
*/ |
uint32_t io_apic_read(uint8_t address) |
{ |
io_regsel_t regsel; |
regsel.value = io_apic[IOREGSEL]; |
regsel.reg_addr = address; |
io_apic[IOREGSEL] = regsel.value; |
return io_apic[IOWIN]; |
} |
/** Write to IO APIC register. |
* |
* @param address IO APIC register address. |
* @param x Content to be written to the addressed IO APIC register. |
*/ |
void io_apic_write(uint8_t address, uint32_t x) |
{ |
io_regsel_t regsel; |
regsel.value = io_apic[IOREGSEL]; |
regsel.reg_addr = address; |
io_apic[IOREGSEL] = regsel.value; |
io_apic[IOWIN] = x; |
} |
/** Change some attributes of one item in I/O Redirection Table. |
* |
* @param pin IO APIC pin number. |
* @param dest Interrupt destination address. |
* @param v Interrupt vector to trigger. |
* @param flags Flags. |
*/ |
void io_apic_change_ioredtbl(int pin, int dest, uint8_t v, int flags) |
{ |
io_redirection_reg_t reg; |
int dlvr = DELMOD_FIXED; |
if (flags & LOPRI) |
dlvr = DELMOD_LOWPRI; |
reg.lo = io_apic_read(IOREDTBL + pin*2); |
reg.hi = io_apic_read(IOREDTBL + pin*2 + 1); |
reg.dest = dest; |
reg.destmod = DESTMOD_LOGIC; |
reg.trigger_mode = TRIGMOD_EDGE; |
reg.intpol = POLARITY_HIGH; |
reg.delmod = dlvr; |
reg.intvec = v; |
io_apic_write(IOREDTBL + pin*2, reg.lo); |
io_apic_write(IOREDTBL + pin*2 + 1, reg.hi); |
} |
/** Mask IRQs in IO APIC. |
* |
* @param irqmask Bitmask of IRQs to be masked (0 = do not mask, 1 = mask). |
*/ |
void io_apic_disable_irqs(uint16_t irqmask) |
{ |
io_redirection_reg_t reg; |
int i, pin; |
for (i=0;i<16;i++) { |
if (irqmask & (1<<i)) { |
/* |
* Mask the signal input in IO APIC if there is a |
* mapping for the respective IRQ number. |
*/ |
pin = smp_irq_to_pin(i); |
if (pin != -1) { |
reg.lo = io_apic_read(IOREDTBL + pin*2); |
reg.masked = true; |
io_apic_write(IOREDTBL + pin*2, reg.lo); |
} |
} |
} |
} |
/** Unmask IRQs in IO APIC. |
* |
* @param irqmask Bitmask of IRQs to be unmasked (0 = do not unmask, 1 = unmask). |
*/ |
void io_apic_enable_irqs(uint16_t irqmask) |
{ |
int i, pin; |
io_redirection_reg_t reg; |
for (i=0;i<16;i++) { |
if (irqmask & (1<<i)) { |
/* |
* Unmask the signal input in IO APIC if there is a |
* mapping for the respective IRQ number. |
*/ |
pin = smp_irq_to_pin(i); |
if (pin != -1) { |
reg.lo = io_apic_read(IOREDTBL + pin*2); |
reg.masked = false; |
io_apic_write(IOREDTBL + pin*2, reg.lo); |
} |
} |
} |
} |
#endif /* CONFIG_SMP */ |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/proc/scheduler.c |
---|
0,0 → 1,81 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_proc |
* @{ |
*/ |
/** @file |
*/ |
#include <proc/scheduler.h> |
#include <cpu.h> |
#include <proc/task.h> |
#include <proc/thread.h> |
#include <arch.h> |
#include <arch/context.h> /* SP_DELTA */ |
#include <arch/debugger.h> |
#include <arch/pm.h> |
#include <arch/asm.h> |
#include <arch/ddi/ddi.h> |
/** Perform ia32 specific tasks needed before the new task is run. |
* |
* Interrupts are disabled. |
*/ |
void before_task_runs_arch(void) |
{ |
// io_perm_bitmap_install(); |
} |
/** Perform ia32 specific tasks needed before the new thread is scheduled. |
* |
* THREAD is locked and interrupts are disabled. |
*/ |
void before_thread_runs_arch(void) |
{ |
CPU->arch.tss->esp0 = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA]; |
CPU->arch.tss->ss0 = selector(KDATA_DES); |
/* Set up TLS in GS register */ |
// set_tls_desc(THREAD->arch.tls); |
#ifdef CONFIG_DEBUG_AS_WATCHPOINT |
/* Set watchpoint on AS to ensure that nobody sets it to zero */ |
if (CPU->id < BKPOINTS_MAX) |
breakpoint_add(&((the_t *) THREAD->kstack)->as, |
BKPOINT_WRITE | BKPOINT_CHECK_ZERO, |
CPU->id); |
#endif |
} |
void after_thread_ran_arch(void) |
{ |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/proc/task.c |
---|
0,0 → 1,61 |
/* |
* Copyright (C) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_proc |
* @{ |
*/ |
/** @file |
*/ |
#include <proc/task.h> |
#include <arch/types.h> |
#include <adt/bitmap.h> |
#include <mm/slab.h> |
/** Perform ia32 specific task initialization. |
* |
* @param t Task to be initialized. |
*/ |
void task_create_arch(task_t *t) |
{ |
t->arch.iomapver = 0; |
bitmap_initialize(&t->arch.iomap, NULL, 0); |
} |
/** Perform ia32 specific task destruction. |
* |
* @param t Task to be initialized. |
*/ |
void task_destroy_arch(task_t *t) |
{ |
if (t->arch.iomap.map) |
free(t->arch.iomap.map); |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/proc/thread.c |
---|
0,0 → 1,47 |
/* |
* Copyright (C) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_proc |
* @{ |
*/ |
/** @file |
*/ |
#include <proc/thread.h> |
/** Perform ia32xen specific thread initialization. |
* |
* @param t Thread to be initialized. |
*/ |
void thread_create_arch(thread_t *t) |
{ |
t->arch.tls = 0; |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/mm/tlb.c |
---|
0,0 → 1,75 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
* @ingroup ia32xen_mm |
*/ |
#include <mm/tlb.h> |
#include <arch/mm/asid.h> |
#include <arch/asm.h> |
#include <arch/types.h> |
#include <arch/hypercall.h> |
/** Invalidate all entries in TLB. */ |
void tlb_invalidate_all(void) |
{ |
mmuext_op_t mmu_ext; |
mmu_ext.cmd = MMUEXT_TLB_FLUSH_LOCAL; |
xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF); |
} |
/** Invalidate all entries in TLB that belong to specified address space. |
* |
* @param asid This parameter is ignored as the architecture doesn't support it. |
*/ |
void tlb_invalidate_asid(asid_t asid) |
{ |
tlb_invalidate_all(); |
} |
/** Invalidate TLB entries for specified page range belonging to specified address space. |
* |
* @param asid This parameter is ignored as the architecture doesn't support it. |
* @param page Address of the first page whose entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
int i; |
for (i = 0; i < cnt; i++) |
invlpg(page + i * PAGE_SIZE); |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/mm/as.c |
---|
0,0 → 1,46 |
/* |
* Copyright (C) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
* @ingroup ia32xen_mm |
*/ |
#include <arch/mm/as.h> |
#include <genarch/mm/as_pt.h> |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
as_operations = &as_pt_operations; |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/mm/frame.c |
---|
0,0 → 1,49 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
* @ingroup ia32xen_mm |
*/ |
#include <mm/frame.h> |
#include <config.h> |
void frame_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
/* The only memory zone */ |
zone_create(meminfo.start, meminfo.size, meminfo.start + meminfo.reserved, 0); |
frame_mark_unavailable(meminfo.start, meminfo.reserved); |
} |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/mm/memory_init.c |
---|
0,0 → 1,52 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/mm/memory_init.h> |
#include <arch/mm/page.h> |
#include <arch/boot/boot.h> |
#include <print.h> |
#include <mm/frame.h> |
size_t get_memory_size(void) |
{ |
return start_info.frames * PAGE_SIZE; |
} |
void memory_print_map(void) |
{ |
printf("Xen memory: %p size: %d (reserved %d)\n", PFN2ADDR(meminfo.start), PFN2ADDR(meminfo.size - meminfo.reserved), PFN2ADDR(meminfo.reserved)); |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/mm/page.c |
---|
0,0 → 1,86 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/mm/page.h> |
#include <genarch/mm/page_pt.h> |
#include <arch/mm/frame.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <mm/as.h> |
#include <arch/types.h> |
#include <align.h> |
#include <config.h> |
#include <func.h> |
#include <arch/interrupt.h> |
#include <arch/asm.h> |
#include <debug.h> |
#include <memstr.h> |
#include <print.h> |
#include <interrupt.h> |
void page_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
page_mapping_operations = &pt_mapping_operations; |
AS_KERNEL->page_table = (pte_t *) KA2PA(start_info.ptl0); |
} else |
SET_PTL0_ADDRESS_ARCH(AS_KERNEL->page_table); |
} |
void page_fault(int n, istate_t *istate) |
{ |
uintptr_t page; |
pf_access_t access; |
page = read_cr2(); |
if (istate->error_word & PFERR_CODE_RSVD) |
panic("Reserved bit set in page directory.\n"); |
if (istate->error_word & PFERR_CODE_RW) |
access = PF_ACCESS_WRITE; |
else |
access = PF_ACCESS_READ; |
if (as_page_fault(page, access, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault: %#x", page); |
PRINT_INFO_ERRCODE(istate); |
printf("page fault address: %#x\n", page); |
panic("page fault\n"); |
} |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/userspace.c |
---|
0,0 → 1,89 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <userspace.h> |
#include <arch/pm.h> |
#include <arch/types.h> |
#include <arch.h> |
#include <proc/uarg.h> |
#include <mm/as.h> |
/** Enter userspace |
* |
* Change CPU protection level to 3, enter userspace. |
* |
*/ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
uint32_t ipl = interrupts_disable(); |
asm volatile ( |
/* |
* Clear nested task flag. |
*/ |
"pushfl\n" |
"pop %%eax\n" |
"and $0xffffbfff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
/* Set up GS register (TLS) */ |
"movl %6, %%gs\n" |
"pushl %0\n" |
"pushl %1\n" |
"pushl %2\n" |
"pushl %3\n" |
"pushl %4\n" |
"movl %5, %%eax\n" |
"iret\n" |
: |
: "i" (selector(UDATA_DES) | PL_USER), |
"r" (kernel_uarg->uspace_stack + THREAD_STACK_SIZE), |
"r" (ipl), |
"i" (selector(UTEXT_DES) | PL_USER), |
"r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg), |
"r" (selector(TLS_DES)) |
: "eax" |
); |
/* Unreachable */ |
for(;;) |
; |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/interrupt.c |
---|
0,0 → 1,192 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_interrupt |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/interrupt.h> |
#include <syscall/syscall.h> |
#include <print.h> |
#include <debug.h> |
#include <panic.h> |
#include <func.h> |
#include <cpu.h> |
#include <arch/asm.h> |
#include <mm/tlb.h> |
#include <mm/as.h> |
#include <arch.h> |
#include <symtab.h> |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <synch/spinlock.h> |
#include <arch/ddi/ddi.h> |
#include <ipc/sysipc.h> |
#include <interrupt.h> |
/* |
* Interrupt and exception dispatching. |
*/ |
void (* disable_irqs_function)(uint16_t irqmask) = NULL; |
void (* enable_irqs_function)(uint16_t irqmask) = NULL; |
void (* eoi_function)(void) = NULL; |
void PRINT_INFO_ERRCODE(istate_t *istate) |
{ |
char *symbol = get_symtab_entry(istate->eip); |
if (!symbol) |
symbol = ""; |
if (CPU) |
printf("----------------EXCEPTION OCCURED (cpu%d)----------------\n", CPU->id); |
else |
printf("----------------EXCEPTION OCCURED----------------\n"); |
printf("%%eip: %#x (%s)\n",istate->eip,symbol); |
printf("ERROR_WORD=%#x\n", istate->error_word); |
printf("%%cs=%#x,flags=%#x\n", istate->cs, istate->eflags); |
printf("%%eax=%#x, %%ecx=%#x, %%edx=%#x, %%esp=%#x\n", istate->eax,istate->ecx,istate->edx,&istate->stack[0]); |
#ifdef CONFIG_DEBUG_ALLREGS |
printf("%%esi=%#x, %%edi=%#x, %%ebp=%#x, %%ebx=%#x\n", istate->esi,istate->edi,istate->ebp,istate->ebx); |
#endif |
printf("stack: %#x, %#x, %#x, %#x\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]); |
printf(" %#x, %#x, %#x, %#x\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]); |
} |
void null_interrupt(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "unserviced interrupt: %d", n); |
PRINT_INFO_ERRCODE(istate); |
panic("unserviced interrupt: %d\n", n); |
} |
/** General Protection Fault. */ |
void gp_fault(int n, istate_t *istate) |
{ |
if (TASK) { |
count_t ver; |
spinlock_lock(&TASK->lock); |
ver = TASK->arch.iomapver; |
spinlock_unlock(&TASK->lock); |
if (CPU->arch.iomapver_copy != ver) { |
/* |
* This fault can be caused by an early access |
* to I/O port because of an out-dated |
* I/O Permission bitmap installed on CPU. |
* Install the fresh copy and restart |
* the instruction. |
*/ |
io_perm_bitmap_install(); |
return; |
} |
fault_if_from_uspace(istate, "general protection fault"); |
} |
PRINT_INFO_ERRCODE(istate); |
panic("general protection fault\n"); |
} |
void ss_fault(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "stack fault"); |
PRINT_INFO_ERRCODE(istate); |
panic("stack fault\n"); |
} |
void simd_fp_exception(int n, istate_t *istate) |
{ |
uint32_t mxcsr; |
asm |
( |
"stmxcsr %0;\n" |
:"=m"(mxcsr) |
); |
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx", |
(unative_t)mxcsr); |
PRINT_INFO_ERRCODE(istate); |
printf("MXCSR: %#zx\n",(unative_t)(mxcsr)); |
panic("SIMD FP exception(19)\n"); |
} |
void nm_fault(int n, istate_t *istate) |
{ |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "fpu fault"); |
panic("fpu fault"); |
#endif |
} |
void syscall(int n, istate_t *istate) |
{ |
panic("Obsolete syscall handler."); |
} |
void tlb_shootdown_ipi(int n, istate_t *istate) |
{ |
trap_virtual_eoi(); |
tlb_shootdown_ipi_recv(); |
} |
void trap_virtual_enable_irqs(uint16_t irqmask) |
{ |
if (enable_irqs_function) |
enable_irqs_function(irqmask); |
else |
panic("no enable_irqs_function\n"); |
} |
void trap_virtual_disable_irqs(uint16_t irqmask) |
{ |
if (disable_irqs_function) |
disable_irqs_function(irqmask); |
else |
panic("no disable_irqs_function\n"); |
} |
void trap_virtual_eoi(void) |
{ |
if (eoi_function) |
eoi_function(); |
else |
panic("no eoi_function\n"); |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/drivers/xconsole.c |
---|
0,0 → 1,86 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** |
* @file |
* @brief ia32xen console driver. |
*/ |
#include <arch/drivers/xconsole.h> |
#include <putchar.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <arch/hypercall.h> |
#define MASK_INDEX(index, ring) ((index) & (sizeof(ring) - 1)) |
static bool asynchronous = false; |
static void xen_putchar(chardev_t *d, const char ch); |
chardev_t xen_console; |
static chardev_operations_t xen_ops = { |
.write = xen_putchar |
}; |
void xen_console_init(void) |
{ |
chardev_initialize("xen_out", &xen_console, &xen_ops); |
stdout = &xen_console; |
if (!(start_info.flags & SIF_INITDOMAIN)) |
asynchronous = true; |
} |
void xen_putchar(chardev_t *d, const char ch) |
{ |
if (asynchronous) { |
uint32_t cons = console_page.out_cons; |
uint32_t prod = console_page.out_prod; |
memory_barrier(); |
if ((prod - cons) > sizeof(console_page.out)) |
return; |
if (ch == '\n') |
console_page.out[MASK_INDEX(prod++, console_page.out)] = '\r'; |
console_page.out[MASK_INDEX(prod++, console_page.out)] = ch; |
write_barrier(); |
console_page.out_prod = prod; |
xen_notify_remote(start_info.console_evtchn); |
} else |
xen_console_io(CONSOLE_IO_WRITE, 1, &ch); |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32xen/src/boot/boot.S |
---|
0,0 → 1,83 |
# |
# Copyright (C) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/boot/boot.h> |
#include <arch/mm/page.h> |
#include <arch/pm.h> |
.section __xen_guest |
.ascii "GUEST_OS=HelenOS," |
.ascii "XEN_VER=xen-3.0," |
.ascii "HYPERCALL_PAGE=0x0000," |
.ascii "LOADER=generic," |
.ascii "FEATURES=writable_page_tables" |
.byte 0 |
.text |
.code32 |
.align 4 |
.global kernel_image_start |
kernel_image_start: |
# copy start_info (esi initialized by Xen) |
movl $start_info, %edi |
movl $START_INFO_SIZE >> 2, %ecx |
cld |
rep movsb |
# switch to temporal kernel stack |
movl $kernel_stack, %esp |
call arch_pre_main |
call main_bsp # never returns |
cli |
hlt |
kernel_stack_bottom: |
.space TEMP_STACK_SIZE |
kernel_stack: |
.section K_TEXT_START, "aw", @progbits |
.global hypercall_page |
.org 0 |
hypercall_page: |
.space PAGE_SIZE |
.global shared_info |
.org 0x1000 |
shared_info: |
.space PAGE_SIZE |
.global console_page |
.org 0x2000 |
console_page: |
.space PAGE_SIZE |
/trunk/kernel/arch/ia32xen/src/asm.S |
---|
0,0 → 1,124 |
# |
# Copyright (C) 2001-2004 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## very low and hardware-level functions |
# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word |
# and 1 means interrupt with error word |
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00 |
.text |
.global xen_callback |
.global xen_failsafe_callback |
.global enable_l_apic_in_msr |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace |
.global memcpy_to_uspace_failover_address |
xen_callback: |
iret |
xen_failsafe_callback: |
iret |
#define MEMCPY_DST 4 |
#define MEMCPY_SRC 8 |
#define MEMCPY_SIZE 12 |
/** Copy memory to/from userspace. |
* |
* This is almost conventional memcpy(). |
* The difference is that there is a failover part |
* to where control is returned from a page fault |
* if the page fault occurs during copy_from_uspace() |
* or copy_to_uspace(). |
* |
* @param MEMCPY_DST(%esp) Destination address. |
* @param MEMCPY_SRC(%esp) Source address. |
* @param MEMCPY_SIZE(%esp) Size. |
* |
* @return MEMCPY_SRC(%esp) on success and 0 on failure. |
*/ |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
movl %edi, %edx /* save %edi */ |
movl %esi, %eax /* save %esi */ |
movl MEMCPY_SIZE(%esp), %ecx |
shrl $2, %ecx /* size / 4 */ |
movl MEMCPY_DST(%esp), %edi |
movl MEMCPY_SRC(%esp), %esi |
rep movsl /* copy as much as possible word by word */ |
movl MEMCPY_SIZE(%esp), %ecx |
andl $3, %ecx /* size % 4 */ |
jz 0f |
rep movsb /* copy the rest byte by byte */ |
0: |
movl %edx, %edi |
movl %eax, %esi |
movl MEMCPY_SRC(%esp), %eax /* MEMCPY_SRC(%esp), success */ |
ret |
/* |
* We got here from as_page_fault() after the memory operations |
* above had caused a page fault. |
*/ |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
movl %edx, %edi |
movl %eax, %esi |
xorl %eax, %eax /* return 0, failure */ |
ret |
## Enable local APIC |
# |
# Enable local APIC in MSR. |
# |
enable_l_apic_in_msr: |
push %eax |
movl $0x1b, %ecx |
rdmsr |
orl $(1<<11),%eax |
orl $(0xfee00000),%eax |
wrmsr |
pop %eax |
ret |
/trunk/kernel/arch/ia32xen/src/fpu_context.c |
---|
0,0 → 1,0 |
link ../../ia32/src/fpu_context.c |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/src/context.s |
---|
0,0 → 1,0 |
link ../../ia32/src/context.s |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/src/debug |
---|
0,0 → 1,0 |
link ../../ia32/src/debug |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/src/cpu |
---|
0,0 → 1,0 |
link ../../ia32/src/cpu |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/src/bios |
---|
0,0 → 1,0 |
link ../../ia32/src/bios |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/src/delay.s |
---|
0,0 → 1,0 |
link ../../ia32/src/delay.s |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/src/ddi |
---|
0,0 → 1,0 |
link ../../ia32/src/ddi |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/src/debugger.c |
---|
0,0 → 1,0 |
link ../../ia32/src/debugger.c |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/src/atomic.S |
---|
0,0 → 1,0 |
link ../../ia32/src/atomic.S |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/trunk/kernel/arch/ia32xen/Makefile.inc |
---|
0,0 → 1,122 |
# |
# Copyright (C) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## Toolchain configuration |
# |
BFD_NAME = elf32-i386 |
BFD_ARCH = i386 |
BFD = elf32-i386 |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/i686/bin |
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__ |
## Accepted CPUs |
# |
ifeq ($(MACHINE),athlon-xp) |
CFLAGS += -march=athlon-xp -mmmx -msse -m3dnow |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_SMP = n |
CONFIG_HT = n |
endif |
ifeq ($(MACHINE),athlon-mp) |
CFLAGS += -march=athlon-mp -mmmx -msse -m3dnow |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_HT = n |
endif |
ifeq ($(MACHINE),pentium3) |
CFLAGS += -march=pentium3 -mmmx -msse |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_HT = n |
endif |
ifeq ($(MACHINE),prescott) |
CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2 -msse3 |
DEFS += -DCONFIG_FENCES_P4 |
endif |
ifeq ($(MACHINE),pentium4) |
CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2 |
DEFS += -DCONFIG_FENCES_P4 |
endif |
## Own configuration directives |
# |
CONFIG_ACPI = y |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Accepted configuration directives |
# |
ifeq ($(CONFIG_SMP),y) |
DEFS += -DCONFIG_SMP |
endif |
ifeq ($(CONFIG_HT),y) |
DEFS += -DCONFIG_HT |
endif |
## Compile with support for software integer division. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(ARCH)/src/context.s \ |
arch/$(ARCH)/src/debug/panic.s \ |
arch/$(ARCH)/src/delay.s \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/proc/task.c \ |
arch/$(ARCH)/src/proc/thread.c \ |
arch/$(ARCH)/src/bios/bios.c \ |
arch/$(ARCH)/src/smp/apic.c \ |
arch/$(ARCH)/src/smp/mps.c \ |
arch/$(ARCH)/src/smp/smp.c \ |
arch/$(ARCH)/src/atomic.S \ |
arch/$(ARCH)/src/smp/ipi.c \ |
arch/$(ARCH)/src/xen32.c \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/pm.c \ |
arch/$(ARCH)/src/userspace.c \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/memory_init.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/xconsole.c \ |
arch/$(ARCH)/src/boot/boot.S \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/debugger.c |
/trunk/kernel/arch/ia32xen/_link.ld.in |
---|
0,0 → 1,41 |
/** Xen32 linker script |
*/ |
#define __ASM__ |
#include <arch/boot/boot.h> |
#include <arch/mm/page.h> |
ENTRY(kernel_image_start) |
SECTIONS { |
__xen_guest : { |
*(__xen_guest); |
} |
.image PA2KA(BOOT_OFFSET): { |
ktext_start = .; |
*(K_TEXT_START); |
*(.text); |
ktext_end = .; |
kdata_start = .; |
*(.data); /* initialized data */ |
*(.rodata*); /* string literals */ |
*(COMMON); /* global variables */ |
hardcoded_load_address = .; |
LONG(PA2KA(0)); |
hardcoded_ktext_size = .; |
LONG(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
LONG(kdata_end - kdata_start); |
symbol_table = .; |
*(symtab.*); /* Symbol table, must be LAST symbol! */ |
*(.bss); /* uninitialized static variables */ |
kdata_end = .; |
} |
/DISCARD/ : { |
*(.note.GNU-stack); |
*(.comment); |
} |
} |