Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 3342 → Rev 3343

/branches/sparc/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_DST(%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_DST(%esp), %eax /* MEMCPY_DST(%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
/branches/sparc/kernel/arch/ia32xen/src/userspace.c
0,0 → 1,93
/*
* 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"
 
/* %ebx is defined to hold pcb_ptr - set it to 0 */
"xorl %%ebx, %%ebx\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(;;)
;
}
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/src/ia32xen.c
0,0 → 1,218
/*
* 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 <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 <interrupt.h>
#include <arch/debugger.h>
#include <proc/thread.h>
#include <syscall/syscall.h>
#include <console/console.h>
#include <ddi/irq.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)
{
pte_t pte;
memsetb(&pte, sizeof(pte), 0);
pte.present = 1;
pte.writeable = 1;
pte.frame_address = ADDR2PFN((uintptr_t) start_info.shared_info);
ASSERT(xen_update_va_mapping(&shared_info, pte, UVMF_INVLPG) == 0);
if (!(start_info.flags & SIF_INITDOMAIN)) {
/* Map console frame */
pte.present = 1;
pte.writeable = 1;
pte.frame_address = start_info.console.domU.mfn;
ASSERT(xen_update_va_mapping(&console_page, pte, UVMF_INVLPG) == 0);
} else
start_info.console.domU.evtchn = 0;
ASSERT(xen_set_callbacks(XEN_CS, xen_callback, XEN_CS, xen_failsafe_callback) == 0);
/* 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((void *) tva, PAGE_SIZE, 0);
pte_t *tptl3 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(tva)));
SET_FRAME_ADDRESS(tptl3, PTL3_INDEX(tva), 0);
SET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(va), tpa);
SET_FRAME_ADDRESS(tptl3, PTL3_INDEX(tva), 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) {
interrupt_init();
// bios_init();
}
}
 
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
/* Initialize IRQ routing */
irq_init(IRQ_COUNT, IRQ_COUNT);
/* 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) {
#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)
{
}
 
void arch_reboot(void)
{
// TODO
while (1);
}
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/src/pm.c
0,0 → 1,206
/*
* 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 <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 <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(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;
}
traps[IDT_ITEMS].vector = 0;
traps[IDT_ITEMS].flags = 0;
traps[IDT_ITEMS].cs = 0;
traps[IDT_ITEMS].address = NULL;
}
 
 
/* 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);
}
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/src/smp/smp.c
0,0 → 1,174
/*
* 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 <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_WRITE);
page_mapping_insert(AS_KERNEL, io_apic_address, (uintptr_t) io_apic,
PAGE_NOT_CACHEABLE | PAGE_WRITE);
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)
{
unsigned 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(&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(unsigned int irq)
{
ASSERT(ops != NULL);
return ops->irq_to_pin(irq);
}
 
#endif /* CONFIG_SMP */
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/src/smp/mps.c
0,0 → 1,433
/*
* 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 <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;
 
unsigned int processor_entry_cnt = 0;
unsigned int bus_entry_cnt = 0;
unsigned int io_apic_entry_cnt = 0;
unsigned int io_intr_entry_cnt = 0;
unsigned 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(unsigned 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", __func__);
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", __func__);
return 1;
}
if (!mps_ct_check()) {
printf("%s: bad ct checksum\n", __func__);
return 1;
}
if (ct->oem_table) {
printf("%s: ct->oem_table not supported\n", __func__);
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", __func__);
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", __func__);
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(unsigned int irq)
{
unsigned 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 */
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/src/smp/apic.c
0,0 → 1,581
/*
* 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 <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;
unsigned 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(uint8_t pin, uint8_t 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;
unsigned int i;
int 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)
{
unsigned int i;
int 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 */
 
/** @}
*/
/branches/sparc/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 */
 
/** @}
*/
/branches/sparc/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
/branches/sparc/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)
{
unsigned int i;
 
for (i = 0; i < cnt; i++)
invlpg(page + i * PAGE_SIZE);
}
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/src/mm/frame.c
0,0 → 1,57
/*
* 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 physmem_print(void)
{
printf("Base Size Reserved\n");
printf("---------- ---------- ---------\n");
printf("%#10x %#10x %#10x\n", PFN2ADDR(meminfo.start),
PFN2ADDR(meminfo.size), PFN2ADDR(meminfo.reserved));
}
 
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);
}
}
 
/** @}
*/
/branches/sparc/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->genarch.page_table = (pte_t *) KA2PA(start_info.ptl0);
} else
SET_PTL0_ADDRESS_ARCH(AS_KERNEL->genarch.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);
decode_istate(istate);
printf("page fault address: %#x\n", page);
panic("page fault\n");
}
}
 
/** @}
*/
/branches/sparc/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/page_pt.h>
 
/** Architecture dependent address space init. */
void as_arch_init(void)
{
as_operations = &as_pt_operations;
}
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/src/interrupt.c
0,0 → 1,248
/*
* 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>
#include <ddi/irq.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 decode_istate(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]);
}
 
static void trap_virtual_eoi(void)
{
if (eoi_function)
eoi_function();
else
panic("no eoi_function\n");
 
}
 
static void null_interrupt(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "unserviced interrupt: %d", n);
 
decode_istate(istate);
panic("unserviced interrupt: %d\n", n);
}
 
/** General Protection Fault. */
static 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");
}
 
decode_istate(istate);
panic("general protection fault\n");
}
 
static void ss_fault(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "stack fault");
 
decode_istate(istate);
panic("stack fault\n");
}
 
static 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);
 
decode_istate(istate);
printf("MXCSR: %#zx\n",(unative_t)(mxcsr));
panic("SIMD FP exception(19)\n");
}
 
static 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
}
 
#ifdef CONFIG_SMP
static void tlb_shootdown_ipi(int n, istate_t *istate)
{
trap_virtual_eoi();
tlb_shootdown_ipi_recv();
}
#endif
 
/** Handler of IRQ exceptions */
static void irq_interrupt(int n, istate_t *istate)
{
ASSERT(n >= IVT_IRQBASE);
int inum = n - IVT_IRQBASE;
bool ack = false;
ASSERT(inum < IRQ_COUNT);
ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
irq_t *irq = irq_dispatch_and_lock(inum);
if (irq) {
/*
* The IRQ handler was found.
*/
if (irq->preack) {
/* Send EOI before processing the interrupt */
trap_virtual_eoi();
ack = true;
}
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
/*
* Spurious interrupt.
*/
#ifdef CONFIG_DEBUG
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum);
#endif
}
if (!ack)
trap_virtual_eoi();
}
 
void interrupt_init(void)
{
int i;
for (i = 0; i < IVT_ITEMS; i++)
exc_register(i, "null", (iroutine) null_interrupt);
for (i = 0; i < IRQ_COUNT; i++) {
if ((i != IRQ_PIC_SPUR) && (i != IRQ_PIC1))
exc_register(IVT_IRQBASE + i, "irq", (iroutine) irq_interrupt);
}
exc_register(7, "nm_fault", (iroutine) nm_fault);
exc_register(12, "ss_fault", (iroutine) ss_fault);
exc_register(13, "gp_fault", (iroutine) gp_fault);
exc_register(19, "simd_fp", (iroutine) simd_fp_exception);
#ifdef CONFIG_SMP
exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", (iroutine) tlb_shootdown_ipi);
#endif
}
 
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");
}
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/src/boot/boot.S
0,0 → 1,102
#
# 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/mm/page.h>
#include <arch/hypercall.h>
 
#define ELFNOTE(name, type, desctype, descval) \
.section .note.name; \
.align 4; \
.long 2f - 1f; \
.long 4f - 3f; \
.long type; \
1:.asciz #name; \
2:.align 4; \
3:desctype descval; \
4:.align 4
 
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "HelenOS")
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, RELEASE)
ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0")
ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .long, PA2KA(BOOT_OFFSET))
ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long, 0)
ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long, kernel_image_start)
ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long, hypercall_page)
ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "auto_translated_physmap|supervisor_mode_kernel")
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "no")
ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")
 
.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
 
# Xen 3.0.3 ELF loader is somehow buggy
# thus this workaround
.global dummy_fill
dummy_fill:
.space (1024 * 1024)
/branches/sparc/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)
{
}
 
/** @}
*/
/branches/sparc/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);
}
 
/** @}
*/
/branches/sparc/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;
}
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/src/drivers/xconsole.c
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.
*/
 
/** @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 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;
}
 
void xen_putchar(chardev_t *d, const char ch)
{
if (start_info.console.domU.evtchn != 0) {
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.domU.evtchn);
} else
xen_console_io(CONSOLE_IO_WRITE, 1, &ch);
}
 
/** @}
*/
/branches/sparc/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
/branches/sparc/kernel/arch/ia32xen/src/debug
0,0 → 1,0
link ../../ia32/src/debug
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/sparc/kernel/arch/ia32xen/src/cpu
0,0 → 1,0
link ../../ia32/src/cpu
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/sparc/kernel/arch/ia32xen/src/bios
0,0 → 1,0
link ../../ia32/src/bios
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/sparc/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
/branches/sparc/kernel/arch/ia32xen/src/ddi
0,0 → 1,0
link ../../ia32/src/ddi
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/sparc/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
/branches/sparc/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
/branches/sparc/kernel/arch/ia32xen/include/mm/page.h
0,0 → 1,257
/*
* 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.
*/
 
/* Number of entries in each level. */
#define PTL0_ENTRIES_ARCH 1024
#define PTL1_ENTRIES_ARCH 0
#define PTL2_ENTRIES_ARCH 0
#define PTL3_ENTRIES_ARCH 1024
 
/* Page table size for each level. */
#define PTL0_SIZE_ARCH ONE_FRAME
#define PTL1_SIZE_ARCH 0
#define PTL2_SIZE_ARCH 0
#define PTL3_SIZE_ARCH ONE_FRAME
 
/* Macros calculating indices into page tables in each level. */
#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)
 
/* Get PTE address accessors for each level. */
#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))
 
/* Set PTE address accessors for each level. */
#define SET_PTL0_ADDRESS_ARCH(ptl0) \
{ \
mmuext_op_t mmu_ext; \
\
mmu_ext.cmd = MMUEXT_NEW_BASEPTR; \
mmu_ext.mfn = ADDR2PFN(PA2MA(ptl0)); \
ASSERT(xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF) == 0); \
}
 
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
{ \
mmuext_op_t mmu_ext; \
\
mmu_ext.cmd = MMUEXT_PIN_L1_TABLE; \
mmu_ext.mfn = ADDR2PFN(PA2MA(a)); \
ASSERT(xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF) == 0); \
\
mmu_update_t update; \
\
update.ptr = PA2MA(KA2PA(&((pte_t *) (ptl0))[(i)])); \
update.val = PA2MA(a); \
ASSERT(xen_mmu_update(&update, 1, NULL, DOMID_SELF) == 0); \
}
 
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
{ \
mmu_update_t update; \
\
update.ptr = PA2MA(KA2PA(&((pte_t *) (ptl3))[(i)])); \
update.val = PA2MA(a); \
ASSERT(xen_mmu_update(&update, 1, NULL, DOMID_SELF) == 0); \
}
 
/* Get PTE flags accessors for each level. */
#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))
 
/* Set PTE flags accessors for each level. */
#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))
 
/* Query macros for the last level. */
#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/mm.h>
#include <arch/hypercall.h>
#include <arch/interrupt.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)
 
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;
mmu_update_t update;
update.ptr = PA2MA(KA2PA(&(pt[i])));
update.pte = p;
xen_mmu_update(&update, 1, NULL, DOMID_SELF);
}
 
extern void page_arch_init(void);
extern void page_fault(int n, istate_t *istate);
 
#endif /* __ASM__ */
 
#endif /* KERNEL */
 
#endif
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/include/mm/frame.h
0,0 → 1,57
/*
* 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__
 
#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);
extern void physmem_print(void);
 
#endif /* __ASM__ */
#endif /* KERNEL */
 
#endif
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/include/mm/as.h
0,0 → 1,64
/*
* 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;
 
#include <genarch/mm/as_pt.h>
 
#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
 
/** @}
*/
/branches/sparc/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
 
/** @}
*/
/branches/sparc/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
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/include/types.h
0,0 → 1,83
/*
* 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
#define false 0
#define true 1
 
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 size_t;
typedef uint32_t count_t;
typedef uint32_t index_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;
 
/** Page Table Entry. */
typedef struct {
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)) pte_t;
 
#endif
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/include/context_offset.h
0,0 → 1,0
link ../../ia32/include/context_offset.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/sparc/kernel/arch/ia32xen/include/pm.h
0,0 → 1,159
/*
* 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 <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
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/include/hypercall.h
0,0 → 1,381
/*
* 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_
 
#ifndef __ASM__
# include <arch/types.h>
# include <macros.h>
#endif
 
#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
 
#define XEN_ELFNOTE_INFO 0
#define XEN_ELFNOTE_ENTRY 1
#define XEN_ELFNOTE_HYPERCALL_PAGE 2
#define XEN_ELFNOTE_VIRT_BASE 3
#define XEN_ELFNOTE_PADDR_OFFSET 4
#define XEN_ELFNOTE_XEN_VERSION 5
#define XEN_ELFNOTE_GUEST_OS 6
#define XEN_ELFNOTE_GUEST_VERSION 7
#define XEN_ELFNOTE_LOADER 8
#define XEN_ELFNOTE_PAE_MODE 9
#define XEN_ELFNOTE_FEATURES 10
#define XEN_ELFNOTE_BSD_SYMTAB 11
 
#define mp_map ((pfn_t *) XEN_VIRT_START)
 
#define SIF_PRIVILEGED (1 << 0) /**< Privileged domain */
#define SIF_INITDOMAIN (1 << 1) /**< Iinitial control domain */
 
#define XEN_CONSOLE_VGA 0x03
#define XEN_CONSOLE_VESA 0x23
 
#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_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 */
 
 
#define DOMID_SELF (0x7FF0U)
#define DOMID_IO (0x7FF1U)
 
#ifndef __ASM__
 
typedef uint16_t domid_t;
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 */
union {
struct {
pfn_t mfn; /**< Console page (machine page) */
evtchn_t evtchn; /**< Event channel for console messages */
} domU;
struct {
uint32_t info_off; /**< Offset of console_info struct */
uint32_t info_size; /**< Size of console_info struct from start */
} dom0;
} console;
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 {
uint8_t video_type;
 
union {
struct {
uint16_t font_height;
uint16_t cursor_x;
uint16_t cursor_y;
uint16_t rows;
uint16_t columns;
} vga;
 
struct {
uint16_t width;
uint16_t height;
uint16_t bytes_per_line;
uint16_t bits_per_pixel;
uint32_t lfb_base;
uint32_t lfb_size;
uint8_t red_pos;
uint8_t red_size;
uint8_t green_pos;
uint8_t green_size;
uint8_t blue_pos;
uint8_t blue_size;
uint8_t rsvd_pos;
uint8_t rsvd_size;
} vesa_lfb;
} info;
} console_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;
 
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 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_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
 
#endif
/branches/sparc/kernel/arch/ia32xen/include/asm.h
0,0 → 1,272
/*
* 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;
}
 
/** 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
 
/** @}
*/
/branches/sparc/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
 
/** @}
*/
/branches/sparc/kernel/arch/ia32xen/include/cycle.h
0,0 → 1,0
link ../../ia32/include/cycle.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/sparc/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
/branches/sparc/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
/branches/sparc/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
/branches/sparc/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
/branches/sparc/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
/branches/sparc/kernel/arch/ia32xen/include/bios
0,0 → 1,0
link ../../ia32/include/bios
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/sparc/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
/branches/sparc/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
/branches/sparc/kernel/arch/ia32xen/include/smp
0,0 → 1,0
link ../../ia32/include/smp
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/sparc/kernel/arch/ia32xen/include/ddi
0,0 → 1,0
link ../../ia32/include/ddi
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/sparc/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
/branches/sparc/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
/branches/sparc/kernel/arch/ia32xen/include/proc
0,0 → 1,0
link ../../ia32/include/proc
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/sparc/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
/branches/sparc/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
/branches/sparc/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
/branches/sparc/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
/branches/sparc/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
/branches/sparc/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
/branches/sparc/kernel/arch/ia32xen/Makefile.inc
0,0 → 1,140
#
# 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
 
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__
 
CMN1 = -m32
GCC_CFLAGS += $(CMN1)
ICC_CFLAGS += $(CMN1)
SUNCC_CFLAGS += $(CMN1)
 
## Accepted CPUs
#
 
ifeq ($(MACHINE),athlon-xp)
CMN2 = -march=athlon-xp -mmmx -msse -m3dnow
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += -xarch=ssea
DEFS += -DCONFIG_FENCES_P3
CONFIG_SMP = n
CONFIG_HT = n
endif
ifeq ($(MACHINE),athlon-mp)
CMN2 = -march=athlon-mp -mmmx -msse -m3dnow
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += -xarch=ssea
DEFS += -DCONFIG_FENCES_P3
CONFIG_HT = n
endif
ifeq ($(MACHINE),pentium3)
CMN2 = -march=pentium3 -mmmx -msse
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += -xarch=sse
DEFS += -DCONFIG_FENCES_P3
CONFIG_HT = n
endif
ifeq ($(MACHINE),core)
CMN2 = -march=prescott -mfpmath=sse -mmmx -msse -msse2 -msse3
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += -xarch=sse3
DEFS += -DCONFIG_FENCES_P4
endif
ifeq ($(MACHINE),pentium4)
GCC_CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2
ICC_CFLAGS += -march=pentium4
SUNCC_CFLAGS += -xarch=sse2
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/ia32xen.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/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
/branches/sparc/kernel/arch/ia32xen/_link.ld.in
0,0 → 1,45
/** ia32xen linker script
*/
 
#include <arch/hypercall.h>
#include <arch/mm/page.h>
 
ENTRY(kernel_image_start)
 
PHDRS {
image PT_LOAD FLAGS(7); /* RWE */
note PT_NOTE FLAGS(4); /* R__ */
}
 
SECTIONS {
.image PA2KA(BOOT_OFFSET): AT (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 = .;
} :image
.notes : {
*(.note.Xen);
} :note
 
/DISCARD/ : {
*(.note.GNU-stack);
*(.comment);
}
}